Forum Rule: Always post complete source code & details to reproduce any issue!
Results 1 to 2 of 2

Thread: Waveform phase problem

  1. #1
    Senior Member Rolfdegen's Avatar
    Join Date
    Sep 2020
    Location
    Germany
    Posts
    124

    Waveform phase problem

    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

  2. #2
    Senior Member Rolfdegen's Avatar
    Join Date
    Sep 2020
    Location
    Germany
    Posts
    124
    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)
    Click image for larger version. 

Name:	Synth-Block6voices.jpg 
Views:	18 
Size:	70.9 KB 
ID:	22218

    Greetings Rolf

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •