summaryrefslogtreecommitdiff
path: root/libs/distrho/src/lv2/lv2-midifunctions.h
blob: d068f498ab7c4b6cba794c4e35806f2f8a9ab318 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
/****************************************************************************
    
    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 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 "lv2-miditype.h"

#ifdef __cplusplus
extern "C" {
#endif

typedef struct {
  LV2_MIDI* midi;
  uint32_t frame_count;
  uint32_t position;
} LV2_MIDIState;


inline 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 = (uint32_t)*(size_t*)(state->midi->data + state->position + sizeof(double));
  *data = state->midi->data + state->position + 
    sizeof(double) + sizeof(size_t);
  return *timestamp;
}


inline double lv2midi_step(LV2_MIDIState* state) {

  if (state->position >= state->midi->size) {
    state->position = state->midi->size;
    return state->frame_count;
  }
  
  state->position += (uint32_t)sizeof(double);
  size_t size = *(size_t*)(state->midi->data + state->position);
  state->position += (uint32_t)sizeof(size_t);
  state->position += (uint32_t)size;
  return *(double*)(state->midi->data + state->position);
}


inline void lv2midi_put_event(LV2_MIDIState* state,
                             double timestamp,
                             uint32_t size,
                             const unsigned char* data) {
  
  if (state->midi->size + sizeof(double) + sizeof(size_t) + size < state->midi->capacity)
  {
    *((double*)(state->midi->data + state->midi->size)) = timestamp;
    state->midi->size += (uint32_t)sizeof(double);
    *((size_t*)(state->midi->data + state->midi->size)) = size;
    state->midi->size += (uint32_t)sizeof(size_t);
    memcpy(state->midi->data + state->midi->size, data, size);

    state->midi->size += size;
    state->midi->event_count++;
  }
}

#ifdef __cplusplus
}  /* extern "C" */
#endif

#endif