source: roaraudio/libroardsp/synth.c @ 5546:faff3e9677c4

Last change on this file since 5546:faff3e9677c4 was 5381:430b1d26e12d, checked in by phi, 12 years ago

updated copyright years

File size: 4.1 KB
RevLine 
[2425]1//synth.c:
2
3/*
[5381]4 *      Copyright (C) Philipp 'ph3-der-loewe' Schafft - 2009-2012
[2425]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
[3517]21 *  the Free Software Foundation, 51 Franklin Street, Fifth Floor,
22 *  Boston, MA 02110-1301, USA.
[2425]23 *
24 */
25
26#include "libroardsp.h"
27
[2482]28#if !defined(ROAR_HAVE_LIBM) && !defined(M_PI)
29#define M_PI 3.141592
30#endif
31
[2426]32#define _CHECK_BASIC() if ( state == NULL ) return -1
[2427]33#define _CHECK_PCMOUT() _CHECK_BASIC(); if ( frames == 0 ) return 0; if ( out == NULL ) return -1
[2426]34
35int roar_synth_init(struct roar_synth_state * state, struct roar_note_octave * note, int rate) {
36 _CHECK_BASIC();
37
38 if ( rate <= 0 )
39  return -1;
40
41 memset(state, 0, sizeof(struct roar_synth_state));
42
[2432]43 state->note   = note; // NULL is valid here!
44 state->rate   = rate;
45 state->volume = 1;
[2426]46
[2483]47 state->func = ROAR_SYNTH_SYNF_DEFAULT;
[2426]48
49 return 0;
50}
51
52int roar_synth_set_offset(struct roar_synth_state * state, size_t offset) {
53 _CHECK_BASIC();
54
55 state->pcmoffset = offset;
56
57 return 0;
58}
59
60int roar_synth_set_func  (struct roar_synth_state * state, ROAR_SYNTH_FUNC_TYPE(func)) {
61 _CHECK_BASIC();
62
[2427]63 if ( func == NULL )
64  return -1;
65
[2426]66 state->func = func;
67
68 return 0;
69}
70
[2432]71int roar_synth_set_volume(struct roar_synth_state * state, float volume) {
72 _CHECK_BASIC();
73
74 state->volume = volume;
75
76 return 0;
77}
78
[2426]79int roar_synth_pcmout_i16n(struct roar_synth_state * state, int16_t * out, size_t frames, int channels) {
[2427]80 _CHECK_PCMOUT();
[2426]81
82 switch (channels) {
83  case 1: return roar_synth_pcmout_i161(state, out, frames);
84  default:
85    return -1;
86 }
87
88 return 0;
89}
90
91int roar_synth_pcmout_i161(struct roar_synth_state * state, int16_t * out, size_t frames) {
[2427]92 float t_step;
93 float t_cur;
[2429]94 float freq;
[2475]95#ifdef DEBUG
96 float cv0, cv1;
97#endif
[5270]98 size_t i;
[2427]99
100 _CHECK_PCMOUT();
101
102 t_step = 1.0/state->rate;
103
[2474]104 ROAR_DBG("roar_synth_pcmout_i161(*): state->pcmoffset=%lu", (unsigned long)state->pcmoffset);
105
[2475]106 t_cur  = (float)state->pcmoffset/(float)state->rate;
[2427]107
[2429]108 freq   = state->note->freq;
109
[2475]110 ROAR_DBG("roar_synth_pcmout_i161(*): t_cur=%f, freq=%f", t_cur, freq);
111
112#ifdef DEBUG
113 cv0 = 2.0*M_PI*freq*t_cur;
114#endif
[2427]115 for (i = 0; i < frames; i++, t_cur += t_step) {
[2432]116  out[i] = 32767.0*state->volume*state->func(2.0*M_PI*freq*t_cur, state);
[2427]117 }
[2475]118#ifdef DEBUG
119 cv1 = 2.0*M_PI*freq*t_cur;
120#endif
121
122#ifdef DEBUG
123 ROAR_DBG("roar_synth_pcmout_i161(*): cv0=%f, cv1=%f, cv1-cv0=%f", cv0, cv1, cv1-cv0);
124#endif
[2427]125
126 state->pcmoffset += frames;
[2426]127
[2474]128 ROAR_DBG("roar_synth_pcmout_i161(*): state->pcmoffset=%lu", (unsigned long)state->pcmoffset);
129
[2428]130 return 0;
[2426]131}
132
[2430]133// basic SINFs:
134float roar_synth_synf_rect (float t, struct roar_synth_state * state) {
[5270]135 (void)state;
136
[2430]137 t /= 2*M_PI;
138 t -= (int)t;
139
140 if ( t < 0.5 )
141  return  1;
142 else
143  return -1;
144}
145
146float roar_synth_synf_saw  (float t, struct roar_synth_state * state) {
[5270]147 (void)state;
148
[2430]149 t /= 2*M_PI;
150 t -= (int)t;
151
152 return 2*t - 1;
153}
154
155float roar_synth_synf_tri  (float t, struct roar_synth_state * state) {
[5270]156 (void)state;
157
[2430]158 t /= 2*M_PI;
159 t -= (int)t;
160
161 if ( t < 0.5 )
162  return   4* t      - 1;
163 else
164  return  -4*(t-0.5) + 1;
165}
166
167float roar_synth_synf_trap (float t, struct roar_synth_state * state) {
[5270]168 (void)state;
169
[2430]170 t /= 2*M_PI;
171 t -= (int)t;
172
173 if ( t < 0.125 || t > 0.875 ) {
174  return -1;
175 } else if ( t < 0.625 && t > 0.375 ) {
176  return  1;
177 } else if ( t < 0.5 ) {
178  return  8*(t-0.375) + 1;
179 } else {
180  return -8*(t-0.625) + 1;
181 }
182}
[2425]183
[2482]184#ifdef ROAR_HAVE_LIBM
[2431]185float roar_synth_synf_s2s  (float t, struct roar_synth_state * state) {
[5270]186 (void)state;
187
[2431]188 float sin2 = sinf(t/1.2);
189
190 return sin2*sin2 * sin(t*1.2);
191}
[2482]192#endif
[2431]193
[2425]194//ll
Note: See TracBrowser for help on using the repository browser.