source: roaraudio/libroardsp/midi.c @ 370:925790633b2a

Last change on this file since 370:925790633b2a was 370:925790633b2a, checked in by phi, 16 years ago

added some BASIC PLAY like functions

File size: 3.3 KB
Line 
1//midi.c:
2
3#include "libroar.h"
4
5struct {
6 uint16_t id;
7 float freq;
8 char * name;
9} _libroar_notes[] = {
10 {ROAR_MIDI_NOTE_C , 261.625565, "C"},
11 {ROAR_MIDI_NOTE_Cs, 277.182631, "C#"},
12 {ROAR_MIDI_NOTE_D , 293.664768, "D"},
13 {ROAR_MIDI_NOTE_Ds, 311.126984, "D#"},
14 {ROAR_MIDI_NOTE_E , 329.627557, "E"},
15 {ROAR_MIDI_NOTE_F , 349.228231, "F"},
16 {ROAR_MIDI_NOTE_Fs, 369.994423, "F#"},
17 {ROAR_MIDI_NOTE_G , 391.995436, "G"},
18 {ROAR_MIDI_NOTE_Gs, 415.304698, "G#"},
19 {ROAR_MIDI_NOTE_A , 440.000000, "A"},
20 {ROAR_MIDI_NOTE_As, 466.163762, "A#"},
21 {ROAR_MIDI_NOTE_B , 493.883301, "B"},
22 {0, 0, NULL}
23};
24
25char         * roar_midi_note2name   (uint16_t note) {
26 int i;
27
28 for (i = 0; _libroar_notes[i].name != NULL; i++)
29  if ( _libroar_notes[i].id == note )
30   return _libroar_notes[i].name;
31
32 return NULL;
33}
34
35uint16_t   roar_midi_name2note   (char * note) {
36 int i;
37
38 for (i = 0; _libroar_notes[i].name != NULL; i++)
39  if ( strcasecmp(_libroar_notes[i].name, note) == 0 )
40   return _libroar_notes[i].id;
41
42 return ROAR_MIDI_NOTE_NONE;
43}
44
45float          roar_midi_note2freq   (uint16_t note) {
46 int i;
47
48 for (i = 0; _libroar_notes[i].name != NULL; i++)
49  if ( _libroar_notes[i].id == note )
50   return _libroar_notes[i].freq;
51
52 return -1;
53}
54
55int            roar_midi_find_octave (char * note);
56int            roar_midi_add_octave  (struct roar_note_octave * note) {
57 note->name[0] = 0;
58 return -1;
59}
60
61int            roar_midi_notefill    (struct roar_note_octave * note) {
62 int oct;
63
64 if ( !note )
65  return -1;
66
67 if ( note->note && note->name[0] == 0 ) {
68  roar_midi_add_octave(note);
69 } else if ( !note->note && note->name[0] != 0 ) {
70  return -1;
71 }
72
73 oct = 1 << abs(note->octave);
74
75 note->freq = roar_midi_note2freq(note->note);
76
77 if ( note->octave < 0 ) {
78  note->freq /= oct;
79 } else {
80  note->freq *= oct;
81 }
82
83 return 0;
84}
85
86int roar_midi_gen_tone (struct roar_note_octave * note, int16_t * samples, float t, int rate, int channels, int type, void * opts) {
87 int i, c;
88 float ct;
89 float step = M_PI*2*note->freq/rate;
90 int16_t s;
91 float (*op)(float x) = NULL;
92
93/*
94 rate: 1/s
95 t   : 1s
96 freq: 1/s
97 rew : 1s
98*/
99
100 if ( type == ROAR_MIDI_TYPE_SINE ) {
101  op = sinf;
102 } else {
103  return -1;
104 }
105
106 if ( op == NULL )
107  return -1;
108
109 for (ct = 0, i = 0; ct <= t; ct += step, i += channels) {
110  s = 32767*op(ct);
111
112  for (c = 0; c < channels; c++)
113   samples[i+c] = s;
114 }
115
116 return 0;
117}
118
119
120int roar_midi_play_note  (struct roar_stream * stream, struct roar_note_octave * note, float len) {
121 return -1;
122}
123
124int roar_midi_basic_init (struct roar_midi_basic_state * state) {
125 if (!state)
126  return -1;
127
128 state->len.mul = 1;
129 state->len.div = 60;
130
131 state->note.note   = ROAR_MIDI_NOTE_NONE;
132 state->note.octave = 0;
133
134 return 0;
135}
136
137int roar_midi_basic_play (struct roar_stream * stream, struct roar_midi_basic_state * state, char * notes) {
138 struct roar_midi_basic_state is;
139 char   cn[ROAR_MIDI_MAX_NOTENAME_LEN+1] = {0};
140 int i;
141 int have = 0;
142 struct roar_note_octave * n;
143
144 if ( !notes )
145  return -1;
146
147 if ( state == NULL ) {
148  state = &is;
149  roar_midi_basic_init(state);
150 }
151
152 n = &(state->note);
153
154 for (; *notes != 0; notes++) {
155  if ( *notes == '>' ) {
156   n->octave++;
157  } else if ( *notes == '<' ) {
158   n->octave--;
159  } else if ( *notes != ' ' ) {
160   have++;
161  }
162
163  if (have) {
164   roar_midi_play_note(stream, n, 60 * state->len.mul / state->len.div);
165   have = 0;
166  }
167 }
168
169 return 0;
170}
171
172//ll
Note: See TracBrowser for help on using the repository browser.