Here is the code . Remember that is was just a test, so it is very crude and incomplete, but it did work
These changes are against a juce git version from Tue Jul 23 17:38:25 2013 , but I think it should still work against juce 3
First I unpacked the kshoji driver stuff in the src directory of the android app
I did patch JuceAppActivity.java with this change:
--- JuceAppActivity.java.orig 2014-05-13 13:28:03.754755800 +0200
+++ JuceAppActivity.java 2014-05-13 13:30:27.740547200 +0200
@@ -53,9 +53,13 @@
import android.media.AudioManager;
import android.media.MediaScannerConnection;
import android.media.MediaScannerConnection.MediaScannerConnectionClient;
+import jp.kshoji.driver.midi.activity.AbstractMidiActivity;
+import android.util.Log;
+import android.hardware.usb.UsbManager;
+import android.content.DialogInterface.OnClickListener;
//==============================================================================
-public final class JuceAppActivity extends Activity
+public final class JuceAppActivity extends AbstractMidiActivity
{
//==============================================================================
static
@@ -63,6 +67,51 @@
System.loadLibrary ("juce_jni");
}
+ private native void midiInputCallback (int arg1, int arg2, int arg3);
+
+ @Override
+ public void onMidiMiscellaneousFunctionCodes(int cable, int byte1, int byte2, int byte3) {}
+
+ @Override
+ public void onMidiCableEvents(int cable, int byte1, int byte2, int byte3) {}
+
+ @Override
+ public void onMidiSystemCommonMessage(int cable, byte[] bytes) {}
+
+ @Override
+ public void onMidiSystemExclusive(int cable, byte[] systemExclusive) {}
+
+ @Override
+ public void onMidiNoteOff(int cable, int channel, int note, int velocity) {
+ midiInputCallback(channel + 0x80, note, velocity);
+ }
+
+ @Override
+ public void onMidiNoteOn(int cable, int channel, int note, int velocity) {
+ midiInputCallback(channel + 0x90, note, velocity);
+ }
+
+ @Override
+ public void onMidiPolyphonicAftertouch(int cable, int channel, int note, int pressure) {}
+
+ @Override
+ public void onMidiControlChange(int cable, int channel, int function, int value) {
+ midiInputCallback(channel + 0xB0, function, value);
+ }
+
+ @Override
+ public void onMidiProgramChange(int cable, int channel, int program) {}
+
+ @Override
+ public void onMidiChannelAftertouch(int cable, int channel, int pressure) {}
+
+ @Override
+ public void onMidiPitchWheel(int cable, int channel, int amount) {}
+
+ @Override
+ public void onMidiSingleByte(int cable, int byte1) {}
+
+
@Override
public final void onCreate (Bundle savedInstanceState)
{
I also changed juce_android_Midi.cpp:
StringArray MidiOutput::getDevices()
{
StringArray devices;
return devices;
}
int MidiOutput::getDefaultDeviceIndex()
{
return 0;
}
MidiOutput* MidiOutput::openDevice (int index)
{
return nullptr;
}
MidiOutput::~MidiOutput()
{
stopBackgroundThread();
}
void MidiOutput::sendMessageNow (const MidiMessage&)
{
}
//==============================================================================
struct AndroidMidiInput {
MidiInputCallback *callback;
MidiInput *owner;
bool started;
AndroidMidiInput(MidiInput *o, MidiInputCallback *cb) : callback(cb), owner(o), started(false) {
jassert(getInstance() == 0);
getInstance() = this;
}
~AndroidMidiInput() {
jassert(getInstance() == this);
getInstance() = 0;
}
void start() { started = true; }
void stop() { started = false; }
void handleIncomingMidiInput(int a1, int a2, int a3) {
if (callback) callback->handleIncomingMidiMessage(owner, MidiMessage(a1, a2, a3, 0.0));
}
static AndroidMidiInput *&getInstance() { static AndroidMidiInput *instance; return instance; }
};
MidiInput::MidiInput (const String& name_)
: name (name_),
internal (0)
{
}
MidiInput::~MidiInput()
{
delete static_cast <AndroidMidiInput*> (internal);
}
void MidiInput::start()
{static_cast <AndroidMidiInput*> (internal)->start();
}
void MidiInput::stop()
{static_cast <AndroidMidiInput*> (internal)->stop();
}
int MidiInput::getDefaultDeviceIndex()
{
return 0;
}
StringArray MidiInput::getDevices()
{
StringArray devs("USB Midi In");;
return devs;
}
JUCE_JNI_CALLBACK (JUCE_ANDROID_ACTIVITY_CLASSNAME, midiInputCallback, void, (JNIEnv* env, jobject activity,
jint arg1, jint arg2, jint arg3))
{
AndroidMidiInput *m = AndroidMidiInput::getInstance();
if (m) m->handleIncomingMidiInput(arg1, arg2, arg3);
}
MidiInput* MidiInput::openDevice (int index, MidiInputCallback* callback)
{
if (index == 0) {
MidiInput *m = new MidiInput("USB Midi In");
m->internal = new AndroidMidiInput(m, callback);
return m;
}
else return nullptr;
}