|
From: | Neil Nelson |
Subject: | [Octal-dev] Octal converted code for SoX flanger.c (soxflanger.c) |
Date: | Sat, 24 Jun 2000 09:58:28 -0700 |
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include "util.h"
#include "machine.h"
#define PI2 (6.28318530717958465692)
#define MOD_SINE 0
#define MOD_TRIANGLE 1
/* The parameters are: gain_in, gain_out, decay, delay,
speed, modulation_type */
enum {ix_gain_in, ix_gain_out, ix_sxfdecay, ix_sxfdelay, ix_speed,
ix_mod_type} param_index;
param_spec sxf_params[] = {
/* First parameter: gain_in. */
{
small,
slider,
"Gain In",
"Gain In",
0,
/* 0 gain */
255,
/* Gain of 1 */
128
/* Approx. 0.5 */
},
/* Second parameter: gain_out. */
{
small,
slider,
"Gain Out",
"Gain Out",
0,
/* 0 gain */
255,
/* Gain of 1 */
255
},
/* Third parameter: decay (sxfdecay). */
{
small,
slider,
"Decay",
"Decay",
0,
255,
/* 1 */
128
/* Approx. 0.5 */
},
/* Fourth parameter: delay (sxfdelay). */
{
small,
slider,
"Delay",
"Delay: 0 to 5 msec.",
1,
/* 1/51 msec. delay */
255,
/* Maximum 5 msec. delay */
151
/* Approx. 3 msec. delay */
},
/* Fifth parameter: speed. */
{
small,
slider,
"Speed",
"Modulation Speed: 0 to 2 Hz.",
10,
/* Approx. 0.078 Hz */
255,
/* 2 Hz */
128
/* Approx. 1 Hz */
},
/* Sixth parameter: modulation type (mod_type).
*/
{
small,
slider,
"Modulation"
"Modulation type: 0=sine (default), 1=triangle",
0,
/* Sine */
1,
/* Triangle */
0
/* Sine by default */
}
};
/* State of the soxflanger. */
typedef struct {
float in_gain;
float out_gain;
float sxfdecay;
float sxfdelay;
float maxsxfdelay;
float speed;
int mod_type;
long smpsxfdelay;
long maxsmpsxfdelay;
long depth;
long phz_width;
samp* dlybuf;
int* tbl_lookup;
int dlycounter;
int phase;
// float clip; // Put in after clipping
issue decided.
} sxf_state;
int ox_init(machine_type *t) {
t->long_name = "soxflanger (Mueller, Nelson, et al.)";
t->short_name = "soxflanger";
t->max_tracks = 1;
t->input_channels = 1;
t->output_channels = 1;
t->num_params = 5;
t->param_specs = sxf_params;
return 1;
}
void ox_create(machine *m) {
sxf_state *s;
s = (sxf_state*) malloc(sizeof(sxf_state));
/* Set defaults */
s->in_gain = 128.0/255.0; /* Approx.
0.5 */
s->out_gain = 1.0;
s->sxfdecay = 128.0/255.0; /* Approx.
0.5 */
s->sxfdelay = 151.0/255.0; /* Approx.
3 msecs */
s->smpsxfdelay = (long)(s->sxfdelay * ((float)OX_SAMPLING_RATE)
/ 1000.0 + 0.5);
s->depth = s->smpsxfdelay - 1;
s->maxsxfdelay = 5.0;
/* 5 msecs */
s->maxsmpsxfdelay = (long)(s->maxsxfdelay * ((float)OX_SAMPLING_RATE)
/ 1000.0
+ 0.5);
s->speed = 1.0;
/* 1 Hz */
s->mod_type = 0;
/* Use sine modulation */
s->phz_width = (long)(((float)OX_SAMPLING_RATE) /
s->speed + 0.5);
s->dlycounter = 1; /* Start at 1 to account for add
of 1 in phase shift below */
s->phase = 0;
// s->clip = ?; // Put in after clipping issue decided.
s->dlybuf = (samp*) malloc(s->maxsmpsxfdelay * sizeof(samp));
// memset(s->dlybuf, 0, s->maxsmpsxfdelay * sizeof(samp));
// Unnecessary
m->state = (void *) s;
return;
}
void ox_destroy(machine *m) {
free( ((sxf_state*)(m->state)) -> dlybuf);
free(m->state);
m->state = NULL;
return;
}
void ox_update(machine *m) {
sxf_state *s = (sxf_state *) m->state;
param temp;
temp = m->params[0][ix_gain_in];
if (temp != nochange) {
if (temp < 0) temp
= 0;
if (temp > 255) temp = 255;
s->in_gain = ((float)temp) / 255.0;
}
temp = m->params[0][ix_gain_out];
if (temp != nochange) {
if (temp < 0) temp
= 0;
if (temp > 255) temp = 255;
s->out_gain = ((float)temp) / 255.0;
}
temp = m->params[0][ix_sxfdecay];
if (temp != nochange) {
if (temp < 0) temp
= 0;
if (temp > 255) temp = 255;
s->sxfdecay = ((float)temp) / 255.0;
}
temp = m->params[0][ix_sxfdelay];
if (temp != nochange) {
if (temp < 1) temp
= 1;
if (temp > 255) temp = 255;
s->sxfdelay = ((float)temp) / 255.0
* 5.0;
s->smpsxfdelay = (long)(s->sxfdelay
* ((float)OX_SAMPLING_RATE) / 1000.0 + 0.5);
s->depth = s->smpsxfdelay - 1;
}
temp = m->params[0][ix_speed];
if (temp != nochange) {
if (temp < 10) temp = 10;
if (temp > 255) temp = 255;
s->speed = ((float)temp) / 255.0
* 2.0;
s->phz_width = (long)(((float)OX_SAMPLING_RATE)
/ s->speed + 0.5);
}
temp = m->params[0][ix_mod_type];
if (temp != nochange) {
if (temp > 1 || temp < 0) temp
= 0;
s->mod_type = temp;
}
return;
}
const char *ox_desc(int which_param, param value) {
static char temp_string[80];
float user_value;
int percent;
sprintf(temp_string, "ERROR");
if (which_param == ix_gain_in || which_param == ix_gain_out
|| which_param == ix_sxfdecay) {
user_value = ((float)value) / 255.0;
percent = (int)(user_value * 100.0
+ 0.5);
sprintf(temp_string, "%d%%", percent);
}
else if (which_param == ix_sxfdelay) {
user_value = (float)value / 255.0
* 5.0;
if (user_value == 0.0)
sprintf(temp_string,
"Delay must be greater than 0 msec.");
else if (user_value > 5.0)
sprintf(temp_string,
"Delay must be not greater than 5 msec.");
else sprintf(temp_string, "%3.2f",
user_value);
}
else if (which_param == ix_speed) {
user_value = ((float) value) / 255.0
* 2.0;
if (user_value < 0.078)
sprintf(temp_string,
"Speed must be not less than .1 Hz (10): %3.2f",
user_value);
else if (user_value > 2.0)
sprintf(temp_string,
"Speed must be not greater than 2 Hz: %3.2f",
user_value);
else sprintf(temp_string, "%3.2f",
user_value);
}
else if (which_param == ix_mod_type) {
switch (value) {
case 0 :
sprintf(temp_string, "Sine"); break;
case 1 :
sprintf(temp_string, "Triangle"); break;
default : sprintf(temp_string,
"Error: Modulation type must be 0 for sine or 1 for triangle.");
}
}
/* Clipping - Be nice and check the hint with warning, if...
if ( flanger->in_gain * ( 1.0 + flanger->sxfdecay
) > 1.0 / flanger->out_gain )
warn("flanger: warning >>> gain-out
can cause saturation or clipping of output <<<");
*/
}
int ox_work(machine *m, int block_size) {
sxf_state *s = (sxf_state *) m->state;
samp* mlout;
samp* mrout;
samp* mlin;
samp* dlybf;
int i, modtype, x_phz, dlyctr;
long phzwidth, phaz, dly;
float x_flt, ingain, outgain, dcy, phzdepth, phz2depth,
phz2width;
double pi2phzwdth;
// float hig_clip, low_clip;
// hig_clip = s->clip;
// low_clip = 0.0 - s->clip;
/* Speed-up variables */
mlout = m->lout;
mrout = m->rout;
mlin = m->lin;
dlybf = s->dlybuf;
modtype = s->mod_type;
ingain = s->in_gain;
outgain = s->out_gain;
phzwidth = s->phz_width;
phzdepth = (float)s->depth;
phaz = s->phase;
dlyctr = s->dlycounter;
dly = s->smpsxfdelay;
dcy = s->sxfdecay;
pi2phzwdth = PI2 / ((double)phzwidth);
phz2width = 2.0 / ((float)phzwidth);
phz2depth = phzdepth / 2.0;
for(i = 0; i < block_size; i++) {
/* Compute output first. */
mlout[i] = mlin[i] * ingain;
if (modtype == MOD_SINE) {
// Get sine phase
shift. 1 added to correct noise at 0.
x_flt = (float)
sin(((double)phaz) * pi2phzwdth);
x_phz = (int)
((1.0 + x_flt) * phz2depth + 0.5) + 1;
}
else { // modtype == MOD_TRIANGLE
// Compute triangle
- ramp up and down.
if (phaz <
(phzwidth / 2)) { // Ramp up
x_flt = ((float)phaz) * phz2width;
x_phz = (int)(x_flt * phzdepth) + 1;
}
else { // Ramp
down
x_flt = (float)(phzwidth - phaz) * phz2width;
x_phz = (int)(x_flt * phzdepth) + 1;
}
}
mlout[i] += dlybf[(dly + dlyctr - x_phz) % dly] * dcy;
/* Adjust the output volume. */
mlout[i] *= outgain;
/* Check for clipping. Not
implemented. */
// if (mlout[i]
> hig_clip) mlout[i] = hig_clip;
// else if (mlout[i] < low_clip)
mlout[i] = low_clip;
/* Mix sxfdecay of sxfdelay and input.
*/
dlybf[dlyctr] = mlin[i];
/* Move delay counter and phase positions
forward.*/
dlyctr = (dlyctr + 1) % dly;
phaz = (phaz + 1) % phzwidth;
}
/* Save speedup variables to state. */
s->dlycounter = dlyctr;
s->phase = phaz;
return 1;
}
void ox_track(machine *m, int change) {
}
[Prev in Thread] | Current Thread | [Next in Thread] |