source: roaraudio/libroardsp/synth.c @ 4708:c9d40761088a

Last change on this file since 4708:c9d40761088a was 4708:c9d40761088a, checked in by phi, 13 years ago

updated copyright statements

File size: 4.0 KB
Line 
1//synth.c:
2
3/*
4 *      Copyright (C) Philipp 'ph3-der-loewe' Schafft - 2009-2011
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, 51 Franklin Street, Fifth Floor,
22 *  Boston, MA 02110-1301, USA.
23 *
24 */
25
26#include "libroardsp.h"
27
28#if !defined(ROAR_HAVE_LIBM) && !defined(M_PI)
29#define M_PI 3.141592
30#endif
31
32#define _CHECK_BASIC() if ( state == NULL ) return -1
33#define _CHECK_PCMOUT() _CHECK_BASIC(); if ( frames == 0 ) return 0; if ( out == NULL ) return -1
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
43 state->note   = note; // NULL is valid here!
44 state->rate   = rate;
45 state->volume = 1;
46
47 state->func = ROAR_SYNTH_SYNF_DEFAULT;
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
63 if ( func == NULL )
64  return -1;
65
66 state->func = func;
67
68 return 0;
69}
70
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
79int roar_synth_pcmout_i16n(struct roar_synth_state * state, int16_t * out, size_t frames, int channels) {
80 _CHECK_PCMOUT();
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) {
92 float t_step;
93 float t_cur;
94 float freq;
95#ifdef DEBUG
96 float cv0, cv1;
97#endif
98 int i;
99
100 _CHECK_PCMOUT();
101
102 t_step = 1.0/state->rate;
103
104 ROAR_DBG("roar_synth_pcmout_i161(*): state->pcmoffset=%lu", (unsigned long)state->pcmoffset);
105
106 t_cur  = (float)state->pcmoffset/(float)state->rate;
107
108 freq   = state->note->freq;
109
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
115 for (i = 0; i < frames; i++, t_cur += t_step) {
116  out[i] = 32767.0*state->volume*state->func(2.0*M_PI*freq*t_cur, state);
117 }
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
125
126 state->pcmoffset += frames;
127
128 ROAR_DBG("roar_synth_pcmout_i161(*): state->pcmoffset=%lu", (unsigned long)state->pcmoffset);
129
130 return 0;
131}
132
133// basic SINFs:
134float roar_synth_synf_rect (float t, struct roar_synth_state * state) {
135 t /= 2*M_PI;
136 t -= (int)t;
137
138 if ( t < 0.5 )
139  return  1;
140 else
141  return -1;
142}
143
144float roar_synth_synf_saw  (float t, struct roar_synth_state * state) {
145 t /= 2*M_PI;
146 t -= (int)t;
147
148 return 2*t - 1;
149}
150
151float roar_synth_synf_tri  (float t, struct roar_synth_state * state) {
152 t /= 2*M_PI;
153 t -= (int)t;
154
155 if ( t < 0.5 )
156  return   4* t      - 1;
157 else
158  return  -4*(t-0.5) + 1;
159}
160
161float roar_synth_synf_trap (float t, struct roar_synth_state * state) {
162 t /= 2*M_PI;
163 t -= (int)t;
164
165 if ( t < 0.125 || t > 0.875 ) {
166  return -1;
167 } else if ( t < 0.625 && t > 0.375 ) {
168  return  1;
169 } else if ( t < 0.5 ) {
170  return  8*(t-0.375) + 1;
171 } else {
172  return -8*(t-0.625) + 1;
173 }
174}
175
176#ifdef ROAR_HAVE_LIBM
177float roar_synth_synf_s2s  (float t, struct roar_synth_state * state) {
178 float sin2 = sinf(t/1.2);
179
180 return sin2*sin2 * sin(t*1.2);
181}
182#endif
183
184//ll
Note: See TracBrowser for help on using the repository browser.