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

Thread: 24bit-48KHz I2S input on Teensy 4.0

  1. #1
    Junior Member
    Join Date
    Nov 2019
    Posts
    7

    24bit-48KHz I2S input on Teensy 4.0

    Quote Originally Posted by muon View Post
    So I'm having a couple of thoughts...

    Here I am testing instances of AudioInputI2S and AudioInputI2S2 for capturing samples in a queue and printing them(mostly copy code from recording example). But this is all gonna take place at 16bit @44.1KHz while I want 24bit@48KHz So...
    Code:
    #include <Audio.h>
    
    AudioInputI2S             i2s1;
    AudioInputI2S2            i2s2;
    AudioRecordQueue          queue1;
    AudioRecordQueue          queue2;
    AudioConnection           patchCord1(i2s1, 0, queue1, 0);
    AudioConnection           patchCord2(i2s2, 0, queue2, 0);
    
    void setup() {
      Serial.begin(115200);
      AudioMemory(60);
      queue1.begin();
      queue2.begin();
    }
    
    void loop() {
      byte buffer1[512];
      byte buffer2[512];
    
      memcpy(buffer1, queue1.readBuffer(), 256);
      queue1.freeBuffer();
      memcpy(buffer1 + 256, queue1.readBuffer(), 256);
      queue1.freeBuffer();
      memcpy(buffer2, queue2.readBuffer(), 256);
      queue2.freeBuffer();
      memcpy(buffer2 + 256, queue2.readBuffer(), 256);
      queue2.freeBuffer();
      for (int i = 0; i < 512; i++)
      {
        Serial.println(buffer1[i]);
      }
      for (int i = 0; i < 512; i++)
      {
        Serial.println(buffer2[i]);
      }
    }
    I think what I might do is inside the "audio_block_struct" in AudioStream.h,
    Attachment 18260
    change the data[AUDIO_BLOCK_SAMPLES] data type from int16_t to int32_t and change the
    #define AUDIO_SAMPLE_RATE_EXACT 44100.0f
    to
    #define AUDIO_SAMPLE_RATE_EXACT 48000.0f

    I don't know how deep the implications of this might be.
    What do you folks think?
    I'm creating this new thread because it can be a topic on its own I think..
    Original source is https://forum.pjrc.com/threads/58474...-1-DAC-UDA1334

  2. #2
    Senior Member PaulStoffregen's Avatar
    Join Date
    Nov 2012
    Posts
    20,769
    Quote Originally Posted by muon View Post
    I don't know how deep the implications of this might be.
    Changing the sample rate will break some parts of the library, especially playing WAV files which are 44100 Hz sample rate. Many other parts will automatically work.

    Changing the data type to int32_t will break almost everything.

  3. #3
    Senior Member DD4WH's Avatar
    Join Date
    Oct 2015
    Location
    Central Europe
    Posts
    505
    Bit depth: Your ADC PCM1808 will hardly be able to really represent 24bits: according to the data sheet it has an SNR of 99dBA, which translates into an effective resolution of about 16bit. So, there is no need at all to deal with 24bits. I use the same ADC PCM1808 and it works perfectly with the Teensy 4 using the standard queue object and 16bit resolution.

    Sample rate: use this code by FrankB to adjust the I2S sample rate of your teensy 4.0 + ADC PCM1808 to your needs (I managed to achieve up to 256ksps sample rate with the PCM1808 :-). But then this is out of specs and could permanently damage your ADC and of course the specs such as SNR and THD are no longer guaranteed, but your desired 48ksps is well inside specs of the PCM1808). As Paul said, you loose some functionality in the audio lib with 48ksps and you have to account for the ratio 44.1/48 when designing filter cutoff frequencies for example

    Code:
    #include <utility/imxrt_hw.h> // needed for setting I2S freq on the Teensy 4.0
    
    // set samplerate code by Frank Bösing
    void setI2SFreq(int freq) {
      // PLL between 27*24 = 648MHz und 54*24=1296MHz
      int n1 = 4; //SAI prescaler 4 => (n1*n2) = multiple of 4
      int n2 = 1 + (24000000 * 27) / (freq * 256 * n1);
      double C = ((double)freq * 256 * n1 * n2) / 24000000;
      int c0 = C;
      int c2 = 10000;
      int c1 = C * c2 - (c0 * c2);
      set_audioClock(c0, c1, c2, true);
      CCM_CS1CDR = (CCM_CS1CDR & ~(CCM_CS1CDR_SAI1_CLK_PRED_MASK | CCM_CS1CDR_SAI1_CLK_PODF_MASK))
           | CCM_CS1CDR_SAI1_CLK_PRED(n1-1) // &0x07
           | CCM_CS1CDR_SAI1_CLK_PODF(n2-1); // &0x3f
    }

  4. #4
    Junior Member
    Join Date
    Nov 2019
    Posts
    7
    Thanks for the help! I didn't know about the 6dB / bit SNR relation. I wonder why they put 24 bit when its 16bit effectively anyways? Where are the other 8 bits going? Shouldn't the lost bits cause bad audio in terms of completely incorrect samples? Unless the 24bits is being linearly scaled down to 16bits.

    I just happened to try outputting the received samples on I2S2 (similary to the
    here is the first version of the "bat detector":
    )and the audio seems jittery, probably because SAI2/I2S2 is still processing @44.1KHz.

    I believe the CCM_CS1CDR is only updating the clock for SAI1 and SAI3(unused by Teensy 4.0), and NOT SAI2 which I happen to be using for audio out.
    Would you happen to have/know a solution to modify the SAI2 freq to 48KHz as well?
    I did look at the data/reference sheets and found the CCM_CS2CDR that might do the trick in case a pre-made solution doesn't exist yet.
    I still haven't discovered what "set_audioClock()" does. I have a feeling I might need to modify that as well for SAI2 clock configuration.

    Thanks!
    Last edited by muon; 11-28-2019 at 10:52 AM.

  5. #5
    Junior Member
    Join Date
    Nov 2019
    Posts
    7
    My assumpltions were correct and I was able to improve the audio output quality by making SAI2 run at 48KHz
    So I was able to modify both the SAI1 & SAI2 clocks using the following updated setI2SFreq(int freq):

    Code:
    #include <utility/imxrt_hw.h> // needed for setting I2S freq on the Teensy 4.0
    
    // set samplerate code by Frank Bösing
    void setI2SFreq(int freq) {
      // PLL between 27*24 = 648MHz und 54*24=1296MHz
      int n1 = 4; //SAI prescaler 4 => (n1*n2) = multiple of 4
      int n2 = 1 + (24000000 * 27) / (freq * 256 * n1);
      double C = ((double)freq * 256 * n1 * n2) / 24000000;
      int c0 = C;
      int c2 = 10000;
      int c1 = C * c2 - (c0 * c2);
      set_audioClock(c0, c1, c2, true);
      CCM_CS1CDR = (CCM_CS1CDR & ~(CCM_CS1CDR_SAI1_CLK_PRED_MASK | CCM_CS1CDR_SAI1_CLK_PODF_MASK))
           | CCM_CS1CDR_SAI1_CLK_PRED(n1-1) // &0x07
           | CCM_CS1CDR_SAI1_CLK_PODF(n2-1); // &0x3f
    
    //START//Added afterwards to make the SAI2 function at the desired frequency as well.
      
    CCM_CS2CDR = (CCM_CS2CDR & ~(CCM_CS2CDR_SAI2_CLK_PRED_MASK | CCM_CS2CDR_SAI2_CLK_PODF_MASK))
           | CCM_CS2CDR_SAI2_CLK_PRED(n1-1) // &0x07
           | CCM_CS2CDR_SAI2_CLK_PODF(n2-1); // &0x3f)
    
    //END//Added afterwards to make the SAI2 function at the desired frequency as well.
    }
    I DID NOT need to modify set_audioClock() as it is working on PLL4 which is common(I'm assuming) to all the SAI peripherals.

  6. #6
    Just because something has a 96dB noise floor doesn't mean that 16 bits is enough - this is the nonsense that led Philips and Sony to think 16 bits was enough for CDs. The ear can pick out a lot of detail of signals buried in noise so a 24 bit convertor still makes sense. From tests we did in the late 1990s those with really good ears can discern detail down to about 22 or 23 bits, depending on the type of signal.

  7. #7
    Senior Member DD4WH's Avatar
    Join Date
    Oct 2015
    Location
    Central Europe
    Posts
    505
    Yes, blind audition tests reveal how much of the dynamic range you are able to hear, good young ears (younger than 25 years !) are capable of 120dB of dynamic range, which is about 20 bits.

    But an ADC with 96dB SNR will NOT increase in quality if you acquire the data with 24 bit resolution, the resolution stays at about 16 bit, so for that particular ADC PCM1808 it does not make sense to acquire the data from the ADC with 24 bits, because all your lower significant bits will contain noise :-).

    If you have scientific evidence or publications that deliver blind test data for people hearing details down to 22/23 bits with a 96dB SNR ADC, I would be very happy to digest those!

  8. #8
    Senior Member PaulStoffregen's Avatar
    Join Date
    Nov 2012
    Posts
    20,769
    Pretty much all semiconductor companies specify "A weighted" signal to noise ratio. So an ADC with 96 dB SNR will have lots of random changes in its 16th bit, and even a good amount in the 15th bit, and of course nothing but noise in those low 8 bits.

    Sometimes it seems pretty much everything about tech specs in the audio world is designed to give people placebo-like specs. It seems to be highly effective at making sales, but the end result is a lot of misinformation and people with utterly unrealistic expectations.

  9. #9
    Senior Member
    Join Date
    Jul 2014
    Posts
    2,398
    So, if the ADC gives SNR of 96 dB, it is integrated over the whole bandwidth (A-weighted) and 15, 16th bit are very likely noisy.
    BUT if you go into spectral analysis (say >1024 point FFT) then you can detect features that are well below the 96 dB.
    For humans, obviously the critical bandwidth varies with frequency , so the noise bandwidth will vary, but it will always be less the full-scale A-weighted noise bandwidth.
    Consequently, having more than 2 noise bits can be very advantageous, as one can detect signals with negative SNR (dB) levels.
    I typically suggest to have 2 noise bits in the spectral band of interest, to ensure to not to miss signals of interest.
    Obviously you not only need low noise ADC's but also very low noise pre-amplifiers and low noise amplification states.
    And in the end it is the application that defines implementation.

  10. #10
    Quote Originally Posted by WMXZ View Post
    So, if the ADC gives SNR of 96 dB, it is integrated over the whole bandwidth (A-weighted) and 15, 16th bit are very likely noisy.
    BUT if you go into spectral analysis (say >1024 point FFT) then you can detect features that are well below the 96 dB.
    For humans, obviously the critical bandwidth varies with frequency , so the noise bandwidth will vary, but it will always be less the full-scale A-weighted noise bandwidth.
    Consequently, having more than 2 noise bits can be very advantageous, as one can detect signals with negative SNR (dB) levels.
    I typically suggest to have 2 noise bits in the spectral band of interest, to ensure to not to miss signals of interest.
    Obviously you not only need low noise ADC's but also very low noise pre-amplifiers and low noise amplification states.
    And in the end it is the application that defines implementation.
    Agreed. We were using 112dB AKM devices and information about 12dB lower can be discerned. In fact if you use pure tones you can hear about another 6dB but that isn't a measure of anything useful.

    And to the other poster, the person with the best ears and is very well known in pro-audio circles was about 50 at the time.

  11. #11
    Senior Member DD4WH's Avatar
    Join Date
    Oct 2015
    Location
    Central Europe
    Posts
    505
    Thats interesting. Did those "pro-audio circles" publish anything (possibly peer-reviewed?), so that others can participate in your knowledge?

  12. #12
    Quote Originally Posted by DD4WH View Post
    Thats interesting. Did those "pro-audio circles" publish anything (possibly peer-reviewed?), so that others can participate in your knowledge?
    This was done in the Soundcraft R&D department where I was Engineering Director at the time. We were far too busy designing new products to compete with Yamaha to have time to publish papers so you can take the information or leave it as you wish. The mixer being used was the Soundcraft 328 and we were testing a concept for extending the dynamic range of the analogue outputs in future digital consoles, over a decade before AKM launched the Velvet Sound range which I suspect uses similar principles.

  13. #13
    Senior Member DD4WH's Avatar
    Join Date
    Oct 2015
    Location
    Central Europe
    Posts
    505
    It was YOU who put out the term "pro-audio circles" ;-) --> #10

    Come on, I am not interested in fairy tales, give me something where I can learn, is there anything you guys published so we can learn from you, or are you still "far too busy"?

  14. #14
    Quote Originally Posted by DD4WH View Post
    It was YOU who put out the term "pro-audio circles" ;-) --> #10

    Come on, I am not interested in fairy tales, give me something where I can learn, is there anything you guys published so we can learn from you, or are you still "far too busy"?
    Not my job to teach you things. Get yourself a programmable signal generator, a mixer and some decent loudspeakers and try it yourself. You'll learn far more than by reading papers or datasheets. And the conclusions of any paper we didn't bother to write have been given above anyway. I suggest you begin by looking at Figure 19 of the 1808 datasheet and the equivalent for whatever DAC you are using so that you can see the noise floor - then start by finding what is the lowest level of tone you can discern above that noise floor. Now change the generator to shaped noise and slowly widen the bandwidth. You'll find a direct correlation between the bandwidth of that noise and at what level you can discern its presense.

Posting Permissions

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