1 /* 2 * Copyright (C) 2018 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 * @addtogroup Midi 18 * @{ 19 */ 20 21 /** 22 * @file AMidi.h 23 */ 24 25 #ifndef ANDROID_MEDIA_AMIDI_H_ 26 #define ANDROID_MEDIA_AMIDI_H_ 27 28 #include <stdarg.h> 29 #include <stdint.h> 30 #include <sys/types.h> 31 32 #include <jni.h> 33 34 #include <media/NdkMediaError.h> 35 36 #ifdef __cplusplus 37 extern "C" { 38 #endif 39 40 #define AMIDI_API __attribute__((visibility("default"))) 41 42 typedef struct AMidiDevice AMidiDevice; 43 typedef struct AMidiInputPort AMidiInputPort; 44 typedef struct AMidiOutputPort AMidiOutputPort; 45 46 /* 47 * Message Op Codes. Used to parse MIDI data packets 48 */ 49 enum { 50 AMIDI_OPCODE_DATA = 1, /* The MIDI packet contains normal MIDI data */ 51 AMIDI_OPCODE_FLUSH = 2, /* The MIDI packet contains just a MIDI FLUSH command. */ 52 /* Forces the send of any pending MIDI data. */ 53 }; 54 55 /* 56 * Type IDs for various MIDI devices. 57 */ 58 enum { 59 AMIDI_DEVICE_TYPE_USB = 1, /* A MIDI device connected to the Android USB port */ 60 AMIDI_DEVICE_TYPE_VIRTUAL = 2, /* A software object implementing MidiDeviceService */ 61 AMIDI_DEVICE_TYPE_BLUETOOTH = 3 /* A MIDI device connected via BlueTooth */ 62 }; 63 64 /* 65 * Protocol IDs for various MIDI devices. 66 * 67 * Introduced in API 33. 68 */ 69 typedef enum AMidiDevice_Protocol : int32_t { 70 /** 71 * Constant representing a default protocol with Universal MIDI Packets (UMP). 72 * UMP is defined in "Universal MIDI Packet (UMP) Format and MIDI 2.0 Protocol" spec. 73 * All UMP data should be a multiple of 4 bytes. 74 * Use UMP to negotiate with the device with MIDI-CI. 75 * MIDI-CI is defined in "MIDI Capability Inquiry (MIDI-CI)" spec. 76 */ 77 AMIDI_DEVICE_PROTOCOL_UMP_USE_MIDI_CI = 0, 78 79 /** 80 * Constant representing a default protocol with Universal MIDI Packets (UMP). 81 * UMP is defined in "Universal MIDI Packet (UMP) Format and MIDI 2.0 Protocol" spec. 82 * All UMP data should be a multiple of 4 bytes. 83 * Use MIDI 1.0 through UMP with packet sizes up to 64 bits. 84 */ 85 AMIDI_DEVICE_PROTOCOL_UMP_MIDI_1_0_UP_TO_64_BITS = 1, 86 87 /** 88 * Constant representing a default protocol with Universal MIDI Packets (UMP). 89 * UMP is defined in "Universal MIDI Packet (UMP) Format and MIDI 2.0 Protocol" spec. 90 * All UMP data should be a multiple of 4 bytes. 91 * Use MIDI 1.0 through UMP with packet sizes up to 64 bits and jitter reduction timestamps. 92 */ 93 AMIDI_DEVICE_PROTOCOL_UMP_MIDI_1_0_UP_TO_64_BITS_AND_JRTS = 2, 94 95 /** 96 * Constant representing a default protocol with Universal MIDI Packets (UMP). 97 * UMP is defined in "Universal MIDI Packet (UMP) Format and MIDI 2.0 Protocol" spec. 98 * All UMP data should be a multiple of 4 bytes. 99 * Use MIDI 1.0 through UMP with packet sizes up to 128 bits. 100 */ 101 AMIDI_DEVICE_PROTOCOL_UMP_MIDI_1_0_UP_TO_128_BITS = 3, 102 103 /** 104 * Constant representing a default protocol with Universal MIDI Packets (UMP). 105 * UMP is defined in "Universal MIDI Packet (UMP) Format and MIDI 2.0 Protocol" spec. 106 * All UMP data should be a multiple of 4 bytes. 107 * Use MIDI 1.0 through UMP with packet sizes up to 128 bits and jitter reduction timestamps. 108 */ 109 AMIDI_DEVICE_PROTOCOL_UMP_MIDI_1_0_UP_TO_128_BITS_AND_JRTS = 4, 110 111 /** 112 * Constant representing a default protocol with Universal MIDI Packets (UMP). 113 * UMP is defined in "Universal MIDI Packet (UMP) Format and MIDI 2.0 Protocol" spec. 114 * All UMP data should be a multiple of 4 bytes. 115 * Use MIDI 2.0 through UMP. 116 */ 117 AMIDI_DEVICE_PROTOCOL_UMP_MIDI_2_0 = 17, 118 119 /** 120 * Constant representing a default protocol with Universal MIDI Packets (UMP). 121 * UMP is defined in "Universal MIDI Packet (UMP) Format and MIDI 2.0 Protocol" spec. 122 * All UMP data should be a multiple of 4 bytes. 123 * Use MIDI 2.0 through UMP and jitter reduction timestamps. 124 */ 125 AMIDI_DEVICE_PROTOCOL_UMP_MIDI_2_0_AND_JRTS = 18, 126 127 /** 128 * Constant representing a device with an unknown default protocol. 129 * If Universal MIDI Packets (UMP) are needed, use MIDI-CI through MIDI 1.0. 130 * UMP is defined in "Universal MIDI Packet (UMP) Format and MIDI 2.0 Protocol" spec. 131 * MIDI-CI is defined in "MIDI Capability Inquiry (MIDI-CI)" spec. 132 */ 133 AMIDI_DEVICE_PROTOCOL_UNKNOWN = -1 134 } AMidiDevice_Protocol; 135 136 /* 137 * Device API 138 */ 139 /** 140 * Connects a native Midi Device object to the associated Java MidiDevice object. Use this 141 * AMidiDevice to access the rest of the native MIDI API. Use AMidiDevice_release() to 142 * disconnect from the Java object when not being used any more. 143 * 144 * @param env Points to the Java Environment. 145 * @param midiDeviceObj The Java MidiDevice Object. 146 * @param outDevicePtrPtr Points to the pointer to receive the AMidiDevice 147 * 148 * @return AMEDIA_OK on success, or a negative error value: 149 * @see AMEDIA_ERROR_INVALID_OBJECT - the midiDeviceObj 150 * is null or already connected to a native AMidiDevice 151 * @see AMEDIA_ERROR_UNKNOWN - an unknown error occurred. 152 */ 153 media_status_t AMIDI_API AMidiDevice_fromJava( 154 JNIEnv *env, jobject midiDeviceObj, AMidiDevice **outDevicePtrPtr) __INTRODUCED_IN(29); 155 156 /** 157 * Disconnects the native Midi Device Object from the associated Java MidiDevice object. 158 * 159 * @param midiDevice Points to the native AMIDI_MidiDevice. 160 * 161 * @return AMEDIA_OK on success, 162 * or a negative error value: 163 * @see AMEDIA_ERROR_INVALID_PARAMETER - the device parameter is NULL. 164 * @see AMEDIA_ERROR_INVALID_OBJECT - the device is not consistent with the associated Java MidiDevice. 165 * @see AMEDIA_ERROR_INVALID_OBJECT - the JNI interface initialization to the associated java MidiDevice failed. 166 * @see AMEDIA_ERROR_UNKNOWN - couldn't retrieve the device info. 167 */ 168 media_status_t AMIDI_API AMidiDevice_release(const AMidiDevice *midiDevice) __INTRODUCED_IN(29); 169 170 /** 171 * Gets the MIDI device type. 172 * 173 * @param device Specifies the MIDI device. 174 * 175 * @return The identifier of the MIDI device type: 176 * AMIDI_DEVICE_TYPE_USB 177 * AMIDI_DEVICE_TYPE_VIRTUAL 178 * AMIDI_DEVICE_TYPE_BLUETOOTH 179 * or a negative error value: 180 * @see AMEDIA_ERROR_INVALID_PARAMETER - the device parameter is NULL. 181 * @see AMEDIA_ERROR_UNKNOWN - Unknown error. 182 */ 183 int32_t AMIDI_API AMidiDevice_getType(const AMidiDevice *device) __INTRODUCED_IN(29); 184 185 /** 186 * Gets the number of input (sending) ports available on the specified MIDI device. 187 * 188 * @param device Specifies the MIDI device. 189 * 190 * @return If successful, returns the number of MIDI input (sending) ports available on the 191 * device. If an error occurs, returns a negative value indicating the error: 192 * @see AMEDIA_ERROR_INVALID_PARAMETER - the device parameter is NULL. 193 * @see AMEDIA_ERROR_UNKNOWN - couldn't retrieve the device info. 194 */ 195 ssize_t AMIDI_API AMidiDevice_getNumInputPorts(const AMidiDevice *device) __INTRODUCED_IN(29); 196 197 /** 198 * Gets the number of output (receiving) ports available on the specified MIDI device. 199 * 200 * @param device Specifies the MIDI device. 201 * 202 * @return If successful, returns the number of MIDI output (receiving) ports available on the 203 * device. If an error occurs, returns a negative value indicating the error: 204 * @see AMEDIA_ERROR_INVALID_PARAMETER - the device parameter is NULL. 205 * @see AMEDIA_ERROR_UNKNOWN - couldn't retrieve the device info. 206 */ 207 ssize_t AMIDI_API AMidiDevice_getNumOutputPorts(const AMidiDevice *device) __INTRODUCED_IN(29); 208 209 /** 210 * Gets the MIDI device default protocol. 211 * 212 * @param device Specifies the MIDI device. 213 * 214 * @return The identifier of the MIDI device default protocol: 215 * AMIDI_DEVICE_PROTOCOL_UMP_USE_MIDI_CI 216 * AMIDI_DEVICE_PROTOCOL_UMP_MIDI_1_0_UP_TO_64_BITS 217 * AMIDI_DEVICE_PROTOCOL_UMP_MIDI_1_0_UP_TO_64_BITS_AND_JRTS 218 * AMIDI_DEVICE_PROTOCOL_UMP_MIDI_1_0_UP_TO_128_BITS 219 * AMIDI_DEVICE_PROTOCOL_UMP_MIDI_1_0_UP_TO_128_BITS_AND_JRTS 220 * AMIDI_DEVICE_PROTOCOL_UMP_MIDI_2_0 221 * AMIDI_DEVICE_PROTOCOL_UMP_MIDI_2_0_AND_JRTS 222 * AMIDI_DEVICE_PROTOCOL_UNKNOWN 223 * 224 * Most devices should return PROTOCOL_UNKNOWN (-1). This is intentional as devices 225 * with default UMP support are not backwards compatible. When the device is null, 226 * return AMIDI_DEVICE_PROTOCOL_UNKNOWN. 227 * 228 * Available since API 33. 229 */ 230 AMidiDevice_Protocol AMIDI_API AMidiDevice_getDefaultProtocol(const AMidiDevice *device) 231 __INTRODUCED_IN(33); 232 233 /* 234 * API for receiving data from the Output port of a device. 235 */ 236 /** 237 * Opens the output port so that the client can receive data from it. The port remains open and 238 * valid until AMidiOutputPort_close() is called for the returned AMidiOutputPort. 239 * 240 * @param device Specifies the MIDI device. 241 * @param portNumber Specifies the zero-based port index on the device to open. This value ranges 242 * between 0 and one less than the number of output ports reported by the 243 * AMidiDevice_getNumOutputPorts function. 244 * @param outOutputPortPtr Receives the native API port identifier of the opened port. 245 * 246 * @return AMEDIA_OK, or a negative error code: 247 * @see AMEDIA_ERROR_UNKNOWN - Unknown Error. 248 */ 249 media_status_t AMIDI_API AMidiOutputPort_open(const AMidiDevice *device, int32_t portNumber, 250 AMidiOutputPort **outOutputPortPtr) __INTRODUCED_IN(29); 251 252 /** 253 * Closes the output port. 254 * 255 * @param outputPort The native API port identifier of the port. 256 */ 257 void AMIDI_API AMidiOutputPort_close(const AMidiOutputPort *outputPort) __INTRODUCED_IN(29); 258 259 /** 260 * Receives the next pending MIDI message. To retrieve all pending messages, the client should 261 * repeatedly call this method until it returns 0. 262 * 263 * Note that this is a non-blocking call. If there are no Midi messages are available, the function 264 * returns 0 immediately (for 0 messages received). 265 * 266 * @param outputPort Identifies the port to receive messages from. 267 * @param opcodePtr Receives the message Op Code. 268 * @param buffer Points to the buffer to receive the message data bytes. 269 * @param maxBytes Specifies the size of the buffer pointed to by the buffer parameter. 270 * @param numBytesReceivedPtr On exit, receives the actual number of bytes stored in buffer. 271 * @param outTimestampPtr If non-NULL, receives the timestamp associated with the message. 272 * (the current value of the running Java Virtual Machine's high-resolution time source, 273 * in nanoseconds) 274 * @return the number of messages received (either 0 or 1), or a negative error code: 275 * @see AMEDIA_ERROR_UNKNOWN - Unknown Error. 276 */ 277 ssize_t AMIDI_API AMidiOutputPort_receive(const AMidiOutputPort *outputPort, int32_t *opcodePtr, 278 uint8_t *buffer, size_t maxBytes, size_t* numBytesReceivedPtr, int64_t *outTimestampPtr) __INTRODUCED_IN(29); 279 280 /* 281 * API for sending data to the Input port of a device. 282 */ 283 /** 284 * Opens the input port so that the client can send data to it. The port remains open and 285 * valid until AMidiInputPort_close() is called for the returned AMidiInputPort. 286 * 287 * @param device Specifies the MIDI device. 288 * @param portNumber Specifies the zero-based port index on the device to open. This value ranges 289 * between 0 and one less than the number of input ports reported by the 290 * AMidiDevice_getNumInputPorts() function.. 291 * @param outInputPortPtr Receives the native API port identifier of the opened port. 292 * 293 * @return AMEDIA_OK, or a negative error code: 294 * @see AMEDIA_ERROR_UNKNOWN - Unknown Error. 295 */ 296 media_status_t AMIDI_API AMidiInputPort_open(const AMidiDevice *device, int32_t portNumber, 297 AMidiInputPort **outInputPortPtr) __INTRODUCED_IN(29); 298 299 /** 300 * Sends data to the specified input port. 301 * 302 * @param inputPort The identifier of the port to send data to. 303 * @param buffer Points to the array of bytes containing the data to send. 304 * @param numBytes Specifies the number of bytes to write. 305 * 306 * @return The number of bytes sent, which could be less than specified or a negative error code: 307 * @see AMEDIA_ERROR_INVALID_PARAMETER - The specified port was NULL, the specified buffer was NULL. 308 */ 309 ssize_t AMIDI_API AMidiInputPort_send(const AMidiInputPort *inputPort, const uint8_t *buffer, 310 size_t numBytes) __INTRODUCED_IN(29); 311 312 /** 313 * Sends data to the specified input port with a timestamp. 314 * 315 * @param inputPort The identifier of the port to send data to. 316 * @param buffer Points to the array of bytes containing the data to send. 317 * @param numBytes Specifies the number of bytes to write. 318 * @param timestamp The CLOCK_MONOTONIC time in nanoseconds to associate with the sent data. 319 * 320 * @return The number of bytes sent, which could be less than specified or a negative error code: 321 * @see AMEDIA_ERROR_INVALID_PARAMETER - The specified port was NULL, the specified buffer was NULL. 322 */ 323 ssize_t AMIDI_API AMidiInputPort_sendWithTimestamp(const AMidiInputPort *inputPort, 324 const uint8_t *buffer, size_t numBytes, int64_t timestamp) __INTRODUCED_IN(29); 325 326 /** 327 * Sends a message with a 'MIDI flush command code' to the specified port. This should cause 328 * a receiver to discard any pending MIDI data it may have accumulated and not processed. 329 * 330 * @param inputPort The identifier of the port to send the flush command to. 331 * 332 * @returns @see AMEDIA_OK if successful, otherwise a negative error code: 333 * @see AMEDIA_ERROR_INVALID_PARAMETER - The specified port was NULL 334 * @see AMEDIA_ERROR_UNSUPPORTED - The FLUSH command couldn't 335 * be sent. 336 */ 337 media_status_t AMIDI_API AMidiInputPort_sendFlush(const AMidiInputPort *inputPort) __INTRODUCED_IN(29); 338 339 /** 340 * Closes the input port. 341 * 342 * @param inputPort Identifies the input (sending) port to close. 343 */ 344 void AMIDI_API AMidiInputPort_close(const AMidiInputPort *inputPort) __INTRODUCED_IN(29); 345 346 #ifdef __cplusplus 347 } 348 #endif 349 350 #endif /* ANDROID_MEDIA_AMIDI_H_ */ 351 /** 352 @} 353 */ 354