Forum Rule: Always post complete source code & details to reproduce any issue!
Page 1 of 4 1 2 3 ... LastLast
Results 1 to 25 of 98

Thread: Discussion about a simple way to change the sample-rate

  1. #1
    Senior Member
    Join Date
    Apr 2014
    Location
    -
    Posts
    9,735

    Discussion about a simple way to change the sample-rate

    Hi,

    i guess, there is a - more or less - simple way to change the samplerate of the audiolibrary at runtime.
    For example, if you use the I2S-Output, i think, it would be sufficient to patch the "timing"-registers (multipliers/dividers) to archive 48KHz.
    - without any changes to the library code -

    Of course, this has several unwanted side-effects, and some things will NOT work.
    But which ?

    For example,
    - the sine-object will work, but with a wrong frequeny. The would be easy to "repair" (call frequency(freq*0.85))
    - mixers will work

    So, which parts will work, which not ? Where are problems ?

    Edit: My reason to ask:
    I re-activated an old project, my webradio, and some stations are using 48KHz. Therey are not usable, at the moment.
    A "hack" like this would allow to play them - without having to patch audio-library sourcecode.
    Last edited by Frank B; 10-27-2016 at 09:26 PM.

  2. #2
    Senior Member
    Join Date
    Jul 2014
    Posts
    3,497
    Quote Originally Posted by Frank B View Post
    Hi,

    i guess, there is a - more or less - simple way to change the samplerate of the audiolibrary at runtime.
    For example, if you use the I2S-Output, i think, it would be sufficient to patch the "timing"-registers (multipliers/dividers) to archive 48KHz.
    Yes, that is the way to do it.
    Consequences:
    I only see: different sampling-> different block duration -> different frequency.
    So all instances that internally use 44.1 kHz must be converted to 48 kHz, as you suggested.

  3. #3
    Member
    Join Date
    Oct 2016
    Location
    Colchester, Essex, UK
    Posts
    56
    Not sure I understand the question, but I think you're asking what will happen if you play audio at a different rate than it was orignially sampled at?
    E.g. audio recorded at 44.1kHz played out at 48kHz.
    If the audio is recorded and you have it all in local storage somewhere, chances are it will work, but you will hear it at a slightly higher pitch (or lower if the other way around).
    If the audio is being streamed live, you might hear audio breaks as you run out of data (clocking it out faster than clocking it in) or you will have to handle buffer overruns (clocking it in faster than clocking out) in your software which will probably sound like short skips in the audio (when you dump a chunk of data).

  4. #4
    Senior Member
    Join Date
    Apr 2014
    Location
    -
    Posts
    9,735
    Quote Originally Posted by mundungus View Post
    Not sure I understand the question, but I think you're asking what will happen if you play audio at a different rate than it was orignially sampled at?
    No.
    I want to know the side-effects of changing the sample-freq at runtime - and if there are workarounds for the different objects.
    And *which* parts make problems.
    Because i want to be able to switch to 48KHz or other freqs and runtime.
    (An other way would be to create a "up/down" sampler that re-samples anything to 44.1KHz - but this is more work and less quality)

    But *without* changing anything in the core- or audiolibrary.

    Ok, I guess, I have to read all the sourcecode..
    Last edited by Frank B; 10-28-2016 at 11:52 AM.

  5. #5
    Senior Member
    Join Date
    Apr 2014
    Location
    -
    Posts
    9,735
    ...if someone wants to try it:

    Code:
    void setI2SFreq(int freq) {
      typedef struct {
        uint8_t mult;
        uint16_t div;
      } tmclk;
    
      const int numfreqs = 14;
      const int samplefreqs[numfreqs] = { 8000, 11025, 16000, 22050, 32000, 44100, 44117.64706 , 48000, 88200, 44117.64706 * 2, 96000, 176400, 44117.64706 * 4, 192000};
    
    #if (F_PLL==16000000)
      const tmclk clkArr[numfreqs] = {{16, 125}, {148, 839}, {32, 125}, {145, 411}, {64, 125}, {151, 214}, {12, 17}, {96, 125}, {151, 107}, {24, 17}, {192, 125}, {127, 45}, {48, 17}, {255, 83} };
    #elif (F_PLL==72000000)
      const tmclk clkArr[numfreqs] = {{32, 1125}, {49, 1250}, {64, 1125}, {49, 625}, {128, 1125}, {98, 625}, {8, 51}, {64, 375}, {196, 625}, {16, 51}, {128, 375}, {249, 397}, {32, 51}, {185, 271} };
    #elif (F_PLL==96000000)
      const tmclk clkArr[numfreqs] = {{8, 375}, {73, 2483}, {16, 375}, {147, 2500}, {32, 375}, {147, 1250}, {2, 17}, {16, 125}, {147, 625}, {4, 17}, {32, 125}, {151, 321}, {8, 17}, {64, 125} };
    #elif (F_PLL==120000000)
      const tmclk clkArr[numfreqs] = {{32, 1875}, {89, 3784}, {64, 1875}, {147, 3125}, {128, 1875}, {205, 2179}, {8, 85}, {64, 625}, {89, 473}, {16, 85}, {128, 625}, {178, 473}, {32, 85}, {145, 354} };
    #elif (F_PLL==144000000)
      const tmclk clkArr[numfreqs] = {{16, 1125}, {49, 2500}, {32, 1125}, {49, 1250}, {64, 1125}, {49, 625}, {4, 51}, {32, 375}, {98, 625}, {8, 51}, {64, 375}, {196, 625}, {16, 51}, {128, 375} };
    #elif (F_PLL==180000000)
      const tmclk clkArr[numfreqs] = {{46, 4043}, {49, 3125}, {73, 3208}, {98, 3125}, {183, 4021}, {196, 3125}, {16, 255}, {128, 1875}, {107, 853}, {32, 255}, {219, 1604}, {214, 853}, {64, 255}, {219, 802} };
    #elif (F_PLL==192000000)
      const tmclk clkArr[numfreqs] = {{4, 375}, {37, 2517}, {8, 375}, {73, 2483}, {16, 375}, {147, 2500}, {1, 17}, {8, 125}, {147, 1250}, {2, 17}, {16, 125}, {147, 625}, {4, 17}, {32, 125} };
    #elif (F_PLL==216000000)
      const tmclk clkArr[numfreqs] = {{32, 3375}, {49, 3750}, {64, 3375}, {49, 1875}, {128, 3375}, {98, 1875}, {8, 153}, {64, 1125}, {196, 1875}, {16, 153}, {128, 1125}, {226, 1081}, {32, 153}, {147, 646} };
    #elif (F_PLL==240000000)
      const tmclk clkArr[numfreqs] = {{16, 1875}, {29, 2466}, {32, 1875}, {89, 3784}, {64, 1875}, {147, 3125}, {4, 85}, {32, 625}, {205, 2179}, {8, 85}, {64, 625}, {89, 473}, {16, 85}, {128, 625} };
    #endif
    
      for (int f = 0; f < numfreqs; f++) {
        if ( freq == samplefreqs[f] ) {
          while (I2S0_MCR & I2S_MCR_DUF) ;
          I2S0_MDR = I2S_MDR_FRACT((clkArr[f].mult - 1)) | I2S_MDR_DIVIDE((clkArr[f].div - 1));
          return;
        }
      }
    }
    (Tested with PT8211 only)
    Last edited by Frank B; 10-31-2016 at 09:33 AM.

  6. #6
    Senior Member
    Join Date
    Nov 2012
    Posts
    1,912
    OOooooohh Frank,
    If you can get the SGTL5000 running at 11025kHz and/or 8kHz sampling rate, life would be so much easier for some things I'd like to play with - assuming that the audio library doesn't require major tweaks to accomodate this.

    Pete

  7. #7
    Senior Member
    Join Date
    Apr 2014
    Location
    -
    Posts
    9,735
    Quote Originally Posted by el_supremo View Post
    OOooooohh Frank,
    If you can get the SGTL5000 running at 11025kHz and/or 8kHz sampling rate, life would be so much easier for some things I'd like to play with - assuming that the audio library doesn't require major tweaks to accomodate this.

    Pete
    Can you try the code above ? Maybe it works ?
    setI2SFreq(11025);

    I don't know if the SGTL accepts that, and i did not look at the datasheet, but it is worth a try

  8. #8
    Senior Member
    Join Date
    Nov 2012
    Posts
    1,912
    Hi Frank,
    Just tried the code in a sketch which routes microphone input straight to output on T3.6 at 180MHz. At 8000 and 11025, neither of them work but it works at 44100.
    This is calling your function immediately after the SGTL enable() function.


    Pete

  9. #9
    Senior Member
    Join Date
    Apr 2014
    Location
    -
    Posts
    9,735
    Quote Originally Posted by el_supremo View Post
    Hi Frank,
    Just tried the code in a sketch which routes microphone input straight to output on T3.6 at 180MHz. At 8000 and 11025, neither of them work but it works at 44100.
    This is calling your function immediately after the SGTL enable() function.


    Pete
    Ok, maybe it needs some additional settings (PLL?)
    I'll try it in a few days

  10. #10
    Senior Member
    Join Date
    Apr 2014
    Location
    -
    Posts
    9,735
    Here's the same for the internal DACs :

    Code:
    void setDACFreq(int freq) {
    const unsigned config = PDB_SC_TRGSEL(15) | PDB_SC_PDBEN | PDB_SC_CONT | PDB_SC_PDBIE | PDB_SC_DMAEN;
        PDB0_SC = 0;
        PDB0_IDLY = 1;
        PDB0_MOD = round((float)F_BUS / freq ) - 1;    
        PDB0_SC = config | PDB_SC_LDOK;
        PDB0_SC = config | PDB_SC_SWTRIG;
        PDB0_CH0C1 = 0x0101;    
    }
    edit: Added one line
    Last edited by Frank B; 08-06-2017 at 08:33 AM.

  11. #11
    Senior Member
    Join Date
    Apr 2014
    Location
    -
    Posts
    9,735
    @el_supremo,

    Well, the SGTL datasheet says, that it supports 8 and 11KHz.I guess, with some additional I2C-commands, it will work.
    I'll look tomorrow.

  12. #12
    Senior Member
    Join Date
    Nov 2012
    Posts
    1,912
    Thanks Frank.

    Pete

  13. #13
    Senior Member
    Join Date
    Apr 2014
    Location
    -
    Posts
    9,735
    Hm, is there was a way to trigger the ADCs from I2S, we could use them, too...
    Anyone knows if the pin-interrupts work with pins set to output?

    Edit:
    Or, even better, is it possible to trigger DMA with a pin-change ?
    Last edited by Frank B; 10-30-2016 at 07:19 PM.

  14. #14
    Senior Member
    Join Date
    Apr 2014
    Location
    -
    Posts
    9,735
    el_supremeo,
    i don't understand..
    please, can you provide a test-sketch that shows the problem ?

    Output works flawlessly:

    Code:
    #include <Audio.h>
    #include <Wire.h>
    #include <SPI.h>
    #include <SD.h>
    #include <SerialFlash.h>
    
    void setI2SFreq(int freq) {
      typedef struct {
        uint8_t mult;
        uint16_t div;
      } __attribute__((__packed__)) tmclk;
    
      const int numfreqs = 14;
      const int samplefreqs[numfreqs] = { 8000, 11025, 16000, 22050, 32000, 44100, 44117.64706 , 48000, 88200, 44117.64706 * 2, 96000, 176400, 44117.64706 * 4, 192000};
    
    #if (F_PLL==16000000)
      const tmclk clkArr[numfreqs] = {{16, 125}, {148, 839}, {32, 125}, {145, 411}, {64, 125}, {151, 214}, {12, 17}, {96, 125}, {151, 107}, {24, 17}, {192, 125}, {127, 45}, {48, 17}, {255, 83} };
    #elif (F_PLL==72000000)
      const tmclk clkArr[numfreqs] = {{32, 1125}, {49, 1250}, {64, 1125}, {49, 625}, {128, 1125}, {98, 625}, {8, 51}, {64, 375}, {196, 625}, {16, 51}, {128, 375}, {249, 397}, {32, 51}, {185, 271} };
    #elif (F_PLL==96000000)
      const tmclk clkArr[numfreqs] = {{8, 375}, {73, 2483}, {16, 375}, {147, 2500}, {32, 375}, {147, 1250}, {2, 17}, {16, 125}, {147, 625}, {4, 17}, {32, 125}, {151, 321}, {8, 17}, {64, 125} };
    #elif (F_PLL==120000000)
      const tmclk clkArr[numfreqs] = {{32, 1875}, {89, 3784}, {64, 1875}, {147, 3125}, {128, 1875}, {205, 2179}, {8, 85}, {64, 625}, {89, 473}, {16, 85}, {128, 625}, {178, 473}, {32, 85}, {145, 354} };
    #elif (F_PLL==144000000)
      const tmclk clkArr[numfreqs] = {{16, 1125}, {49, 2500}, {32, 1125}, {49, 1250}, {64, 1125}, {49, 625}, {4, 51}, {32, 375}, {98, 625}, {8, 51}, {64, 375}, {196, 625}, {16, 51}, {128, 375} };
    #elif (F_PLL==180000000)
      const tmclk clkArr[numfreqs] = {{46, 4043}, {49, 3125}, {73, 3208}, {98, 3125}, {183, 4021}, {196, 3125}, {16, 255}, {128, 1875}, {107, 853}, {32, 255}, {219, 1604}, {214, 853}, {64, 255}, {219, 802} };
    #elif (F_PLL==192000000)
      const tmclk clkArr[numfreqs] = {{4, 375}, {37, 2517}, {8, 375}, {73, 2483}, {16, 375}, {147, 2500}, {1, 17}, {8, 125}, {147, 1250}, {2, 17}, {16, 125}, {147, 625}, {4, 17}, {32, 125} };
    #elif (F_PLL==216000000)
      const tmclk clkArr[numfreqs] = {{32, 3375}, {49, 3750}, {64, 3375}, {49, 1875}, {128, 3375}, {98, 1875}, {8, 153}, {64, 1125}, {196, 1875}, {16, 153}, {128, 1125}, {226, 1081}, {32, 153}, {147, 646} };
    #elif (F_PLL==240000000)
      const tmclk clkArr[numfreqs] = {{16, 1875}, {29, 2466}, {32, 1875}, {89, 3784}, {64, 1875}, {147, 3125}, {4, 85}, {32, 625}, {205, 2179}, {8, 85}, {64, 625}, {89, 473}, {16, 85}, {128, 625} };
    #endif
    
      for (int f = 0; f < numfreqs; f++) {
        if ( freq == samplefreqs[f] ) {
          while (I2S0_MCR & I2S_MCR_DUF) ;
          I2S0_MDR = I2S_MDR_FRACT((clkArr[f].mult - 1)) | I2S_MDR_DIVIDE((clkArr[f].div - 1));
          return;
        }
      }
    }
    
    // GUItool: begin automatically generated code
    AudioSynthWaveform       waveform1;      //xy=110,75
    AudioOutputI2S           output;          //xy=303,78
    AudioConnection          patchCord1(waveform1, 0, output, 0);
    AudioConnection          patchCord2(waveform1, 0, output, 1);
    // GUItool: end automatically generated code
    AudioControlSGTL5000 codec;
    
    void setup() {
      const int freq = 1000;
      const int samplefreq = 8000;
      AudioMemory(15);
      codec.enable();
      codec.volume(0.35);  
      waveform1.begin(WAVEFORM_SINE);
      waveform1.frequency(AUDIO_SAMPLE_RATE_EXACT/samplefreq*freq);
      waveform1.amplitude(0.99); 
      setI2SFreq(samplefreq);
    }
    
    void loop() {
      /* 
      float vol = analogRead(15);
      vol = vol / 1024;
      codec.volume(vol);
      */
    }
    Last edited by Frank B; 10-31-2016 at 09:36 AM.

  15. #15
    Senior Member
    Join Date
    Nov 2012
    Posts
    1,912
    Hi Frank,
    I used a simple microphone input to headphone output sketch and just got silence unless I chose the 44100 rate.

    What/where is audioutil.h?

    Pete

  16. #16
    Senior Member
    Join Date
    Apr 2014
    Location
    -
    Posts
    9,735
    audioutil. sorry, delete it, it's not needed.
    Can you post the sketch ? i've never used micropohone. Just to make sure, that the sketch i will use is correct.

  17. #17
    Senior Member
    Join Date
    Nov 2012
    Posts
    1,912
    Just tried your sketch and it looks like it is working. I'd like to try an audio filter at the sampling rate of 8000 - shouldn't take long to put together.

    Pete

  18. #18
    Senior Member
    Join Date
    Apr 2014
    Location
    -
    Posts
    9,735
    Pete, i've attached the mic
    Took some time, to find it... lol

  19. #19
    Senior Member
    Join Date
    Apr 2014
    Location
    -
    Posts
    9,735
    works! (????)
    Code:
    #include <Audio.h>
    #include <Wire.h>
    #include <SPI.h>
    #include <SD.h>
    #include <SerialFlash.h>
    
    
    void setI2SFreq(int freq) {
      typedef struct {
        uint8_t mult;
        uint16_t div;
      } __attribute__((__packed__)) tmclk;
      const int numfreqs = 14;
      const int samplefreqs[numfreqs] = { 8000, 11025, 16000, 22050, 32000, 44100, 44117.64706 , 48000, 88200, 44117.64706 * 2, 96000, 176400, 44117.64706 * 4, 192000};
    
    #if (F_PLL==16000000)
      const tmclk clkArr[numfreqs] = {{16, 125}, {148, 839}, {32, 125}, {145, 411}, {64, 125}, {151, 214}, {12, 17}, {96, 125}, {151, 107}, {24, 17}, {192, 125}, {127, 45}, {48, 17}, {255, 83} };
    #elif (F_PLL==72000000)
      const tmclk clkArr[numfreqs] = {{32, 1125}, {49, 1250}, {64, 1125}, {49, 625}, {128, 1125}, {98, 625}, {8, 51}, {64, 375}, {196, 625}, {16, 51}, {128, 375}, {249, 397}, {32, 51}, {185, 271} };
    #elif (F_PLL==96000000)
      const tmclk clkArr[numfreqs] = {{8, 375}, {73, 2483}, {16, 375}, {147, 2500}, {32, 375}, {147, 1250}, {2, 17}, {16, 125}, {147, 625}, {4, 17}, {32, 125}, {151, 321}, {8, 17}, {64, 125} };
    #elif (F_PLL==120000000)
      const tmclk clkArr[numfreqs] = {{32, 1875}, {89, 3784}, {64, 1875}, {147, 3125}, {128, 1875}, {205, 2179}, {8, 85}, {64, 625}, {89, 473}, {16, 85}, {128, 625}, {178, 473}, {32, 85}, {145, 354} };
    #elif (F_PLL==144000000)
      const tmclk clkArr[numfreqs] = {{16, 1125}, {49, 2500}, {32, 1125}, {49, 1250}, {64, 1125}, {49, 625}, {4, 51}, {32, 375}, {98, 625}, {8, 51}, {64, 375}, {196, 625}, {16, 51}, {128, 375} };
    #elif (F_PLL==180000000)
      const tmclk clkArr[numfreqs] = {{46, 4043}, {49, 3125}, {73, 3208}, {98, 3125}, {183, 4021}, {196, 3125}, {16, 255}, {128, 1875}, {107, 853}, {32, 255}, {219, 1604}, {214, 853}, {64, 255}, {219, 802} };
    #elif (F_PLL==192000000)
      const tmclk clkArr[numfreqs] = {{4, 375}, {37, 2517}, {8, 375}, {73, 2483}, {16, 375}, {147, 2500}, {1, 17}, {8, 125}, {147, 1250}, {2, 17}, {16, 125}, {147, 625}, {4, 17}, {32, 125} };
    #elif (F_PLL==216000000)
      const tmclk clkArr[numfreqs] = {{32, 3375}, {49, 3750}, {64, 3375}, {49, 1875}, {128, 3375}, {98, 1875}, {8, 153}, {64, 1125}, {196, 1875}, {16, 153}, {128, 1125}, {226, 1081}, {32, 153}, {147, 646} };
    #elif (F_PLL==240000000)
      const tmclk clkArr[numfreqs] = {{16, 1875}, {29, 2466}, {32, 1875}, {89, 3784}, {64, 1875}, {147, 3125}, {4, 85}, {32, 625}, {205, 2179}, {8, 85}, {64, 625}, {89, 473}, {16, 85}, {128, 625} };
    #endif
    
      for (int f = 0; f < numfreqs; f++) {
        if ( freq == samplefreqs[f] ) {
          while (I2S0_MCR & I2S_MCR_DUF) ;
          I2S0_MDR = I2S_MDR_FRACT((clkArr[f].mult - 1)) | I2S_MDR_DIVIDE((clkArr[f].div - 1));
          return;
        }
      }
    }
    
    
    // GUItool: begin automatically generated code
    AudioInputI2S            i2s1;           //xy=250,232
    AudioOutputI2S           i2s2;           //xy=455,243
    AudioConnection          patchCord1(i2s1, 0, i2s2, 0);
    AudioConnection          patchCord2(i2s1, 1, i2s2, 1);
    // GUItool: end automatically generated code
    
    AudioControlSGTL5000 sgtl5000_1;
    
    const int samplefreq = 8000;
      
    void setup() {
      Serial.begin(9600);
      AudioMemory(8);
      sgtl5000_1.enable();
      sgtl5000_1.volume(0.5);
      sgtl5000_1.inputSelect(AUDIO_INPUT_MIC);
      sgtl5000_1.micGain(36);
      setI2SFreq(samplefreq);
    }
    
    void loop() {}
    Last edited by Frank B; 10-31-2016 at 09:36 AM.

  20. #20
    Senior Member
    Join Date
    Nov 2012
    Posts
    1,912
    I've got a simple bandpass filter working at a sampling rate of 8000Hz but the audio quality is awful. When the audio is passed through unfiltered it sounds fine. When I switch in the filter, the filtering itself is obviously working but the audio quality is not good at all. I'll dig into what's going on with the filter. Maybe I haven't initialized it correctly or something like that.

    Pete

  21. #21
    Senior Member
    Join Date
    Apr 2014
    Location
    -
    Posts
    9,735
    But not a filter on the SGTL, right ?
    I guess, this will not work good.. we're lieing about the freq, so any filters on the SGTL can not work, with this simple patch. The SGTL still thinks, we're @ 44100 kHz

    For parts in the audio-lib, you' need to lie too (like in my sine-example above) :

    waveform1.frequency(AUDIO_SAMPLE_RATE_EXACT/samplefreq*freq);

  22. #22
    Senior Member
    Join Date
    Nov 2012
    Posts
    1,912
    Your sketch in #19 works at 8000, 11025, 22050, 44100.

    For the filter, I don't think I have to lie to anything (and BTW this uses the line input). I am just getting the samples from the queue, filtering them and then sending them back to the queue. As long as the audio sampling rate on input and output really is 8000, things should work. In fact, as I mentioned, the filter is functioning as intended (about 200Hz wide, centred at 774Hz). It's just that when the filter is switched in, a lot of out-of-band noise gets through the filter too. I'll keep digging.

    Pete

  23. #23
    Senior Member
    Join Date
    Nov 2012
    Posts
    1,912
    Got it. As I thought. A bug. I hadn't specified the correct buffer size at one point. With the correct buffer size, the filter now works as expected.
    Fabulous. Well done Frank.

    Pete

  24. #24
    Senior Member
    Join Date
    Apr 2014
    Location
    -
    Posts
    9,735
    Ok, i've checked it. My Multimeter shows exactly 8000Hz (on LRCLK).

    Good night. It's 00:30 here.
    I hope you get it working !

  25. #25
    Senior Member
    Join Date
    Oct 2015
    Location
    Vermont, USA
    Posts
    321
    Has anyone tried faster sample rates? There are several people who might be interested in doing ultrasound experiments (bat listening!) if they can sample at, say, 96 kHz. The Teensy 3.6 should have enough horsepower, and the STGL5000 itself is rated up to that speed...but can the Audio Library be convinced to run the STGL5000 that fast?

    Chip

Posting Permissions

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