source: roaraudio/roard/ssynth.c @ 3811:49db840fb4f4

Last change on this file since 3811:49db840fb4f4 was 3811:49db840fb4f4, checked in by phi, 14 years ago

fixed some copyright statements

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