Jack2 1.9.8
|
00001 /* 00002 Copyright (C) 2010 Devin Anderson 00003 00004 This program is free software; you can redistribute it and/or modify 00005 it under the terms of the GNU Lesser General Public License as published by 00006 the Free Software Foundation; either version 2.1 of the License, or 00007 (at your option) any later version. 00008 00009 This program is distributed in the hope that it will be useful, 00010 but WITHOUT ANY WARRANTY; without even the implied warranty of 00011 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00012 GNU Lesser General Public License for more details. 00013 00014 You should have received a copy of the GNU Lesser General Public License 00015 along with this program; if not, write to the Free Software 00016 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 00017 00018 */ 00019 00020 #include <new> 00021 00022 #include "JackMidiAsyncQueue.h" 00023 00024 using Jack::JackMidiAsyncQueue; 00025 00026 JackMidiAsyncQueue::JackMidiAsyncQueue(size_t max_bytes, size_t max_messages) 00027 { 00028 data_buffer = new jack_midi_data_t[max_bytes]; 00029 byte_ring = jack_ringbuffer_create((max_bytes * sizeof(jack_midi_data_t)) + 00030 1); 00031 if (byte_ring) { 00032 info_ring = jack_ringbuffer_create((max_messages * INFO_SIZE) + 1); 00033 if (info_ring) { 00034 jack_ringbuffer_mlock(byte_ring); 00035 jack_ringbuffer_mlock(info_ring); 00036 this->max_bytes = max_bytes; 00037 return; 00038 } 00039 jack_ringbuffer_free(byte_ring); 00040 } 00041 delete data_buffer; 00042 throw std::bad_alloc(); 00043 } 00044 00045 JackMidiAsyncQueue::~JackMidiAsyncQueue() 00046 { 00047 jack_ringbuffer_free(byte_ring); 00048 jack_ringbuffer_free(info_ring); 00049 delete[] data_buffer; 00050 } 00051 00052 jack_midi_event_t * 00053 JackMidiAsyncQueue::DequeueEvent() 00054 { 00055 jack_midi_event_t *event = 0; 00056 if (jack_ringbuffer_read_space(info_ring) >= INFO_SIZE) { 00057 size_t size; 00058 event = &dequeue_event; 00059 jack_ringbuffer_read(info_ring, (char *) &(event->time), 00060 sizeof(jack_nframes_t)); 00061 jack_ringbuffer_read(info_ring, (char *) &size, 00062 sizeof(size_t)); 00063 jack_ringbuffer_read(byte_ring, (char *) data_buffer, 00064 size * sizeof(jack_midi_data_t)); 00065 event->buffer = data_buffer; 00066 event->size = size; 00067 } 00068 return event; 00069 } 00070 00071 Jack::JackMidiWriteQueue::EnqueueResult 00072 JackMidiAsyncQueue::EnqueueEvent(jack_nframes_t time, size_t size, 00073 jack_midi_data_t *buffer) 00074 { 00075 if (size > max_bytes) { 00076 return BUFFER_TOO_SMALL; 00077 } 00078 if (! ((jack_ringbuffer_write_space(info_ring) >= INFO_SIZE) && 00079 (jack_ringbuffer_write_space(byte_ring) >= 00080 (size * sizeof(jack_midi_data_t))))) { 00081 return BUFFER_FULL; 00082 } 00083 jack_ringbuffer_write(byte_ring, (const char *) buffer, 00084 size * sizeof(jack_midi_data_t)); 00085 jack_ringbuffer_write(info_ring, (const char *) (&time), 00086 sizeof(jack_nframes_t)); 00087 jack_ringbuffer_write(info_ring, (const char *) (&size), sizeof(size_t)); 00088 return OK; 00089 } 00090 00091 size_t 00092 JackMidiAsyncQueue::GetAvailableSpace() 00093 { 00094 return jack_ringbuffer_write_space(info_ring) < INFO_SIZE ? 0 : 00095 max_bytes - jack_ringbuffer_read_space(byte_ring); 00096 }