1/* 2 * Copyright (c) 2002, 2015, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. Oracle designates this 8 * particular file as subject to the "Classpath" exception as provided 9 * by Oracle in the LICENSE file that accompanied this code. 10 * 11 * This code is distributed in the hope that it will be useful, but WITHOUT 12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 14 * version 2 for more details (a copy is included in the LICENSE file that 15 * accompanied this code). 16 * 17 * You should have received a copy of the GNU General Public License version 18 * 2 along with this work; if not, write to the Free Software Foundation, 19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 20 * 21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 22 * or visit www.oracle.com if you need additional information or have any 23 * questions. 24 */ 25 26 27#define USE_ERROR 28#define USE_TRACE 29 30#include "PlatformMidi.h" 31 32#include <stdlib.h> 33 34char* GetInternalErrorStr(INT32 err) { 35 switch (err) { 36 case MIDI_SUCCESS: return ""; 37 case MIDI_NOT_SUPPORTED: return "feature not supported"; 38 case MIDI_INVALID_DEVICEID: return "invalid device ID"; 39 case MIDI_INVALID_HANDLE: return "internal error: invalid handle"; 40 case MIDI_OUT_OF_MEMORY: return "out of memory"; 41 } 42 return NULL; 43} 44 45/* 46 * internal implementation for getting error string 47 */ 48char* MIDI_IN_InternalGetErrorString(INT32 err) { 49 char* result = GetInternalErrorStr(err); 50 51#if USE_PLATFORM_MIDI_IN == TRUE 52 if (!result) { 53 result = MIDI_IN_GetErrorStr(err); 54 } 55#endif 56 if (!result) { 57 result = GetInternalErrorStr(MIDI_NOT_SUPPORTED); 58 } 59 return result; 60} 61 62/* 63 * internal implementation for getting error string 64 */ 65char* MIDI_OUT_InternalGetErrorString(INT32 err) { 66 char* result = GetInternalErrorStr(err); 67 68#if USE_PLATFORM_MIDI_OUT == TRUE 69 if (!result) { 70 result = MIDI_OUT_GetErrorStr(err); 71 } 72#endif 73 if (!result) { 74 result = GetInternalErrorStr(MIDI_NOT_SUPPORTED); 75 } 76 return result; 77} 78 79 80#if USE_MIDI_QUEUE == TRUE 81 82// MessageQueue implementation 83 84MidiMessageQueue* MIDI_CreateQueue(int capacity) { 85 MidiMessageQueue* queue = (MidiMessageQueue*) malloc(sizeof(MidiMessageQueue) + ((capacity-1) * sizeof(MidiMessage))); 86 if (queue) { 87 TRACE0("MIDI_CreateQueue\n"); 88 queue->lock = MIDI_CreateLock(); 89 queue->capacity = capacity; 90 queue->size = 0; 91 queue->readIndex = 0; 92 queue->writeIndex = 0; 93 } 94 return queue; 95} 96 97void MIDI_DestroyQueue(MidiMessageQueue* queue) { 98 if (queue) { 99 void* lock = queue->lock; 100 MIDI_Lock(lock); 101 free(queue); 102 MIDI_Unlock(lock); 103 MIDI_DestroyLock(lock); 104 TRACE0("MIDI_DestroyQueue\n"); 105 } 106} 107 108// if overwrite is true, oldest messages will be overwritten when the queue is full 109// returns true, if message has been added 110int MIDI_QueueAddShort(MidiMessageQueue* queue, UINT32 packedMsg, INT64 timestamp, int overwrite) { 111 if (queue) { 112 MIDI_Lock(queue->lock); 113 if (queue->size == queue->capacity) { 114 TRACE0("MIDI_QueueAddShort: overflow\n"); 115 if (!overwrite || queue->queue[queue->writeIndex].locked) { 116 return FALSE; // failed 117 } 118 // adjust overwritten readIndex 119 queue->readIndex = (queue->readIndex+1) % queue->capacity; 120 } else { 121 queue->size++; 122 } 123 TRACE2("MIDI_QueueAddShort. index=%d, size=%d\n", queue->writeIndex, queue->size); 124 queue->queue[queue->writeIndex].type = SHORT_MESSAGE; 125 queue->queue[queue->writeIndex].data.s.packedMsg = packedMsg; 126 queue->queue[queue->writeIndex].timestamp = timestamp; 127 queue->writeIndex = (queue->writeIndex+1) % queue->capacity; 128 MIDI_Unlock(queue->lock); 129 return TRUE; 130 } 131 return FALSE; 132} 133 134int MIDI_QueueAddLong(MidiMessageQueue* queue, UBYTE* data, UINT32 size, 135 INT32 sysexIndex, INT64 timestamp, int overwrite) { 136 if (queue) { 137 MIDI_Lock(queue->lock); 138 if (queue->size == queue->capacity) { 139 TRACE0("MIDI_QueueAddLong: overflow\n"); 140 if (!overwrite || queue->queue[queue->writeIndex].locked) { 141 return FALSE; // failed 142 } 143 // adjust overwritten readIndex 144 queue->readIndex = (queue->readIndex+1) % queue->capacity; 145 } else { 146 queue->size++; 147 } 148 TRACE2("MIDI_QueueAddLong. index=%d, size=%d\n", queue->writeIndex, queue->size); 149 //fprintf(stdout, "MIDI_QueueAddLong sysex-index %d\n", sysexIndex); fflush(stdout); 150 queue->queue[queue->writeIndex].type = LONG_MESSAGE; 151 queue->queue[queue->writeIndex].data.l.size = size; 152 queue->queue[queue->writeIndex].data.l.data = data; 153 queue->queue[queue->writeIndex].data.l.index = sysexIndex; 154 queue->queue[queue->writeIndex].timestamp = timestamp; 155 queue->writeIndex = (queue->writeIndex+1) % queue->capacity; 156 MIDI_Unlock(queue->lock); 157 return TRUE; 158 } 159 return FALSE; 160} 161 162// returns NULL if no messages in queue. 163MidiMessage* MIDI_QueueRead(MidiMessageQueue* queue) { 164 MidiMessage* msg = NULL; 165 if (queue) { 166 MIDI_Lock(queue->lock); 167 if (queue->size > 0) { 168 msg = &(queue->queue[queue->readIndex]); 169 TRACE2("MIDI_QueueRead. index=%d, size=%d\n", queue->readIndex, queue->size); 170 msg->locked = TRUE; 171 } 172 MIDI_Unlock(queue->lock); 173 } 174 return msg; 175} 176 177void MIDI_QueueRemove(MidiMessageQueue* queue, INT32 onlyLocked) { 178 if (queue) { 179 MIDI_Lock(queue->lock); 180 if (queue->size > 0) { 181 MidiMessage* msg = &(queue->queue[queue->readIndex]); 182 if (!onlyLocked || msg->locked) { 183 TRACE2("MIDI_QueueRemove. index=%d, size=%d\n", queue->readIndex, queue->size); 184 queue->readIndex = (queue->readIndex+1) % queue->capacity; 185 queue->size--; 186 } 187 msg->locked = FALSE; 188 } 189 MIDI_Unlock(queue->lock); 190 } 191} 192 193void MIDI_QueueClear(MidiMessageQueue* queue) { 194 if (queue) { 195 MIDI_Lock(queue->lock); 196 queue->size = 0; 197 queue->readIndex = 0; 198 queue->writeIndex = 0; 199 MIDI_Unlock(queue->lock); 200 } 201} 202 203#endif 204