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 "JackMidiAsyncWaitQueue.h" 00023 #include "JackMidiUtil.h" 00024 #include "JackTime.h" 00025 00026 using Jack::JackMidiAsyncWaitQueue; 00027 00028 JackMidiAsyncWaitQueue::JackMidiAsyncWaitQueue(size_t max_bytes, 00029 size_t max_messages): 00030 JackMidiAsyncQueue(max_bytes, max_messages) 00031 { 00032 if (semaphore.Allocate("JackMidiAsyncWaitQueue", "midi-thread", 0)) { 00033 throw std::bad_alloc(); 00034 } 00035 } 00036 00037 JackMidiAsyncWaitQueue::~JackMidiAsyncWaitQueue() 00038 { 00039 semaphore.Destroy(); 00040 } 00041 00042 jack_midi_event_t * 00043 JackMidiAsyncWaitQueue::DequeueEvent() 00044 { 00045 return DequeueEvent((long) 0); 00046 } 00047 00048 jack_midi_event_t * 00049 JackMidiAsyncWaitQueue::DequeueEvent(jack_nframes_t frame) 00050 { 00051 00052 // XXX: I worry about timer resolution on Solaris and Windows. When the 00053 // resolution for the `JackSynchro` object is milliseconds, the worst-case 00054 // scenario for processor objects is that the wait time becomes less than a 00055 // millisecond, and the processor object continually calls this method, 00056 // expecting to wait a certain amount of microseconds, and ends up not 00057 // waiting at all each time, essentially busy-waiting until the current 00058 // frame is reached. Perhaps there should be a #define that indicates the 00059 // wait time resolution for `JackSynchro` objects so that we can wait a 00060 // little longer if necessary. 00061 00062 jack_time_t frame_time = GetTimeFromFrames(frame); 00063 jack_time_t current_time = GetMicroSeconds(); 00064 return DequeueEvent((frame_time < current_time) ? 0 : 00065 (long) (frame_time - current_time)); 00066 } 00067 00068 jack_midi_event_t * 00069 JackMidiAsyncWaitQueue::DequeueEvent(long usec) 00070 { 00071 return ((usec < 0) ? semaphore.Wait() : semaphore.TimedWait(usec)) ? 00072 JackMidiAsyncQueue::DequeueEvent() : 0; 00073 } 00074 00075 Jack::JackMidiWriteQueue::EnqueueResult 00076 JackMidiAsyncWaitQueue::EnqueueEvent(jack_nframes_t time, size_t size, 00077 jack_midi_data_t *buffer) 00078 { 00079 EnqueueResult result = JackMidiAsyncQueue::EnqueueEvent(time, size, 00080 buffer); 00081 if (result == OK) { 00082 semaphore.Signal(); 00083 } 00084 return result; 00085 }