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.R;
import com.levien.synthesizer.android.AndroidGlue; import com.levien.synthesizer.android.AndroidGlue;
import com.levien.synthesizer.android.usb.UsbMidiDevice; 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.midi.MidiListener;
import com.levien.synthesizer.core.model.composite.MultiChannelSynthesizer; import com.levien.synthesizer.core.model.composite.MultiChannelSynthesizer;
@ -85,6 +86,15 @@ public class SynthesizerService extends Service {
params.bufferSize = 64; params.bufferSize = 64;
androidGlue_ = new AndroidGlue(); 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); androidGlue_.start(params.sampleRate, params.bufferSize);
InputStream patchIs = getResources().openRawResource(R.raw.rom1a); InputStream patchIs = getResources().openRawResource(R.raw.rom1a);
byte[] patchData = new byte[4104]; byte[] patchData = new byte[4104];
@ -129,7 +139,7 @@ public class SynthesizerService extends Service {
} }
public MidiListener getMidiListener() { public MidiListener getMidiListener() {
return androidGlue_; return midiListener_;
} }
/** /**
@ -214,7 +224,7 @@ public class SynthesizerService extends Service {
usbDevice_ = device; usbDevice_ = device;
usbMidiConnection_ = connection; usbMidiConnection_ = connection;
usbMidiInterface_ = intf; usbMidiInterface_ = intf;
usbMidiDevice_ = new UsbMidiDevice(androidGlue_, usbMidiConnection_, intf); usbMidiDevice_ = new UsbMidiDevice(midiListener_, usbMidiConnection_, intf);
usbMidiDevice_.start(); usbMidiDevice_.start();
return true; return true;
} else { } 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. // Binder to use for Activities in this process.
private final IBinder binder_ = new LocalBinder(); private final IBinder binder_ = new LocalBinder();
@ -275,4 +295,7 @@ public class SynthesizerService extends Service {
private UsbMidiDevice usbMidiDevice_; private UsbMidiDevice usbMidiDevice_;
private UsbInterface usbMidiInterface_; private UsbInterface usbMidiInterface_;
private UsbDevice usbDeviceNeedsPermission_; 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.LocalBinder binder = (SynthesizerService.LocalBinder)service;
synthesizerService_ = binder.getService(); synthesizerService_ = binder.getService();
piano_.bindTo(synthesizerService_.getMidiListener()); 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(); List<String> patchNames = synthesizerService_.getPatchNames();
ArrayAdapter<String> adapter = new ArrayAdapter<String>( ArrayAdapter<String> adapter = new ArrayAdapter<String>(
PianoActivity2.this, android.R.layout.simple_spinner_item, patchNames); PianoActivity2.this, android.R.layout.simple_spinner_item, patchNames);
adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item); adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
presetSpinner_.setAdapter(adapter); presetSpinner_.setAdapter(adapter);
// Handle any pending USB device events
if (usbDevicePending_ != null) { if (usbDevicePending_ != null) {
synthesizerService_.connectUsbMidi(usbDevicePending_); synthesizerService_.connectUsbMidi(usbDevicePending_);
usbDevicePending_ = null; 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) { public void onServiceDisconnected(ComponentName className) {
synthesizerService_ = null; 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) { public void setValue(double value) {
if (value < min_) { if (value < min_) {
@ -157,9 +159,6 @@ public class KnobView extends View {
} else { } else {
knobValue_ = (value - min_) / (max_ - min_); knobValue_ = (value - min_) / (max_ - min_);
} }
if (listener_ != null) {
listener_.onKnobChanged(value);
}
invalidate(); invalidate();
} }

Loading…
Cancel
Save