diff options
author | David Robillard <d@drobilla.net> | 2007-01-12 04:32:44 +0000 |
---|---|---|
committer | David Robillard <d@drobilla.net> | 2007-01-12 04:32:44 +0000 |
commit | cd88e6750d837f8f7aa2b7f3ca54e929172fbbef (patch) | |
tree | e1ba5b9325e5352cf8715c5cd553d88655e872b5 /examples/hosts/lv2-midifunctions.h | |
parent | e75478522b098a1016042a7538953f2ff2c3aadb (diff) | |
download | lilv-cd88e6750d837f8f7aa2b7f3ca54e929172fbbef.tar.gz lilv-cd88e6750d837f8f7aa2b7f3ca54e929172fbbef.tar.bz2 lilv-cd88e6750d837f8f7aa2b7f3ca54e929172fbbef.zip |
Split jack_host into slv2_simple_jack_host and slv2_host, added MIDI support to slv2_host.
git-svn-id: http://svn.drobilla.net/lad/slv2@251 a436a847-0d15-0410-975c-d299462d15a1
Diffstat (limited to 'examples/hosts/lv2-midifunctions.h')
-rw-r--r-- | examples/hosts/lv2-midifunctions.h | 161 |
1 files changed, 161 insertions, 0 deletions
diff --git a/examples/hosts/lv2-midifunctions.h b/examples/hosts/lv2-midifunctions.h new file mode 100644 index 0000000..68691f3 --- /dev/null +++ b/examples/hosts/lv2-midifunctions.h @@ -0,0 +1,161 @@ +/**************************************************************************** + + lv2-midifunctions.h - support file for using MIDI in LV2 plugins + + Copyright (C) 2006 Lars Luthman <lars.luthman@gmail.com> + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 01222-1307 USA + +****************************************************************************/ + +#ifndef LV2_MIDIFUNCTIONS +#define LV2_MIDIFUNCTIONS + +#include <string.h> + +#include "lv2-miditype.h" + + +/** This structure contains information about a MIDI port buffer, the + current period size, and the position in the MIDI data buffer that + we are currently reading from or writing to. It needs to be recreated + or at least reinitialised every process() call. */ +typedef struct { + + /** The MIDI port structure that we want to read or write. */ + LV2_MIDI* midi; + + /** The number of frames in this process cycle. */ + uint32_t frame_count; + + /** The current position in the data buffer. Should be initialised to 0. */ + uint32_t position; + +} LV2_MIDIState; + + +static LV2_MIDI* lv2midi_new(uint32_t capacity) +{ + LV2_MIDI* midi = malloc(sizeof(LV2_MIDI)); + + midi->event_count = 0; + midi->capacity = capacity; + midi->size = 0; + midi->data = malloc(sizeof(char) * capacity); + + return midi; +} + + +static void lv2midi_free(LV2_MIDI* midi) +{ + free(midi->data); + free(midi); +} + + +static void lv2midi_reset_buffer(LV2_MIDI* midi) +{ + midi->event_count = 0; + midi->size = 0; +} + +static void lv2midi_reset_state(LV2_MIDIState* state, LV2_MIDI* midi, uint32_t frame_count) +{ + state->midi = midi; + state->frame_count = frame_count; + state->position = 0; +} + + +/** This function advances the read/write position in @c state to the next + event and returns its timestamp, or the @c frame_count member of @c state + is there are no more events. */ +static double lv2midi_increment(LV2_MIDIState* state) { + + if (state->position + sizeof(double) + sizeof(size_t) >= state->midi->size) { + state->position = state->midi->size; + return state->frame_count; + } + + state->position += sizeof(double); + size_t size = *(size_t*)(state->midi->data + state->position); + state->position += sizeof(size_t); + state->position += size; + + if (state->position >= state->midi->size) + return state->frame_count; + + return *(double*)(state->midi->data + state->position); +} + + +/** This function reads one event from the port associated with the @c state + parameter and writes its timestamp, size and a pointer to its data bytes + into the parameters @c timestamp, @c size and @c data, respectively. + It does not advance the read position in the MIDI data buffer, two + subsequent calls to lv2midi_get_event() will read the same event. + + The function returns the timestamp for the read event, or the @c frame_count + member of @c state if there are no more events in the buffer. */ +static double lv2midi_get_event(LV2_MIDIState* state, + double* timestamp, + uint32_t* size, + unsigned char** data) { + + if (state->position >= state->midi->size) { + state->position = state->midi->size; + *timestamp = state->frame_count; + *size = 0; + *data = NULL; + return *timestamp; + } + + *timestamp = *(double*)(state->midi->data + state->position); + *size = *(size_t*)(state->midi->data + state->position + sizeof(double)); + *data = state->midi->data + state->position + + sizeof(double) + sizeof(size_t); + return *timestamp; +} + + +/** This function writes one MIDI event to the port buffer associated with + @c state. It returns 0 when the event was written successfully to the + buffer, and -1 when there was not enough room. The read/write position + is advanced automatically. */ +static int lv2midi_put_event(LV2_MIDIState* state, + double timestamp, + uint32_t size, + const unsigned char* data) { + + if (state->midi->capacity - state->midi->size < + sizeof(double) + sizeof(size_t) + size) + return -1; + + *(double*)(state->midi->data + state->midi->size) = timestamp; + state->midi->size += sizeof(double); + *(size_t*)(state->midi->data + state->midi->size) = size; + state->midi->size += sizeof(size_t); + memcpy(state->midi->data + state->midi->size, data, size); + state->midi->size += size; + + ++state->midi->event_count; + + return 0; +} + + +#endif + |