octal-dev
[Top][All Lists]
Advanced

[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
-------------------------------------------------------------------------------



reply via email to

[Prev in Thread] Current Thread [Next in Thread]