Merge "Revert "MidiScope: Add a new sample"" into mnc-preview-docs
diff --git a/common/src/java/com/example/android/common/midi/EventScheduler.java b/common/src/java/com/example/android/common/midi/EventScheduler.java
deleted file mode 100644
index 37c0140..0000000
--- a/common/src/java/com/example/android/common/midi/EventScheduler.java
+++ /dev/null
@@ -1,243 +0,0 @@
-/*
- * Copyright (C) 2015 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.example.android.common.midi;
-
-import java.util.SortedMap;
-import java.util.TreeMap;
-
-/**
- * Store SchedulableEvents in a timestamped buffer.
- * Events may be written in any order.
- * Events will be read in sorted order.
- * Events with the same timestamp will be read in the order they were added.
- *
- * Only one Thread can write into the buffer.
- * And only one Thread can read from the buffer.
- */
-public class EventScheduler {
- private static final long NANOS_PER_MILLI = 1000000;
-
- private final Object lock = new Object();
- private SortedMap<Long, FastEventQueue> mEventBuffer;
- // This does not have to be guarded. It is only set by the writing thread.
- // If the reader sees a null right before being set then that is OK.
- private FastEventQueue mEventPool = null;
- private static final int MAX_POOL_SIZE = 200;
-
- public EventScheduler() {
- mEventBuffer = new TreeMap<Long, FastEventQueue>();
- }
-
- // If we keep at least one node in the list then it can be atomic
- // and non-blocking.
- private class FastEventQueue {
- // One thread takes from the beginning of the list.
- volatile SchedulableEvent mFirst;
- // A second thread returns events to the end of the list.
- volatile SchedulableEvent mLast;
- volatile long mEventsAdded;
- volatile long mEventsRemoved;
-
- FastEventQueue(SchedulableEvent event) {
- mFirst = event;
- mLast = mFirst;
- mEventsAdded = 1; // Always created with one event added. Never empty.
- mEventsRemoved = 0; // None removed yet.
- }
-
- int size() {
- return (int)(mEventsAdded - mEventsRemoved);
- }
-
- /**
- * Do not call this unless there is more than one event
- * in the list.
- * @return first event in the list
- */
- public SchedulableEvent remove() {
- // Take first event.
- mEventsRemoved++;
- SchedulableEvent event = mFirst;
- mFirst = event.mNext;
- return event;
- }
-
- /**
- * @param event
- */
- public void add(SchedulableEvent event) {
- event.mNext = null;
- mLast.mNext = event;
- mLast = event;
- mEventsAdded++;
- }
- }
-
- /**
- * Base class for events that can be stored in the EventScheduler.
- */
- public static class SchedulableEvent {
- private long mTimestamp;
- private SchedulableEvent mNext = null;
-
- /**
- * @param timestamp
- */
- public SchedulableEvent(long timestamp) {
- mTimestamp = timestamp;
- }
-
- /**
- * @return timestamp
- */
- public long getTimestamp() {
- return mTimestamp;
- }
-
- /**
- * The timestamp should not be modified when the event is in the
- * scheduling buffer.
- */
- public void setTimestamp(long timestamp) {
- mTimestamp = timestamp;
- }
- }
-
- /**
- * Get an event from the pool.
- * Always leave at least one event in the pool.
- * @return event or null
- */
- public SchedulableEvent removeEventfromPool() {
- SchedulableEvent event = null;
- if (mEventPool != null && (mEventPool.size() > 1)) {
- event = mEventPool.remove();
- }
- return event;
- }
-
- /**
- * Return events to a pool so they can be reused.
- *
- * @param event
- */
- public void addEventToPool(SchedulableEvent event) {
- if (mEventPool == null) {
- mEventPool = new FastEventQueue(event);
- // If we already have enough items in the pool then just
- // drop the event. This prevents unbounded memory leaks.
- } else if (mEventPool.size() < MAX_POOL_SIZE) {
- mEventPool.add(event);
- }
- }
-
- /**
- * Add an event to the scheduler. Events with the same time will be
- * processed in order.
- *
- * @param event
- */
- public void add(SchedulableEvent event) {
- synchronized (lock) {
- FastEventQueue list = mEventBuffer.get(event.getTimestamp());
- if (list == null) {
- long lowestTime = mEventBuffer.isEmpty() ? Long.MAX_VALUE
- : mEventBuffer.firstKey();
- list = new FastEventQueue(event);
- mEventBuffer.put(event.getTimestamp(), list);
- // If the event we added is earlier than the previous earliest
- // event then notify any threads waiting for the next event.
- if (event.getTimestamp() < lowestTime) {
- lock.notify();
- }
- } else {
- list.add(event);
- }
- }
- }
-
- // Caller must synchronize on lock before calling.
- private SchedulableEvent removeNextEventLocked(long lowestTime) {
- SchedulableEvent event;
- FastEventQueue list = mEventBuffer.get(lowestTime);
- // Remove list from tree if this is the last node.
- if ((list.size() == 1)) {
- mEventBuffer.remove(lowestTime);
- }
- event = list.remove();
- return event;
- }
-
- /**
- * Check to see if any scheduled events are ready to be processed.
- *
- * @param timestamp
- * @return next event or null if none ready
- */
- public SchedulableEvent getNextEvent(long time) {
- SchedulableEvent event = null;
- synchronized (lock) {
- if (!mEventBuffer.isEmpty()) {
- long lowestTime = mEventBuffer.firstKey();
- // Is it time for this list to be processed?
- if (lowestTime <= time) {
- event = removeNextEventLocked(lowestTime);
- }
- }
- }
- // Log.i(TAG, "getNextEvent: event = " + event);
- return event;
- }
-
- /**
- * Return the next available event or wait until there is an event ready to
- * be processed. This method assumes that the timestamps are in nanoseconds
- * and that the current time is System.nanoTime().
- *
- * @return event
- * @throws InterruptedException
- */
- public SchedulableEvent waitNextEvent() throws InterruptedException {
- SchedulableEvent event = null;
- while (true) {
- long millisToWait = Integer.MAX_VALUE;
- synchronized (lock) {
- if (!mEventBuffer.isEmpty()) {
- long now = System.nanoTime();
- long lowestTime = mEventBuffer.firstKey();
- // Is it time for the earliest list to be processed?
- if (lowestTime <= now) {
- event = removeNextEventLocked(lowestTime);
- break;
- } else {
- // Figure out how long to sleep until next event.
- long nanosToWait = lowestTime - now;
- // Add 1 millisecond so we don't wake up before it is
- // ready.
- millisToWait = 1 + (nanosToWait / NANOS_PER_MILLI);
- // Clip 64-bit value to 32-bit max.
- if (millisToWait > Integer.MAX_VALUE) {
- millisToWait = Integer.MAX_VALUE;
- }
- }
- }
- lock.wait((int) millisToWait);
- }
- }
- return event;
- }
-}
diff --git a/common/src/java/com/example/android/common/midi/MidiConstants.java b/common/src/java/com/example/android/common/midi/MidiConstants.java
deleted file mode 100644
index 38c25d5..0000000
--- a/common/src/java/com/example/android/common/midi/MidiConstants.java
+++ /dev/null
@@ -1,102 +0,0 @@
-/*
- * Copyright (C) 2015 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.example.android.common.midi;
-
-/**
- * MIDI related constants and static methods.
- * These values are defined in the MIDI Standard 1.0
- * available from the MIDI Manufacturers Association.
- */
-public class MidiConstants {
- protected final static String TAG = "MidiTools";
- public static final byte STATUS_COMMAND_MASK = (byte) 0xF0;
- public static final byte STATUS_CHANNEL_MASK = (byte) 0x0F;
-
- // Channel voice messages.
- public static final byte STATUS_NOTE_OFF = (byte) 0x80;
- public static final byte STATUS_NOTE_ON = (byte) 0x90;
- public static final byte STATUS_POLYPHONIC_AFTERTOUCH = (byte) 0xA0;
- public static final byte STATUS_CONTROL_CHANGE = (byte) 0xB0;
- public static final byte STATUS_PROGRAM_CHANGE = (byte) 0xC0;
- public static final byte STATUS_CHANNEL_PRESSURE = (byte) 0xD0;
- public static final byte STATUS_PITCH_BEND = (byte) 0xE0;
-
- // System Common Messages.
- public static final byte STATUS_SYSTEM_EXCLUSIVE = (byte) 0xF0;
- public static final byte STATUS_MIDI_TIME_CODE = (byte) 0xF1;
- public static final byte STATUS_SONG_POSITION = (byte) 0xF2;
- public static final byte STATUS_SONG_SELECT = (byte) 0xF3;
- public static final byte STATUS_TUNE_REQUEST = (byte) 0xF6;
- public static final byte STATUS_END_SYSEX = (byte) 0xF7;
-
- // System Real-Time Messages
- public static final byte STATUS_TIMING_CLOCK = (byte) 0xF8;
- public static final byte STATUS_START = (byte) 0xFA;
- public static final byte STATUS_CONTINUE = (byte) 0xFB;
- public static final byte STATUS_STOP = (byte) 0xFC;
- public static final byte STATUS_ACTIVE_SENSING = (byte) 0xFE;
- public static final byte STATUS_RESET = (byte) 0xFF;
-
- /** Number of bytes in a message nc from 8c to Ec */
- public final static int CHANNEL_BYTE_LENGTHS[] = { 3, 3, 3, 3, 2, 2, 3 };
-
- /** Number of bytes in a message Fn from F0 to FF */
- public final static int SYSTEM_BYTE_LENGTHS[] = { 1, 2, 3, 2, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1 };
-
- /**
- * MIDI messages, except for SysEx, are 1,2 or 3 bytes long.
- * You can tell how long a MIDI message is from the first status byte.
- * Do not call this for SysEx, which has variable length.
- * @param statusByte
- * @return number of bytes in a complete message, zero if data byte passed
- */
- public static int getBytesPerMessage(byte statusByte) {
- // Java bytes are signed so we need to mask off the high bits
- // to get a value between 0 and 255.
- int statusInt = statusByte & 0xFF;
- if (statusInt >= 0xF0) {
- // System messages use low nibble for size.
- return SYSTEM_BYTE_LENGTHS[statusInt & 0x0F];
- } else if(statusInt >= 0x80) {
- // Channel voice messages use high nibble for size.
- return CHANNEL_BYTE_LENGTHS[(statusInt >> 4) - 8];
- } else {
- return 0; // data byte
- }
- }
-
- /**
- * @param msg
- * @param offset
- * @param count
- * @return true if the entire message is ActiveSensing commands
- */
- public static boolean isAllActiveSensing(byte[] msg, int offset,
- int count) {
- // Count bytes that are not active sensing.
- int goodBytes = 0;
- for (int i = 0; i < count; i++) {
- byte b = msg[offset + i];
- if (b != MidiConstants.STATUS_ACTIVE_SENSING) {
- goodBytes++;
- }
- }
- return (goodBytes == 0);
- }
-
-}
diff --git a/common/src/java/com/example/android/common/midi/MidiDispatcher.java b/common/src/java/com/example/android/common/midi/MidiDispatcher.java
deleted file mode 100644
index b7f1fe1..0000000
--- a/common/src/java/com/example/android/common/midi/MidiDispatcher.java
+++ /dev/null
@@ -1,95 +0,0 @@
-/*
- * Copyright (C) 2015 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.example.android.common.midi;
-
-import android.media.midi.MidiReceiver;
-import android.media.midi.MidiSender;
-
-import java.io.IOException;
-import java.util.concurrent.CopyOnWriteArrayList;
-
-/**
- * Utility class for dispatching MIDI data to a list of {@link MidiReceiver}s.
- * This class subclasses {@link MidiReceiver} and dispatches any data it receives
- * to its receiver list. Any receivers that throw an exception upon receiving data will
- * be automatically removed from the receiver list, but no IOException will be returned
- * from the dispatcher's {@link MidiReceiver#onReceive} in that case.
- */
-public final class MidiDispatcher extends MidiReceiver {
-
- private final CopyOnWriteArrayList<MidiReceiver> mReceivers
- = new CopyOnWriteArrayList<MidiReceiver>();
-
- private final MidiSender mSender = new MidiSender() {
- /**
- * Called to connect a {@link MidiReceiver} to the sender
- *
- * @param receiver the receiver to connect
- */
- @Override
- public void onConnect(MidiReceiver receiver) {
- mReceivers.add(receiver);
- }
-
- /**
- * Called to disconnect a {@link MidiReceiver} from the sender
- *
- * @param receiver the receiver to disconnect
- */
- @Override
- public void onDisconnect(MidiReceiver receiver) {
- mReceivers.remove(receiver);
- }
- };
-
- /**
- * Returns the number of {@link MidiReceiver}s this dispatcher contains.
- * @return the number of receivers
- */
- public int getReceiverCount() {
- return mReceivers.size();
- }
-
- /**
- * Returns a {@link MidiSender} which is used to add and remove
- * {@link MidiReceiver}s
- * to the dispatcher's receiver list.
- * @return the dispatcher's MidiSender
- */
- public MidiSender getSender() {
- return mSender;
- }
-
- @Override
- public void onSend(byte[] msg, int offset, int count, long timestamp) throws IOException {
- for (MidiReceiver receiver : mReceivers) {
- try {
- receiver.send(msg, offset, count, timestamp);
- } catch (IOException e) {
- // if the receiver fails we remove the receiver but do not propagate the exception
- mReceivers.remove(receiver);
- }
- }
- }
-
- @Override
- public void flush() throws IOException {
- for (MidiReceiver receiver : mReceivers) {
- receiver.flush();
- }
- }
-}
diff --git a/common/src/java/com/example/android/common/midi/MidiEventScheduler.java b/common/src/java/com/example/android/common/midi/MidiEventScheduler.java
deleted file mode 100644
index 513d393..0000000
--- a/common/src/java/com/example/android/common/midi/MidiEventScheduler.java
+++ /dev/null
@@ -1,119 +0,0 @@
-/*
- * Copyright (C) 2015 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.example.android.common.midi;
-
-import android.media.midi.MidiReceiver;
-
-import java.io.IOException;
-
-/**
- * Add MIDI Events to an EventScheduler
- */
-public class MidiEventScheduler extends EventScheduler {
- private static final String TAG = "MidiEventScheduler";
- // Maintain a pool of scheduled events to reduce memory allocation.
- // This pool increases performance by about 14%.
- private final static int POOL_EVENT_SIZE = 16;
- private MidiReceiver mReceiver = new SchedulingReceiver();
-
- private class SchedulingReceiver extends MidiReceiver
- {
- /**
- * Store these bytes in the EventScheduler to be delivered at the specified
- * time.
- */
- @Override
- public void onSend(byte[] msg, int offset, int count, long timestamp)
- throws IOException {
- MidiEvent event = createScheduledEvent(msg, offset, count, timestamp);
- if (event != null) {
- add(event);
- }
- }
- }
-
- public static class MidiEvent extends SchedulableEvent {
- public int count = 0;
- public byte[] data;
-
- private MidiEvent(int count) {
- super(0);
- data = new byte[count];
- }
-
- private MidiEvent(byte[] msg, int offset, int count, long timestamp) {
- super(timestamp);
- data = new byte[count];
- System.arraycopy(msg, offset, data, 0, count);
- this.count = count;
- }
-
- @Override
- public String toString() {
- String text = "Event: ";
- for (int i = 0; i < count; i++) {
- text += data[i] + ", ";
- }
- return text;
- }
- }
-
- /**
- * Create an event that contains the message.
- */
- private MidiEvent createScheduledEvent(byte[] msg, int offset, int count,
- long timestamp) {
- MidiEvent event;
- if (count > POOL_EVENT_SIZE) {
- event = new MidiEvent(msg, offset, count, timestamp);
- } else {
- event = (MidiEvent) removeEventfromPool();
- if (event == null) {
- event = new MidiEvent(POOL_EVENT_SIZE);
- }
- System.arraycopy(msg, offset, event.data, 0, count);
- event.count = count;
- event.setTimestamp(timestamp);
- }
- return event;
- }
-
- /**
- * Return events to a pool so they can be reused.
- *
- * @param event
- */
- @Override
- public void addEventToPool(SchedulableEvent event) {
- // Make sure the event is suitable for the pool.
- if (event instanceof MidiEvent) {
- MidiEvent midiEvent = (MidiEvent) event;
- if (midiEvent.data.length == POOL_EVENT_SIZE) {
- super.addEventToPool(event);
- }
- }
- }
-
- /**
- * This MidiReceiver will write date to the scheduling buffer.
- * @return the MidiReceiver
- */
- public MidiReceiver getReceiver() {
- return mReceiver;
- }
-
-}
diff --git a/common/src/java/com/example/android/common/midi/MidiEventThread.java b/common/src/java/com/example/android/common/midi/MidiEventThread.java
deleted file mode 100644
index 626e83c..0000000
--- a/common/src/java/com/example/android/common/midi/MidiEventThread.java
+++ /dev/null
@@ -1,90 +0,0 @@
-/*
- * Copyright (C) 2015 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.example.android.common.midi;
-
-import android.media.midi.MidiSender;
-import android.util.Log;
-
-import java.io.IOException;
-
-public class MidiEventThread extends MidiEventScheduler {
- protected static final String TAG = "MidiEventThread";
-
- private EventThread mEventThread;
- MidiDispatcher mDispatcher = new MidiDispatcher();
-
- class EventThread extends Thread {
- private boolean go = true;
-
- @Override
- public void run() {
- while (go) {
- try {
- MidiEvent event = (MidiEvent) waitNextEvent();
- try {
- Log.i(TAG, "Fire event " + event.data[0] + " at "
- + event.getTimestamp());
- mDispatcher.send(event.data, 0,
- event.count, event.getTimestamp());
- } catch (IOException e) {
- e.printStackTrace();
- }
- // Put event back in the pool for future use.
- addEventToPool(event);
- } catch (InterruptedException e) {
- // OK, this is how we stop the thread.
- }
- }
- }
-
- /**
- * Asynchronously tell the thread to stop.
- */
- public void requestStop() {
- go = false;
- interrupt();
- }
- }
-
- public void start() {
- stop();
- mEventThread = new EventThread();
- mEventThread.start();
- }
-
- /**
- * Asks the thread to stop then waits for it to stop.
- */
- public void stop() {
- if (mEventThread != null) {
- mEventThread.requestStop();
- try {
- mEventThread.join(500);
- } catch (InterruptedException e) {
- Log.e(TAG,
- "Interrupted while waiting for MIDI EventScheduler thread to stop.");
- } finally {
- mEventThread = null;
- }
- }
- }
-
- public MidiSender getSender() {
- return mDispatcher.getSender();
- }
-
-}
diff --git a/common/src/java/com/example/android/common/midi/MidiFramer.java b/common/src/java/com/example/android/common/midi/MidiFramer.java
deleted file mode 100644
index c274925..0000000
--- a/common/src/java/com/example/android/common/midi/MidiFramer.java
+++ /dev/null
@@ -1,112 +0,0 @@
-/*
- * Copyright (C) 2015 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.example.android.common.midi;
-
-import android.media.midi.MidiReceiver;
-import android.util.Log;
-
-import java.io.IOException;
-
-/**
- * Convert stream of arbitrary MIDI bytes into discrete messages.
- *
- * Parses the incoming bytes and then posts individual messages to the receiver
- * specified in the constructor. Short messages of 1-3 bytes will be complete.
- * System Exclusive messages may be posted in pieces.
- *
- * Resolves Running Status and interleaved System Real-Time messages.
- */
-public class MidiFramer extends MidiReceiver {
- private MidiReceiver mReceiver;
- private byte[] mBuffer = new byte[3];
- private int mCount;
- private byte mRunningStatus;
- private int mNeeded;
- private boolean mInSysEx;
-
- public MidiFramer(MidiReceiver receiver) {
- mReceiver = receiver;
- }
-
- /*
- * @see android.midi.MidiReceiver#onSend(byte[], int, int, long)
- */
- @Override
- public void onSend(byte[] data, int offset, int count, long timestamp)
- throws IOException {
- int sysExStartOffset = (mInSysEx ? offset : -1);
-
- for (int i = 0; i < count; i++) {
- final byte currentByte = data[offset];
- final int currentInt = currentByte & 0xFF;
- if (currentInt >= 0x80) { // status byte?
- if (currentInt < 0xF0) { // channel message?
- mRunningStatus = currentByte;
- mCount = 1;
- mNeeded = MidiConstants.getBytesPerMessage(currentByte) - 1;
- } else if (currentInt < 0xF8) { // system common?
- if (currentInt == 0xF0 /* SysEx Start */) {
- // Log.i(TAG, "SysEx Start");
- mInSysEx = true;
- sysExStartOffset = offset;
- } else if (currentInt == 0xF7 /* SysEx End */) {
- // Log.i(TAG, "SysEx End");
- if (mInSysEx) {
- mReceiver.send(data, sysExStartOffset,
- offset - sysExStartOffset + 1, timestamp);
- mInSysEx = false;
- sysExStartOffset = -1;
- }
- } else {
- mBuffer[0] = currentByte;
- mRunningStatus = 0;
- mCount = 1;
- mNeeded = MidiConstants.getBytesPerMessage(currentByte) - 1;
- }
- } else { // real-time?
- // Single byte message interleaved with other data.
- if (mInSysEx) {
- mReceiver.send(data, sysExStartOffset,
- offset - sysExStartOffset, timestamp);
- sysExStartOffset = offset + 1;
- }
- mReceiver.send(data, offset, 1, timestamp);
- }
- } else { // data byte
- if (!mInSysEx) {
- mBuffer[mCount++] = currentByte;
- if (--mNeeded == 0) {
- if (mRunningStatus != 0) {
- mBuffer[0] = mRunningStatus;
- }
- mReceiver.send(mBuffer, 0, mCount, timestamp);
- mNeeded = MidiConstants.getBytesPerMessage(mBuffer[0]) - 1;
- mCount = 1;
- }
- }
- }
- ++offset;
- }
-
- // send any accumulatedSysEx data
- if (sysExStartOffset >= 0 && sysExStartOffset < offset) {
- mReceiver.send(data, sysExStartOffset,
- offset - sysExStartOffset, timestamp);
- }
- }
-
-}
diff --git a/common/src/java/com/example/android/common/midi/MidiInputPortSelector.java b/common/src/java/com/example/android/common/midi/MidiInputPortSelector.java
deleted file mode 100644
index 7ca2272..0000000
--- a/common/src/java/com/example/android/common/midi/MidiInputPortSelector.java
+++ /dev/null
@@ -1,90 +0,0 @@
-/*
- * Copyright (C) 2015 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.example.android.common.midi;
-
-import android.app.Activity;
-import android.media.midi.MidiDevice;
-import android.media.midi.MidiDeviceInfo;
-import android.media.midi.MidiInputPort;
-import android.media.midi.MidiManager;
-import android.media.midi.MidiReceiver;
-import android.os.Handler;
-import android.os.Looper;
-import android.util.Log;
-
-import java.io.IOException;
-
-/**
- * Manages a Spinner for selecting a MidiInputPort.
- */
-public class MidiInputPortSelector extends MidiPortSelector {
- private static final String TAG = "MidiInputPortSelector";
-
- private MidiInputPort mInputPort;
- private MidiDevice mOpenDevice;
-
- /**
- * @param midiManager
- * @param activity
- * @param spinnerId ID from the layout resource
- */
- public MidiInputPortSelector(MidiManager midiManager, Activity activity,
- int spinnerId) {
- super(midiManager, activity, spinnerId, TYPE_INPUT);
- }
-
- @Override
- public void onPortSelected(final MidiPortWrapper wrapper) {
- onClose();
-
- final MidiDeviceInfo info = wrapper.getDeviceInfo();
- if (info != null) {
- mMidiManager.openDevice(info, new MidiManager.OnDeviceOpenedListener() {
- @Override
- public void onDeviceOpened(MidiDevice device) {
- if (device == null) {
- Log.e(TAG, "could not open " + info);
- } else {
- mOpenDevice = device;
- mInputPort = mOpenDevice.openInputPort(
- wrapper.getPortIndex());
- }
- }
- }, new Handler(Looper.getMainLooper()));
- }
- }
-
- public MidiReceiver getReceiver() {
- return mInputPort;
- }
-
- @Override
- public void onClose() {
- try {
- if (mInputPort != null) {
- mInputPort.close();
- }
- mInputPort = null;
- if (mOpenDevice != null) {
- mOpenDevice.close();
- }
- mOpenDevice = null;
- } catch (IOException e) {
- Log.e(TAG, "cleanup failed", e);
- }
- }
-}
diff --git a/common/src/java/com/example/android/common/midi/MidiOutputPortSelector.java b/common/src/java/com/example/android/common/midi/MidiOutputPortSelector.java
deleted file mode 100644
index d01d304..0000000
--- a/common/src/java/com/example/android/common/midi/MidiOutputPortSelector.java
+++ /dev/null
@@ -1,105 +0,0 @@
-/*
- * Copyright (C) 2015 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.example.android.common.midi;
-
-import android.app.Activity;
-import android.media.midi.MidiDevice;
-import android.media.midi.MidiDeviceInfo;
-import android.media.midi.MidiManager;
-import android.media.midi.MidiOutputPort;
-import android.media.midi.MidiSender;
-import android.os.Handler;
-import android.os.Looper;
-import android.util.Log;
-
-import java.io.IOException;
-
-/**
- * Manages a Spinner for selecting a MidiOutputPort.
- */
-public class MidiOutputPortSelector extends MidiPortSelector {
-
- private static final String TAG = "MidiOutputPortSelector";
-
- private MidiOutputPort mSender;
- private MidiDispatcher mDispatcher = new MidiDispatcher();
- private MidiDevice mOpenDevice;
-
- /**
- * @param midiManager
- * @param activity
- * @param spinnerId ID from the layout resource
- */
- public MidiOutputPortSelector(MidiManager midiManager, Activity activity,
- int spinnerId) {
- super(midiManager, activity, spinnerId, TYPE_OUTPUT);
- }
-
- @Override
- public void onPortSelected(final MidiPortWrapper wrapper) {
- Log.i(TAG, "onPortSelected: " + wrapper);
- onClose();
-
- final MidiDeviceInfo info = wrapper.getDeviceInfo();
- if (info != null) {
- mMidiManager.openDevice(info, new MidiManager.OnDeviceOpenedListener() {
-
- @Override
- public void onDeviceOpened(MidiDevice device) {
- if (device == null) {
- Log.e(TAG, "could not open " + info);
- } else {
- mOpenDevice = device;
- mSender = device.openOutputPort(wrapper.getPortIndex());
- if (mSender == null) {
- Log.e(TAG,
- "could not get sender for " + info);
- return;
- }
- mSender.connect(mDispatcher);
- }
- }
- }, new Handler(Looper.getMainLooper()));
- }
- }
-
- @Override
- public void onClose() {
- try {
- if (mSender != null) {
- mSender.disconnect(mDispatcher);
- }
- mSender = null;
- if (mOpenDevice != null) {
- mOpenDevice.close();
- }
- mOpenDevice = null;
- } catch (IOException e) {
- Log.e(TAG, "cleanup failed", e);
- }
- }
-
- /**
- * You can connect your MidiReceivers to this sender. The user will then select which output
- * port will send messages through this MidiSender.
- * @return a MidiSender that will send the messages from the selected port.
- */
- public MidiSender getSender() {
- return mDispatcher.getSender();
- }
-
-}
diff --git a/common/src/java/com/example/android/common/midi/MidiPortConnector.java b/common/src/java/com/example/android/common/midi/MidiPortConnector.java
deleted file mode 100644
index 92517be..0000000
--- a/common/src/java/com/example/android/common/midi/MidiPortConnector.java
+++ /dev/null
@@ -1,217 +0,0 @@
-/*
- * Copyright (C) 2015 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.example.android.common.midi;
-
-import android.media.midi.MidiDevice;
-import android.media.midi.MidiDevice.MidiConnection;
-import android.media.midi.MidiDeviceInfo;
-import android.media.midi.MidiInputPort;
-import android.media.midi.MidiManager;
-import android.os.Handler;
-import android.util.Log;
-
-import java.io.IOException;
-
-/**
- * Simple wrapper for connecting MIDI ports.
- */
-public class MidiPortConnector {
- private final MidiManager mMidiManager;
- private MidiDevice mSourceDevice;
- private MidiDevice mDestinationDevice;
- private MidiConnection mConnection;
-
- /**
- * @param mMidiManager
- */
- public MidiPortConnector(MidiManager midiManager) {
- mMidiManager = midiManager;
- }
-
- public void close() throws IOException {
- if (mConnection != null) {
- mConnection.close();
- mConnection = null;
- }
- if (mSourceDevice != null) {
- mSourceDevice.close();
- mSourceDevice = null;
- }
- if (mDestinationDevice != null) {
- mDestinationDevice.close();
- mDestinationDevice = null;
- }
- }
-
- /**
- * @return a device that matches the manufacturer and product or null
- */
- public MidiDeviceInfo findDevice(String manufacturer, String product) {
- for (MidiDeviceInfo info : mMidiManager.getDevices()) {
- String deviceManufacturer = info.getProperties()
- .getString(MidiDeviceInfo.PROPERTY_MANUFACTURER);
- if ((manufacturer != null)
- && manufacturer.equals(deviceManufacturer)) {
- String deviceProduct = info.getProperties()
- .getString(MidiDeviceInfo.PROPERTY_PRODUCT);
- if ((product != null) && product.equals(deviceProduct)) {
- return info;
- }
- }
- }
- return null;
- }
-
- /**
- * Listener class used for receiving the results of
- * {@link #connectToDevicePort}
- */
- public interface OnPortsConnectedListener {
- /**
- * Called to respond to a {@link #connectToDevicePort} request
- *
- * @param connection
- * a {@link MidiConnection} that represents the connected
- * ports, or null if connection failed
- */
- abstract public void onPortsConnected(MidiConnection connection);
- }
-
- /**
- * Open two devices and connect their ports.
- *
- * @param sourceDeviceInfo
- * @param sourcePortIndex
- * @param destinationDeviceInfo
- * @param destinationPortIndex
- */
- public void connectToDevicePort(final MidiDeviceInfo sourceDeviceInfo,
- final int sourcePortIndex,
- final MidiDeviceInfo destinationDeviceInfo,
- final int destinationPortIndex) {
- connectToDevicePort(sourceDeviceInfo, sourcePortIndex,
- destinationDeviceInfo, destinationPortIndex, null, null);
- }
-
- /**
- * Open two devices and connect their ports.
- *
- * @param sourceDeviceInfo
- * @param sourcePortIndex
- * @param destinationDeviceInfo
- * @param destinationPortIndex
- */
- public void connectToDevicePort(final MidiDeviceInfo sourceDeviceInfo,
- final int sourcePortIndex,
- final MidiDeviceInfo destinationDeviceInfo,
- final int destinationPortIndex,
- final OnPortsConnectedListener listener, final Handler handler) {
- mMidiManager.openDevice(destinationDeviceInfo,
- new MidiManager.OnDeviceOpenedListener() {
- @Override
- public void onDeviceOpened(MidiDevice device) {
- if (device == null) {
- Log.e(MidiConstants.TAG,
- "could not open " + destinationDeviceInfo);
- if (listener != null) {
- listener.onPortsConnected(null);
- }
- } else {
- Log.i(MidiConstants.TAG,
- "connectToDevicePort opened "
- + destinationDeviceInfo);
- // Destination device was opened so go to next step.
- mDestinationDevice = device;
- MidiInputPort destinationInputPort = device
- .openInputPort(destinationPortIndex);
- if (destinationInputPort != null) {
- Log.i(MidiConstants.TAG,
- "connectToDevicePort opened port on "
- + destinationDeviceInfo);
- connectToDevicePort(sourceDeviceInfo,
- sourcePortIndex, destinationInputPort,
- listener, handler);
- } else {
- Log.e(MidiConstants.TAG,
- "could not open port on "
- + destinationDeviceInfo);
- if (listener != null) {
- listener.onPortsConnected(null);
- }
- }
- }
- }
- }, handler);
- }
-
- /**
- * Open a source device and connect its output port to the
- * destinationInputPort.
- *
- * @param sourceDeviceInfo
- * @param sourcePortIndex
- * @param destinationInputPort
- */
- public void connectToDevicePort(final MidiDeviceInfo sourceDeviceInfo,
- final int sourcePortIndex,
- final MidiInputPort destinationInputPort) {
- connectToDevicePort(sourceDeviceInfo, sourcePortIndex,
- destinationInputPort, null, null);
- }
-
- /**
- * Open a source device and connect its output port to the
- * destinationInputPort.
- *
- * @param sourceDeviceInfo
- * @param sourcePortIndex
- * @param destinationInputPort
- */
- public void connectToDevicePort(final MidiDeviceInfo sourceDeviceInfo,
- final int sourcePortIndex, final MidiInputPort destinationInputPort,
- final OnPortsConnectedListener listener, final Handler handler) {
- mMidiManager.openDevice(sourceDeviceInfo,
- new MidiManager.OnDeviceOpenedListener() {
- @Override
- public void onDeviceOpened(MidiDevice device) {
- if (device == null) {
- Log.e(MidiConstants.TAG,
- "could not open " + sourceDeviceInfo);
- if (listener != null) {
- listener.onPortsConnected(null);
- }
- } else {
- Log.i(MidiConstants.TAG,
- "connectToDevicePort opened "
- + sourceDeviceInfo);
- // Device was opened so connect the ports.
- mSourceDevice = device;
- mConnection = device.connectPorts(
- destinationInputPort, sourcePortIndex);
- if (mConnection == null) {
- Log.e(MidiConstants.TAG, "could not connect to "
- + sourceDeviceInfo);
- }
- if (listener != null) {
- listener.onPortsConnected(mConnection);
- }
- }
- }
- }, handler);
- }
-
-}
diff --git a/common/src/java/com/example/android/common/midi/MidiPortSelector.java b/common/src/java/com/example/android/common/midi/MidiPortSelector.java
deleted file mode 100644
index d491c03..0000000
--- a/common/src/java/com/example/android/common/midi/MidiPortSelector.java
+++ /dev/null
@@ -1,127 +0,0 @@
-/*
- * Copyright (C) 2015 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.example.android.common.midi;
-
-import android.app.Activity;
-import android.media.midi.MidiDeviceInfo;
-import android.media.midi.MidiManager;
-import android.media.midi.MidiManager.DeviceCallback;
-import android.os.Handler;
-import android.os.Looper;
-import android.view.View;
-import android.widget.AdapterView;
-import android.widget.ArrayAdapter;
-import android.widget.Spinner;
-
-/**
- * Base class that uses a Spinner to select available MIDI ports.
- */
-public abstract class MidiPortSelector extends DeviceCallback {
-
- public static final int TYPE_INPUT = 0;
- public static final int TYPE_OUTPUT = 1;
- private int mType = TYPE_INPUT;
- protected ArrayAdapter<MidiPortWrapper> mAdapter;
- private Spinner mSpinner;
- protected MidiManager mMidiManager;
- protected Activity mActivity;
- private MidiPortWrapper mCurrentWrapper;
-
- /**
- *
- * @param midiManager
- * @param activity
- * @param spinnerId ID from the layout resource
- * @param type TYPE_INPUT or TYPE_OUTPUT
- */
- public MidiPortSelector(MidiManager midiManager, Activity activity,
- int spinnerId, int type) {
- mMidiManager = midiManager;
- mActivity = activity;
- mType = type;
- mAdapter = new ArrayAdapter<MidiPortWrapper>(activity,
- android.R.layout.simple_spinner_item);
- mAdapter.setDropDownViewResource(
- android.R.layout.simple_spinner_dropdown_item);
- mAdapter.add(new MidiPortWrapper(null, 0));
-
- mSpinner = (Spinner) activity.findViewById(spinnerId);
- mSpinner.setOnItemSelectedListener(
- new AdapterView.OnItemSelectedListener() {
-
- public void onItemSelected(AdapterView<?> parent, View view,
- int pos, long id) {
- mCurrentWrapper = mAdapter.getItem(pos);
- onPortSelected(mCurrentWrapper);
- }
-
- public void onNothingSelected(AdapterView<?> parent) {
- onPortSelected(null);
- mCurrentWrapper = null;
- }
- });
- mSpinner.setAdapter(mAdapter);
-
- mMidiManager.registerDeviceCallback(this,
- new Handler(Looper.getMainLooper()));
-
- MidiDeviceInfo[] infos = mMidiManager.getDevices();
- for (MidiDeviceInfo info : infos) {
- onDeviceAdded(info);
- }
- }
-
- private int getInfoPortCount(final MidiDeviceInfo info) {
- int portCount = (mType == TYPE_INPUT) ? info.getInputPortCount()
- : info.getOutputPortCount();
- return portCount;
- }
-
- @Override
- public void onDeviceAdded(final MidiDeviceInfo info) {
- int portCount = getInfoPortCount(info);
- for (int i = 0; i < portCount; ++i) {
- mAdapter.add(new MidiPortWrapper(info, i));
- }
- }
-
- @Override
- public void onDeviceRemoved(final MidiDeviceInfo info) {
- int portCount = getInfoPortCount(info);
- for (int i = 0; i < portCount; ++i) {
- MidiPortWrapper wrapper = new MidiPortWrapper(info, i);
- MidiPortWrapper currentWrapper = mCurrentWrapper;
- mAdapter.remove(wrapper);
- // If the currently selected port was removed then select no port.
- if (wrapper.equals(currentWrapper)) {
- mSpinner.setSelection(0);
- }
- }
- }
-
- /**
- * Implement this method to handle the user selecting a port on a device.
- *
- * @param wrapper
- */
- public abstract void onPortSelected(MidiPortWrapper wrapper);
-
- /**
- * Implement this method to clean up any open resources.
- */
- public abstract void onClose();
-}
diff --git a/common/src/java/com/example/android/common/midi/MidiPortWrapper.java b/common/src/java/com/example/android/common/midi/MidiPortWrapper.java
deleted file mode 100644
index 9f82694..0000000
--- a/common/src/java/com/example/android/common/midi/MidiPortWrapper.java
+++ /dev/null
@@ -1,82 +0,0 @@
-/*
- * Copyright (C) 2015 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.example.android.common.midi;
-
-import android.media.midi.MidiDeviceInfo;
-import android.media.midi.MidiDeviceInfo.PortInfo;
-
-// Wrapper for a MIDI device and port description.
-public class MidiPortWrapper {
- private MidiDeviceInfo mInfo;
- private int mPortIndex;
- private String mString;
-
- public MidiPortWrapper(MidiDeviceInfo info, int portIndex) {
- mInfo = info;
- mPortIndex = portIndex;
- if (mInfo == null) {
- mString = "- - - - - -";
- } else {
- StringBuilder sb = new StringBuilder();
- String name = mInfo.getProperties()
- .getString(MidiDeviceInfo.PROPERTY_NAME);
- if (name == null) {
- name = mInfo.getProperties()
- .getString(MidiDeviceInfo.PROPERTY_MANUFACTURER)
- + ", " + mInfo.getProperties()
- .getString(MidiDeviceInfo.PROPERTY_PRODUCT);
- }
- sb.append("#" + mInfo.getId()).append(", ").append(name);
- PortInfo portInfo = mInfo.getPorts()[portIndex];
- sb.append(", ").append(portInfo.getName());
- mString = sb.toString();
- }
- }
-
- public int getPortIndex() {
- return mPortIndex;
- }
-
- public MidiDeviceInfo getDeviceInfo() {
- return mInfo;
- }
-
- @Override
- public String toString() {
- return mString;
- }
-
- @Override
- public boolean equals(Object other) {
- if (other == null)
- return false;
- if (!(other instanceof MidiPortWrapper))
- return false;
- MidiPortWrapper otherWrapper = (MidiPortWrapper) other;
- if (mPortIndex != otherWrapper.mPortIndex)
- return false;
- if (mInfo == null)
- return (otherWrapper.mInfo == null);
- return mInfo.equals(otherWrapper.mInfo);
- }
-
- @Override
- public int hashCode() {
- return toString().hashCode();
- }
-
-}
diff --git a/common/src/java/com/example/android/common/midi/synth/EnvelopeADSR.java b/common/src/java/com/example/android/common/midi/synth/EnvelopeADSR.java
deleted file mode 100644
index a29a193..0000000
--- a/common/src/java/com/example/android/common/midi/synth/EnvelopeADSR.java
+++ /dev/null
@@ -1,111 +0,0 @@
-/*
- * Copyright (C) 2015 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.example.android.common.midi.synth;
-
-/**
- * Very simple Attack, Decay, Sustain, Release envelope with linear ramps.
- *
- * Times are in seconds.
- */
-public class EnvelopeADSR extends SynthUnit {
- private static final int IDLE = 0;
- private static final int ATTACK = 1;
- private static final int DECAY = 2;
- private static final int SUSTAIN = 3;
- private static final int RELEASE = 4;
- private static final int FINISHED = 5;
- private static final float MIN_TIME = 0.001f;
-
- private float mAttackRate;
- private float mRreleaseRate;
- private float mSustainLevel;
- private float mDecayRate;
- private float mCurrent;
- private int mSstate = IDLE;
-
- public EnvelopeADSR() {
- setAttackTime(0.003f);
- setDecayTime(0.08f);
- setSustainLevel(0.3f);
- setReleaseTime(1.0f);
- }
-
- public void setAttackTime(float time) {
- if (time < MIN_TIME)
- time = MIN_TIME;
- mAttackRate = 1.0f / (SynthEngine.FRAME_RATE * time);
- }
-
- public void setDecayTime(float time) {
- if (time < MIN_TIME)
- time = MIN_TIME;
- mDecayRate = 1.0f / (SynthEngine.FRAME_RATE * time);
- }
-
- public void setSustainLevel(float level) {
- if (level < 0.0f)
- level = 0.0f;
- mSustainLevel = level;
- }
-
- public void setReleaseTime(float time) {
- if (time < MIN_TIME)
- time = MIN_TIME;
- mRreleaseRate = 1.0f / (SynthEngine.FRAME_RATE * time);
- }
-
- public void on() {
- mSstate = ATTACK;
- }
-
- public void off() {
- mSstate = RELEASE;
- }
-
- @Override
- public float render() {
- switch (mSstate) {
- case ATTACK:
- mCurrent += mAttackRate;
- if (mCurrent > 1.0f) {
- mCurrent = 1.0f;
- mSstate = DECAY;
- }
- break;
- case DECAY:
- mCurrent -= mDecayRate;
- if (mCurrent < mSustainLevel) {
- mCurrent = mSustainLevel;
- mSstate = SUSTAIN;
- }
- break;
- case RELEASE:
- mCurrent -= mRreleaseRate;
- if (mCurrent < 0.0f) {
- mCurrent = 0.0f;
- mSstate = FINISHED;
- }
- break;
- }
- return mCurrent;
- }
-
- public boolean isDone() {
- return mSstate == FINISHED;
- }
-
-}
diff --git a/common/src/java/com/example/android/common/midi/synth/SawOscillator.java b/common/src/java/com/example/android/common/midi/synth/SawOscillator.java
deleted file mode 100644
index c02a6a1..0000000
--- a/common/src/java/com/example/android/common/midi/synth/SawOscillator.java
+++ /dev/null
@@ -1,73 +0,0 @@
-/*
- * Copyright (C) 2015 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.example.android.common.midi.synth;
-
-public class SawOscillator extends SynthUnit {
- private float mPhase = 0.0f;
- private float mPhaseIncrement = 0.01f;
- private float mFrequency = 0.0f;
- private float mFrequencyScaler = 1.0f;
- private float mAmplitude = 1.0f;
-
- public void setPitch(float pitch) {
- float freq = (float) pitchToFrequency(pitch);
- setFrequency(freq);
- }
-
- public void setFrequency(float frequency) {
- mFrequency = frequency;
- updatePhaseIncrement();
- }
-
- private void updatePhaseIncrement() {
- mPhaseIncrement = 2.0f * mFrequency * mFrequencyScaler / 48000.0f;
- }
-
- public void setAmplitude(float amplitude) {
- mAmplitude = amplitude;
- }
-
- public float getAmplitude() {
- return mAmplitude;
- }
-
- public float getFrequencyScaler() {
- return mFrequencyScaler;
- }
-
- public void setFrequencyScaler(float frequencyScaler) {
- mFrequencyScaler = frequencyScaler;
- updatePhaseIncrement();
- }
-
- float incrementWrapPhase() {
- mPhase += mPhaseIncrement;
- while (mPhase > 1.0) {
- mPhase -= 2.0;
- }
- while (mPhase < -1.0) {
- mPhase += 2.0;
- }
- return mPhase;
- }
-
- @Override
- public float render() {
- return incrementWrapPhase() * mAmplitude;
- }
-
-}
diff --git a/common/src/java/com/example/android/common/midi/synth/SawOscillatorDPW.java b/common/src/java/com/example/android/common/midi/synth/SawOscillatorDPW.java
deleted file mode 100644
index e5d661d..0000000
--- a/common/src/java/com/example/android/common/midi/synth/SawOscillatorDPW.java
+++ /dev/null
@@ -1,52 +0,0 @@
-/*
- * Copyright (C) 2015 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.example.android.common.midi.synth;
-
-/**
- * Band limited sawtooth oscillator.
- * This will have very little aliasing at high frequencies.
- */
-public class SawOscillatorDPW extends SawOscillator {
- private float mZ1 = 0.0f; // delayed values
- private float mZ2 = 0.0f;
- private float mScaler; // frequency dependent scaler
- private final static float VERY_LOW_FREQ = 0.0000001f;
-
- @Override
- public void setFrequency(float freq) {
- /* Calculate scaling based on frequency. */
- freq = Math.abs(freq);
- super.setFrequency(freq);
- if (freq < VERY_LOW_FREQ) {
- mScaler = (float) (0.125 * 44100 / VERY_LOW_FREQ);
- } else {
- mScaler = (float) (0.125 * 44100 / freq);
- }
- }
-
- @Override
- public float render() {
- float phase = incrementWrapPhase();
- /* Square the raw sawtooth. */
- float squared = phase * phase;
- float diffed = squared - mZ2;
- mZ2 = mZ1;
- mZ1 = squared;
- return diffed * mScaler * getAmplitude();
- }
-
-}
diff --git a/common/src/java/com/example/android/common/midi/synth/SawVoice.java b/common/src/java/com/example/android/common/midi/synth/SawVoice.java
deleted file mode 100644
index 3b3e543..0000000
--- a/common/src/java/com/example/android/common/midi/synth/SawVoice.java
+++ /dev/null
@@ -1,65 +0,0 @@
-/*
- * Copyright (C) 2015 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.example.android.common.midi.synth;
-
-/**
- * Sawtooth oscillator with an ADSR.
- */
-public class SawVoice extends SynthVoice {
- private SawOscillator mOscillator;
- private EnvelopeADSR mEnvelope;
-
- public SawVoice() {
- mOscillator = createOscillator();
- mEnvelope = new EnvelopeADSR();
- }
-
- protected SawOscillator createOscillator() {
- return new SawOscillator();
- }
-
- @Override
- public void noteOn(int noteIndex, int velocity) {
- super.noteOn(noteIndex, velocity);
- mOscillator.setPitch(noteIndex);
- mOscillator.setAmplitude(getAmplitude());
- mEnvelope.on();
- }
-
- @Override
- public void noteOff() {
- super.noteOff();
- mEnvelope.off();
- }
-
- @Override
- public void setFrequencyScaler(float scaler) {
- mOscillator.setFrequencyScaler(scaler);
- }
-
- @Override
- public float render() {
- float output = mOscillator.render() * mEnvelope.render();
- return output;
- }
-
- @Override
- public boolean isDone() {
- return mEnvelope.isDone();
- }
-
-}
diff --git a/common/src/java/com/example/android/common/midi/synth/SimpleAudioOutput.java b/common/src/java/com/example/android/common/midi/synth/SimpleAudioOutput.java
deleted file mode 100644
index 04aa19c..0000000
--- a/common/src/java/com/example/android/common/midi/synth/SimpleAudioOutput.java
+++ /dev/null
@@ -1,95 +0,0 @@
-/*
- * Copyright (C) 2015 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.example.android.common.midi.synth;
-
-import android.media.AudioFormat;
-import android.media.AudioManager;
-import android.media.AudioTrack;
-import android.util.Log;
-
-/**
- * Simple base class for implementing audio output for examples.
- * This can be sub-classed for experimentation or to redirect audio output.
- */
-public class SimpleAudioOutput {
-
- private static final String TAG = "AudioOutputTrack";
- public static final int SAMPLES_PER_FRAME = 2;
- public static final int BYTES_PER_SAMPLE = 4; // float
- public static final int BYTES_PER_FRAME = SAMPLES_PER_FRAME * BYTES_PER_SAMPLE;
- private AudioTrack mAudioTrack;
- private int mFrameRate;
-
- /**
- *
- */
- public SimpleAudioOutput() {
- super();
- }
-
- /**
- * Create an audio track then call play().
- *
- * @param frameRate
- */
- public void start(int frameRate) {
- stop();
- mFrameRate = frameRate;
- mAudioTrack = createAudioTrack(frameRate);
- // AudioTrack will wait until it has enough data before starting.
- mAudioTrack.play();
- }
-
- public AudioTrack createAudioTrack(int frameRate) {
- int minBufferSizeBytes = AudioTrack.getMinBufferSize(frameRate,
- AudioFormat.CHANNEL_OUT_STEREO, AudioFormat.ENCODING_PCM_FLOAT);
- Log.i(TAG, "AudioTrack.minBufferSize = " + minBufferSizeBytes
- + " bytes = " + (minBufferSizeBytes / BYTES_PER_FRAME)
- + " frames");
- int bufferSize = 8 * minBufferSizeBytes / 8;
- int outputBufferSizeFrames = bufferSize / BYTES_PER_FRAME;
- Log.i(TAG, "actual bufferSize = " + bufferSize + " bytes = "
- + outputBufferSizeFrames + " frames");
-
- AudioTrack player = new AudioTrack(AudioManager.STREAM_MUSIC,
- mFrameRate, AudioFormat.CHANNEL_OUT_STEREO,
- AudioFormat.ENCODING_PCM_FLOAT, bufferSize,
- AudioTrack.MODE_STREAM);
- Log.i(TAG, "created AudioTrack");
- return player;
- }
-
- public int write(float[] buffer, int offset, int length) {
- return mAudioTrack.write(buffer, offset, length,
- AudioTrack.WRITE_BLOCKING);
- }
-
- public void stop() {
- if (mAudioTrack != null) {
- mAudioTrack.stop();
- mAudioTrack = null;
- }
- }
-
- public int getFrameRate() {
- return mFrameRate;
- }
-
- public AudioTrack getAudioTrack() {
- return mAudioTrack;
- }
-}
diff --git a/common/src/java/com/example/android/common/midi/synth/SineOscillator.java b/common/src/java/com/example/android/common/midi/synth/SineOscillator.java
deleted file mode 100644
index c638c34..0000000
--- a/common/src/java/com/example/android/common/midi/synth/SineOscillator.java
+++ /dev/null
@@ -1,54 +0,0 @@
-/*
- * Copyright (C) 2015 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.example.android.common.midi.synth;
-
-/**
- * Sinewave oscillator.
- */
-public class SineOscillator extends SawOscillator {
- // Factorial constants.
- private static final float IF3 = 1.0f / (2 * 3);
- private static final float IF5 = IF3 / (4 * 5);
- private static final float IF7 = IF5 / (6 * 7);
- private static final float IF9 = IF7 / (8 * 9);
- private static final float IF11 = IF9 / (10 * 11);
-
- /**
- * Calculate sine using Taylor expansion. Do not use values outside the range.
- *
- * @param currentPhase in the range of -1.0 to +1.0 for one cycle
- */
- public static float fastSin(float currentPhase) {
-
- /* Wrap phase back into region where results are more accurate. */
- float yp = (currentPhase > 0.5f) ? 1.0f - currentPhase
- : ((currentPhase < (-0.5f)) ? (-1.0f) - currentPhase : currentPhase);
-
- float x = (float) (yp * Math.PI);
- float x2 = (x * x);
- /* Taylor expansion out to x**11/11! factored into multiply-adds */
- return x * (x2 * (x2 * (x2 * (x2 * ((x2 * (-IF11)) + IF9) - IF7) + IF5) - IF3) + 1);
- }
-
- @Override
- public float render() {
- // Convert raw sawtooth to sine.
- float phase = incrementWrapPhase();
- return fastSin(phase) * getAmplitude();
- }
-
-}
diff --git a/common/src/java/com/example/android/common/midi/synth/SineVoice.java b/common/src/java/com/example/android/common/midi/synth/SineVoice.java
deleted file mode 100644
index e80d2c7..0000000
--- a/common/src/java/com/example/android/common/midi/synth/SineVoice.java
+++ /dev/null
@@ -1,27 +0,0 @@
-/*
- * Copyright (C) 2015 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.example.android.common.midi.synth;
-
-/**
- * Replace sawtooth with a sine wave.
- */
-public class SineVoice extends SawVoice {
- @Override
- protected SawOscillator createOscillator() {
- return new SineOscillator();
- }
-}
diff --git a/common/src/java/com/example/android/common/midi/synth/SynthEngine.java b/common/src/java/com/example/android/common/midi/synth/SynthEngine.java
deleted file mode 100644
index 6cd02a6..0000000
--- a/common/src/java/com/example/android/common/midi/synth/SynthEngine.java
+++ /dev/null
@@ -1,284 +0,0 @@
-/*
- * Copyright (C) 2015 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.example.android.common.midi.synth;
-
-import android.media.midi.MidiReceiver;
-import android.util.Log;
-
-import com.example.android.common.midi.MidiConstants;
-import com.example.android.common.midi.MidiEventScheduler;
-import com.example.android.common.midi.MidiEventScheduler.MidiEvent;
-import com.example.android.common.midi.MidiFramer;
-
-import java.io.IOException;
-import java.util.ArrayList;
-import java.util.Hashtable;
-import java.util.Iterator;
-
-/**
- * Very simple polyphonic, single channel synthesizer. It runs a background
- * thread that processes MIDI events and synthesizes audio.
- */
-public class SynthEngine extends MidiReceiver {
-
- private static final String TAG = "SynthEngine";
-
- public static final int FRAME_RATE = 48000;
- private static final int FRAMES_PER_BUFFER = 240;
- private static final int SAMPLES_PER_FRAME = 2;
-
- private boolean go;
- private Thread mThread;
- private float[] mBuffer = new float[FRAMES_PER_BUFFER * SAMPLES_PER_FRAME];
- private float mFrequencyScaler = 1.0f;
- private float mBendRange = 2.0f; // semitones
- private int mProgram;
-
- private ArrayList<SynthVoice> mFreeVoices = new ArrayList<SynthVoice>();
- private Hashtable<Integer, SynthVoice>
- mVoices = new Hashtable<Integer, SynthVoice>();
- private MidiEventScheduler mEventScheduler;
- private MidiFramer mFramer;
- private MidiReceiver mReceiver = new MyReceiver();
- private SimpleAudioOutput mAudioOutput;
-
- public SynthEngine() {
- this(new SimpleAudioOutput());
- }
-
- public SynthEngine(SimpleAudioOutput audioOutput) {
- mReceiver = new MyReceiver();
- mFramer = new MidiFramer(mReceiver);
- mAudioOutput = audioOutput;
- }
-
- @Override
- public void onSend(byte[] data, int offset, int count, long timestamp)
- throws IOException {
- if (mEventScheduler != null) {
- if (!MidiConstants.isAllActiveSensing(data, offset, count)) {
- mEventScheduler.getReceiver().send(data, offset, count,
- timestamp);
- }
- }
- }
-
- private class MyReceiver extends MidiReceiver {
- @Override
- public void onSend(byte[] data, int offset, int count, long timestamp)
- throws IOException {
- byte command = (byte) (data[0] & MidiConstants.STATUS_COMMAND_MASK);
- int channel = (byte) (data[0] & MidiConstants.STATUS_CHANNEL_MASK);
- switch (command) {
- case MidiConstants.STATUS_NOTE_OFF:
- noteOff(channel, data[1], data[2]);
- break;
- case MidiConstants.STATUS_NOTE_ON:
- noteOn(channel, data[1], data[2]);
- break;
- case MidiConstants.STATUS_PITCH_BEND:
- int bend = (data[2] << 7) + data[1];
- pitchBend(channel, bend);
- break;
- case MidiConstants.STATUS_PROGRAM_CHANGE:
- mProgram = data[1];
- mFreeVoices.clear();
- break;
- default:
- logMidiMessage(data, offset, count);
- break;
- }
- }
- }
-
- class MyRunnable implements Runnable {
- @Override
- public void run() {
- try {
- mAudioOutput.start(FRAME_RATE);
- onLoopStarted();
- while (go) {
- processMidiEvents();
- generateBuffer();
- mAudioOutput.write(mBuffer, 0, mBuffer.length);
- onBufferCompleted(FRAMES_PER_BUFFER);
- }
- } catch (Exception e) {
- Log.e(TAG, "SynthEngine background thread exception.", e);
- } finally {
- onLoopEnded();
- mAudioOutput.stop();
- }
- }
- }
-
- /**
- * This is called form the synthesis thread before it starts looping.
- */
- public void onLoopStarted() {
- }
-
- /**
- * This is called once at the end of each synthesis loop.
- *
- * @param framesPerBuffer
- */
- public void onBufferCompleted(int framesPerBuffer) {
- }
-
- /**
- * This is called form the synthesis thread when it stop looping.
- */
- public void onLoopEnded() {
- }
-
- /**
- * Assume message has been aligned to the start of a MIDI message.
- *
- * @param data
- * @param offset
- * @param count
- */
- public void logMidiMessage(byte[] data, int offset, int count) {
- String text = "Received: ";
- for (int i = 0; i < count; i++) {
- text += String.format("0x%02X, ", data[offset + i]);
- }
- Log.i(TAG, text);
- }
-
- /**
- * @throws IOException
- *
- */
- private void processMidiEvents() throws IOException {
- long now = System.nanoTime(); // TODO use audio presentation time
- MidiEvent event = (MidiEvent) mEventScheduler.getNextEvent(now);
- while (event != null) {
- mFramer.send(event.data, 0, event.count, event.getTimestamp());
- mEventScheduler.addEventToPool(event);
- event = (MidiEvent) mEventScheduler.getNextEvent(now);
- }
- }
-
- /**
- *
- */
- private void generateBuffer() {
- for (int i = 0; i < mBuffer.length; i++) {
- mBuffer[i] = 0.0f;
- }
- Iterator<SynthVoice> iterator = mVoices.values().iterator();
- while (iterator.hasNext()) {
- SynthVoice voice = iterator.next();
- if (voice.isDone()) {
- iterator.remove();
- // mFreeVoices.add(voice);
- } else {
- voice.mix(mBuffer, SAMPLES_PER_FRAME, 0.25f);
- }
- }
- }
-
- public void noteOff(int channel, int noteIndex, int velocity) {
- SynthVoice voice = mVoices.get(noteIndex);
- if (voice != null) {
- voice.noteOff();
- }
- }
-
- public void allNotesOff() {
- Iterator<SynthVoice> iterator = mVoices.values().iterator();
- while (iterator.hasNext()) {
- SynthVoice voice = iterator.next();
- voice.noteOff();
- }
- }
-
- /**
- * Create a SynthVoice.
- */
- public SynthVoice createVoice(int program) {
- // For every odd program number use a sine wave.
- if ((program & 1) == 1) {
- return new SineVoice();
- } else {
- return new SawVoice();
- }
- }
-
- /**
- *
- * @param channel
- * @param noteIndex
- * @param velocity
- */
- public void noteOn(int channel, int noteIndex, int velocity) {
- if (velocity == 0) {
- noteOff(channel, noteIndex, velocity);
- } else {
- mVoices.remove(noteIndex);
- SynthVoice voice;
- if (mFreeVoices.size() > 0) {
- voice = mFreeVoices.remove(mFreeVoices.size() - 1);
- } else {
- voice = createVoice(mProgram);
- }
- voice.setFrequencyScaler(mFrequencyScaler);
- voice.noteOn(noteIndex, velocity);
- mVoices.put(noteIndex, voice);
- }
- }
-
- public void pitchBend(int channel, int bend) {
- double semitones = (mBendRange * (bend - 0x2000)) / 0x2000;
- mFrequencyScaler = (float) Math.pow(2.0, semitones / 12.0);
- Iterator<SynthVoice> iterator = mVoices.values().iterator();
- while (iterator.hasNext()) {
- SynthVoice voice = iterator.next();
- voice.setFrequencyScaler(mFrequencyScaler);
- }
- }
-
- /**
- * Start the synthesizer.
- */
- public void start() {
- stop();
- go = true;
- mThread = new Thread(new MyRunnable());
- mEventScheduler = new MidiEventScheduler();
- mThread.start();
- }
-
- /**
- * Stop the synthesizer.
- */
- public void stop() {
- go = false;
- if (mThread != null) {
- try {
- mThread.interrupt();
- mThread.join(500);
- } catch (InterruptedException e) {
- // OK, just stopping safely.
- }
- mThread = null;
- mEventScheduler = null;
- }
- }
-}
diff --git a/common/src/java/com/example/android/common/midi/synth/SynthUnit.java b/common/src/java/com/example/android/common/midi/synth/SynthUnit.java
deleted file mode 100644
index 90599e2..0000000
--- a/common/src/java/com/example/android/common/midi/synth/SynthUnit.java
+++ /dev/null
@@ -1,35 +0,0 @@
-/*
- * Copyright (C) 2015 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.example.android.common.midi.synth;
-
-public abstract class SynthUnit {
-
- private static final double CONCERT_A_PITCH = 69.0;
- private static final double CONCERT_A_FREQUENCY = 440.0;
-
- /**
- * @param pitch
- * MIDI pitch in semitones
- * @return frequency
- */
- public static double pitchToFrequency(double pitch) {
- double semitones = pitch - CONCERT_A_PITCH;
- return CONCERT_A_FREQUENCY * Math.pow(2.0, semitones / 12.0);
- }
-
- public abstract float render();
-}
diff --git a/common/src/java/com/example/android/common/midi/synth/SynthVoice.java b/common/src/java/com/example/android/common/midi/synth/SynthVoice.java
deleted file mode 100644
index 78ba09a..0000000
--- a/common/src/java/com/example/android/common/midi/synth/SynthVoice.java
+++ /dev/null
@@ -1,85 +0,0 @@
-/*
- * Copyright (C) 2015 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.example.android.common.midi.synth;
-
-/**
- * Base class for a polyphonic synthesizer voice.
- */
-public abstract class SynthVoice {
- private int mNoteIndex;
- private float mAmplitude;
- public static final int STATE_OFF = 0;
- public static final int STATE_ON = 1;
- private int mState = STATE_OFF;
-
- public SynthVoice() {
- mNoteIndex = -1;
- }
-
- public void noteOn(int noteIndex, int velocity) {
- mState = STATE_ON;
- this.mNoteIndex = noteIndex;
- setAmplitude(velocity / 128.0f);
- }
-
- public void noteOff() {
- mState = STATE_OFF;
- }
-
- /**
- * Add the output of this voice to an output buffer.
- *
- * @param outputBuffer
- * @param samplesPerFrame
- * @param level
- */
- public void mix(float[] outputBuffer, int samplesPerFrame, float level) {
- int numFrames = outputBuffer.length / samplesPerFrame;
- for (int i = 0; i < numFrames; i++) {
- float output = render();
- int offset = i * samplesPerFrame;
- for (int jf = 0; jf < samplesPerFrame; jf++) {
- outputBuffer[offset + jf] += output * level;
- }
- }
- }
-
- public abstract float render();
-
- public boolean isDone() {
- return mState == STATE_OFF;
- }
-
- public int getNoteIndex() {
- return mNoteIndex;
- }
-
- public float getAmplitude() {
- return mAmplitude;
- }
-
- public void setAmplitude(float amplitude) {
- this.mAmplitude = amplitude;
- }
-
- /**
- * @param scaler
- */
- public void setFrequencyScaler(float scaler) {
- }
-
-}
diff --git a/media/MidiScope/Application/.gitignore b/media/MidiScope/Application/.gitignore
deleted file mode 100644
index 6eb878d..0000000
--- a/media/MidiScope/Application/.gitignore
+++ /dev/null
@@ -1,16 +0,0 @@
-# Copyright 2013 The Android Open Source Project
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-src/template/
-src/common/
-build.gradle
diff --git a/media/MidiScope/Application/proguard-project.txt b/media/MidiScope/Application/proguard-project.txt
deleted file mode 100644
index f2fe155..0000000
--- a/media/MidiScope/Application/proguard-project.txt
+++ /dev/null
@@ -1,20 +0,0 @@
-# To enable ProGuard in your project, edit project.properties
-# to define the proguard.config property as described in that file.
-#
-# Add project specific ProGuard rules here.
-# By default, the flags in this file are appended to flags specified
-# in ${sdk.dir}/tools/proguard/proguard-android.txt
-# You can edit the include path and order by changing the ProGuard
-# include property in project.properties.
-#
-# For more details, see
-# http://developer.android.com/guide/developing/tools/proguard.html
-
-# Add any project specific keep options here:
-
-# If your project uses WebView with JS, uncomment the following
-# and specify the fully qualified class name to the JavaScript interface
-# class:
-#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
-# public *;
-#}
diff --git a/media/MidiScope/Application/src/androidTest/java/com/example/android/midiscope/test/SampleTests.java b/media/MidiScope/Application/src/androidTest/java/com/example/android/midiscope/test/SampleTests.java
deleted file mode 100644
index e132dae..0000000
--- a/media/MidiScope/Application/src/androidTest/java/com/example/android/midiscope/test/SampleTests.java
+++ /dev/null
@@ -1,54 +0,0 @@
-/*
- * Copyright 2015 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.example.android.midiscope.test;
-
-import com.example.android.midiscope.*;
-
-import android.test.ActivityInstrumentationTestCase2;
-
-/**
- * Tests for MidiScope sample.
- */
-public class SampleTests extends ActivityInstrumentationTestCase2<MainActivity> {
-
- private MainActivity mTestActivity;
-
- public SampleTests() {
- super(MainActivity.class);
- }
-
- @Override
- protected void setUp() throws Exception {
- super.setUp();
-
- // Starts the activity under test using the default Intent with:
- // action = {@link Intent#ACTION_MAIN}
- // flags = {@link Intent#FLAG_ACTIVITY_NEW_TASK}
- // All other fields are null or empty.
- mTestActivity = getActivity();
- }
-
- /**
- * Test if the test fixture has been set up correctly.
- */
- public void testPreconditions() {
- //Try to add a message to add context to your assertions. These messages will be shown if
- //a tests fails and make it easy to understand why a test failed
- assertNotNull("mTestActivity is null", mTestActivity);
- }
-
-}
diff --git a/media/MidiScope/Application/src/main/AndroidManifest.xml b/media/MidiScope/Application/src/main/AndroidManifest.xml
deleted file mode 100644
index 7e41105..0000000
--- a/media/MidiScope/Application/src/main/AndroidManifest.xml
+++ /dev/null
@@ -1,55 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
- Copyright 2015 The Android Open Source Project
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
--->
-<manifest
- package="com.example.android.midiscope"
- xmlns:android="http://schemas.android.com/apk/res/android"
- android:versionCode="1"
- android:versionName="1.0">
-
- <uses-feature
- android:name="android.software.midi"
- android:required="true"/>
-
- <application
- android:allowBackup="true"
- android:icon="@mipmap/ic_launcher"
- android:label="@string/app_name"
- android:theme="@style/AppTheme">
-
- <activity
- android:name=".MainActivity"
- android:label="@string/app_name">
- <intent-filter>
- <action android:name="android.intent.action.MAIN"/>
- <category android:name="android.intent.category.LAUNCHER"/>
- </intent-filter>
- </activity>
-
- <service
- android:name="MidiScope"
- android:permission="android.permission.BIND_MIDI_DEVICE_SERVICE">
- <intent-filter>
- <action android:name="android.media.midi.MidiDeviceService"/>
- </intent-filter>
- <meta-data
- android:name="android.media.midi.MidiDeviceService"
- android:resource="@xml/scope_device_info"/>
- </service>
-
- </application>
-
-</manifest>
diff --git a/media/MidiScope/Application/src/main/java/com/example/android/midiscope/LoggingReceiver.java b/media/MidiScope/Application/src/main/java/com/example/android/midiscope/LoggingReceiver.java
deleted file mode 100644
index 23ce8f7..0000000
--- a/media/MidiScope/Application/src/main/java/com/example/android/midiscope/LoggingReceiver.java
+++ /dev/null
@@ -1,62 +0,0 @@
-/*
- * Copyright (C) 2015 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.example.android.midiscope;
-
-import android.media.midi.MidiReceiver;
-import android.util.Log;
-
-import java.io.IOException;
-import java.util.concurrent.TimeUnit;
-
-/**
- * Convert incoming MIDI messages to a string and write them to a ScopeLogger.
- * Assume that messages have been aligned using a MidiFramer.
- */
-public class LoggingReceiver extends MidiReceiver {
- public static final String TAG = "MidiScope";
- private static final long NANOS_PER_SECOND = TimeUnit.SECONDS.toNanos(1);
- private long mStartTime;
- private ScopeLogger mLogger;
-
- public LoggingReceiver(ScopeLogger logger) {
- mStartTime = System.nanoTime();
- mLogger = logger;
- }
-
- /*
- * @see android.media.midi.MidiReceiver#onReceive(byte[], int, int, long)
- */
- @Override
- public void onSend(byte[] data, int offset, int count, long timestamp)
- throws IOException {
- StringBuilder sb = new StringBuilder();
- if (timestamp == 0) {
- sb.append(String.format("-----0----: "));
- } else {
- long monoTime = timestamp - mStartTime;
- double seconds = (double) monoTime / NANOS_PER_SECOND;
- sb.append(String.format("%10.3f: ", seconds));
- }
- sb.append(MidiPrinter.formatBytes(data, offset, count));
- sb.append(": ");
- sb.append(MidiPrinter.formatMessage(data, offset, count));
- String text = sb.toString();
- mLogger.log(text);
- Log.i(TAG, text);
- }
-
-}
\ No newline at end of file
diff --git a/media/MidiScope/Application/src/main/java/com/example/android/midiscope/MainActivity.java b/media/MidiScope/Application/src/main/java/com/example/android/midiscope/MainActivity.java
deleted file mode 100644
index 41d74f0..0000000
--- a/media/MidiScope/Application/src/main/java/com/example/android/midiscope/MainActivity.java
+++ /dev/null
@@ -1,162 +0,0 @@
-/*
- * Copyright (C) 2015 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.example.android.midiscope;
-
-import android.app.ActionBar;
-import android.app.Activity;
-import android.media.midi.MidiDeviceInfo;
-import android.media.midi.MidiManager;
-import android.media.midi.MidiReceiver;
-import android.os.Bundle;
-import android.view.Menu;
-import android.view.MenuItem;
-import android.view.View;
-import android.view.WindowManager;
-import android.widget.ScrollView;
-import android.widget.TextView;
-import android.widget.Toolbar;
-
-import com.example.android.common.midi.MidiFramer;
-import com.example.android.common.midi.MidiOutputPortSelector;
-import com.example.android.common.midi.MidiPortWrapper;
-
-import java.util.LinkedList;
-
-/**
- * App that provides a MIDI echo service.
- */
-public class MainActivity extends Activity implements ScopeLogger {
-
- private static final int MAX_LINES = 100;
-
- private final LinkedList<String> mLogLines = new LinkedList<>();
- private TextView mLog;
- private ScrollView mScroller;
- private MidiOutputPortSelector mLogSenderSelector;
-
- @Override
- public void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- setContentView(R.layout.main);
-
- setActionBar((Toolbar) findViewById(R.id.toolbar));
- ActionBar actionBar = getActionBar();
- if (actionBar != null) {
- actionBar.setDisplayShowTitleEnabled(false);
- }
-
- mLog = (TextView) findViewById(R.id.log);
- mScroller = (ScrollView) findViewById(R.id.scroll);
-
- // Setup MIDI
- MidiManager midiManager = (MidiManager) getSystemService(MIDI_SERVICE);
-
- // Receiver that prints the messages.
- MidiReceiver loggingReceiver = new LoggingReceiver(this);
-
- // Receiver that parses raw data into complete messages.
- MidiFramer connectFramer = new MidiFramer(loggingReceiver);
-
- // Setup a menu to select an input source.
- mLogSenderSelector = new MidiOutputPortSelector(midiManager, this, R.id.spinner_senders) {
- @Override
- public void onPortSelected(final MidiPortWrapper wrapper) {
- super.onPortSelected(wrapper);
- if (wrapper != null) {
- mLogLines.clear();
- MidiDeviceInfo deviceInfo = wrapper.getDeviceInfo();
- if (deviceInfo == null) {
- log(getString(R.string.header_text));
- } else {
- log(MidiPrinter.formatDeviceInfo(deviceInfo));
- }
- }
- }
- };
- mLogSenderSelector.getSender().connect(connectFramer);
-
- // Tell the virtual device to log its messages here..
- MidiScope.setScopeLogger(this);
- }
-
- @Override
- public void onDestroy() {
- mLogSenderSelector.onClose();
- // The scope will live on as a service so we need to tell it to stop
- // writing log messages to this Activity.
- MidiScope.setScopeLogger(null);
- super.onDestroy();
- }
-
- @Override
- public boolean onCreateOptionsMenu(Menu menu) {
- getMenuInflater().inflate(R.menu.main, menu);
- setKeepScreenOn(menu.findItem(R.id.action_keep_screen_on).isChecked());
- return true;
- }
-
- @Override
- public boolean onOptionsItemSelected(MenuItem item) {
- switch (item.getItemId()) {
- case R.id.action_clear_all:
- mLogLines.clear();
- logOnUiThread("");
- break;
- case R.id.action_keep_screen_on:
- boolean checked = !item.isChecked();
- setKeepScreenOn(checked);
- item.setChecked(checked);
- break;
- }
- return super.onOptionsItemSelected(item);
- }
-
- private void setKeepScreenOn(boolean keepScreenOn) {
- if (keepScreenOn) {
- getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
- } else {
- getWindow().clearFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
- }
- }
-
- @Override
- public void log(final String string) {
- runOnUiThread(new Runnable() {
- @Override
- public void run() {
- logOnUiThread(string);
- }
- });
- }
-
- /**
- * Logs a message to our TextView. This needs to be called from the UI thread.
- */
- private void logOnUiThread(String s) {
- mLogLines.add(s);
- if (mLogLines.size() > MAX_LINES) {
- mLogLines.removeFirst();
- }
- // Render line buffer to one String.
- StringBuilder sb = new StringBuilder();
- for (String line : mLogLines) {
- sb.append(line).append('\n');
- }
- mLog.setText(sb.toString());
- mScroller.fullScroll(View.FOCUS_DOWN);
- }
-}
diff --git a/media/MidiScope/Application/src/main/java/com/example/android/midiscope/MidiPrinter.java b/media/MidiScope/Application/src/main/java/com/example/android/midiscope/MidiPrinter.java
deleted file mode 100644
index 9e97c04..0000000
--- a/media/MidiScope/Application/src/main/java/com/example/android/midiscope/MidiPrinter.java
+++ /dev/null
@@ -1,108 +0,0 @@
-/*
- * Copyright (C) 2015 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.example.android.midiscope;
-
-import android.media.midi.MidiDeviceInfo;
-import android.media.midi.MidiDeviceInfo.PortInfo;
-import android.os.Bundle;
-
-import com.example.android.common.midi.MidiConstants;
-
-/**
- * Format a MIDI message for printing.
- */
-public class MidiPrinter {
-
- public static final String[] CHANNEL_COMMAND_NAMES = { "NoteOff", "NoteOn",
- "PolyTouch", "Control", "Program", "Pressure", "Bend" };
- public static final String[] SYSTEM_COMMAND_NAMES = { "SysEx", // F0
- "TimeCode", // F1
- "SongPos", // F2
- "SongSel", // F3
- "F4", // F4
- "F5", // F5
- "TuneReq", // F6
- "EndSysex", // F7
- "TimingClock", // F8
- "F9", // F9
- "Start", // FA
- "Continue", // FB
- "Stop", // FC
- "FD", // FD
- "ActiveSensing", // FE
- "Reset" // FF
- };
-
- public static String getName(int status) {
- if (status >= 0xF0) {
- int index = status & 0x0F;
- return SYSTEM_COMMAND_NAMES[index];
- } else if (status >= 0x80) {
- int index = (status >> 4) & 0x07;
- return CHANNEL_COMMAND_NAMES[index];
- } else {
- return "data";
- }
- }
-
- public static String formatBytes(byte[] data, int offset, int count) {
- StringBuilder sb = new StringBuilder();
- for (int i = 0; i < count; i++) {
- sb.append(String.format(" %02X", data[offset + i]));
- }
- return sb.toString();
- }
-
- public static String formatMessage(byte[] data, int offset, int count) {
- StringBuilder sb = new StringBuilder();
- byte statusByte = data[offset++];
- int status = statusByte & 0xFF;
- sb.append(getName(status)).append("(");
- int numData = MidiConstants.getBytesPerMessage(statusByte) - 1;
- if ((status >= 0x80) && (status < 0xF0)) { // channel message
- int channel = status & 0x0F;
- // Add 1 for humans who think channels are numbered 1-16.
- sb.append((channel + 1)).append(", ");
- }
- for (int i = 0; i < numData; i++) {
- if (i > 0) {
- sb.append(", ");
- }
- sb.append(data[offset++]);
- }
- sb.append(")");
- return sb.toString();
- }
-
- public static String formatDeviceInfo(MidiDeviceInfo info) {
- StringBuilder sb = new StringBuilder();
- if (info != null) {
- Bundle properties = info.getProperties();
- for (String key : properties.keySet()) {
- Object value = properties.get(key);
- sb.append(key).append(" = ").append(value).append('\n');
- }
- for (PortInfo port : info.getPorts()) {
- sb.append((port.getType() == PortInfo.TYPE_INPUT) ? "input"
- : "output");
- sb.append("[").append(port.getPortNumber()).append("] = \"").append(port.getName()
- + "\"\n");
- }
- }
- return sb.toString();
- }
-}
diff --git a/media/MidiScope/Application/src/main/java/com/example/android/midiscope/MidiScope.java b/media/MidiScope/Application/src/main/java/com/example/android/midiscope/MidiScope.java
deleted file mode 100644
index 3965d83..0000000
--- a/media/MidiScope/Application/src/main/java/com/example/android/midiscope/MidiScope.java
+++ /dev/null
@@ -1,83 +0,0 @@
-/*
- * Copyright (C) 2015 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.example.android.midiscope;
-
-import android.media.midi.MidiDeviceService;
-import android.media.midi.MidiDeviceStatus;
-import android.media.midi.MidiReceiver;
-
-import com.example.android.common.midi.MidiFramer;
-
-import java.io.IOException;
-
-/**
- * Virtual MIDI Device that logs messages to a ScopeLogger.
- */
-
-public class MidiScope extends MidiDeviceService {
-
- private static ScopeLogger mScopeLogger;
- private MidiReceiver mInputReceiver = new MyReceiver();
- private static MidiFramer mDeviceFramer;
-
- @Override
- public MidiReceiver[] onGetInputPortReceivers() {
- return new MidiReceiver[] { mInputReceiver };
- }
-
- public static ScopeLogger getScopeLogger() {
- return mScopeLogger;
- }
-
- public static void setScopeLogger(ScopeLogger logger) {
- if (logger != null) {
- // Receiver that prints the messages.
- LoggingReceiver loggingReceiver = new LoggingReceiver(logger);
- mDeviceFramer = new MidiFramer(loggingReceiver);
- }
- mScopeLogger = logger;
- }
-
- private static class MyReceiver extends MidiReceiver {
- @Override
- public void onSend(byte[] data, int offset, int count,
- long timestamp) throws IOException {
- if (mScopeLogger != null) {
- // Send raw data to be parsed into discrete messages.
- mDeviceFramer.send(data, offset, count, timestamp);
- }
- }
- }
-
- /**
- * This will get called when clients connect or disconnect.
- * Log device information.
- */
- @Override
- public void onDeviceStatusChanged(MidiDeviceStatus status) {
- if (mScopeLogger != null) {
- if (status.isInputPortOpen(0)) {
- mScopeLogger.log("=== connected ===");
- String text = MidiPrinter.formatDeviceInfo(
- status.getDeviceInfo());
- mScopeLogger.log(text);
- } else {
- mScopeLogger.log("--- disconnected ---");
- }
- }
- }
-}
diff --git a/media/MidiScope/Application/src/main/java/com/example/android/midiscope/ScopeLogger.java b/media/MidiScope/Application/src/main/java/com/example/android/midiscope/ScopeLogger.java
deleted file mode 100644
index dc52efd..0000000
--- a/media/MidiScope/Application/src/main/java/com/example/android/midiscope/ScopeLogger.java
+++ /dev/null
@@ -1,25 +0,0 @@
-/*
- * Copyright (C) 2015 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.example.android.midiscope;
-
-public interface ScopeLogger {
- /**
- * Write the text string somewhere that the user can see it.
- * @param text
- */
- void log(String text);
-}
diff --git a/media/MidiScope/Application/src/main/res/drawable-hdpi/ic_clear_all.png b/media/MidiScope/Application/src/main/res/drawable-hdpi/ic_clear_all.png
deleted file mode 100755
index e23d886..0000000
--- a/media/MidiScope/Application/src/main/res/drawable-hdpi/ic_clear_all.png
+++ /dev/null
Binary files differ
diff --git a/media/MidiScope/Application/src/main/res/drawable-mdpi/ic_clear_all.png b/media/MidiScope/Application/src/main/res/drawable-mdpi/ic_clear_all.png
deleted file mode 100755
index dca3048..0000000
--- a/media/MidiScope/Application/src/main/res/drawable-mdpi/ic_clear_all.png
+++ /dev/null
Binary files differ
diff --git a/media/MidiScope/Application/src/main/res/drawable-xhdpi/ic_clear_all.png b/media/MidiScope/Application/src/main/res/drawable-xhdpi/ic_clear_all.png
deleted file mode 100755
index fef5dcd..0000000
--- a/media/MidiScope/Application/src/main/res/drawable-xhdpi/ic_clear_all.png
+++ /dev/null
Binary files differ
diff --git a/media/MidiScope/Application/src/main/res/drawable-xxhdpi/ic_clear_all.png b/media/MidiScope/Application/src/main/res/drawable-xxhdpi/ic_clear_all.png
deleted file mode 100755
index 51d2d3d..0000000
--- a/media/MidiScope/Application/src/main/res/drawable-xxhdpi/ic_clear_all.png
+++ /dev/null
Binary files differ
diff --git a/media/MidiScope/Application/src/main/res/drawable-xxxhdpi/ic_clear_all.png b/media/MidiScope/Application/src/main/res/drawable-xxxhdpi/ic_clear_all.png
deleted file mode 100755
index 9dbccf3..0000000
--- a/media/MidiScope/Application/src/main/res/drawable-xxxhdpi/ic_clear_all.png
+++ /dev/null
Binary files differ
diff --git a/media/MidiScope/Application/src/main/res/layout/main.xml b/media/MidiScope/Application/src/main/res/layout/main.xml
deleted file mode 100644
index 71c52aa..0000000
--- a/media/MidiScope/Application/src/main/res/layout/main.xml
+++ /dev/null
@@ -1,60 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
- Copyright (C) 2015 The Android Open Source Project
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
--->
-
-<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
- android:layout_width="match_parent"
- android:layout_height="match_parent"
- android:orientation="vertical">
-
- <Toolbar
- android:id="@+id/toolbar"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:background="?android:attr/colorPrimary"
- android:elevation="4dp"
- android:minHeight="?android:attr/actionBarSize"
- android:popupTheme="@android:style/ThemeOverlay.Material.Light"
- android:theme="@android:style/ThemeOverlay.Material.Dark.ActionBar">
-
- <Spinner
- android:id="@+id/spinner_senders"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:entries="@array/senders"
- android:popupTheme="@android:style/ThemeOverlay.Material.Light"/>
-
- </Toolbar>
-
- <ScrollView
- android:id="@+id/scroll"
- android:layout_width="match_parent"
- android:layout_height="0px"
- android:layout_weight="1">
-
- <TextView
- android:id="@+id/log"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:paddingBottom="8dp"
- android:paddingEnd="16dp"
- android:paddingStart="16dp"
- android:paddingTop="8dp"
- android:textAppearance="?android:attr/textAppearanceMedium"/>
-
- </ScrollView>
-
-</LinearLayout>
diff --git a/media/MidiScope/Application/src/main/res/menu/main.xml b/media/MidiScope/Application/src/main/res/menu/main.xml
deleted file mode 100644
index abb1842..0000000
--- a/media/MidiScope/Application/src/main/res/menu/main.xml
+++ /dev/null
@@ -1,32 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
- Copyright 2015 The Android Open Source Project
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
--->
-<menu xmlns:android="http://schemas.android.com/apk/res/android">
-
- <item
- android:id="@+id/action_clear_all"
- android:icon="@drawable/ic_clear_all"
- android:showAsAction="ifRoom"
- android:title="@string/clear_log"/>
-
- <item
- android:id="@+id/action_keep_screen_on"
- android:checkable="true"
- android:checked="true"
- android:showAsAction="never"
- android:title="@string/keep_screen_on"/>
-
-</menu>
diff --git a/media/MidiScope/Application/src/main/res/mipmap-hdpi/ic_launcher.png b/media/MidiScope/Application/src/main/res/mipmap-hdpi/ic_launcher.png
deleted file mode 100755
index 4a75524..0000000
--- a/media/MidiScope/Application/src/main/res/mipmap-hdpi/ic_launcher.png
+++ /dev/null
Binary files differ
diff --git a/media/MidiScope/Application/src/main/res/mipmap-mdpi/ic_launcher.png b/media/MidiScope/Application/src/main/res/mipmap-mdpi/ic_launcher.png
deleted file mode 100755
index 09a4271..0000000
--- a/media/MidiScope/Application/src/main/res/mipmap-mdpi/ic_launcher.png
+++ /dev/null
Binary files differ
diff --git a/media/MidiScope/Application/src/main/res/mipmap-xhdpi/ic_launcher.png b/media/MidiScope/Application/src/main/res/mipmap-xhdpi/ic_launcher.png
deleted file mode 100755
index e9c9a36..0000000
--- a/media/MidiScope/Application/src/main/res/mipmap-xhdpi/ic_launcher.png
+++ /dev/null
Binary files differ
diff --git a/media/MidiScope/Application/src/main/res/mipmap-xxhdpi/ic_launcher.png b/media/MidiScope/Application/src/main/res/mipmap-xxhdpi/ic_launcher.png
deleted file mode 100755
index 6e79c3b..0000000
--- a/media/MidiScope/Application/src/main/res/mipmap-xxhdpi/ic_launcher.png
+++ /dev/null
Binary files differ
diff --git a/media/MidiScope/Application/src/main/res/mipmap-xxxhdpi/ic_launcher.png b/media/MidiScope/Application/src/main/res/mipmap-xxxhdpi/ic_launcher.png
deleted file mode 100755
index 638d4e1..0000000
--- a/media/MidiScope/Application/src/main/res/mipmap-xxxhdpi/ic_launcher.png
+++ /dev/null
Binary files differ
diff --git a/media/MidiScope/Application/src/main/res/values/colors.xml b/media/MidiScope/Application/src/main/res/values/colors.xml
deleted file mode 100644
index eef48d8..0000000
--- a/media/MidiScope/Application/src/main/res/values/colors.xml
+++ /dev/null
@@ -1,26 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
- Copyright 2015 The Android Open Source Project
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
--->
-<resources>
- <color name="primary">#009688</color>
- <color name="primary_dark">#00796B</color>
- <color name="primary_light">#B2DFDB</color>
- <color name="accent">#FFC107</color>
- <color name="primary_text">#212121</color>
- <color name="secondary_text">#727272</color>
- <color name="icons">#FFFFFF</color>
- <color name="divider">#B6B6B6</color>
-</resources>
diff --git a/media/MidiScope/Application/src/main/res/values/strings.xml b/media/MidiScope/Application/src/main/res/values/strings.xml
deleted file mode 100644
index 505f3d2..0000000
--- a/media/MidiScope/Application/src/main/res/values/strings.xml
+++ /dev/null
@@ -1,26 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
- Copyright 2015 The Android Open Source Project
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
--->
-<resources>
- <string name="app_name">MidiScope</string>
-
- <string name="header_text">Select a MIDI source from the Spinner above or send messages to MidiScope.</string>
- <string name="clear_log">Clear Log</string>
- <string name="keep_screen_on">Keep Screen On</string>
- <string-array name="senders">
- <item>"none"</item>
- </string-array>
-</resources>
diff --git a/media/MidiScope/Application/src/main/res/values/styles.xml b/media/MidiScope/Application/src/main/res/values/styles.xml
deleted file mode 100644
index bdea6da..0000000
--- a/media/MidiScope/Application/src/main/res/values/styles.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
- Copyright 2015 The Android Open Source Project
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
--->
-<resources>
-
- <style name="AppTheme" parent="android:Theme.Material.Light.NoActionBar">
- <item name="android:colorPrimary">@color/primary</item>
- <item name="android:colorPrimaryDark">@color/primary_dark</item>
- <item name="android:colorAccent">@color/accent</item>
- </style>
-
-</resources>
diff --git a/media/MidiScope/Application/src/main/res/xml/scope_device_info.xml b/media/MidiScope/Application/src/main/res/xml/scope_device_info.xml
deleted file mode 100644
index f89f110..0000000
--- a/media/MidiScope/Application/src/main/res/xml/scope_device_info.xml
+++ /dev/null
@@ -1,24 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
- Copyright 2015 The Android Open Source Project
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
--->
-<devices>
- <device
- name="AndroidMidiScope"
- manufacturer="AndroidTest"
- product="Scope">
- <input-port name="input"/>
- </device>
-</devices>
diff --git a/media/MidiScope/build.gradle b/media/MidiScope/build.gradle
deleted file mode 100644
index 9b6a9ce..0000000
--- a/media/MidiScope/build.gradle
+++ /dev/null
@@ -1,12 +0,0 @@
-
-
-// BEGIN_EXCLUDE
-import com.example.android.samples.build.SampleGenPlugin
-apply plugin: SampleGenPlugin
-
-samplegen {
- pathToBuild "../../../../build"
- pathToSamplesCommon "../../common"
-}
-apply from: "../../../../build/build.gradle"
-// END_EXCLUDE
diff --git a/media/MidiScope/buildSrc/build.gradle b/media/MidiScope/buildSrc/build.gradle
deleted file mode 100644
index d77115d..0000000
--- a/media/MidiScope/buildSrc/build.gradle
+++ /dev/null
@@ -1,16 +0,0 @@
-
-repositories {
- jcenter()
-}
-dependencies {
- compile 'org.freemarker:freemarker:2.3.20'
-}
-
-sourceSets {
- main {
- groovy {
- srcDir new File(rootDir, "../../../../../build/buildSrc/src/main/groovy")
- }
- }
-}
-
diff --git a/media/MidiScope/gradle/wrapper/gradle-wrapper.jar b/media/MidiScope/gradle/wrapper/gradle-wrapper.jar
deleted file mode 100644
index 8c0fb64..0000000
--- a/media/MidiScope/gradle/wrapper/gradle-wrapper.jar
+++ /dev/null
Binary files differ
diff --git a/media/MidiScope/gradle/wrapper/gradle-wrapper.properties b/media/MidiScope/gradle/wrapper/gradle-wrapper.properties
deleted file mode 100644
index afb3296..0000000
--- a/media/MidiScope/gradle/wrapper/gradle-wrapper.properties
+++ /dev/null
@@ -1,6 +0,0 @@
-#Wed Apr 10 15:27:10 PDT 2013
-distributionBase=GRADLE_USER_HOME
-distributionPath=wrapper/dists
-zipStoreBase=GRADLE_USER_HOME
-zipStorePath=wrapper/dists
-distributionUrl=http\://services.gradle.org/distributions/gradle-2.2.1-bin.zip
diff --git a/media/MidiScope/gradlew b/media/MidiScope/gradlew
deleted file mode 100755
index 91a7e26..0000000
--- a/media/MidiScope/gradlew
+++ /dev/null
@@ -1,164 +0,0 @@
-#!/usr/bin/env bash
-
-##############################################################################
-##
-## Gradle start up script for UN*X
-##
-##############################################################################
-
-# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
-DEFAULT_JVM_OPTS=""
-
-APP_NAME="Gradle"
-APP_BASE_NAME=`basename "$0"`
-
-# Use the maximum available, or set MAX_FD != -1 to use that value.
-MAX_FD="maximum"
-
-warn ( ) {
- echo "$*"
-}
-
-die ( ) {
- echo
- echo "$*"
- echo
- exit 1
-}
-
-# OS specific support (must be 'true' or 'false').
-cygwin=false
-msys=false
-darwin=false
-case "`uname`" in
- CYGWIN* )
- cygwin=true
- ;;
- Darwin* )
- darwin=true
- ;;
- MINGW* )
- msys=true
- ;;
-esac
-
-# For Cygwin, ensure paths are in UNIX format before anything is touched.
-if $cygwin ; then
- [ -n "$JAVA_HOME" ] && JAVA_HOME=`cygpath --unix "$JAVA_HOME"`
-fi
-
-# Attempt to set APP_HOME
-# Resolve links: $0 may be a link
-PRG="$0"
-# Need this for relative symlinks.
-while [ -h "$PRG" ] ; do
- ls=`ls -ld "$PRG"`
- link=`expr "$ls" : '.*-> \(.*\)$'`
- if expr "$link" : '/.*' > /dev/null; then
- PRG="$link"
- else
- PRG=`dirname "$PRG"`"/$link"
- fi
-done
-SAVED="`pwd`"
-cd "`dirname \"$PRG\"`/" >&-
-APP_HOME="`pwd -P`"
-cd "$SAVED" >&-
-
-CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
-
-# Determine the Java command to use to start the JVM.
-if [ -n "$JAVA_HOME" ] ; then
- if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
- # IBM's JDK on AIX uses strange locations for the executables
- JAVACMD="$JAVA_HOME/jre/sh/java"
- else
- JAVACMD="$JAVA_HOME/bin/java"
- fi
- if [ ! -x "$JAVACMD" ] ; then
- die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
-
-Please set the JAVA_HOME variable in your environment to match the
-location of your Java installation."
- fi
-else
- JAVACMD="java"
- which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
-
-Please set the JAVA_HOME variable in your environment to match the
-location of your Java installation."
-fi
-
-# Increase the maximum file descriptors if we can.
-if [ "$cygwin" = "false" -a "$darwin" = "false" ] ; then
- MAX_FD_LIMIT=`ulimit -H -n`
- if [ $? -eq 0 ] ; then
- if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
- MAX_FD="$MAX_FD_LIMIT"
- fi
- ulimit -n $MAX_FD
- if [ $? -ne 0 ] ; then
- warn "Could not set maximum file descriptor limit: $MAX_FD"
- fi
- else
- warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
- fi
-fi
-
-# For Darwin, add options to specify how the application appears in the dock
-if $darwin; then
- GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
-fi
-
-# For Cygwin, switch paths to Windows format before running java
-if $cygwin ; then
- APP_HOME=`cygpath --path --mixed "$APP_HOME"`
- CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
-
- # We build the pattern for arguments to be converted via cygpath
- ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
- SEP=""
- for dir in $ROOTDIRSRAW ; do
- ROOTDIRS="$ROOTDIRS$SEP$dir"
- SEP="|"
- done
- OURCYGPATTERN="(^($ROOTDIRS))"
- # Add a user-defined pattern to the cygpath arguments
- if [ "$GRADLE_CYGPATTERN" != "" ] ; then
- OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
- fi
- # Now convert the arguments - kludge to limit ourselves to /bin/sh
- i=0
- for arg in "$@" ; do
- CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
- CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
-
- if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
- eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
- else
- eval `echo args$i`="\"$arg\""
- fi
- i=$((i+1))
- done
- case $i in
- (0) set -- ;;
- (1) set -- "$args0" ;;
- (2) set -- "$args0" "$args1" ;;
- (3) set -- "$args0" "$args1" "$args2" ;;
- (4) set -- "$args0" "$args1" "$args2" "$args3" ;;
- (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
- (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
- (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
- (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
- (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
- esac
-fi
-
-# Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules
-function splitJvmOpts() {
- JVM_OPTS=("$@")
-}
-eval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS
-JVM_OPTS[${#JVM_OPTS[*]}]="-Dorg.gradle.appname=$APP_BASE_NAME"
-
-exec "$JAVACMD" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@"
diff --git a/media/MidiScope/gradlew.bat b/media/MidiScope/gradlew.bat
deleted file mode 100644
index aec9973..0000000
--- a/media/MidiScope/gradlew.bat
+++ /dev/null
@@ -1,90 +0,0 @@
-@if "%DEBUG%" == "" @echo off
-@rem ##########################################################################
-@rem
-@rem Gradle startup script for Windows
-@rem
-@rem ##########################################################################
-
-@rem Set local scope for the variables with windows NT shell
-if "%OS%"=="Windows_NT" setlocal
-
-@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
-set DEFAULT_JVM_OPTS=
-
-set DIRNAME=%~dp0
-if "%DIRNAME%" == "" set DIRNAME=.
-set APP_BASE_NAME=%~n0
-set APP_HOME=%DIRNAME%
-
-@rem Find java.exe
-if defined JAVA_HOME goto findJavaFromJavaHome
-
-set JAVA_EXE=java.exe
-%JAVA_EXE% -version >NUL 2>&1
-if "%ERRORLEVEL%" == "0" goto init
-
-echo.
-echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
-echo.
-echo Please set the JAVA_HOME variable in your environment to match the
-echo location of your Java installation.
-
-goto fail
-
-:findJavaFromJavaHome
-set JAVA_HOME=%JAVA_HOME:"=%
-set JAVA_EXE=%JAVA_HOME%/bin/java.exe
-
-if exist "%JAVA_EXE%" goto init
-
-echo.
-echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
-echo.
-echo Please set the JAVA_HOME variable in your environment to match the
-echo location of your Java installation.
-
-goto fail
-
-:init
-@rem Get command-line arguments, handling Windowz variants
-
-if not "%OS%" == "Windows_NT" goto win9xME_args
-if "%@eval[2+2]" == "4" goto 4NT_args
-
-:win9xME_args
-@rem Slurp the command line arguments.
-set CMD_LINE_ARGS=
-set _SKIP=2
-
-:win9xME_args_slurp
-if "x%~1" == "x" goto execute
-
-set CMD_LINE_ARGS=%*
-goto execute
-
-:4NT_args
-@rem Get arguments from the 4NT Shell from JP Software
-set CMD_LINE_ARGS=%$
-
-:execute
-@rem Setup the command line
-
-set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
-
-@rem Execute Gradle
-"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
-
-:end
-@rem End local scope for the variables with windows NT shell
-if "%ERRORLEVEL%"=="0" goto mainEnd
-
-:fail
-rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
-rem the _cmd.exe /c_ return code!
-if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
-exit /b 1
-
-:mainEnd
-if "%OS%"=="Windows_NT" endlocal
-
-:omega
diff --git a/media/MidiScope/screenshots/1-main.png b/media/MidiScope/screenshots/1-main.png
deleted file mode 100644
index 0b4fb8e..0000000
--- a/media/MidiScope/screenshots/1-main.png
+++ /dev/null
Binary files differ
diff --git a/media/MidiScope/screenshots/2-signals.png b/media/MidiScope/screenshots/2-signals.png
deleted file mode 100644
index 7e4b443..0000000
--- a/media/MidiScope/screenshots/2-signals.png
+++ /dev/null
Binary files differ
diff --git a/media/MidiScope/screenshots/icon-web.png b/media/MidiScope/screenshots/icon-web.png
deleted file mode 100644
index 6daec5c..0000000
--- a/media/MidiScope/screenshots/icon-web.png
+++ /dev/null
Binary files differ
diff --git a/media/MidiScope/settings.gradle b/media/MidiScope/settings.gradle
deleted file mode 100644
index 0a5c310..0000000
--- a/media/MidiScope/settings.gradle
+++ /dev/null
@@ -1,2 +0,0 @@
-
-include 'Application'
diff --git a/media/MidiScope/template-params.xml b/media/MidiScope/template-params.xml
deleted file mode 100644
index efdfa2d..0000000
--- a/media/MidiScope/template-params.xml
+++ /dev/null
@@ -1,78 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
- Copyright 2015 The Android Open Source Project
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
--->
-<sample>
- <name>MidiScope</name>
- <group>Media</group>
- <package>com.example.android.midiscope</package>
- <minSdk>'MNC'</minSdk>
- <compileSdkVersion>'android-MNC'</compileSdkVersion>
-
- <strings>
- <intro>
- <![CDATA[
-This sample demonstrates how to use the MIDI API to receive and process MIDI signals coming from an
-attached input device.
- ]]>
- </intro>
- </strings>
-
- <common src="midi"/>
-
- <metadata>
- <status>PUBLISHED</status>
- <categories>Media</categories>
- <technologies>Android</technologies>
- <languages>Java</languages>
- <solutions>Mobile</solutions>
- <level>INTERMEDIATE</level>
- <icon>screenshots/icon-web.png</icon>
- <screenshots>
- <img>screenshots/1-main.png</img>
- <img>screenshots/2-settings.png</img>
- </screenshots>
- <api_refs>
- <android>android.media.midi.MidiManager</android>
- <android>android.media.midi.MidiReceiver</android>
- </api_refs>
-
- <!-- 1-3 line description of the sample here.
-
- Avoid simply rearranging the sample's title. What does this sample actually
- accomplish, and how does it do it? -->
- <description>
- <![CDATA[
-Sample demonstrating how to use the MIDI API to receive and process MIDI signals coming from an
-attached device.
- ]]>
- </description>
-
- <!-- Multi-paragraph introduction to sample, from an educational point-of-view.
- Makrdown formatting allowed. This will be used to generate a mini-article for the
- sample on DAC. -->
- <intro>
- <![CDATA[
-The Android MIDI API ([android.media.midi][1]) allows developers to connect a MIDI device to Android
-and process MIDI signals coming from it. This sample demonstrates some basic features of the MIDI
-API, such as enumeration of currently available devices (Information includes name, vendor,
-capabilities, etc), notification when MIDI devices are plugged in or unplugged, and receiving MIDI
-signals. This sample simply shows all the received MIDI signals to the screen log and does not play
-any sound for them.
-[1]: https://developer.android.com/reference/android/media/midi/package-summary.html
- ]]>
- </intro>
- </metadata>
-</sample>