[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Octal-dev] soxchorus, svfilter and soxflanger example. svfilter last up
From: |
Avelino |
Subject: |
[Octal-dev] soxchorus, svfilter and soxflanger example. svfilter last update. |
Date: |
Thu, 29 Jun 2000 18:47:00 +0100 (BST) |
Here is a new update for svfitler.c, the resonance part at
ox_update() has been recoded, because, with the old implementation, an
high resonance parameter value, causes low resonance; and and a low
resonance value causes very resonance (resonance is reversed). With this
new update the resonance value will be according with the hearded
resonance :-)
Bye
----------------- svfilter.c ---------------------
/*
* SVFILTER.C
* A simple octal machine for 12 dB/oct low/high pass and 6 dB/oct band pass
* filtering (state variable 2-pole filter). Works in mono.
*
* Copyright 2000 Avelino Herrera Morales.
* address@hidden
* address@hidden
*
* This software is distributed under the terms of the
* GNU General Public License (GPL). Read de included file
* COPYING for more information.
*/
#include <stdio.h>
#include <stdlib.h>
#include "util.h"
#include "machine.h"
/* Three parameters: cutoff frequency, resonance and filter type. */
enum {ix_cutoff, ix_resonance, ix_filter_type} param_index;
param_spec svfilter_params[] = {
/* First parameter: cutoff. */
{
small,
slider,
"Cutoff",
"Cutoff frequency",
0x00, /* 0 Hz. */
0xFF, /* Sampling freq / 2. */
0xFF,
},
/* Second parameter: resonance. */
{
small,
slider,
"Resonance",
"Resonance",
0x00, /* No resonance. */
0xFF, /* Maximun resonance
(auto-oscillation). */
0x00,
},
/* Third parameter: filter type. */
{
small,
slider,
"Filter type",
"Filter type: 0=Low pass, 1=band pass 2=high pass",
0x00,
0x02,
0x00 /* By default low pass type. */
}
};
/* State of the state variable filter. */
typedef struct {
samp low, mid, hig; /* Signal history. */
float freq, reso; /* Cutoff freq and resonance. */
int filter_type; /* Idem third parameter. */
} svfilter_state;
int ox_init(machine_type *t) {
t->long_name = "2-pole state variable filter (Avelino Herrera)";
t->short_name = "svfilter";
t->max_tracks = 1;
t->input_channels = 1;
t->output_channels = 1;
t->num_params = 2;
t->param_specs = svfilter_params;
return 1;
}
void ox_create(machine *m) {
svfilter_state *s;
s = malloc(sizeof(svfilter_state));
s->low = s->mid = s->hig = 0;
s->freq = s->reso = 1;
m->state = (void *) s;
return;
}
void ox_destroy(machine *m) {
free(m->state);
m->state = NULL;
return;
}
void ox_update(machine *m) {
svfilter_state *s;
float cut, res;
s = (svfilter_state *) m->state;
if (m->params[0][ix_cutoff] != nochange) {
cut = (float) m->params[0][ix_cutoff];
s->freq = cut / 255.0;
}
if (m->params[0][ix_resonance] != nochange) {
res = (float) m->params[0][ix_resonance];
/* Max resonance is 0 and min resonance is 1. */
s->reso = 1 - (res / 255.0);
}
if (m->params[0][ix_filter_type] != nochange)
s->filter_type = (int) m->params[0][ix_filter_type];
return;
}
const char *ox_desc(int which_param, param value) {
static char temp_string[80];
float x;
int percent;
sprintf(temp_string, "ERROR");
if ((which_param == ix_cutoff) || (which_param == ix_resonance)) {
x = ((float) value) / 255.0;
percent = (int)(x * 100);
sprintf(temp_string, "%d%%", percent);
}
else if (which_param == ix_filter_type) {
switch (value) {
case 0 : sprintf(temp_string, "low pass"); break;
case 1 : sprintf(temp_string, "band pass"); break;
case 2 : sprintf(temp_string, "high pass"); break;
}
}
return temp_string;
}
int ox_work(machine *m, int block_size) {
int i, filter_type;
svfilter_state *s;
float feedback, hig, mid, low, freq, reso;
s = (svfilter_state *) m->state;
/* Store at local variables to avoid massive use of '->' operand in the
main loop. */
hig = s->hig;
mid = s->mid;
low = s->low;
freq = s->freq;
reso = s->reso;
filter_type = s->filter_type;
for (i = 0; i < block_size; i++) {
/* A discrete implementation of a state variable filter
(an adder plus two integrators in cascade). */
feedback = reso * mid;
hig = m->lin[i] - feedback - low;
mid += hig * freq;
low += mid * freq;
/* Output can be extracted from the three circuit points to
obtain
low pass, band pass or high pass. */
switch (filter_type) {
case 0 : m->lout[i] = low; break; /* Low pass. */
case 1 : m->lout[i] = mid; break; /* Band pass. */
case 2 : m->lout[i] = hig; break; /* High pass. */
}
}
/* Store filter state for next block. */
s->hig = hig;
s->mid = mid;
s->low = low;
return 1;
}
void ox_track(machine *m, int change) {
}
-------------------------------------------
Here is a sample code to test the svfilter, soxflanger and soxchorus.
--------------- main.c --------------------
/* $Header: /home/dto/octal/RCS/main.c,v 1.4 2000/02/23 04:30:39 dto
* Exp dto $ (C) 2000 David O'Toole $Date: 2000/06/10 01:11:06 $
*
* MAIN.C
*
* Once again this is just for testing... all will be replaced.
*
* $Revision: 1.11 $
*
* This software is distributed under the terms of the
* GNU General Public License (GPL). Read the included file
* COPYING for more information.
*
*/
/* some temporary #defines */
#define TICK 44100
#define BLOCK (TICK/5)
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <values.h>
#include "output.h"
#include "util.h"
#include "machine.h"
#include "engine.h"
static const char rcsid[]="$Id: main.c,v 1.11 2000/06/10 01:11:06 dto Exp dto
$";
char melody[15][8] = {
"g-4",
"g-4",
"g-4",
"d-5",
"d-5",
"d-5",
"c-5",
"b-4", /* can you guess the song? */
"a-4",
"g-5",
"g-5",
"g-5",
"d-5",
"d-5",
"d-5", };
int main() {
machine *square;
machine *delay;
machine *filter;
machine *flanger;
machine *chorus;
engine* e;
int square_ix, delay_ix,
filter_ix, flanger_ix, chorus_ix; /* indexes */
int i, j;
printf("* This is OCTAL. \n------------\n");
e = create_engine();
e->block_size = 8820;
set_block_size(e->block_size);
init_sound(OX_SAMPLING_RATE);
init_freq_table();
init_note_names();
load_type_registry(".");
square = create_machine(get_type("dtosquare"));
delay = create_machine(get_type("mdelay"));
filter = create_machine(get_type("svfilter"));
flanger = create_machine(get_type("soxflanger"));
chorus = create_machine(get_type("soxchorus"));
square_ix = add_machine(e, square);
delay_ix = add_machine(e, delay);
filter_ix = add_machine(e, filter);
flanger_ix = add_machine(e, flanger);
chorus_ix = add_machine(e, chorus);
printf("Created machines. %p %d %p %d %p %d %p %d\n",
square, square_ix, delay, delay_ix,
filter, filter_ix, chorus, chorus_ix);
connect(e, en_normal, delay_ix, 0);
connect(e, en_normal, chorus_ix, delay_ix);
connect(e, en_normal, flanger_ix, chorus_ix);
connect(e, en_normal, filter_ix, flanger_ix);
connect(e, en_normal, square_ix, filter_ix);
for (i=0; i<5; i++) {
for (j=0; j<5; j++)
printf("%d ", e->signals[i][j]);
printf("\n");
}
printf("Attempting to run signal network.\n");
square->params[0][1] = 0x40; /* square generator. */
delay->params[0][1] = 0x90; /* delay. */
filter->params[0][1] = 0xF6; /* low pass filter. */
filter->params[0][2] = 0;
flanger->params[0][0] = 128; /* flanger. */
flanger->params[0][1] = 255;
flanger->params[0][2] = 128;
flanger->params[0][3] = 151;
flanger->params[0][4] = 64;
flanger->params[0][5] = 0;
chorus->params[0][0] = 220; /* chorus. */
chorus->params[0][1] = 230;
chorus->params[0][2] = 240;
chorus->params[0][3] = 255;
chorus->params[0][4] = 20;
chorus->params[0][5] = 255;
chorus->params[0][6] = 1;
chorus->params[0][7] = 150;
chorus->params[0][8] = 255;
chorus->params[0][9] = 50;
chorus->params[0][10] = 255;
chorus->params[0][11] = 0;
chorus->params[0][12] = 100;
chorus->params[0][13] = 255;
chorus->params[0][14] = 255;
chorus->params[0][15] = 255;
chorus->params[0][16] = 0;
srand((unsigned int) time(NULL));
for (i=0; i<15; i++) {
printf("%s\n", melody[i]);
square->params[0][0] = text2note(melody[i]);
filter->params[0][0] = 5 + ((float)(14 - i) * 150 / 14);
(*square->type->ox_update)(square);
(*filter->type->ox_update)(filter);
(*flanger->type->ox_update)(flanger);
(*chorus->type->ox_update)(chorus);
(*delay->type->ox_update)(delay);
do_block(e, master);
output_block(e->lmix, e->rmix, e->block_size);
}
close_sound();
destroy_machine(square);
destroy_machine(delay);
destroy_machine(filter);
destroy_machine(flanger);
destroy_machine(chorus);
return(0);
}
/* End $Source: /home/dto/octal/RCS/main.c,v $ */
-------------------------------------------------------------------------------
Avelino Herrera Morales. E-Mail: address@hidden
address@hidden
HTTP: http://www.avelino.turincon.com
http://www.geocities.com/avelinoherrera/
Powered by SunOS 5.7
Centro Superior de Informatica
UNIVERSIDAD DE LA LAGUNA
-------------------------------------------------------------------------------
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- [Octal-dev] soxchorus, svfilter and soxflanger example. svfilter last update.,
Avelino <=