Initial attempt at timestretching implementation.
[calfbox.git] / midi.h
blob2c03953daf1960ab05f1998b9ee9912f2c12e8a7
1 /*
2 Calf Box, an open source musical instrument.
3 Copyright (C) 2010-2013 Krzysztof Foltman
5 This program is free software: you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation, either version 3 of the License, or
8 (at your option) any later version.
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
15 You should have received a copy of the GNU General Public License
16 along with this program. If not, see <http://www.gnu.org/licenses/>.
19 #ifndef CBOX_MIDI_H
20 #define CBOX_MIDI_H
22 #include <ctype.h>
23 #include <stdint.h>
24 #include <stdlib.h>
25 #include <string.h>
27 struct cbox_midi_event
29 uint32_t time;
30 uint32_t size;
31 union {
32 uint8_t data_inline[4]; /* up to 4 bytes */
33 uint8_t *data_ext; /* if larger than 4 bytes */
37 #define CBOX_MIDI_MAX_EVENTS 256
38 #define CBOX_MIDI_MAX_LONG_DATA 256
40 struct cbox_midi_buffer
42 uint32_t count;
43 uint32_t long_data_size;
44 struct cbox_midi_event events[CBOX_MIDI_MAX_EVENTS];
45 uint8_t long_data[CBOX_MIDI_MAX_LONG_DATA];
48 static inline void cbox_midi_buffer_init(struct cbox_midi_buffer *buffer)
50 buffer->count = 0;
51 buffer->long_data_size = 0;
54 static inline void cbox_midi_buffer_clear(struct cbox_midi_buffer *buffer)
56 buffer->count = 0;
57 buffer->long_data_size = 0;
60 static inline void cbox_midi_buffer_copy(struct cbox_midi_buffer *dst, const struct cbox_midi_buffer *src)
62 dst->count = src->count;
63 dst->long_data_size = src->long_data_size;
64 memcpy(dst->events, src->events, src->count * sizeof(struct cbox_midi_event));
65 memcpy(dst->long_data, src->long_data, src->long_data_size);
66 // for any long events, update data pointers
67 for (int i = 0; i < src->count; i++)
69 if (dst->events[i].size > 4)
70 dst->events[i].data_ext += &dst->long_data[0] - &src->long_data[0];
74 static inline uint32_t cbox_midi_buffer_get_count(struct cbox_midi_buffer *buffer)
76 return buffer->count;
79 static inline uint32_t cbox_midi_buffer_get_last_event_time(struct cbox_midi_buffer *buffer)
81 if (!buffer->count)
82 return 0;
83 return buffer->events[buffer->count - 1].time;
86 static inline int cbox_midi_buffer_can_store_msg(struct cbox_midi_buffer *buffer, int size)
88 if (buffer->count >= CBOX_MIDI_MAX_EVENTS)
89 return 0;
90 if (size < 4)
91 return 1;
92 return buffer->long_data_size + size <= CBOX_MIDI_MAX_LONG_DATA;
95 static inline const struct cbox_midi_event *cbox_midi_buffer_get_event(const struct cbox_midi_buffer *buffer, uint32_t pos)
97 if (pos >= buffer->count)
98 return NULL;
99 return &buffer->events[pos];
102 static inline const uint8_t *cbox_midi_event_get_data(const struct cbox_midi_event *evt)
104 return evt->size > 4 ? evt->data_ext : evt->data_inline;
107 static inline int midi_cmd_size(uint8_t cmd)
109 static const int sizes[] = { 3, 3, 3, 3, 2, 2, 3, 1 };
110 if (cmd < 128)
111 return 0;
112 return sizes[(cmd >> 4) - 8];
115 extern int cbox_midi_buffer_write_event(struct cbox_midi_buffer *buffer, uint32_t time, uint8_t *data, uint32_t size);
117 extern int cbox_midi_buffer_write_inline(struct cbox_midi_buffer *buffer, uint32_t time, ...);
119 extern int cbox_midi_buffer_copy_event(struct cbox_midi_buffer *buffer, const struct cbox_midi_event *event, int new_time);
121 extern int note_from_string(const char *note);
123 extern int cbox_config_get_note(const char *cfg_section, const char *key, int def_value);
125 #endif