Update controller views from MIDI keyboard

This patch adds plumbing so that changing the controller values from
a USB MIDI keyboard updates the knob views as well.
master
Raph Levien 11 years ago
parent b22117bb52
commit 7a5706054e
  1. 27
      android/src/com/levien/synthesizer/android/service/SynthesizerService.java
  2. 22
      android/src/com/levien/synthesizer/android/ui/PianoActivity2.java
  3. 7
      android/src/com/levien/synthesizer/android/widgets/knob/KnobView.java

@ -41,6 +41,7 @@ import android.util.Log;
import com.levien.synthesizer.R;
import com.levien.synthesizer.android.AndroidGlue;
import com.levien.synthesizer.android.usb.UsbMidiDevice;
import com.levien.synthesizer.core.midi.MessageForwarder;
import com.levien.synthesizer.core.midi.MidiListener;
import com.levien.synthesizer.core.model.composite.MultiChannelSynthesizer;
@ -85,6 +86,15 @@ public class SynthesizerService extends Service {
params.bufferSize = 64;
androidGlue_ = new AndroidGlue();
midiListener_ = new MessageForwarder(androidGlue_) {
@Override
public void onController(int channel, int control, int value) {
super.onController(channel, control, value);
if (onCcListener_!= null) {
onCcListener_.onCcChange(channel, control, value);
}
}
};
androidGlue_.start(params.sampleRate, params.bufferSize);
InputStream patchIs = getResources().openRawResource(R.raw.rom1a);
byte[] patchData = new byte[4104];
@ -129,7 +139,7 @@ public class SynthesizerService extends Service {
}
public MidiListener getMidiListener() {
return androidGlue_;
return midiListener_;
}
/**
@ -214,7 +224,7 @@ public class SynthesizerService extends Service {
usbDevice_ = device;
usbMidiConnection_ = connection;
usbMidiInterface_ = intf;
usbMidiDevice_ = new UsbMidiDevice(androidGlue_, usbMidiConnection_, intf);
usbMidiDevice_ = new UsbMidiDevice(midiListener_, usbMidiConnection_, intf);
usbMidiDevice_.start();
return true;
} else {
@ -262,6 +272,16 @@ public class SynthesizerService extends Service {
}
};
public interface OnCcListener {
abstract void onCcChange(int channel, int cc, int value);
}
public void setOnCcListener(OnCcListener onCcListener) {
onCcListener_ = onCcListener;
}
private MidiListener midiListener_;
// Binder to use for Activities in this process.
private final IBinder binder_ = new LocalBinder();
@ -275,4 +295,7 @@ public class SynthesizerService extends Service {
private UsbMidiDevice usbMidiDevice_;
private UsbInterface usbMidiInterface_;
private UsbDevice usbDeviceNeedsPermission_;
// Plumbing for MIDI events
private OnCcListener onCcListener_;
}

@ -205,11 +205,16 @@ public class PianoActivity2 extends Activity {
SynthesizerService.LocalBinder binder = (SynthesizerService.LocalBinder)service;
synthesizerService_ = binder.getService();
piano_.bindTo(synthesizerService_.getMidiListener());
// Populate patch names (note: we could update an existing list rather than
// creating a new adapter, but it probably wouldn't save all that much).
List<String> patchNames = synthesizerService_.getPatchNames();
ArrayAdapter<String> adapter = new ArrayAdapter<String>(
PianoActivity2.this, android.R.layout.simple_spinner_item, patchNames);
adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
presetSpinner_.setAdapter(adapter);
// Handle any pending USB device events
if (usbDevicePending_ != null) {
synthesizerService_.connectUsbMidi(usbDevicePending_);
usbDevicePending_ = null;
@ -225,6 +230,23 @@ public class PianoActivity2 extends Activity {
}
}
}
// Connect controller changes to knob views
synthesizerService_.setOnCcListener(new SynthesizerService.OnCcListener() {
public void onCcChange(final int channel, final int cc, final int value) {
runOnUiThread(new Runnable() {
public void run() {
if (cc == 1) {
cutoffKnob_.setValue(value * (1.0 / 127));
} else if (cc == 2) {
resonanceKnob_.setValue(value * (1.0 / 127));
} else if (cc == 3) {
overdriveKnob_.setValue(value * (1.0 / 127));
}
}
});
}
});
}
public void onServiceDisconnected(ComponentName className) {
synthesizerService_ = null;

@ -147,7 +147,9 @@ public class KnobView extends View {
}
/**
* Sets the current value of the knob.
* Sets the current value of the knob. Note that this call does not
* invoke the listener. The assumption is that any caller will also
* update the client.
*/
public void setValue(double value) {
if (value < min_) {
@ -157,9 +159,6 @@ public class KnobView extends View {
} else {
knobValue_ = (value - min_) / (max_ - min_);
}
if (listener_ != null) {
listener_.onKnobChanged(value);
}
invalidate();
}

Loading…
Cancel
Save