Waveform phase problem

Rolfdegen

Well-known member
Hello friends
I cannot start the LFO phase with Midi NoteOn at zero degrees. The phases are synchronous but continue to run. What am I doing wrong.

Code:
//*************************************************************************
// set Voice on
//*************************************************************************
void set_Voice_on(uint8_t note)
{
	float freq = NoteFreq[note];
	float value = (note * DIV127 * keytrackingAmount);   // E3 
	AudioNoInterrupts();
	
	LFO1_1.begin(0.5f,0.2f,1);		// LFO Saw
	LFO1_2.begin(0.5f,0.2f,1);
	LFO1_3.begin(0.5f,0.2f,1);
	LFO1_4.begin(0.5f,0.2f,1);
	LFO1_5.begin(0.5f,0.2f,1);
	LFO1_6.begin(0.5f,0.2f,1);
	
	LFO1_1.phase(0.0f);
	LFO1_2.phase(0.0f);
	LFO1_3.phase(0.0f);
	LFO1_4.phase(0.0f);
	LFO1_5.phase(0.0f);
	LFO1_6.phase(0.0f);	
		
	switch(getVoiceNo(-1))
	{
		case 1:
			KeyTrak1.amplitude(value);
			waveform1.frequency(freq * BendFactor);
			//LFO1_1.frequency((freq / 8) * BendFactor);
			envelope1_0.noteOn();
			envelope1_1.noteOn();
			voices[0].note = note;
			voices[0].timeOn = millis();
			voices[0].voiceOn = true;
			disp.fillRect(133, 3, 7, 4, ST7735_RED);	// Lamp1 on
		break;
		
		case 2:
			KeyTrak2.amplitude(value);
			waveform2.frequency(freq * BendFactor);
			//LFO1_2.frequency((freq / 8) * BendFactor);
			envelope2_0.noteOn();
			envelope2_1.noteOn();
			voices[1].note = note;
			voices[1].timeOn = millis();
			voices[1].voiceOn = true;
			disp.fillRect(133+10, 3, 7, 4, ST7735_RED);	// Lamp2 on
		break;
		
		case 3:
			KeyTrak3.amplitude(value);
			waveform3.frequency(freq * BendFactor);
			//LFO1_3.frequency((freq / 8) * BendFactor);
			envelope3_0.noteOn();
			envelope3_1.noteOn();
			voices[2].note = note;
			voices[2].timeOn = millis();
			voices[2].voiceOn = true;
			disp.fillRect(133+20, 3, 7, 4, ST7735_RED);	// Lamp3 on
		break;
			
		case 4:
			KeyTrak4.amplitude(value);
			waveform4.frequency(freq * BendFactor);
			//LFO1_4.frequency((freq / 8) * BendFactor);
			envelope4_0.noteOn();
			envelope4_1.noteOn();
			voices[3].note = note;
			voices[3].timeOn = millis();
			voices[3].voiceOn = true;
			disp.fillRect(133, 11, 7, 4, ST7735_RED);	// Lamp4 on
		break;
		
		case 5:
			KeyTrak5.amplitude(value);
			waveform5.frequency(freq * BendFactor);
			//LFO1_5.frequency((freq / 8) * BendFactor);
			envelope5_0.noteOn();
			envelope5_1.noteOn();
			voices[4].note = note;
			voices[4].timeOn = millis();
			voices[4].voiceOn = true;
			disp.fillRect(133+10, 11, 7, 4, ST7735_RED);	// Lamp5 on
		break;
		
		case 6:
			KeyTrak6.amplitude(value);
			waveform6.frequency(freq * BendFactor);
			//LFO1_6.frequency((freq / 8) * BendFactor);
			envelope6_0.noteOn();
			envelope6_1.noteOn();
			voices[5].note = note;
			voices[5].timeOn = millis();
			voices[5].voiceOn = true;
			disp.fillRect(133+20, 11, 7, 4, ST7735_RED);	// Lamp6 on
		break;
	}
	AudioInterrupts();
}

Thanks for help. Greetings Rolf
 
Hi

Ok I think the problem is with the audio buffer. I will use another audio function with sync for the waveform oscillators.

Here is an example from UHF from the forum

Code:
 ElectroTechnique 2020
 Added WAVEFORM_SILENT, sync()                           
 */

#ifndef synth_waveform_h_
#define synth_waveform_h_

#include <Arduino.h>
#include "AudioStream.h"
#include "arm_math.h"

// waveforms.c
extern "C" {
extern const int16_t AudioWaveformSine[257];
}


#define WAVEFORM_SINE              0
#define WAVEFORM_SAWTOOTH          1
#define WAVEFORM_SQUARE            2
#define WAVEFORM_TRIANGLE          3
#define WAVEFORM_ARBITRARY         4
#define WAVEFORM_PULSE             5
#define WAVEFORM_SAWTOOTH_REVERSE  6
#define WAVEFORM_SAMPLE_HOLD       7
#define WAVEFORM_TRIANGLE_VARIABLE 8
#define WAVEFORM_BANDLIMIT_SAWTOOTH  9
#define WAVEFORM_BANDLIMIT_SAWTOOTH_REVERSE 10
#define WAVEFORM_BANDLIMIT_SQUARE 11
#define WAVEFORM_BANDLIMIT_PULSE  12
#define WAVEFORM_SILENT       19

typedef struct step_state
{
  int offset ;
  bool positive ;
} step_state ;


class BandLimitedWaveform
{
public:
  BandLimitedWaveform (void) ;
  int16_t generate_sawtooth (uint32_t new_phase, int i) ;
  int16_t generate_square (uint32_t new_phase, int i) ;
  int16_t generate_pulse (uint32_t new_phase, uint32_t pulse_width, int i) ;
  void init_sawtooth (uint32_t freq_word) ;
  void init_square (uint32_t freq_word) ;
  void init_pulse (uint32_t freq_word, uint32_t pulse_width) ;
  

private:
  int32_t lookup (int offset) ;
  void insert_step (int offset, bool rising, int i) ;
  int32_t process_step (int i) ;
  int32_t process_active_steps (uint32_t new_phase) ;
  int32_t process_active_steps_saw (uint32_t new_phase) ;
  int32_t process_active_steps_pulse (uint32_t new_phase, uint32_t pulse_width) ;
  void new_step_check_square (uint32_t new_phase, int i) ;
  void new_step_check_pulse (uint32_t new_phase, uint32_t pulse_width, int i) ;
  void new_step_check_saw (uint32_t new_phase, int i) ;

  
  uint32_t phase_word ;
  int32_t dc_offset ;
  step_state states [32] ; // circular buffer of active steps
  int newptr ;         // buffer pointers into states, AND'd with PTRMASK to keep in buffer range.
  int delptr ;
  int32_t  cyclic[16] ;    // circular buffer of output samples
  bool pulse_state ;
  uint32_t sampled_width ; // pulse width is sampled once per waveform
};


class AudioSynthWaveformTS : public AudioStream
{
public:
  AudioSynthWaveformTS(void) : AudioStream(0,NULL),
    phase_accumulator(0), phase_increment(0), phase_offset(0),
    magnitude(0), pulse_width(0x40000000),
    arbdata(NULL), sample(0), tone_type(WAVEFORM_SINE),
    tone_offset(0),syncFlag(0)  {
  }

  void frequency(float freq) {
    if (freq < 0.0) {
      freq = 0.0;
    } else if (freq > AUDIO_SAMPLE_RATE_EXACT / 2) {
      freq = AUDIO_SAMPLE_RATE_EXACT / 2;
    }
    phase_increment = freq * (4294967296.0 / AUDIO_SAMPLE_RATE_EXACT);
    if (phase_increment > 0x7FFE0000u) phase_increment = 0x7FFE0000;
  }
  void phase(float angle) {
    if (angle < 0.0) {
      angle = 0.0;
    } else if (angle > 360.0) {
      angle = angle - 360.0;
      if (angle >= 360.0) return;
    }
    phase_offset = angle * (4294967296.0 / 360.0);
  }
  void sync() {
    syncFlag = 1;
  }       
  void amplitude(float n) { // 0 to 1.0
    if (n < 0) {
      n = 0;
    } else if (n > 1.0) {
      n = 1.0;
    }
    magnitude = n * 65536.0;
  }
  void offset(float n) {
    if (n < -1.0) {
      n = -1.0;
    } else if (n > 1.0) {
      n = 1.0;
    }
    tone_offset = n * 32767.0;
  }
  void pulseWidth(float n) {  // 0.0 to 1.0
    if (n < 0) {
      n = 0;
    } else if (n > 1.0) {
      n = 1.0;
    }
    pulse_width = n * 4294967296.0;
  }
  void begin(short t_type) {
    phase_offset = 0;
    tone_type = t_type;
    if (t_type == WAVEFORM_BANDLIMIT_SQUARE)
      band_limit_waveform.init_square (phase_increment) ;
    else if (t_type == WAVEFORM_BANDLIMIT_PULSE)
      band_limit_waveform.init_pulse (phase_increment, pulse_width) ;
    else if (t_type == WAVEFORM_BANDLIMIT_SAWTOOTH || t_type == WAVEFORM_BANDLIMIT_SAWTOOTH_REVERSE)
      band_limit_waveform.init_sawtooth (phase_increment) ;
  }
  void begin(float t_amp, float t_freq, short t_type) {
    amplitude(t_amp);
    frequency(t_freq);
    phase_offset = 0;
    begin (t_type);
  }
  void arbitraryWaveform(const int16_t *data, float maxFreq) {
    arbdata = data;
  }
  virtual void update(void);

private:
  uint32_t phase_accumulator;
  uint32_t phase_increment;
  uint32_t phase_offset;
  int32_t  magnitude;
  uint32_t pulse_width;
  const int16_t *arbdata;
  int16_t  sample; // for WAVEFORM_SAMPLE_HOLD
  short    tone_type;
  int16_t  tone_offset;
    int16_t   syncFlag;
        BandLimitedWaveform band_limit_waveform ;
};


class AudioSynthWaveformModulatedTS : public AudioStream
{
public:
  AudioSynthWaveformModulatedTS(void) : AudioStream(2, inputQueueArray),
    phase_accumulator(0), phase_increment(0), modulation_factor(32768),
    magnitude(0), arbdata(NULL), sample(0), tone_offset(0),
    tone_type(WAVEFORM_SINE), modulation_type(0), syncFlag(0) {
  }

  void frequency(float freq) {
    if (freq < 0.0) {
      freq = 0.0;
    } else if (freq > AUDIO_SAMPLE_RATE_EXACT / 2) {
      freq = AUDIO_SAMPLE_RATE_EXACT / 2;
    }
    phase_increment = freq * (4294967296.0 / AUDIO_SAMPLE_RATE_EXACT);
    if (phase_increment > 0x7FFE0000u) phase_increment = 0x7FFE0000;
  }
  void amplitude(float n) { // 0 to 1.0
    if (n < 0) {
      n = 0;
    } else if (n > 1.0) {
      n = 1.0;
    }
    magnitude = n * 65536.0;
  }
  void sync() {
    syncFlag = 1;
  }              
  void offset(float n) {
    if (n < -1.0) {
      n = -1.0;
    } else if (n > 1.0) {
      n = 1.0;
    }
    tone_offset = n * 32767.0;
  }
  void begin(short t_type) {
    tone_type = t_type;
    if (t_type == WAVEFORM_BANDLIMIT_SQUARE)
      band_limit_waveform.init_square (phase_increment) ;
    else if (t_type == WAVEFORM_BANDLIMIT_PULSE)
      band_limit_waveform.init_pulse (phase_increment, 0x80000000u) ;
    else if (t_type == WAVEFORM_BANDLIMIT_SAWTOOTH || t_type == WAVEFORM_BANDLIMIT_SAWTOOTH_REVERSE)
      band_limit_waveform.init_sawtooth (phase_increment) ;
  }
  void begin(float t_amp, float t_freq, short t_type) {
    amplitude(t_amp);
    frequency(t_freq);
    begin (t_type) ;
  }
  void arbitraryWaveform(const int16_t *data, float maxFreq) {
    arbdata = data;
  }
  void frequencyModulation(float octaves) {
    if (octaves > 12.0) {
      octaves = 12.0;
    } else if (octaves < 0.1) {
      octaves = 0.1;
    }
    modulation_factor = octaves * 4096.0;
    modulation_type = 0;
  }
  void phaseModulation(float degrees) {
    if (degrees > 9000.0) {
      degrees = 9000.0;
    } else if (degrees < 30.0) {
      degrees = 30.0;
    }
    modulation_factor = degrees * (65536.0 / 180.0);
    modulation_type = 1;
  }
  virtual void update(void);

private:
  audio_block_t *inputQueueArray[2];
  uint32_t phase_accumulator;
  uint32_t phase_increment;
  uint32_t modulation_factor;
  int32_t  magnitude;
  const int16_t *arbdata;
  uint32_t phasedata[AUDIO_BLOCK_SAMPLES];
  int16_t  sample; // for WAVEFORM_SAMPLE_HOLD
  int16_t  tone_offset;
  uint8_t  tone_type;
  uint8_t  modulation_type;
    int16_t   syncFlag;
        BandLimitedWaveform band_limit_waveform ;
};


#endif


My Synth block with 6 voices (Still at work)
Synth-Block6voices.jpg

Greetings Rolf
 
Back
Top