00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021 #include "JackError.h"
00022 #include "JackPortType.h"
00023 #include "JackMidiPort.h"
00024 #include <assert.h>
00025 #include <string.h>
00026
00027 namespace Jack
00028 {
00029
00030 SERVER_EXPORT void JackMidiBuffer::Reset(jack_nframes_t nframes)
00031 {
00032
00033 this->nframes = nframes;
00034 write_pos = 0;
00035 event_count = 0;
00036 lost_events = 0;
00037 mix_index = 0;
00038 }
00039
00040 SERVER_EXPORT jack_shmsize_t JackMidiBuffer::MaxEventSize() const
00041 {
00042 assert (((jack_shmsize_t) - 1) < 0);
00043 jack_shmsize_t left = buffer_size - (sizeof(JackMidiBuffer) + sizeof(JackMidiEvent) * (event_count + 1) + write_pos);
00044 if (left < 0)
00045 return 0;
00046 if (left <= JackMidiEvent::INLINE_SIZE_MAX)
00047 return JackMidiEvent::INLINE_SIZE_MAX;
00048 return left;
00049 }
00050
00051 SERVER_EXPORT jack_midi_data_t* JackMidiBuffer::ReserveEvent(jack_nframes_t time, jack_shmsize_t size)
00052 {
00053 jack_shmsize_t space = MaxEventSize();
00054 if (space == 0 || size > space) {
00055 jack_error("JackMidiBuffer::ReserveEvent - the buffer does not have "
00056 "enough room to enqueue a %lu byte event", size);
00057 lost_events++;
00058 return 0;
00059 }
00060 JackMidiEvent* event = &events[event_count++];
00061 event->time = time;
00062 event->size = size;
00063 if (size <= JackMidiEvent::INLINE_SIZE_MAX)
00064 return event->data;
00065
00066 write_pos += size;
00067 event->offset = buffer_size - write_pos;
00068 return (jack_midi_data_t*)this + event->offset;
00069 }
00070
00071 static void MidiBufferInit(void* buffer, size_t buffer_size, jack_nframes_t nframes)
00072 {
00073 JackMidiBuffer* midi = (JackMidiBuffer*)buffer;
00074 midi->magic = JackMidiBuffer::MAGIC;
00075
00076 midi->buffer_size = BUFFER_SIZE_MAX * sizeof(jack_default_audio_sample_t);
00077 midi->Reset(nframes);
00078 }
00079
00080
00081
00082
00083
00084
00085
00086
00087
00088
00089
00090 static void MidiBufferMixdown(void* mixbuffer, void** src_buffers, int src_count, jack_nframes_t nframes)
00091 {
00092 JackMidiBuffer* mix = static_cast<JackMidiBuffer*>(mixbuffer);
00093 if (!mix->IsValid()) {
00094 jack_error("Jack::MidiBufferMixdown - invalid mix buffer");
00095 return;
00096 }
00097 mix->Reset(nframes);
00098
00099 int event_count = 0;
00100 for (int i = 0; i < src_count; ++i) {
00101 JackMidiBuffer* buf = static_cast<JackMidiBuffer*>(src_buffers[i]);
00102 if (!buf->IsValid()) {
00103 jack_error("Jack::MidiBufferMixdown - invalid source buffer");
00104 return;
00105 }
00106 buf->mix_index = 0;
00107 event_count += buf->event_count;
00108 mix->lost_events += buf->lost_events;
00109 }
00110
00111 int events_done;
00112 for (events_done = 0; events_done < event_count; ++events_done) {
00113 JackMidiBuffer* next_buf = 0;
00114 JackMidiEvent* next_event = 0;
00115
00116
00117 for (int i = 0; i < src_count; ++i) {
00118 JackMidiBuffer* buf = static_cast<JackMidiBuffer*>(src_buffers[i]);
00119 if (buf->mix_index >= buf->event_count)
00120 continue;
00121 JackMidiEvent* e = &buf->events[buf->mix_index];
00122 if (!next_event || e->time < next_event->time) {
00123 next_event = e;
00124 next_buf = buf;
00125 }
00126 }
00127 assert(next_event != 0);
00128
00129
00130 jack_midi_data_t* dest = mix->ReserveEvent(next_event->time, next_event->size);
00131 if (!dest)
00132 break;
00133 memcpy(dest, next_event->GetData(next_buf), next_event->size);
00134 next_buf->mix_index++;
00135 }
00136 mix->lost_events += event_count - events_done;
00137 }
00138
00139 static size_t MidiBufferSize()
00140 {
00141 return BUFFER_SIZE_MAX * sizeof(jack_default_audio_sample_t);
00142 }
00143
00144 const JackPortType gMidiPortType =
00145 {
00146 JACK_DEFAULT_MIDI_TYPE,
00147 MidiBufferSize,
00148 MidiBufferInit,
00149 MidiBufferMixdown
00150 };
00151
00152 }