You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
125 lines
3.6 KiB
125 lines
3.6 KiB
/*
|
|
Calf Box, an open source musical instrument.
|
|
Copyright (C) 2010-2013 Krzysztof Foltman
|
|
|
|
This program is free software: you can redistribute it and/or modify
|
|
it under the terms of the GNU General Public License as published by
|
|
the Free Software Foundation, either version 3 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 General Public License for more details.
|
|
|
|
You should have received a copy of the GNU General Public License
|
|
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
*/
|
|
|
|
#ifndef CBOX_MIDI_H
|
|
#define CBOX_MIDI_H
|
|
|
|
#include <ctype.h>
|
|
#include <stdint.h>
|
|
#include <stdlib.h>
|
|
#include <string.h>
|
|
|
|
struct cbox_midi_event
|
|
{
|
|
uint32_t time;
|
|
uint32_t size;
|
|
union {
|
|
uint8_t data_inline[4]; /* up to 4 bytes */
|
|
uint8_t *data_ext; /* if larger than 4 bytes */
|
|
};
|
|
};
|
|
|
|
#define CBOX_MIDI_MAX_EVENTS 256
|
|
#define CBOX_MIDI_MAX_LONG_DATA 256
|
|
|
|
struct cbox_midi_buffer
|
|
{
|
|
uint32_t count;
|
|
uint32_t long_data_size;
|
|
struct cbox_midi_event events[CBOX_MIDI_MAX_EVENTS];
|
|
uint8_t long_data[CBOX_MIDI_MAX_LONG_DATA];
|
|
};
|
|
|
|
static inline void cbox_midi_buffer_init(struct cbox_midi_buffer *buffer)
|
|
{
|
|
buffer->count = 0;
|
|
buffer->long_data_size = 0;
|
|
}
|
|
|
|
static inline void cbox_midi_buffer_clear(struct cbox_midi_buffer *buffer)
|
|
{
|
|
buffer->count = 0;
|
|
buffer->long_data_size = 0;
|
|
}
|
|
|
|
static inline void cbox_midi_buffer_copy(struct cbox_midi_buffer *dst, const struct cbox_midi_buffer *src)
|
|
{
|
|
dst->count = src->count;
|
|
dst->long_data_size = src->long_data_size;
|
|
memcpy(dst->events, src->events, src->count * sizeof(struct cbox_midi_event));
|
|
memcpy(dst->long_data, src->long_data, src->long_data_size);
|
|
// for any long events, update data pointers
|
|
for (uint32_t i = 0; i < src->count; i++)
|
|
{
|
|
if (dst->events[i].size > 4)
|
|
dst->events[i].data_ext += &dst->long_data[0] - &src->long_data[0];
|
|
}
|
|
}
|
|
|
|
static inline uint32_t cbox_midi_buffer_get_count(struct cbox_midi_buffer *buffer)
|
|
{
|
|
return buffer->count;
|
|
}
|
|
|
|
static inline uint32_t cbox_midi_buffer_get_last_event_time(struct cbox_midi_buffer *buffer)
|
|
{
|
|
if (!buffer->count)
|
|
return 0;
|
|
return buffer->events[buffer->count - 1].time;
|
|
}
|
|
|
|
static inline int cbox_midi_buffer_can_store_msg(struct cbox_midi_buffer *buffer, int size)
|
|
{
|
|
if (buffer->count >= CBOX_MIDI_MAX_EVENTS)
|
|
return 0;
|
|
if (size < 4)
|
|
return 1;
|
|
return buffer->long_data_size + size <= CBOX_MIDI_MAX_LONG_DATA;
|
|
}
|
|
|
|
static inline const struct cbox_midi_event *cbox_midi_buffer_get_event(const struct cbox_midi_buffer *buffer, uint32_t pos)
|
|
{
|
|
if (pos >= buffer->count)
|
|
return NULL;
|
|
return &buffer->events[pos];
|
|
}
|
|
|
|
static inline const uint8_t *cbox_midi_event_get_data(const struct cbox_midi_event *evt)
|
|
{
|
|
return evt->size > 4 ? evt->data_ext : evt->data_inline;
|
|
}
|
|
|
|
static inline int midi_cmd_size(uint8_t cmd)
|
|
{
|
|
static const int sizes[] = { 3, 3, 3, 3, 2, 2, 3, 1 };
|
|
if (cmd < 128)
|
|
return 0;
|
|
return sizes[(cmd >> 4) - 8];
|
|
}
|
|
|
|
extern int cbox_midi_buffer_write_event(struct cbox_midi_buffer *buffer, uint32_t time, uint8_t *data, uint32_t size);
|
|
|
|
extern int cbox_midi_buffer_write_inline(struct cbox_midi_buffer *buffer, uint32_t time, ...);
|
|
|
|
extern int cbox_midi_buffer_copy_event(struct cbox_midi_buffer *buffer, const struct cbox_midi_event *event, int new_time);
|
|
|
|
extern int note_from_string(const char *note);
|
|
|
|
extern int cbox_config_get_note(const char *cfg_section, const char *key, int def_value);
|
|
|
|
#endif
|
|
|