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 *****************************************************************************/
27 #include "portamento.h"
30 #include "oscillator.h"
31 #include "addsynth_component.h"
33 //#define LOG_LEVEL LOG_LEVEL_DEBUG
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
52 struct zyn_portamento
* portamento_ptr
,
60 portamento_ptr
->x
= 0.0;
62 if (portamento_ptr
->used
)
64 LOG_DEBUG("Not using portamento, already used");
68 if (!portamento_ptr
->enabled
)
70 LOG_DEBUG("Not using portamento, disabled");
74 portamentotime
= powf(100.0, portamento_ptr
->time
) / 50.0; // portamento time in seconds
76 if (portamento_ptr
->up_down_time_stretch
>= 0.0 &&
79 if (portamento_ptr
->up_down_time_stretch
== 1.0)
81 LOG_DEBUG("Not using portamento down portamento because of time stretch value");
85 portamentotime
*= pow(0.1, portamento_ptr
->up_down_time_stretch
);
88 if (portamento_ptr
->up_down_time_stretch
< 0.0 &&
91 if (portamento_ptr
->up_down_time_stretch
== -1.0)
93 LOG_DEBUG("Not using portamento up portamento because of time stretch value");
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
;
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");
121 if (portamento_ptr
->pitch_threshold_above
&&
122 tmprap
+ 0.00001 < thresholdrap
)
124 LOG_DEBUG("Not using portamento because it is not above threshold");
128 LOG_DEBUG("Using portamento");
130 portamento_ptr
->used
= true;
131 portamento_ptr
->freqrap
=portamento_ptr
->origfreqrap
;
136 // update portamento values
138 zyn_portamento_update(
139 struct zyn_portamento
* portamento_ptr
)
141 if (!portamento_ptr
->used
)
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)
160 zyn_component_portamento_get_float(
162 unsigned int 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
;
171 LOG_ERROR("Unknown portamento float parameter %u", parameter
);
177 zyn_component_portamento_set_float(
179 unsigned int parameter
,
184 case ZYNADD_PARAMETER_FLOAT_PORTAMENTO_TIME
:
185 portamento_ptr
->time
= value
;
187 case ZYNADD_PARAMETER_FLOAT_PORTAMENTO_TIME_STRETCH
:
188 portamento_ptr
->up_down_time_stretch
= value
;
191 LOG_ERROR("Unknown portamento float parameter %u", parameter
);
197 zyn_component_portamento_get_int(
199 unsigned int parameter
)
203 case ZYNADD_PARAMETER_INT_PORTAMENTO_PITCH_THRESHOLD
:
204 return portamento_ptr
->pitch_threshold
;
206 LOG_ERROR("Unknown portamento int parameter %u", parameter
);
212 zyn_component_portamento_set_int(
214 unsigned int parameter
,
219 case ZYNADD_PARAMETER_INT_PORTAMENTO_PITCH_THRESHOLD
:
220 portamento_ptr
->pitch_threshold
= value
;
223 LOG_ERROR("Unknown portamento int parameter %u", parameter
);
229 zyn_component_portamento_get_bool(
231 unsigned int 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
;
240 LOG_ERROR("Unknown bool portamento parameter %u", parameter
);
246 zyn_component_portamento_set_bool(
248 unsigned int parameter
,
253 case ZYNADD_PARAMETER_BOOL_PORTAMENTO_ENABLED
:
254 portamento_ptr
->enabled
= value
;
256 case ZYNADD_PARAMETER_BOOL_PORTAMENTO_PITCH_THRESHOLD_ABOVE
:
257 portamento_ptr
->pitch_threshold_above
= value
;
260 LOG_ERROR("Unknown bool portamento parameter %u", parameter
);
265 #undef portamento_ptr
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_
);