Filtering help

Hi all,

I'm currently building a synth that uses an SSM2044 chip for filter enveloping. However, now I am adding polyphony, I've realised that If i want to keep the polyphony, I'm going to have to do all the filtering before the voices leave the arduino....

I understand that 'smooth' is a low-pass function, but are there any better ways to implement a simple low pass filter in code that I could use for enveloping?

Or just any better ideas in general. I'm trying to keep cost down to an absolute minimum.

Thanks,

Matt

We can't see your code so it is very hard to see what to advice...
what is the datarate, bitdepth etc?

and, what did you try allready?

Indeed, show us the code, show us everything. :wink:

Wk

OK.... Here she is... it's adapted from adrian freed's code (I'm sure you guys are familiar with!) Arduino sketch for high frequency precision sine wave tone sound synthesis | Adrian Freed.

I haven't really tried anything yet because I have no idea how to go about it!

#define PWM_PIN 3
#define PWM_VALUE_DESTINATION OCR2B
#define PWM_INTERRUPT TIMER2_OVF_vect

#ifndef cbi
#define cbi(sfr, bit) (_SFR_BYTE(sfr) &= ~_BV(bit))
#endif
#ifndef sbi
#define sbi(sfr, bit) (_SFR_BYTE(sfr) |= _BV(bit))
#endif 

uint8_t outputvalue = 0;
uint8_t count = 0;
int pot1 = 0;
uint8_t fMod = 0;
int mix = 0;
int invmix = 0;
uint8_t freq = 0;

const unsigned int LUTsize = 1<<8;
const int timerPrescale=1<<9;
const int fractionalbits = 16;
const int predivide = 8;



struct osc1
{
    uint32_t phase;
    int32_t phase_increment;
    uint16_t amplitude;
} osc1;



struct osc2
{
    uint32_t phase;
    int32_t phase_increment;
    uint16_t amplitude;
} osc2;


struct lfo1
{
    uint32_t phase;
    int32_t phase_increment;
    uint16_t amplitude;
} lfo1;



unsigned long phaseinc(float frequency_in_Hz)
{
   return LUTsize *(1l<<fractionalbits)* frequency_in_Hz/(F_CPU/timerPrescale);
}

unsigned long phaseinc_from_fractional_frequency(unsigned long frequency_in_Hz_times_256)
{
    return (1l<<(fractionalbits-predivide))* ((LUTsize*(timerPrescale/(1<<predivide))*frequency_in_Hz_times_256)/(F_CPU/(1<<predivide)));

}


#include <avr/pgmspace.h>


int8_t sintable[] PROGMEM = { 
  127,130,133,136,139,143,146,149,152,155,158,161,164,167,170,173,
  176,179,182,184,187,190,193,195,198,200,203,205,208,210,213,215,
  217,219,221,224,226,228,229,231,233,235,236,238,239,241,242,244,
  245,246,247,248,249,250,251,251,252,253,253,254,254,254,254,254,
  255,254,254,254,254,254,253,253,252,251,251,250,249,248,247,246,
  245,244,242,241,239,238,236,235,233,231,229,228,226,224,221,219,
  217,215,213,210,208,205,203,200,198,195,193,190,187,184,182,179,
  176,173,170,167,164,161,158,155,152,149,146,143,139,136,133,130,
  127,124,121,118,115,111,108,105,102,99,96,93,90,87,84,81,
  78,75,72,70,67,64,61,59,56,54,51,49,46,44,41,39,
  37,35,33,30,28,26,25,23,21,19,18,16,15,13,12,10,
  9,8,7,6,5,4,3,3,2,1,1,0,0,0,0,0,
  0,0,0,0,0,0,1,1,2,3,3,4,5,6,7,8,
  9,10,12,13,15,16,18,19,21,23,25,26,28,30,33,35,
  37,39,41,44,46,49,51,54,56,59,61,64,67,70,72,75,
  78,81,84,87,90,93,96,99,102,105,108,111,115,118,121,124};
  
  
int8_t tritable[] PROGMEM = {
  0x00,0x02,0x04,0x06,0x08,0x0a,0x0c,0x0e,0x10,0x12,0x14,0x16,0x18,0x1a,0x1c,0x1e,
  0x20,0x22,0x24,0x26,0x28,0x2a,0x2c,0x2e,0x30,0x32,0x34,0x36,0x38,0x3a,0x3c,0x3e,
  0x40,0x42,0x44,0x46,0x48,0x4a,0x4c,0x4e,0x50,0x52,0x54,0x56,0x58,0x5a,0x5c,0x5e,
  0x60,0x62,0x64,0x66,0x68,0x6a,0x6c,0x6e,0x70,0x72,0x74,0x76,0x78,0x7a,0x7c,0x7e,
  0x80,0x82,0x84,0x86,0x88,0x8a,0x8c,0x8e,0x90,0x92,0x94,0x96,0x98,0x9a,0x9c,0x9e,
  0xa0,0xa2,0xa4,0xa6,0xa8,0xaa,0xac,0xae,0xb0,0xb2,0xb4,0xb6,0xb8,0xba,0xbc,0xbe,
  0xc0,0xc2,0xc4,0xc6,0xc8,0xca,0xcc,0xce,0xd0,0xd2,0xd4,0xd6,0xd8,0xda,0xdc,0xde,
  0xe0,0xe2,0xe4,0xe6,0xe8,0xea,0xec,0xee,0xf0,0xf2,0xf4,0xf6,0xf8,0xfa,0xfc,0xfe,
  0xff,0xfd,0xfb,0xf9,0xf7,0xf5,0xf3,0xf1,0xef,0xed,0xeb,0xe9,0xe7,0xe5,0xe3,0xe1,
  0xdf,0xdd,0xdb,0xd9,0xd7,0xd5,0xd3,0xd1,0xcf,0xcd,0xcb,0xc9,0xc7,0xc5,0xc3,0xc1,
  0xbf,0xbd,0xbb,0xb9,0xb7,0xb5,0xb3,0xb1,0xaf,0xad,0xab,0xa9,0xa7,0xa5,0xa3,0xa1,
  0x9f,0x9d,0x9b,0x99,0x97,0x95,0x93,0x91,0x8f,0x8d,0x8b,0x89,0x87,0x85,0x83,0x81,
  0x7f,0x7d,0x7b,0x79,0x77,0x75,0x73,0x71,0x6f,0x6d,0x6b,0x69,0x67,0x65,0x63,0x61,
  0x5f,0x5d,0x5b,0x59,0x57,0x55,0x53,0x51,0x4f,0x4d,0x4b,0x49,0x47,0x45,0x43,0x41,
  0x3f,0x3d,0x3b,0x39,0x37,0x35,0x33,0x31,0x2f,0x2d,0x2b,0x29,0x27,0x25,0x23,0x21,
  0x1f,0x1d,0x1b,0x19,0x17,0x15,0x13,0x11,0x0f,0x0d,0x0b,0x09,0x07,0x05,0x03,0x01,

};

int8_t squaretable[] PROGMEM = {
  
  254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,
  254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,
  254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,
  254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,
  254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,
  254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,
  254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,
  254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,
  0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
  0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
  0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
  0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
  0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
  0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
  0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
  0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,

};

int8_t sawtable[] PROGMEM = {
  
0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,
16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,
32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,
48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,
64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,
80,81,82,83,84,85,86,87,88,89,90,91,92,93,94,95,
96,97,98,99,100,101,102,103,104,105,106,107,108,109,110,111,
112,113,114,115,116,117,118,119,120,121,122,123,124,125,126,127,
128,129,130,131,132,133,134,135,136,137,138,139,140,141,142,143,
144,145,146,147,148,149,150,151,152,153,154,155,156,157,158,159,
160,161,162,163,164,165,166,167,168,169,170,171,172,173,174,175,
176,177,178,179,180,181,182,183,184,185,186,187,188,189,190,191,
192,193,194,195,196,197,198,199,200,201,202,203,204,205,206,207,
208,209,210,211,212,213,214,215,216,217,218,219,220,221,222,223,
224,225,226,227,228,229,230,231,232,233,234,235,236,237,238,239,
240,241,242,243,244,245,246,247,248,249,250,251,152,153,154,255,

};


#include <avr/io.h>
#include <avr/interrupt.h>
#include <avr/pgmspace.h>
#include "wavetables.h"
#include "declares.h"

void setup()
{
  
   osc1.phase = 0;
   osc1.phase_increment = 0;
   osc1.amplitude = 255*256;
   osc2.phase = 0;
   osc2.phase_increment = 0;
   osc2.amplitude = 0;
   lfo1.phase = 0;
   lfo1.phase_increment = 0;
   lfo1.amplitude = 255*256;

  TCCR2A = _BV(COM2B1) | _BV(WGM20);
  TCCR2B = _BV(CS20);
  TIMSK2 = _BV(TOIE2);
  pinMode(PWM_PIN,OUTPUT);
  sbi(ADCSRA,ADPS2) ;
  cbi(ADCSRA,ADPS1) ;  
  cbi(ADCSRA,ADPS0) ;
);
 }

void loop() {
 
 pot1 = analogRead(0);
 mix = (pot1>>2)+1;
 invmix = abs((mix*-1)+255);
 MIDI.read();
}



SIGNAL(PWM_INTERRUPT)
{
  
   PWM_VALUE_DESTINATION = outputvalue;  
   
   outputvalue = (((pgm_read_byte(sintable+((osc1.phase>>16)%LUTsize))*(mix>>1))>>8) + ((pgm_read_byte(tritable+((osc2.phase>>16)%LUTsize))*(invmix>>1))>>8))  *0.5;

   
   
   fMod = (pgm_read_byte(sintable+((lfo1.phase>>16)%LUTsize)));
 
   osc1.phase += (uint32_t)osc1.phase_increment;
   osc2.phase += (uint32_t)osc2.phase_increment;
   lfo1.phase += (uint32_t)lfo1.phase_increment;
   

 lfo1.phase_increment = phaseinc(0);
 osc1.phase_increment = phaseinc(300);
 osc2.phase_increment = phaseinc(300);


}