25
26 /*
27 **
28 ** Overview:
29 ** Implementation of the functions used for both MIDI in and MIDI out.
30 **
31 ** Java package com.sun.media.sound defines the AbstractMidiDevice class
32 ** which encapsulates functionalities shared by both MidiInDevice and
33 ** MidiOutDevice classes in the same package.
34 **
35 ** The Java layer classes MidiInDevice and MidiOutDevice in turn map to
36 ** the MIDIEndpointRef data type in the CoreMIDI framework, which
37 ** represents a source or destination for a standard 16-channel MIDI data
38 ** stream.
39 */
40 /*****************************************************************************/
41
42 //#define USE_ERROR
43 //#define USE_TRACE
44
45 /* Use THIS_FILE when it is available. */
46 #ifndef THIS_FILE
47 #define THIS_FILE __FILE__
48 #endif
49
50 #if (USE_PLATFORM_MIDI_IN == TRUE) || (USE_PLATFORM_MIDI_OUT == TRUE)
51
52 #include "PLATFORM_API_MacOSX_MidiUtils.h"
53 #include <pthread.h>
54 #include <assert.h>
55
56 // Constant character string definitions of CoreMIDI's corresponding error codes.
57
58 static const char* strMIDIInvalidClient =
59 "An invalid MIDIClientRef was passed.";
60 static const char* strMIDIInvalidPort =
61 "An invalid MIDIPortRef was passed.";
62 static const char* strMIDIWrongEndpointType =
63 "A source endpoint was passed to a function expecting a destination, or vice versa.";
64 static const char* strMIDINoConnection =
65 "Attempt to close a non-existant connection.";
66 static const char* strMIDIUnknownEndpoint =
67 "An invalid MIDIEndpointRef was passed.";
68 static const char* strMIDIUnknownProperty =
69 "Attempt to query a property not set on the object.";
305 pendingDataLength = 0;
306 }
307 } else {
308 if (byte < 0x80) {
309 // Not a status byte -- check our history.
310 if (handle->readingSysExData) {
311 CFDataAppendBytes(handle->readingSysExData, &byte, 1);
312
313 } else if (pendingDataIndex < pendingDataLength) {
314 pendingData[pendingDataIndex] = byte;
315 pendingDataIndex++;
316
317 if (pendingDataIndex == pendingDataLength) {
318 // This message is now done -- do the final processing.
319 if (pendingDataLength == 2) {
320 packedMsg = pendingMessageStatus | pendingData[0] << 8 | pendingData[1] << 16;
321 } else if (pendingDataLength == 1) {
322 packedMsg = pendingMessageStatus | pendingData[0] << 8;
323 } else {
324 fprintf(stderr, "%s: %d->internal error: pendingMessageStatus=0x%X, pendingDataLength=%d\n",
325 THIS_FILE, __LINE__, pendingMessageStatus, pendingDataLength);
326 byteIsInvalid = TRUE;
327 }
328 pendingDataLength = 0;
329 }
330 } else {
331 // Skip this byte -- it is invalid.
332 byteIsInvalid = TRUE;
333 }
334 } else {
335 if (handle->readingSysExData /* && (byte == 0xF7) */) {
336 // We have reached the end of system exclusive message -- send it finally.
337 const UInt8* bytes = CFDataGetBytePtr(handle->readingSysExData);
338 CFIndex size = CFDataGetLength(handle->readingSysExData);
339 MIDI_QueueAddLong(handle->h.queue,
340 (UBYTE*) bytes,
341 (UINT32) size,
342 0, // Don't care, windowish porting only.
343 (INT64) (AudioConvertHostTimeToNanos(ts) + 500) / 1000,
344 TRUE);
345 CFRelease(handle->readingSysExData);
|
25
26 /*
27 **
28 ** Overview:
29 ** Implementation of the functions used for both MIDI in and MIDI out.
30 **
31 ** Java package com.sun.media.sound defines the AbstractMidiDevice class
32 ** which encapsulates functionalities shared by both MidiInDevice and
33 ** MidiOutDevice classes in the same package.
34 **
35 ** The Java layer classes MidiInDevice and MidiOutDevice in turn map to
36 ** the MIDIEndpointRef data type in the CoreMIDI framework, which
37 ** represents a source or destination for a standard 16-channel MIDI data
38 ** stream.
39 */
40 /*****************************************************************************/
41
42 //#define USE_ERROR
43 //#define USE_TRACE
44
45 #if (USE_PLATFORM_MIDI_IN == TRUE) || (USE_PLATFORM_MIDI_OUT == TRUE)
46
47 #include "PLATFORM_API_MacOSX_MidiUtils.h"
48 #include <pthread.h>
49 #include <assert.h>
50
51 // Constant character string definitions of CoreMIDI's corresponding error codes.
52
53 static const char* strMIDIInvalidClient =
54 "An invalid MIDIClientRef was passed.";
55 static const char* strMIDIInvalidPort =
56 "An invalid MIDIPortRef was passed.";
57 static const char* strMIDIWrongEndpointType =
58 "A source endpoint was passed to a function expecting a destination, or vice versa.";
59 static const char* strMIDINoConnection =
60 "Attempt to close a non-existant connection.";
61 static const char* strMIDIUnknownEndpoint =
62 "An invalid MIDIEndpointRef was passed.";
63 static const char* strMIDIUnknownProperty =
64 "Attempt to query a property not set on the object.";
300 pendingDataLength = 0;
301 }
302 } else {
303 if (byte < 0x80) {
304 // Not a status byte -- check our history.
305 if (handle->readingSysExData) {
306 CFDataAppendBytes(handle->readingSysExData, &byte, 1);
307
308 } else if (pendingDataIndex < pendingDataLength) {
309 pendingData[pendingDataIndex] = byte;
310 pendingDataIndex++;
311
312 if (pendingDataIndex == pendingDataLength) {
313 // This message is now done -- do the final processing.
314 if (pendingDataLength == 2) {
315 packedMsg = pendingMessageStatus | pendingData[0] << 8 | pendingData[1] << 16;
316 } else if (pendingDataLength == 1) {
317 packedMsg = pendingMessageStatus | pendingData[0] << 8;
318 } else {
319 fprintf(stderr, "%s: %d->internal error: pendingMessageStatus=0x%X, pendingDataLength=%d\n",
320 __FILE__, __LINE__, pendingMessageStatus, pendingDataLength);
321 byteIsInvalid = TRUE;
322 }
323 pendingDataLength = 0;
324 }
325 } else {
326 // Skip this byte -- it is invalid.
327 byteIsInvalid = TRUE;
328 }
329 } else {
330 if (handle->readingSysExData /* && (byte == 0xF7) */) {
331 // We have reached the end of system exclusive message -- send it finally.
332 const UInt8* bytes = CFDataGetBytePtr(handle->readingSysExData);
333 CFIndex size = CFDataGetLength(handle->readingSysExData);
334 MIDI_QueueAddLong(handle->h.queue,
335 (UBYTE*) bytes,
336 (UINT32) size,
337 0, // Don't care, windowish porting only.
338 (INT64) (AudioConvertHostTimeToNanos(ts) + 500) / 1000,
339 TRUE);
340 CFRelease(handle->readingSysExData);
|