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

Thread: Problem with noise harmonics at higher sgtl5000.volume(X) settings

  1. #1
    Junior Member
    Join Date
    Feb 2019
    Posts
    5

    Problem with noise harmonics at higher sgtl5000.volume(X) settings

    Hello,
    That should be something simple but looks strange.
    I have a simple idea to test the simultaneous generation of 20 tones. For that I use a Teensy 3.2 and a Teensy Audio board.
    I have drawn in the web GUI a simple scheme where I have 20 x AudioSynthWaveform objects connected to 5 x AudioMixer objects and those in turn are connected to 2 x AudioMixer and finally we go into a AudioOutputI2S.

    Then I initiate the 20 x AudioSynthWaveform with Waveform.amplitude(1.0/20); so that the summ of all the 20 amplitudes is always <= 1.0 and the Waveform_N.frequency(F0 + F0*N); . All the AudioMIxers are set to linear summ of the inputs - mixer1.gain(0,1.0); . To control the volume I use the sgtl5000_1.volume(X); , I know that there is also the sgtl5000_1.dacVolume(Y); but I did not get how it relates to the .volume(X) , so I simply did not use it.
    The Problem:
    If I start with a low sgtl5000_1.volume(0.2) I get a nice output of the Waveforms (here 10 but identical with 20): Click image for larger version. 

Name:	20_percent_sgt5000_vol.png 
Views:	22 
Size:	297.9 KB 
ID:	17110

    At sgtl5000_1.volume(0.3) it is still working (but actually is too quite to listen):
    Click image for larger version. 

Name:	30_percent_sgt5000_vol.png 
Views:	2 
Size:	290.4 KB 
ID:	17111

    But anything higher than ~0.33 in the main volume setting gives:
    Click image for larger version. 

Name:	40_percent_sgt5000_vol.png 
Views:	2 
Size:	274.2 KB 
ID:	17112

    Actually if I use a potentiometer to change live the sgtl5000_1.volume(X); I get a very net change of the behavior at that volume setting.
    I think that I do something wrong in how I control the volume, but did not find the solution yet.

    The code below is for 10 tones but for me it is working exactly the same as for 20. After the code is loaded one need to use the serial terminal to press 0 -9 value that will switch on/off the respective tone and the main volume is to be changed in the code before the compilation.

    Code:
    
    #include <Audio.h>
    #include <Wire.h>
    #include <SPI.h>
    #include <SD.h>
    #include <SerialFlash.h>
    
    // GUItool: begin automatically generated code
    AudioSynthWaveform       waveform6;      //xy=96,558
    AudioSynthWaveform       waveform7;      //xy=108,607
    AudioSynthWaveform       waveform8;      //xy=109,653
    AudioSynthWaveform       waveform5;      //xy=110,516
    AudioSynthWaveform       waveform9;      //xy=113,707
    AudioSynthWaveform       waveform10;     //xy=115,754
    AudioSynthWaveform       waveform1;      //xy=118,325
    AudioSynthWaveform       waveform2;      //xy=118,370
    AudioSynthWaveform       waveform4;      //xy=119,464
    AudioSynthWaveform       waveform3;      //xy=120,416
    AudioMixer4              mixer1;         //xy=357,388
    AudioMixer4              mixer2;         //xy=359,562
    AudioMixer4              mixer3;         //xy=361,741
    AudioMixer4              mixer4;         //xy=596,540
    AudioOutputI2S           i2s1;           //xy=806,525
    
    AudioConnection          patchCord1(waveform6, 0, mixer2, 1);
    AudioConnection          patchCord2(waveform7, 0, mixer2, 2);
    AudioConnection          patchCord3(waveform8, 0, mixer2, 3);
    AudioConnection          patchCord4(waveform5, 0, mixer2, 0);
    AudioConnection          patchCord5(waveform9, 0, mixer3, 0);
    AudioConnection          patchCord6(waveform10, 0, mixer3, 1);
    AudioConnection          patchCord7(waveform1, 0, mixer1, 0);
    AudioConnection          patchCord8(waveform2, 0, mixer1, 1);
    AudioConnection          patchCord9(waveform4, 0, mixer1, 3);
    AudioConnection          patchCord10(waveform3, 0, mixer1, 2);
    AudioConnection          patchCord11(mixer1, 0, mixer4, 0);
    AudioConnection          patchCord12(mixer2, 0, mixer4, 1);
    AudioConnection          patchCord13(mixer3, 0, mixer4, 2);
    AudioConnection          patchCord14(mixer4, 0, i2s1, 0);
    AudioConnection          patchCord15(mixer4, 0, i2s1, 1);
    AudioControlSGTL5000     sgtl5000_1;     //xy=614,187
    // GUItool: end automatically generated code
    
    int inByte = 0;
    int call_N = 0;
    const int N_waves = 10;
    
    AudioSynthWaveform * Waves[N_waves] = 
    {
      &waveform1, &waveform2, &waveform3, &waveform4, &waveform5, &waveform6, &waveform7, &waveform8, &waveform9, &waveform10
    }; 
    
    float Note_list[][N_waves] = 
    {
      {587.33 , 1174.66 , 1761.99 , 2349.32 , 2936.65 , 3523.98 , 4111.31 , 4698.64 , 5285.97 , 5873.3},
      {739.99 , 1479.98 , 2219.97 , 2959.96 , 3699.95 , 4439.94 , 5179.93 , 5919.92 , 6659.91 , 7399.9},
      {830.61 , 1661.22 , 2491.83 , 3322.44 , 4153.05 , 4983.66 , 5814.26 , 6644.88 , 7475.49 , 8306.1},
      {987.77 , 1975.54 , 2963.31 , 3951.08 , 4938.85 , 5926.62 , 6914.39 , 7902.16 , 8889.93 , 9877.7}
    };
    
    float Tone_state[N_waves] = {0};
    
    int set_note(int N_note)
    {
      AudioNoInterrupts();
      
      for(int i=0; i < N_waves; ++i)
      {
        Tone_state[i] = 0.1;
        Waves[i]-> frequency(Note_list[N_note][i]);
        Waves[i]-> amplitude( Tone_state[i] );
        Waves[i]-> phase(0.0);
      }
    
      AudioInterrupts(); 
    
      for(int i=0; i < N_waves; ++i)
      {
        Waves[i]-> begin(WAVEFORM_SINE);
      }
    
      Serial.print("Reproducing the note N-");
      Serial.println(N_note);
    
      return 0;  
    }
    
    int toggle_tone(int N_tone)
    {
    
      if(Tone_state[N_tone] == 0)
      {
        Tone_state[N_tone] = 0.1;
      }
      else
      {
        Tone_state[N_tone] = 0.0;
      }
      
      AudioNoInterrupts();
      
      Waves[N_tone]-> amplitude(Tone_state[N_tone]);
    
      AudioInterrupts();
    
      Serial.print("Tone N-");
      Serial.print(N_tone);
      Serial.print(", changing volume to ");
      Serial.println(Tone_state[N_tone]);
      
      return 0;  
    }
    
    void setup() {
     
      Serial.begin(9600);
    
      while (!Serial && millis() < 2500) ; // wait
    
      establishContact();
      
      Serial.println("Ready!");
      
      AudioMemory(20);
      analogReference(INTERNAL);   
    
      mixer1.gain(0,1.0);
      mixer1.gain(1,1.0);
      mixer1.gain(2,1.0);
      mixer1.gain(3,1.0);
    
      mixer2.gain(0,1.0);
      mixer2.gain(1,1.0);
      mixer2.gain(2,1.0);
      mixer2.gain(3,1.0);
    
      mixer3.gain(0,1.0);
      mixer3.gain(1,1.0);
    
      mixer4.gain(0,1.0);
      mixer4.gain(1,1.0);
      mixer4.gain(2,1.0);
      mixer4.gain(3,1.0);
    
      set_note(0);
    
      sgtl5000_1.enable();
      sgtl5000_1.volume(0.2);     // set the main volume...
      sgtl5000_1.adcHighPassFilterDisable();
    //  sgtl5000_1.dacVolume(0.5);    // set the "dac" volume (extra control)
    //  sgtl5000_1.dacVolumeRampDisable();
    
    }
    
    void loop() {
    
     if (Serial.available() > 0)
      {
        inByte = Serial.read() - 48;
        Serial.print(inByte);
        Serial.print(" Call N-");
        Serial.println(call_N);
    
        ++call_N;
    
        if(inByte >= 0 && inByte <= 9)
        {
          
          toggle_tone(inByte);
          
        }
        else if(inByte == 65 || inByte == 71 || inByte == 53 || inByte == 66)
        {
          if(inByte == 65)
          {
            set_note(0);
          }
          else if(inByte == 71)
          {
            set_note(1);
          }
          else if(inByte == 53)
          {
            set_note(2);
          }
          else if(inByte == 66)
          {
            set_note(3);
          }
          
        }
        else if(inByte == 67)
        {
          
        }
        else
        {
          Serial.println("Wrong argument");
        }
       
        delay(300);
    
      }
    
    }
    
    void establishContact() {
      while (Serial.available() <= 0) {
        Serial.print('A');   // send a capital A
        delay(300);
      }
    }
    Any suggestion is welcome. Thanks.

  2. #2
    My initial reaction is to turn the mixer gains down to .7 rather than 1.0, and actually increase the amplitude of each oscillator a bit, so you have a little more dynamic range in the calculations.

    Really though, take it stage by stage: 4 oscillators into 1 mixer, then connect that directly to the I2S output. Does that work as expected or not? Okay, move on by adding another 4 oscillators and another layer of mixers. That is basically the approach we would have to take to debug.

    Two other things to think about: enable USB audio so you can capture directly and eliminate any analog weirdness that's going on, also try leaving the high pass filter in place.

Posting Permissions

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