Android MIDI Over BLE을 시도했습니다.
Android는 6.0(SDK 23)에서 Android MIDI
지금까지 Android에서 MIDI를 사용하기 위해서.
그리고 안드로이드 MIDI에서는 향기 소지도 사용할 수 있기 때문에 그것을 해 보겠습니다.
Apple의 BLE MIDI 규격을 사용할 수 있다는 것은 Mac과 연결할 수도 있다는 것입니다만, 모처럼이니까 이번에는 이전에 만든 Apple의 BLE MIDI 표준을 사용했습니다.
이거
이거는 뭔가 간단하게 설명하면, 자작의 MIDI 컨트롤러입니다.
8자에 비어 있는 곳이 터치 센서가 되어 있어, 악어 입 클립으로 야채나 바나나라든지와 연결해 악기로 해 버립니다.
그것을 BLE MIDI로 iPad로 보내 GarageBand에서 소리를 들고 놀았는데, 이 이야기는 그다지 상관없기 때문에 이 정도로 할 때입니다.
BluetoothDevice 검색
먼저 Android 6.0부터 Ble 스캔에 ACCESS_COARSE_LOCATION 또는 ACCESS_FINE_LOCATION이 필요합니다.
<uses-permission android:name="android.permission.BLUETOOTH"/>
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN"/>
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/>
요청합니다.
if (checkSelfPermission(Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
requestPermissions(new String[]{Manifest.permission.ACCESS_COARSE_LOCATION}, 0);
}
스캔하여 검색된 BluetoothDevice를 저장합니다.
static final UUID MIDI_SERVICE_UUID = UUID.fromString("03B80E5A-EDE8-4B33-A751-6CE34EC4C700");
BluetoothDevice mDevice = null;
void scanStart() {
ScanSettings settings = new ScanSettings.Builder().setScanMode(ScanSettings.SCAN_MODE_LOW_LATENCY).build();
ScanFilter uuidFilter = new ScanFilter.Builder().setServiceUuid(new ParcelUuid(MIDI_SERVICE_UUID)).build();
List<ScanFilter> scanFilters = new ArrayList<>();
scanFilters.add(uuidFilter);
BluetoothAdapter.getDefaultAdapter().getBluetoothLeScanner().startScan(scanFilters, settings, mScanCallback);
}
void scanStop() {
BluetoothAdapter.getDefaultAdapter().getBluetoothLeScanner().stopScan(mScanCallback);
}
ScanCallback mScanCallback =
new ScanCallback() {
@Override
public void onScanResult(int callbackType, ScanResult result) {
mDevice = result.getDevice();
scanStop();
}
@Override
public void onBatchScanResults(List<ScanResult> results) {
if(0 < results.size()){
mDevice = results.get(0).getDevice();
}
scanStop();
}
@Override
public void onScanFailed(int errorCode) {
scanStop();
}
};
BluetoothDevice에 연결
BluetoothDevice를 MIDI 장치로 연결합니다.
MidiManager m = (MidiManager) getSystemService(Context.MIDI_SERVICE);
m.openBluetoothDevice(mDevice, new MidiManager.OnDeviceOpenedListener() {
@Override
public void onDeviceOpened(MidiDevice device) {
if(0 < device.getInfo().getOutputPortCount()){
MidiOutputPort outputPort = device.openOutputPort(0);
outputPort.connect(new MyReceiver());
}
}
}, new Handler(Looper.getMainLooper()));
MyReceiver에서 수신합니다.
※ 우선 노트 온·노트 오프만.
class MyReceiver extends MidiReceiver {
@Override
public void onSend(byte[] data, int offset,
int count, long timestamp) throws IOException {
int i = offset;
byte message = (byte) (data[i++] & 0xF0);
byte noteNo = data[i++];
byte velocity = data[i];
if (message == (byte)0x80 || ((message == (byte)0x90 && velocity == 0))) {
Log.d(TAG, String.format("noteOff: 0x%02x", noteNo));
}else if (message == (byte)0x90) {
Log.d(TAG, String.format("noteOn: 0x%02x, velocity: 0x%02x", noteNo, velocity));
}
}
}
이번은 하고 있지 않습니다만, 송신도 할 수 있다고 합니다.
다른 앱에서 사용
iOS의 경우, Core MIDI에 대응하고 있지만, BLE MIDI에는 대응하지 않는 앱( Send a NoteOn - Android MIDI User Guide라든지)에서도 GarageBand 등으로 BLE MIDI 접속해 버리면, BLE라든지 관계없이 MIDI 디바이스로서 사용할 수 있도록(듯이) 됩니다.
이것이 Android MIDI에서도 가능한지 시도해 보았습니다.
BLE를 사용하지 않는 Android MIDI 앱 만들기
BLE 를 사용하지 않기 때문에 Permission 는 불필요합니다.
BLE를 사용하면 음악 앱인데 위치 정보의 허가가 필요하거나 사용자에게 알 수 없게 되어 버리므로 상당히 중요한 것입니다.
<!-- Permission 不要 -->
버튼 클릭하면 연결된 MIDI 장치의 목록을 가져와서 한 번에 연결합니다.
@Override
public void onClick(View v) {
MidiManager m = (MidiManager) getSystemService(Context.MIDI_SERVICE);
MidiDeviceInfo[] devices = m.getDevices();
Log.d(TAG, "devices: " + Arrays.toString(devices));
if(0 < devices.length){
m.openDevice(devices[0], new MidiManager.OnDeviceOpenedListener() {
@Override
public void onDeviceOpened(MidiDevice device) {
if(0 < device.getInfo().getOutputPortCount()){
MidiOutputPort outputPort = device.openOutputPort(0);
outputPort.connect(new MyReceiver());
}
}
}, new Handler(Looper.getMainLooper()));
}
}
MyReceiver는 조금 전과 같습니다.
BLE 지원 앱으로 연결한 후 BLE 지원 없는 앱에서 MIDI 장치 목록을 가져오면 다음과 같이 BluetoothDevice도 포함됩니다.
※ Log 출력 결과입니다.
devices: [MidiDeviceInfo[mType=3,mInputPortCount=1,mOutputPortCount=1,mProperties=Bundle[{name=WDMD01, bluetooth_device=C6:0E:FC:01:05:87}],mIsPrivate=false]
그 후, BLE MIDI 디바이스로부터, 노트 온·노트 오프를 보내면, BLE 비대응 앱에서도 제대로 수신할 수 있었습니다.
또한 BLE 지원 앱을 종료해도 연결이 살아있는 것처럼 보이지만 BLE 지원되지 않는 앱에서 여전히 수신할 수 있습니다.
이것이라면 GarageBand 와 같은, 표준이 되는 앱만 BLE MIDI 대응해 버리면, 다른 앱은 대응 불필요하게 되기 때문에 좋네요.
그렇다고 해도 Android에는 GarageBand가 없기 때문에 Music Studio의 Android 버전이라고 기대하고 있습니다.
요약
Android MIDI는 iOS의 Core MIDI와 마찬가지로 사용할 수 있습니다.
오, 그럼
BLE에는 대응하고 있지 않습니다만, Android MIDI API의 공식 샘플이 나온 것 같습니다.
Music Studio
Reference
이 문제에 관하여(Android MIDI Over BLE을 시도했습니다.), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://qiita.com/miyakeryo/items/b1a87cb3f55c902070aa텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)