Home | History | Annotate | Download | only in midi
      1 /*
      2  * Copyright (C) 2015 The Android Open Source Project
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  *      http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License.
     15  */
     16 
     17 package com.example.android.common.midi;
     18 
     19 import android.media.midi.MidiDevice;
     20 import android.media.midi.MidiDevice.MidiConnection;
     21 import android.media.midi.MidiDeviceInfo;
     22 import android.media.midi.MidiInputPort;
     23 import android.media.midi.MidiManager;
     24 import android.os.Handler;
     25 import android.util.Log;
     26 
     27 import java.io.IOException;
     28 
     29 /**
     30  * Tool for connecting MIDI ports on two remote devices.
     31  */
     32 public class MidiPortConnector {
     33     private final MidiManager mMidiManager;
     34     private MidiDevice mSourceDevice;
     35     private MidiDevice mDestinationDevice;
     36     private MidiConnection mConnection;
     37 
     38     /**
     39      * @param mMidiManager
     40      */
     41     public MidiPortConnector(MidiManager midiManager) {
     42         mMidiManager = midiManager;
     43     }
     44 
     45     public void close() throws IOException {
     46         if (mConnection != null) {
     47             Log.i(MidiConstants.TAG,
     48                     "MidiPortConnector closing connection " + mConnection);
     49             mConnection.close();
     50             mConnection = null;
     51         }
     52         if (mSourceDevice != null) {
     53             mSourceDevice.close();
     54             mSourceDevice = null;
     55         }
     56         if (mDestinationDevice != null) {
     57             mDestinationDevice.close();
     58             mDestinationDevice = null;
     59         }
     60     }
     61 
     62     private void safeClose() {
     63         try {
     64             close();
     65         } catch (IOException e) {
     66             Log.e(MidiConstants.TAG, "could not close resources", e);
     67         }
     68     }
     69 
     70     /**
     71      * Listener class used for receiving the results of
     72      * {@link #connectToDevicePort}
     73      */
     74     public interface OnPortsConnectedListener {
     75         /**
     76          * Called to respond to a {@link #connectToDevicePort} request
     77          *
     78          * @param connection
     79          *            a {@link MidiConnection} that represents the connected
     80          *            ports, or null if connection failed
     81          */
     82         abstract public void onPortsConnected(MidiConnection connection);
     83     }
     84 
     85     /**
     86      * Open two devices and connect their ports.
     87      *
     88      * @param sourceDeviceInfo
     89      * @param sourcePortIndex
     90      * @param destinationDeviceInfo
     91      * @param destinationPortIndex
     92      */
     93     public void connectToDevicePort(final MidiDeviceInfo sourceDeviceInfo,
     94             final int sourcePortIndex,
     95             final MidiDeviceInfo destinationDeviceInfo,
     96             final int destinationPortIndex) {
     97         connectToDevicePort(sourceDeviceInfo, sourcePortIndex,
     98                 destinationDeviceInfo, destinationPortIndex, null, null);
     99     }
    100 
    101     /**
    102      * Open two devices and connect their ports.
    103      *
    104      * @param sourceDeviceInfo
    105      * @param sourcePortIndex
    106      * @param destinationDeviceInfo
    107      * @param destinationPortIndex
    108      */
    109     public void connectToDevicePort(final MidiDeviceInfo sourceDeviceInfo,
    110             final int sourcePortIndex,
    111             final MidiDeviceInfo destinationDeviceInfo,
    112             final int destinationPortIndex,
    113             final OnPortsConnectedListener listener, final Handler handler) {
    114         safeClose();
    115         mMidiManager.openDevice(destinationDeviceInfo,
    116                 new MidiManager.OnDeviceOpenedListener() {
    117                     @Override
    118                     public void onDeviceOpened(MidiDevice destinationDevice) {
    119                         if (destinationDevice == null) {
    120                             Log.e(MidiConstants.TAG,
    121                                     "could not open " + destinationDeviceInfo);
    122                             if (listener != null) {
    123                                 listener.onPortsConnected(null);
    124                             }
    125                         } else {
    126                             mDestinationDevice = destinationDevice;
    127                             Log.i(MidiConstants.TAG,
    128                                     "connectToDevicePort opened "
    129                                             + destinationDeviceInfo);
    130                             // Destination device was opened so go to next step.
    131                             MidiInputPort destinationInputPort = destinationDevice
    132                                     .openInputPort(destinationPortIndex);
    133                             if (destinationInputPort != null) {
    134                                 Log.i(MidiConstants.TAG,
    135                                         "connectToDevicePort opened port on "
    136                                                 + destinationDeviceInfo);
    137                                 connectToDevicePort(sourceDeviceInfo,
    138                                         sourcePortIndex,
    139                                         destinationInputPort,
    140                                         listener, handler);
    141                             } else {
    142                                 Log.e(MidiConstants.TAG,
    143                                         "could not open port on "
    144                                                 + destinationDeviceInfo);
    145                                 safeClose();
    146                                 if (listener != null) {
    147                                     listener.onPortsConnected(null);
    148                                 }
    149                             }
    150                         }
    151                     }
    152                 }, handler);
    153     }
    154 
    155 
    156     /**
    157      * Open a source device and connect its output port to the
    158      * destinationInputPort.
    159      *
    160      * @param sourceDeviceInfo
    161      * @param sourcePortIndex
    162      * @param destinationInputPort
    163      */
    164     private void connectToDevicePort(final MidiDeviceInfo sourceDeviceInfo,
    165             final int sourcePortIndex,
    166             final MidiInputPort destinationInputPort,
    167             final OnPortsConnectedListener listener, final Handler handler) {
    168         mMidiManager.openDevice(sourceDeviceInfo,
    169                 new MidiManager.OnDeviceOpenedListener() {
    170                     @Override
    171                     public void onDeviceOpened(MidiDevice device) {
    172                         if (device == null) {
    173                             Log.e(MidiConstants.TAG,
    174                                     "could not open " + sourceDeviceInfo);
    175                             safeClose();
    176                             if (listener != null) {
    177                                 listener.onPortsConnected(null);
    178                             }
    179                         } else {
    180                             Log.i(MidiConstants.TAG,
    181                                     "connectToDevicePort opened "
    182                                             + sourceDeviceInfo);
    183                             // Device was opened so connect the ports.
    184                             mSourceDevice = device;
    185                             mConnection = device.connectPorts(
    186                                     destinationInputPort, sourcePortIndex);
    187                             if (mConnection == null) {
    188                                 Log.e(MidiConstants.TAG, "could not connect to "
    189                                         + sourceDeviceInfo);
    190                                 safeClose();
    191                             }
    192                             if (listener != null) {
    193                                 listener.onPortsConnected(mConnection);
    194                             }
    195                         }
    196                     }
    197                 }, handler);
    198     }
    199 
    200 }
    201