source: roaraudio/roard/ssynth.c @ 2469:e9f81bfa4020

Last change on this file since 2469:e9f81bfa4020 was 2469:e9f81bfa4020, checked in by phi, 15 years ago

alloc buffers, and free them again

File size: 5.2 KB
Line 
1//ssynth.c:
2
3/*
4 *      Copyright (C) Philipp 'ph3-der-loewe' Schafft - 2009
5 *
6 *  This file is part of roard 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 *  RoarAudio 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 "roard.h"
26
27float ssynth_polys[SSYNTH_POLY_POLYMAX][SSYNTH_POLY_COEFF] = {
28       {0.300000,  0.958333, -0.550000,  0.091667},
29       {0.700010, -0.083333, -0.150000,  0.033333}
30      };
31
32int ssynth_init_config(void) {
33 memset(&ssynth_conf, 0, sizeof(ssynth_conf));
34
35 return 0;
36}
37
38#define _err() streams_delete(sid); return -1
39int ssynth_init (void) {
40 struct roar_stream_server * ss;
41 struct roar_stream        *  s;
42 int sid;
43
44 if ( !ssynth_conf.enable )
45  return 0;
46
47 memset(&g_ssynth, 0, sizeof(g_ssynth));
48 g_ssynth.stream = -1;
49
50 if ( (sid = streams_new()) == -1 )
51  return -1;
52
53 if ( streams_set_client(sid, g_self_client) == -1 ) {
54  _err();
55 }
56
57 if ( streams_set_dir(sid, ROAR_DIR_BRIDGE, 1) == -1 ) {
58  _err();
59 }
60
61 if ( streams_set_flag(sid, ROAR_FLAG_PRIMARY) == -1 ) {
62  _err();
63 }
64
65 if ( streams_set_name(sid, "Simple Synthesizer") == -1 ) {
66  _err();
67 }
68
69 if ( streams_get(sid, &ss) == -1 ) {
70  _err();
71 }
72
73 s = ROAR_STREAM(ss);
74
75 memcpy(&(s->info), g_sa, sizeof(struct roar_audio_info));
76
77 s->info.channels = 1;
78 s->info.codec    = ROAR_CODEC_DEFAULT;
79
80 g_ssynth.stream  = sid;
81
82 return 0;
83}
84
85int ssynth_free (void) {
86 int i;
87
88 if ( !ssynth_conf.enable )
89  return 0;
90
91 for (i = 0; i < SSYNTH_NOTES_MAX; i++) {
92  if ( g_ssynth.notes[i].buf != NULL ) {
93   roar_buffer_free(g_ssynth.notes[i].buf);
94   g_ssynth.notes[i].buf = NULL;
95  }
96 }
97
98 return streams_delete(g_ssynth.stream);
99}
100
101int ssynth_update (void) {
102 struct roar_stream_server * ss;
103 struct roar_stream        *  s;
104 struct roar_buffer        * buf;
105 size_t buflen;
106 size_t needlen;
107 int i;
108
109 if ( !ssynth_conf.enable )
110  return 0;
111
112 if ( streams_get(g_ssynth.stream, &ss) == -1 ) {
113  return -1;
114 }
115
116 s = ROAR_STREAM(ss);
117
118 needlen = ROAR_OUTPUT_CALC_OUTBUFSIZE(&(s->info));
119
120 for (i = 0; i < SSYNTH_NOTES_MAX; i++) {
121  if ( g_ssynth.notes[i].stage != SSYNTH_STAGE_UNUSED ) {
122   if ( g_ssynth.notes[i].buf == NULL ) {
123    if ( roar_buffer_new(&buf, needlen) == -1 )
124     continue;
125
126    g_ssynth.notes[i].buf = buf;
127   } else {
128    buf = g_ssynth.notes[i].buf;
129
130    if ( roar_buffer_get_len(buf, &buflen) == -1 )
131     continue;
132
133    if ( buflen < needlen ) {
134     if ( roar_buffer_set_len(buf, needlen) == -1 )
135      continue;
136    }
137   }
138  }
139 }
140
141 return -1;
142}
143
144
145int ssynth_note_new(struct roar_note_octave * note, char vv) {
146 int i;
147
148 for (i = 0; i < SSYNTH_NOTES_MAX; i++) {
149  if ( g_ssynth.notes[i].stage == SSYNTH_STAGE_UNUSED ) {
150   // TODO: do some error checking here
151   g_ssynth.notes[i].vv_down = vv;
152   memcpy(&(g_ssynth.notes[i].note), note, sizeof(struct roar_note_octave));
153   roar_synth_init(&(g_ssynth.notes[i].synth), &(g_ssynth.notes[i].note), g_sa->rate);
154   ssynth_note_set_stage(i, SSYNTH_STAGE_KEYSTROKE);
155   return i;
156  }
157 }
158
159 return -1;
160}
161
162int ssynth_note_free(int id) {
163 g_ssynth.notes[id].stage = SSYNTH_STAGE_UNUSED;
164 return 0;
165}
166
167int ssynth_note_find(struct roar_note_octave * note) {
168 struct roar_note_octave * cn;
169 int i;
170
171 for (i = 0; i < SSYNTH_NOTES_MAX; i++) {
172  if ( g_ssynth.notes[i].stage == SSYNTH_STAGE_UNUSED )
173   continue;
174
175  cn = &(g_ssynth.notes[i].note);
176
177  if ( !(note->note == cn->note && note->octave == cn->octave) )
178   continue;
179
180  return i;
181 }
182
183 return -1;
184}
185
186int ssynth_note_set_stage(int id, int stage) {
187 int r = -1;
188
189 switch (stage) {
190  case SSYNTH_STAGE_UNUSED:
191    r = ssynth_note_free(id);
192   break;
193  case SSYNTH_STAGE_KEYSTROKE:
194    r = roar_fader_init(&(g_ssynth.notes[id].fader), ssynth_polys[SSYNTH_POLY_KEYDOWN], SSYNTH_POLY_COEFF);
195   break;
196  case SSYNTH_STAGE_MIDSECTION:
197    r = 0;
198   break;
199  case SSYNTH_STAGE_KEYRELEASE:
200    r = roar_fader_init(&(g_ssynth.notes[id].fader), ssynth_polys[SSYNTH_POLY_KEYUP], SSYNTH_POLY_COEFF);
201   break;
202 }
203
204 if ( r == 0 )
205  g_ssynth.notes[id].stage = stage;
206
207 return r;
208}
209
210int ssynth_note_on       (struct roar_note_octave * note, char vv) {
211 return ssynth_note_new(note, vv);
212}
213
214int ssynth_note_off      (struct roar_note_octave * note, char vv) {
215 int id;
216
217 if ( (id = ssynth_note_find(note)) == -1 )
218  return -1;
219
220 // add support to for keyups...
221
222 return ssynth_note_free(id);
223}
224
225int ssynth_eval_message (struct midi_message * mes) {
226 if ( !ssynth_conf.enable )
227  return -1;
228
229 switch (mes->type) {
230  case MIDI_TYPE_NOTE_OFF:
231    return ssynth_note_off(&(mes->d.note), mes->vv);
232   break;
233  case MIDI_TYPE_NOTE_ON:
234    return ssynth_note_off(&(mes->d.note), mes->vv);
235   break;
236  default:
237    /* ignore all other events at the moment */
238    return 0;
239 }
240
241 return -1;
242}
243
244//ll
Note: See TracBrowser for help on using the repository browser.