source: roaraudio/roard/ssynth.c @ 3234:33163b08ad79

Last change on this file since 3234:33163b08ad79 was 2932:09d25b79ce75, checked in by phi, 15 years ago

removed now non-needed mix_clients*()

File size: 7.0 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
27#ifndef ROAR_WITHOUT_DCOMP_SSYNTH
28
29float ssynth_polys[SSYNTH_POLY_POLYMAX][SSYNTH_POLY_COEFF] = {
30       {0.300000,  0.958333, -0.550000,  0.091667},
31       {0.700010, -0.083333, -0.150000,  0.033333}
32      };
33
34int ssynth_init_config(void) {
35 memset(&ssynth_conf, 0, sizeof(ssynth_conf));
36
37 return 0;
38}
39
40#define _err() streams_delete(sid); return -1
41int ssynth_init (void) {
42 struct roar_stream_server * ss;
43 struct roar_stream        *  s;
44 int sid;
45
46 if ( !ssynth_conf.enable )
47  return 0;
48
49 memset(&g_ssynth, 0, sizeof(g_ssynth));
50 g_ssynth.stream = -1;
51
52 if ( (sid = streams_new()) == -1 )
53  return -1;
54
55 if ( streams_set_client(sid, g_self_client) == -1 ) {
56  _err();
57 }
58
59 if ( streams_set_dir(sid, ROAR_DIR_BRIDGE, 1) == -1 ) {
60  _err();
61 }
62
63 if ( streams_set_flag(sid, ROAR_FLAG_PRIMARY) == -1 ) {
64  _err();
65 }
66
67 if ( streams_set_name(sid, "Simple Synthesizer") == -1 ) {
68  _err();
69 }
70
71 if ( streams_get(sid, &ss) == -1 ) {
72  _err();
73 }
74
75 s = ROAR_STREAM(ss);
76
77 memcpy(&(s->info), g_sa, sizeof(struct roar_audio_info));
78
79 s->info.channels = 1;
80 s->info.codec    = ROAR_CODEC_DEFAULT;
81
82 g_ssynth.stream  = sid;
83
84 return 0;
85}
86
87int ssynth_free (void) {
88 int i;
89
90 if ( !ssynth_conf.enable )
91  return 0;
92
93 for (i = 0; i < SSYNTH_NOTES_MAX; i++) {
94  if ( g_ssynth.notes[i].buf != NULL ) {
95   roar_buffer_free(g_ssynth.notes[i].buf);
96   g_ssynth.notes[i].buf = NULL;
97  }
98 }
99
100 return streams_delete(g_ssynth.stream);
101}
102
103int ssynth_update (void) {
104 struct roar_stream_server * ss;
105 struct roar_stream        *  s;
106 struct roar_buffer        * buf;
107 struct roar_buffer        * outbuf;
108 void                      * outbufdata;
109 void                      * indbufs[SSYNTH_NOTES_MAX+1];
110 int                         curin = 0;
111 size_t buflen;
112 size_t needlen;
113 int i;
114
115 if ( !ssynth_conf.enable )
116  return 0;
117
118 ROAR_DBG("ssynth_update(void) = ?");
119
120 if ( streams_get(g_ssynth.stream, &ss) == -1 ) {
121  return -1;
122 }
123
124 memset(indbufs, 0, sizeof(indbufs));
125
126 s = ROAR_STREAM(ss);
127
128 needlen = ROAR_OUTPUT_CALC_OUTBUFSIZE(&(s->info));
129
130 ROAR_DBG("ssynth_update(void): needlen=%lu", (unsigned long)needlen);
131
132 for (i = 0; i < SSYNTH_NOTES_MAX; i++) {
133  if ( g_ssynth.notes[i].stage != SSYNTH_STAGE_UNUSED ) {
134   ROAR_DBG("ssynth_update(void): used note slot: %i", i);
135   if ( g_ssynth.notes[i].buf == NULL ) {
136    if ( roar_buffer_new(&buf, needlen) == -1 )
137     continue;
138
139    g_ssynth.notes[i].buf = buf;
140   } else {
141    buf = g_ssynth.notes[i].buf;
142
143    if ( roar_buffer_get_len(buf, &buflen) == -1 )
144     continue;
145
146    if ( buflen < needlen ) {
147     if ( roar_buffer_set_len(buf, needlen) == -1 )
148      continue;
149    }
150   }
151
152   if ( roar_buffer_get_data(buf, &(indbufs[curin])) == -1 )
153    continue;
154
155   if ( ssynth_note_render(i, indbufs[curin]) == -1 )
156    continue;
157
158   curin++;
159  }
160 }
161
162 ROAR_DBG("ssynth_update(void): found streams: %i", curin);
163
164 if ( curin > 0 ) {
165  if ( roar_buffer_new(&outbuf, needlen) == -1 )
166   return -1;
167
168  if ( roar_buffer_get_data(outbuf, &outbufdata) == -1 ) {
169   roar_buffer_free(outbuf);
170   return -1;
171  }
172
173  if ( roar_mix_pcm(outbufdata, g_sa->bits, indbufs, ROAR_OUTPUT_BUFFER_SAMPLES) == -1 ) {
174   roar_buffer_free(outbuf);
175   return -1;
176  }
177
178  if ( stream_add_buffer(g_ssynth.stream, outbuf) == -1 ) {
179   roar_buffer_free(outbuf);
180   return -1;
181  }
182 }
183
184 ROAR_DBG("ssynth_update(void) = 0");
185 return 0;
186}
187
188
189int ssynth_note_new(struct roar_note_octave * note, char vv) {
190 int i;
191
192 ROAR_DBG("ssynth_note_new(note=%p, vv=%i) = ?", note, vv);
193
194 for (i = 0; i < SSYNTH_NOTES_MAX; i++) {
195  if ( g_ssynth.notes[i].stage == SSYNTH_STAGE_UNUSED ) {
196   // TODO: do some error checking here
197   g_ssynth.notes[i].vv_down = vv;
198   memcpy(&(g_ssynth.notes[i].note), note, sizeof(struct roar_note_octave));
199   roar_synth_init(&(g_ssynth.notes[i].synth), &(g_ssynth.notes[i].note), g_sa->rate);
200   roar_synth_set_volume(&(g_ssynth.notes[i].synth), 0.25);
201   roar_synth_set_func(&(g_ssynth.notes[i].synth), ROAR_SYNTH_SYNF_TRAP);
202   ssynth_note_set_stage(i, SSYNTH_STAGE_KEYSTROKE);
203   ROAR_DBG("ssynth_note_new(note=%p, vv=%i) = %i", note, vv, i);
204   return i;
205  }
206 }
207
208 ROAR_DBG("ssynth_note_new(note=%p, vv=%i) = -1", note, vv);
209 return -1;
210}
211
212int ssynth_note_free(int id) {
213 g_ssynth.notes[id].stage = SSYNTH_STAGE_UNUSED;
214 return 0;
215}
216
217int ssynth_note_find(struct roar_note_octave * note) {
218 struct roar_note_octave * cn;
219 int i;
220
221 for (i = 0; i < SSYNTH_NOTES_MAX; i++) {
222  if ( g_ssynth.notes[i].stage == SSYNTH_STAGE_UNUSED )
223   continue;
224
225  cn = &(g_ssynth.notes[i].note);
226
227  if ( !(note->note == cn->note && note->octave == cn->octave) )
228   continue;
229
230  return i;
231 }
232
233 return -1;
234}
235
236int ssynth_note_set_stage(int id, int stage) {
237 int r = -1;
238
239 switch (stage) {
240  case SSYNTH_STAGE_UNUSED:
241    r = ssynth_note_free(id);
242   break;
243  case SSYNTH_STAGE_KEYSTROKE:
244    r = roar_fader_init(&(g_ssynth.notes[id].fader), ssynth_polys[SSYNTH_POLY_KEYDOWN], SSYNTH_POLY_COEFF);
245   break;
246  case SSYNTH_STAGE_MIDSECTION:
247    r = 0;
248   break;
249  case SSYNTH_STAGE_KEYRELEASE:
250    r = roar_fader_init(&(g_ssynth.notes[id].fader), ssynth_polys[SSYNTH_POLY_KEYUP], SSYNTH_POLY_COEFF);
251   break;
252 }
253
254 if ( r == 0 )
255  g_ssynth.notes[id].stage = stage;
256
257 return r;
258}
259
260int ssynth_note_render   (int id, void * data) {
261 if ( g_sa->bits != 16 )
262  return -1;
263
264 return roar_synth_pcmout_i161(&(g_ssynth.notes[id].synth), data, ROAR_OUTPUT_BUFFER_SAMPLES);
265}
266
267int ssynth_note_on       (struct roar_note_octave * note, char vv) {
268 ROAR_DBG("ssynth_note_on(note=%p, vv=%i) = ?", note, vv);
269 return ssynth_note_new(note, vv);
270}
271
272int ssynth_note_off      (struct roar_note_octave * note, char vv) {
273 int id;
274
275 ROAR_DBG("ssynth_note_off(note=%p, vv=%i) = ?", note, vv);
276
277 if ( (id = ssynth_note_find(note)) == -1 )
278  return -1;
279
280 // add support to for keyups...
281
282 return ssynth_note_free(id);
283}
284
285int ssynth_eval_message (struct midi_message * mes) {
286 if ( !ssynth_conf.enable )
287  return -1;
288
289 ROAR_DBG("ssynth_eval_message(mes=%p) = ?", mes);
290
291 switch (mes->type) {
292  case MIDI_TYPE_NOTE_OFF:
293    return ssynth_note_off(&(mes->d.note), mes->vv);
294   break;
295  case MIDI_TYPE_NOTE_ON:
296    return ssynth_note_on(&(mes->d.note), mes->vv);
297   break;
298  default:
299    /* ignore all other events at the moment */
300    return 0;
301 }
302
303 ROAR_DBG("ssynth_eval_message(mes=%p) = -1", mes);
304 return -1;
305}
306
307#endif
308
309//ll
Note: See TracBrowser for help on using the repository browser.