source: roaraudio/libroardsp/midi.c @ 5381:430b1d26e12d

Last change on this file since 5381:430b1d26e12d was 5381:430b1d26e12d, checked in by phi, 12 years ago

updated copyright years

File size: 5.3 KB
Line 
1//midi.c:
2
3/*
4 *      Copyright (C) Philipp 'ph3-der-loewe' Schafft - 2008-2012
5 *
6 *  This file is part of libroardsp a part of RoarAudio,
7 *  a cross-platform sound system for both, home and professional use.
8 *  See README for details.
9 *
10 *  This file is free software; you can redistribute it and/or modify
11 *  it under the terms of the GNU General Public License version 3
12 *  as published by the Free Software Foundation.
13 *
14 *  libroardsp is distributed in the hope that it will be useful,
15 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
16 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17 *  GNU General Public License for more details.
18 *
19 *  You should have received a copy of the GNU General Public License
20 *  along with this software; see the file COPYING.  If not, write to
21 *  the Free Software Foundation, 51 Franklin Street, Fifth Floor,
22 *  Boston, MA 02110-1301, USA.
23 *
24 */
25
26#include "libroardsp.h"
27
28struct {
29 uint16_t id;
30 unsigned char midiid;
31 float freq;
32 char * name;
33} _libroar_notes[] = {
34 {ROAR_MIDI_NOTE_C , 60, 261.625565, "C" },
35 {ROAR_MIDI_NOTE_Cs, 61, 277.182631, "C#"},
36 {ROAR_MIDI_NOTE_D , 62, 293.664768, "D" },
37 {ROAR_MIDI_NOTE_Ds, 63, 311.126984, "D#"},
38 {ROAR_MIDI_NOTE_E , 64, 329.627557, "E" },
39 {ROAR_MIDI_NOTE_F , 65, 349.228231, "F" },
40 {ROAR_MIDI_NOTE_Fs, 66, 369.994423, "F#"},
41 {ROAR_MIDI_NOTE_G , 67, 391.995436, "G" },
42 {ROAR_MIDI_NOTE_Gs, 68, 415.304698, "G#"},
43 {ROAR_MIDI_NOTE_A , 69, 440.000000, "A" },
44 {ROAR_MIDI_NOTE_As, 70, 466.163762, "A#"},
45 {ROAR_MIDI_NOTE_B , 71, 493.883301, "B" },
46 {0, 0, 0, NULL}
47};
48
49char         * roar_midi_note2name   (uint16_t note) {
50 int i;
51
52 for (i = 0; _libroar_notes[i].name != NULL; i++)
53  if ( _libroar_notes[i].id == note )
54   return _libroar_notes[i].name;
55
56 return NULL;
57}
58
59uint16_t   roar_midi_name2note   (char * note) {
60 int i;
61
62 for (i = 0; _libroar_notes[i].name != NULL; i++)
63  if ( strcasecmp(_libroar_notes[i].name, note) == 0 )
64   return _libroar_notes[i].id;
65
66 return ROAR_MIDI_NOTE_NONE;
67}
68
69uint16_t       roar_midi_midi2note   (unsigned char midiid) {
70 int i;
71
72 for (i = 0; _libroar_notes[i].name != NULL; i++)
73  if ( _libroar_notes[i].midiid == midiid )
74   return _libroar_notes[i].id;
75
76 return ROAR_MIDI_NOTE_NONE;
77}
78
79float          roar_midi_note2freq   (uint16_t note) {
80 int i;
81
82 for (i = 0; _libroar_notes[i].name != NULL; i++)
83  if ( _libroar_notes[i].id == note )
84   return _libroar_notes[i].freq;
85
86 return -1;
87}
88
89int            roar_midi_note_from_midiid(struct roar_note_octave * note, unsigned char midiid) {
90 int oct;
91
92 if ( note == NULL || midiid > 127 )
93  return -1;
94
95 memset(note, 0, sizeof(struct roar_note_octave));
96
97 note->octave = ((int) midiid/12) - 5;
98 note->note   = roar_midi_midi2note((midiid % 12) + 60);
99
100 oct = 1 << abs(note->octave);
101
102 note->freq = roar_midi_note2freq(note->note);
103
104 if ( note->octave < 0 ) {
105  note->freq /= oct;
106 } else {
107  note->freq *= oct;
108 }
109
110 return 0;
111}
112
113int            roar_midi_find_octave (char * note);
114int            roar_midi_add_octave  (struct roar_note_octave * note) {
115 note->name[0] = 0;
116 return -1;
117}
118
119int            roar_midi_notefill    (struct roar_note_octave * note) {
120 int oct;
121
122 if ( !note )
123  return -1;
124
125 if ( note->note && note->name[0] == 0 ) {
126  roar_midi_add_octave(note);
127 } else if ( !note->note && note->name[0] != 0 ) {
128  return -1;
129 }
130
131 oct = 1 << abs(note->octave);
132
133 note->freq = roar_midi_note2freq(note->note);
134
135 // TODO: fix this: freq is freq*2^octave
136 if ( note->octave < 0 ) {
137  note->freq /= oct;
138 } else {
139  note->freq *= oct;
140 }
141
142 return 0;
143}
144
145int roar_midi_gen_tone (struct roar_note_octave * note, int16_t * samples, float t, int rate, int channels, int type, void * opts) {
146#ifdef ROAR_HAVE_LIBM
147 int i, c;
148 float ct;
149 float step = 1.0/rate;
150 int16_t s;
151 float (*op)(float x) = NULL;
152
153/*
154 rate: 1/s
155 t   : 1s
156 freq: 1/s
157 rew : 1s
158*/
159
160 if ( type == ROAR_MIDI_TYPE_SINE ) {
161  op = sinf;
162 } else {
163  return -1;
164 }
165
166 if ( op == NULL )
167  return -1;
168
169 ROAR_DBG("roar_midi_gen_tone(*): t=%f", t);
170
171 for (ct = 0, i = 0; ct <= t; ct += step, i += channels) {
172  s = 32767*op(2.0*M_PI*note->freq*ct);
173
174//  ROAR_DBG("roar_midi_gen_tone(*): t=%f, ct=%f, i=%i", t, ct, i);
175
176  for (c = 0; c < channels; c++)
177   samples[i+c] = s;
178 }
179
180 ROAR_DBG("roar_midi_gen_tone(*): t=%f, ct=%f, i=%i", t, ct, i);
181
182 return 0;
183#else
184 return -1;
185#endif
186}
187
188
189int roar_midi_play_note  (struct roar_stream * stream, struct roar_note_octave * note, float len) {
190 return -1;
191}
192
193int roar_midi_basic_init (struct roar_midi_basic_state * state) {
194 if (!state)
195  return -1;
196
197 state->len.mul = 1;
198 state->len.div = 60;
199
200 state->note.note   = ROAR_MIDI_NOTE_NONE;
201 state->note.octave = 0;
202
203 return 0;
204}
205
206int roar_midi_basic_play (struct roar_stream * stream, struct roar_midi_basic_state * state, char * notes) {
207 struct roar_midi_basic_state is;
208#if 0
209 char   cn[ROAR_MIDI_MAX_NOTENAME_LEN+1] = {0};
210 int i;
211#endif
212 int have = 0;
213 struct roar_note_octave * n;
214
215 if ( !notes )
216  return -1;
217
218 if ( state == NULL ) {
219  state = &is;
220  roar_midi_basic_init(state);
221 }
222
223 n = &(state->note);
224
225 for (; *notes != 0; notes++) {
226  if ( *notes == '>' ) {
227   n->octave++;
228  } else if ( *notes == '<' ) {
229   n->octave--;
230  } else if ( *notes != ' ' ) {
231   have++;
232  }
233
234  if (have) {
235   roar_midi_play_note(stream, n, 60 * state->len.mul / state->len.div);
236   have = 0;
237  }
238 }
239
240 return 0;
241}
242
243//ll
Note: See TracBrowser for help on using the repository browser.