source: roaraudio/libroardsp/midi.c @ 687:b69676c475b4

Last change on this file since 687:b69676c475b4 was 687:b69676c475b4, checked in by phi, 16 years ago

added copyright statements

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