source: roaraudio/libroardsp/midi.c @ 1879:6f1ac40aae5d

Last change on this file since 1879:6f1ac40aae5d was 1854:0a8a71892f5e, checked in by phi, 15 years ago

added basic MIDI Note IDs to lookup table, added very basic search function

File size: 4.6 KB
Line 
1//midi.c:
2
3/*
4 *      Copyright (C) Philipp 'ph3-der-loewe' Schafft - August 2008
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, 675 Mass Ave, Cambridge, MA 02139, USA.
22 *
23 */
24
25#include "libroardsp.h"
26
27struct {
28 uint16_t id;
29 unsigned char midiid;
30 float freq;
31 char * name;
32} _libroar_notes[] = {
33 {ROAR_MIDI_NOTE_C , 60, 261.625565, "C" },
34 {ROAR_MIDI_NOTE_Cs, 61, 277.182631, "C#"},
35 {ROAR_MIDI_NOTE_D , 62, 293.664768, "D" },
36 {ROAR_MIDI_NOTE_Ds, 63, 311.126984, "D#"},
37 {ROAR_MIDI_NOTE_E , 64, 329.627557, "E" },
38 {ROAR_MIDI_NOTE_F , 65, 349.228231, "F" },
39 {ROAR_MIDI_NOTE_Fs, 66, 369.994423, "F#"},
40 {ROAR_MIDI_NOTE_G , 67, 391.995436, "G" },
41 {ROAR_MIDI_NOTE_Gs, 68, 415.304698, "G#"},
42 {ROAR_MIDI_NOTE_A , 69, 440.000000, "A" },
43 {ROAR_MIDI_NOTE_As, 70, 466.163762, "A#"},
44 {ROAR_MIDI_NOTE_B , 71, 493.883301, "B" },
45 {0, 0, 0, NULL}
46};
47
48char         * roar_midi_note2name   (uint16_t note) {
49 int i;
50
51 for (i = 0; _libroar_notes[i].name != NULL; i++)
52  if ( _libroar_notes[i].id == note )
53   return _libroar_notes[i].name;
54
55 return NULL;
56}
57
58uint16_t   roar_midi_name2note   (char * note) {
59 int i;
60
61 for (i = 0; _libroar_notes[i].name != NULL; i++)
62  if ( strcasecmp(_libroar_notes[i].name, note) == 0 )
63   return _libroar_notes[i].id;
64
65 return ROAR_MIDI_NOTE_NONE;
66}
67
68uint16_t       roar_midi_midi2note   (unsigned char midiid) {
69 int i;
70
71 for (i = 0; _libroar_notes[i].name != NULL; i++)
72  if ( _libroar_notes[i].midiid == midiid )
73   return _libroar_notes[i].id;
74
75 return ROAR_MIDI_NOTE_NONE;
76}
77
78float          roar_midi_note2freq   (uint16_t note) {
79 int i;
80
81 for (i = 0; _libroar_notes[i].name != NULL; i++)
82  if ( _libroar_notes[i].id == note )
83   return _libroar_notes[i].freq;
84
85 return -1;
86}
87
88int            roar_midi_find_octave (char * note);
89int            roar_midi_add_octave  (struct roar_note_octave * note) {
90 note->name[0] = 0;
91 return -1;
92}
93
94int            roar_midi_notefill    (struct roar_note_octave * note) {
95 int oct;
96
97 if ( !note )
98  return -1;
99
100 if ( note->note && note->name[0] == 0 ) {
101  roar_midi_add_octave(note);
102 } else if ( !note->note && note->name[0] != 0 ) {
103  return -1;
104 }
105
106 oct = 1 << abs(note->octave);
107
108 note->freq = roar_midi_note2freq(note->note);
109
110 // TODO: fix this: freq is freq*2^octave
111 if ( note->octave < 0 ) {
112  note->freq /= oct;
113 } else {
114  note->freq *= oct;
115 }
116
117 return 0;
118}
119
120int roar_midi_gen_tone (struct roar_note_octave * note, int16_t * samples, float t, int rate, int channels, int type, void * opts) {
121#ifdef ROAR_HAVE_LIBM
122 int i, c;
123 float ct;
124 float step = M_PI*2*note->freq/rate;
125 int16_t s;
126 float (*op)(float x) = NULL;
127
128/*
129 rate: 1/s
130 t   : 1s
131 freq: 1/s
132 rew : 1s
133*/
134
135 if ( type == ROAR_MIDI_TYPE_SINE ) {
136  op = sinf;
137 } else {
138  return -1;
139 }
140
141 if ( op == NULL )
142  return -1;
143
144 for (ct = 0, i = 0; ct <= t; ct += step, i += channels) {
145  s = 32767*op(ct);
146
147  for (c = 0; c < channels; c++)
148   samples[i+c] = s;
149 }
150
151 return 0;
152#else
153 return -1;
154#endif
155}
156
157
158int roar_midi_play_note  (struct roar_stream * stream, struct roar_note_octave * note, float len) {
159 return -1;
160}
161
162int roar_midi_basic_init (struct roar_midi_basic_state * state) {
163 if (!state)
164  return -1;
165
166 state->len.mul = 1;
167 state->len.div = 60;
168
169 state->note.note   = ROAR_MIDI_NOTE_NONE;
170 state->note.octave = 0;
171
172 return 0;
173}
174
175int roar_midi_basic_play (struct roar_stream * stream, struct roar_midi_basic_state * state, char * notes) {
176 struct roar_midi_basic_state is;
177 char   cn[ROAR_MIDI_MAX_NOTENAME_LEN+1] = {0};
178 int i;
179 int have = 0;
180 struct roar_note_octave * n;
181
182 if ( !notes )
183  return -1;
184
185 if ( state == NULL ) {
186  state = &is;
187  roar_midi_basic_init(state);
188 }
189
190 n = &(state->note);
191
192 for (; *notes != 0; notes++) {
193  if ( *notes == '>' ) {
194   n->octave++;
195  } else if ( *notes == '<' ) {
196   n->octave--;
197  } else if ( *notes != ' ' ) {
198   have++;
199  }
200
201  if (have) {
202   roar_midi_play_note(stream, n, 60 * state->len.mul / state->len.div);
203   have = 0;
204  }
205 }
206
207 return 0;
208}
209
210//ll
Note: See TracBrowser for help on using the repository browser.