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 }
00038
00039 SERVER_EXPORT jack_shmsize_t JackMidiBuffer::MaxEventSize() const
00040 {
00041 assert (((jack_shmsize_t) - 1) < 0);
00042 jack_shmsize_t left = buffer_size - (sizeof(JackMidiBuffer) + sizeof(JackMidiEvent) * (event_count + 1) + write_pos);
00043 if (left < 0) {
00044 return 0;
00045 }
00046 if (left <= JackMidiEvent::INLINE_SIZE_MAX) {
00047 return JackMidiEvent::INLINE_SIZE_MAX;
00048 }
00049 return left;
00050 }
00051
00052 SERVER_EXPORT jack_midi_data_t* JackMidiBuffer::ReserveEvent(jack_nframes_t time, jack_shmsize_t size)
00053 {
00054 jack_shmsize_t space = MaxEventSize();
00055 if (space == 0 || size > space) {
00056 jack_error("JackMidiBuffer::ReserveEvent - the buffer does not have "
00057 "enough room to enqueue a %lu byte event", size);
00058 lost_events++;
00059 return 0;
00060 }
00061 JackMidiEvent* event = &events[event_count++];
00062 event->time = time;
00063 event->size = size;
00064
00065 if (size <= JackMidiEvent::INLINE_SIZE_MAX) {
00066 return event->data;
00067 }
00068
00069 write_pos += size;
00070 event->offset = buffer_size - write_pos;
00071 return (jack_midi_data_t*)this + event->offset;
00072 }
00073
00074 void MidiBufferInit(void* buffer, size_t buffer_size, jack_nframes_t nframes)
00075 {
00076 JackMidiBuffer* midi = (JackMidiBuffer*)buffer;
00077 midi->magic = JackMidiBuffer::MAGIC;
00078
00079 midi->buffer_size = BUFFER_SIZE_MAX * sizeof(jack_default_audio_sample_t);
00080 midi->Reset(nframes);
00081 }
00082
00083
00084
00085
00086
00087
00088
00089
00090
00091
00092
00093 static void MidiBufferMixdown(void* mixbuffer, void** src_buffers, int src_count, jack_nframes_t nframes)
00094 {
00095 JackMidiBuffer* mix = static_cast<JackMidiBuffer*>(mixbuffer);
00096 if (!mix->IsValid()) {
00097 jack_error("Jack::MidiBufferMixdown - invalid mix buffer");
00098 return;
00099 }
00100 mix->Reset(nframes);
00101
00102 uint32_t mix_index[src_count];
00103 int event_count = 0;
00104 for (int i = 0; i < src_count; ++i) {
00105 JackMidiBuffer* buf = static_cast<JackMidiBuffer*>(src_buffers[i]);
00106 if (!buf->IsValid()) {
00107 jack_error("Jack::MidiBufferMixdown - invalid source buffer");
00108 return;
00109 }
00110 mix_index[i] = 0;
00111 event_count += buf->event_count;
00112 mix->lost_events += buf->lost_events;
00113 }
00114
00115 int events_done;
00116 for (events_done = 0; events_done < event_count; ++events_done) {
00117 JackMidiBuffer* next_buf = 0;
00118 JackMidiEvent* next_event = 0;
00119 uint32_t next_buf_index = 0;
00120
00121
00122 for (int i = 0; i < src_count; ++i) {
00123 JackMidiBuffer* buf = static_cast<JackMidiBuffer*>(src_buffers[i]);
00124 if (mix_index[i] >= buf->event_count)
00125 continue;
00126 JackMidiEvent* e = &buf->events[mix_index[i]];
00127 if (!next_event || e->time < next_event->time) {
00128 next_event = e;
00129 next_buf = buf;
00130 next_buf_index = i;
00131 }
00132 }
00133 assert(next_event != 0);
00134
00135
00136 jack_midi_data_t* dest = mix->ReserveEvent(next_event->time, next_event->size);
00137 if (!dest) break;
00138
00139 memcpy(dest, next_event->GetData(next_buf), next_event->size);
00140 mix_index[next_buf_index]++;
00141 }
00142 mix->lost_events += event_count - events_done;
00143 }
00144
00145 static size_t MidiBufferSize()
00146 {
00147 return BUFFER_SIZE_MAX * sizeof(jack_default_audio_sample_t);
00148 }
00149
00150 const JackPortType gMidiPortType =
00151 {
00152 JACK_DEFAULT_MIDI_TYPE,
00153 MidiBufferSize,
00154 MidiBufferInit,
00155 MidiBufferMixdown
00156 };
00157
00158 }