Expose voice detune parameter of the lv2 plugin
[zyn.git] / portamento.c
blob54348eedb8d95d216dc26c9f70157ad095ffb729
1 /* -*- Mode: C ; c-basic-offset: 2 -*- */
2 /*****************************************************************************
4 * Copyright (C) 2006,2007,2008,2009 Nedko Arnaudov <nedko@arnaudov.name>
5 * Copyright (C) 2002-2005 Nasca Octavian Paul
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; version 2 of the License
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20 *****************************************************************************/
22 #include <stdbool.h>
23 #include <math.h>
24 #include <assert.h>
26 #include "globals.h"
27 #include "portamento.h"
28 #include "addsynth.h"
29 #include "fft.h"
30 #include "oscillator.h"
31 #include "addsynth_component.h"
33 //#define LOG_LEVEL LOG_LEVEL_DEBUG
34 #include "log.h"
36 void
37 zyn_portamento_init(
38 struct zyn_portamento * portamento_ptr)
40 portamento_ptr->enabled = false;
41 portamento_ptr->used = false;
42 portamento_ptr->time = 0.5;
43 portamento_ptr->up_down_time_stretch = 0.0;
44 portamento_ptr->pitch_threshold = 3; /* 3 equally tempered semitones */
45 portamento_ptr->pitch_threshold_above = true;
48 // returns true if the portamento's conditions are true, else returns false
49 bool
50 zyn_portamento_start(
51 float sample_rate,
52 struct zyn_portamento * portamento_ptr,
53 float oldfreq,
54 float newfreq)
56 float portamentotime;
57 float tmprap;
58 float thresholdrap;
60 portamento_ptr->x = 0.0;
62 if (portamento_ptr->used)
64 LOG_DEBUG("Not using portamento, already used");
65 return false;
68 if (!portamento_ptr->enabled)
70 LOG_DEBUG("Not using portamento, disabled");
71 return false;
74 portamentotime = powf(100.0, portamento_ptr->time) / 50.0; // portamento time in seconds
76 if (portamento_ptr->up_down_time_stretch >= 0.0 &&
77 newfreq < oldfreq)
79 if (portamento_ptr->up_down_time_stretch == 1.0)
81 LOG_DEBUG("Not using portamento down portamento because of time stretch value");
82 return false;
85 portamentotime *= pow(0.1, portamento_ptr->up_down_time_stretch);
88 if (portamento_ptr->up_down_time_stretch < 0.0 &&
89 newfreq > oldfreq)
91 if (portamento_ptr->up_down_time_stretch == -1.0)
93 LOG_DEBUG("Not using portamento up portamento because of time stretch value");
94 return false;
97 portamentotime *= pow(0.1, -portamento_ptr->up_down_time_stretch);
100 portamento_ptr->dx = SOUND_BUFFER_SIZE / (portamentotime * sample_rate);
101 portamento_ptr->origfreqrap = oldfreq / newfreq;
103 if (portamento_ptr->origfreqrap > 1.0)
105 tmprap = portamento_ptr->origfreqrap;
107 else
109 tmprap = 1.0 / portamento_ptr->origfreqrap;
112 thresholdrap = pow(2.0, portamento_ptr->pitch_threshold / 12.0);
114 if (!portamento_ptr->pitch_threshold_above &&
115 tmprap - 0.00001 > thresholdrap)
117 LOG_DEBUG("Not using portamento because it is not below threshold");
118 return false;
121 if (portamento_ptr->pitch_threshold_above &&
122 tmprap + 0.00001 < thresholdrap)
124 LOG_DEBUG("Not using portamento because it is not above threshold");
125 return false;
128 LOG_DEBUG("Using portamento");
130 portamento_ptr->used = true;
131 portamento_ptr->freqrap=portamento_ptr->origfreqrap;
133 return true;
136 // update portamento values
137 void
138 zyn_portamento_update(
139 struct zyn_portamento * portamento_ptr)
141 if (!portamento_ptr->used)
143 return;
146 portamento_ptr->x += portamento_ptr->dx;
148 if (portamento_ptr->x > 1.0)
150 portamento_ptr->x = 1.0;
151 portamento_ptr->used = false;
154 portamento_ptr->freqrap = (1.0 - portamento_ptr->x) * portamento_ptr->origfreqrap + portamento_ptr->x;
157 #define portamento_ptr ((struct zyn_portamento * )context)
159 float
160 zyn_component_portamento_get_float(
161 void * context,
162 unsigned int parameter)
164 switch (parameter)
166 case ZYNADD_PARAMETER_FLOAT_PORTAMENTO_TIME:
167 return portamento_ptr->time;
168 case ZYNADD_PARAMETER_FLOAT_PORTAMENTO_TIME_STRETCH:
169 return portamento_ptr->up_down_time_stretch;
170 default:
171 LOG_ERROR("Unknown portamento float parameter %u", parameter);
172 assert(0);
176 void
177 zyn_component_portamento_set_float(
178 void * context,
179 unsigned int parameter,
180 float value)
182 switch (parameter)
184 case ZYNADD_PARAMETER_FLOAT_PORTAMENTO_TIME:
185 portamento_ptr->time = value;
186 return;
187 case ZYNADD_PARAMETER_FLOAT_PORTAMENTO_TIME_STRETCH:
188 portamento_ptr->up_down_time_stretch = value;
189 return;
190 default:
191 LOG_ERROR("Unknown portamento float parameter %u", parameter);
192 assert(0);
196 signed int
197 zyn_component_portamento_get_int(
198 void * context,
199 unsigned int parameter)
201 switch (parameter)
203 case ZYNADD_PARAMETER_INT_PORTAMENTO_PITCH_THRESHOLD:
204 return portamento_ptr->pitch_threshold;
205 default:
206 LOG_ERROR("Unknown portamento int parameter %u", parameter);
207 assert(0);
211 void
212 zyn_component_portamento_set_int(
213 void * context,
214 unsigned int parameter,
215 signed int value)
217 switch (parameter)
219 case ZYNADD_PARAMETER_INT_PORTAMENTO_PITCH_THRESHOLD:
220 portamento_ptr->pitch_threshold = value;
221 return;
222 default:
223 LOG_ERROR("Unknown portamento int parameter %u", parameter);
224 assert(0);
228 bool
229 zyn_component_portamento_get_bool(
230 void * context,
231 unsigned int parameter)
233 switch (parameter)
235 case ZYNADD_PARAMETER_BOOL_PORTAMENTO_ENABLED:
236 return portamento_ptr->enabled;
237 case ZYNADD_PARAMETER_BOOL_PORTAMENTO_PITCH_THRESHOLD_ABOVE:
238 return portamento_ptr->pitch_threshold_above;
239 default:
240 LOG_ERROR("Unknown bool portamento parameter %u", parameter);
241 assert(0);
245 void
246 zyn_component_portamento_set_bool(
247 void * context,
248 unsigned int parameter,
249 bool value)
251 switch (parameter)
253 case ZYNADD_PARAMETER_BOOL_PORTAMENTO_ENABLED:
254 portamento_ptr->enabled = value;
255 return;
256 case ZYNADD_PARAMETER_BOOL_PORTAMENTO_PITCH_THRESHOLD_ABOVE:
257 portamento_ptr->pitch_threshold_above = value;
258 return;
259 default:
260 LOG_ERROR("Unknown bool portamento parameter %u", parameter);
261 assert(0);
265 #undef portamento_ptr
267 void
268 zyn_addsynth_component_init_portamento(
269 struct zyn_component_descriptor * component_ptr,
270 struct zyn_portamento * portamento_ptr)
272 ZYN_INIT_COMPONENT(component_ptr, portamento_ptr, zyn_component_portamento_);