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

Thread: SGTL5000 compared to PT8211

  1. #1

    SGTL5000 compared to PT8211

    Hi!

    I used for my project (MicroDexed) a Teensy-Audio-Board (SGTL5000) and it sounds really good (and works for 16 voices with only 2 Blocks of audio memory). But when using the same code (adapted for the PT8211, using the Teensy-Audio-Design-Tool) it seems that I am getting much memory problems. AudioMemoryUsageMax() reports something about 50.000 (!!!). I have seen that four-times-oversampling uses much memory, so I turned it of for a test. But there were also drop outs due to memory problems.

    Does the PT8211 "driver" really needs much more memory than the SGTL5000 - or do I have a problem in my code?

    Thanks and Regards, Holger

  2. #2
    Senior Member+ Theremingenieur's Avatar
    Join Date
    Feb 2014
    Location
    Colmar, France
    Posts
    2,118
    Without looking deeper into the audio library’s source code, I’d guess that a simple PT8211 output without oversampling should not be that memory consuming and I’d look for the problem elsewhere.
    The oversampling itself, when it is done with a lengthy zero phase FIR, might be extremely resource consuming. I made some tests, just generating a 48ks/s sine wave in real time with a high Q SVF, followed by x8 oversampling on a Teensy 3.2 without audio library, some years ago, and that was enough to saturate the poor little Teensy.

    Besides of that, new designs based on the obsolete PT8211 are not recommended.

  3. #3
    Quote Originally Posted by Theremingenieur View Post
    Without looking deeper into the audio library’s source code, I’d guess that a simple PT8211 output without oversampling should not be that memory consuming and I’d look for the problem elsewhere.
    The oversampling itself, when it is done with a lengthy zero phase FIR, might be extremely resource consuming. I made some tests, just generating a 48ks/s sine wave in real time with a high Q SVF, followed by x8 oversampling on a Teensy 3.2 without audio library, some years ago, and that was enough to saturate the poor little Teensy.
    Ok, thanks for this information. I have an idea where the memory problems may come from.

    Quote Originally Posted by Theremingenieur View Post
    Besides of that, new designs based on the obsolete PT8211 are not recommended.
    Sure, but the PT8211 is currently the easiest and cheapest way to get something like sound out of the Teensy via I2S. The TSOP housing is the only way for me to get an I2S interface soldered on a PCB :-(

    Regards, Holger

  4. #4
    Senior Member+ Theremingenieur's Avatar
    Join Date
    Feb 2014
    Location
    Colmar, France
    Posts
    2,118
    I'm currently experimenting with a cheap (3.14€) chinese PCM5102A breakout module. The PCM5102A has integrated x8 oversampling which makes things much easier.

  5. #5
    Quote Originally Posted by Theremingenieur View Post
    I'm currently experimenting with a cheap (3.14) chinese PCM5102A breakout module. The PCM5102A has integrated x8 oversampling which makes things much easier.
    I successfully used the PCM5102A and it sounds much better than the Audio Shield.
    https://forum.pjrc.com/threads/53069...Module-via-I2S

    Ultimately, though I wish to use the PCM5242. This would give me entry level audiophile quality sound. I just bought the evaluation module and I'll be hooking it up. I'm not a coder though, so I suspect I'll struggle "writing" the firmware to initialize the chip. I'll try...

    My goal will be to run the PCM5242 DAC in TDM mode with a Teensy. I'll be looking to hire a good firmware developer to help me along. If anyone is interested in paid work to do this let me know.

  6. #6
    Senior Member+ Frank B's Avatar
    Join Date
    Apr 2014
    Location
    Germany NRW
    Posts
    5,065
    The pt8211 code does not use that much memory. It does not use more than the SGTL code.
    Can you please post an example?
    I wrote parts of the code and would like to fix the bug- if there is any. But I need something that helps me to reproduce the problem.
    This is the first time I hear about it, and it is unlikely that it has a memory problem.

    Also, please give examplecode for dropouts.
    Last edited by Frank B; 09-22-2018 at 09:27 AM.

  7. #7
    Hi @Frank B

    thanks for replying to my post!

    Quote Originally Posted by Frank B View Post
    The pt8211 code does not use that much memory. It does not use more than the SGTL code.
    Can you please post an example?
    I am not really sure what is the problem - maybe I am doing something wrong...
    I tested the simple hardware example sketch and the PT8211Sine works without a problem. So I replaced the SGTL code inside my (far more complex code) with the PI8211 driver (currently this is done by a #undef TEENSY_AUDIO_BOARD):

    Code:
    // GUItool: begin automatically generated code
    AudioPlayQueue           queue1;         //xy=494,404
    AudioAnalyzePeak         peak1;          //xy=695,491
    #ifdef TEENSY_AUDIO_BOARD
    AudioOutputI2S           i2s1;           //xy=1072,364
    AudioConnection          patchCord1(queue1, peak1);
    AudioConnection          patchCord2(queue1, 0, i2s1, 0);
    AudioConnection          patchCord3(queue1, 0, i2s1, 1);
    AudioControlSGTL5000     sgtl5000_1;     //xy=700,536
    #else
    AudioOutputPT8211        pt8211_1;       //xy=1079,320
    AudioAmplifier           volume_master;           //xy=678,393
    AudioAmplifier           volume_r;           //xy=818,370
    AudioAmplifier           volume_l;           //xy=818,411
    AudioConnection          patchCord1(queue1, peak1);
    AudioConnection          patchCord2(queue1, volume_master);
    AudioConnection          patchCord3(volume_master, volume_r);
    AudioConnection          patchCord4(volume_master, volume_l);
    AudioConnection          patchCord5(volume_r, 0, pt8211_1, 0);
    AudioConnection          patchCord6(volume_l, 0, pt8211_1, 1);
    #endif
    // GUItool: end automatically generated code
    (The complete project is located at https://teahub.io/dcoredump/MicroDexed.git).

    Normally I only need to reserve 2 blocks of audio memory for the SGTL5000. I tried with several other values (up to ~500). I can hear something similar of a sound but there are much drops and reports about huge memory usage. I was trying with AUDIO_BLOCK_SAMPLES sizes of 128 (default) and 64 (which I am using for the SGTL5000 based code). The following is the main-loop:

    Code:
    void loop()
    {
      int16_t* audio_buffer; // pointer to AUDIO_BLOCK_SAMPLES * int16_t
      const uint16_t audio_block_time_ms = 1000000 / (SAMPLE_RATE / AUDIO_BLOCK_SAMPLES);
    
      while (42 == 42) // DON'T PANIC!
      {
    #if defined (DEBUG) && defined (SHOW_CPU_LOAD_MSEC)
        if (cpu_mem_millis > SHOW_CPU_LOAD_MSEC)
        {
          show_cpu_and_mem_usage();
          cpu_mem_millis = 0;
        }
    #endif
    
        handle_input();
    
        audio_buffer = queue1.getBuffer();
        if (audio_buffer == NULL)
        {
          Serial.println(F("E: audio_buffer allocation problems!"));
        }
    
        if (!queue1.available())
          continue;
    
        elapsedMicros t1;
        dexed->getSamples(AUDIO_BLOCK_SAMPLES, audio_buffer);
        if (t1 > audio_block_time_ms) // everything greater 2.9ms is a buffer underrun!
          xrun++;
        if (t1 > render_time_max)
          render_time_max = t1;
        if (peak1.available())
        {
          if (peak1.read() > 0.99)
            peak++;
        }
    #ifndef TEENSY_AUDIO_BOARD
        for (uint8_t i = 0; i <= AUDIO_BLOCK_SAMPLES; i++)
          audio_buffer[i] *= vol;
    #endif
        queue1.playBuffer();
      }
    }
    [ While I am writing this reply I can see that I am declaring "int16_t* audio_buffer; // pointer to AUDIO_BLOCK_SAMPLES * int16_t" outside the endless-while-loop. Is this the problem? ]

    What is strange: AudioMemoryUsageMax() is reporting values about 50.000 or 65.000 blocks after a note-on event.

    Quote Originally Posted by Frank B View Post
    I wrote parts of the code and would like to fix the bug- if there is any. But I need something that helps me to reproduce the problem.
    This is the first time I hear about it, and it is unlikely that it has a memory problem.

    Also, please give examplecode for dropouts.
    I hope those small pieces of code are helping. The whole project is much bigger... perhaps it is a problem of the combination of the queue object with the PT8211 driver? I think I will try to write a smaller program which only generates a sine wave inside a queue...

    Regards, Holger

  8. #8
    Senior Member PaulStoffregen's Avatar
    Join Date
    Nov 2012
    Posts
    19,006
    Quote Originally Posted by C0d3man View Post
    I think I will try to write a smaller program which only generates a sine wave inside a queue
    Yes, a smaller program would be a huge help.

    The queue objects are tough to use and can quickly burn up memory if your code doesn't keep up with the full audio rate. If there really is a bug in the PT8211 code, a test program not using any queues would be really helpful.

  9. #9
    Quote Originally Posted by PaulStoffregen View Post
    Yes, a smaller program would be a huge help.

    The queue objects are tough to use and can quickly burn up memory if your code doesn't keep up with the full audio rate. If there really is a bug in the PT8211 code, a test program not using any queues would be really helpful.
    The example program PT8211Sine is doing fine. I don't think that there is a problem in the PT8211 code. I think I am doing something wrong with the queue. The strange thing is: the SGTL5000 implementation works, and the PT8211 not (same code, only some amps (for panning a mono signal) were added). I'm a little confused at this point:

    Code:
    audio_buffer = queue1.getBuffer();
        if (audio_buffer == NULL)
        {
          Serial.println(F("E: audio_buffer allocation problems!"));
        }
    
        if (!queue1.available())
          continue;
    I thought that queue1.available() should block if there is no audio buffer free. So, if I use
    Code:
    AudioMemory(8);
    , then there should not be used more than these 8 audio buffers and the function should block or continue() withoud allocating, or am I wrong?

    Regards, Holger

  10. #10
    Senior Member PaulStoffregen's Avatar
    Join Date
    Nov 2012
    Posts
    19,006
    The PT8211 code does a bunch of extra work to interpolate samples. The I2S code just quickly copies them to a buffer.

    Perhaps this extra CPU time consumed by the PT8211 code is impacting the timing of the rest of your program enough that you're using the queue differently?

  11. #11
    Quote Originally Posted by PaulStoffregen View Post
    The PT8211 code does a bunch of extra work to interpolate samples. The I2S code just quickly copies them to a buffer.

    Perhaps this extra CPU time consumed by the PT8211 code is impacting the timing of the rest of your program enough that you're using the queue differently?
    I have seen that there is software oversampling and other stuff implented and I "#undef"-ed them inside the driver with no improvement. I am pretty sure that I am doing something wrong with the queue().

    Does queue1.available() block? If not I think I know what I am doing wrong...

    Regard, Holger

  12. #12
    Senior Member+ Frank B's Avatar
    Join Date
    Apr 2014
    Location
    Germany NRW
    Posts
    5,065
    Hm, seeing the code here: https://github.com/PaulStoffregen/Au..._queue.cpp#L31
    I think your code should probably look like this:

    Code:
    if (queue1.available()) {   
      audio_buffer = queue1.getBuffer();
      ..fill buffer here..
      queue1.playBuffer(); 
      ...
    }
    The documentation for the queue does not look correct..

    Functions

    play(int16);
    not yet implemented


    play(int16[], length);

    not yet implemented


    getBuffer();

    Returns a pointer to an array of 128 int16. This buffer is within the audio library memory pool, providing the most efficient way to input data to the audio system. The buffer is likely to be populated by previously used data, so the entire 128 words should be written before calling playBuffer(). Only a single buffer should be requested at a time. This function may return NULL if no memory is available.


    playBuffer();

    Transmit the buffer previously obtained from getBuffer().
    Apart from the missing available() which allocates the buffer, getBuffer never returns null, but waits for a free buffer.
    Last edited by Frank B; 09-24-2018 at 04:30 PM.

  13. #13
    Quote Originally Posted by Frank B View Post
    Hm, seeing the code here: https://github.com/PaulStoffregen/Au..._queue.cpp#L31
    I think your code should probably look like this:

    Code:
    if (queue1.available()) {   
      audio_buffer = queue1.getBuffer();
      ..fill buffer here..
      queue1.playBuffer(); 
      ...
    }
    The documentation for the queue does not look correct..


    Apart from the missing available() which allocates the buffer, getBuffer never returns null, but waits for a free buffer.
    Thanks @Frank B! This may be the cause for my (perhaps) faulty implementation. I just have not much time for testing this. Will do this at weekend and report here.

    Regards, Holger
    Last edited by C0d3man; 09-25-2018 at 03:12 PM.

  14. #14

    Problem solved!

    I GOT IT!!!

    First I tried to rewrite my main loop as @Frank B sugessted. But this changed nothing. But then I recognized a really stupid problem made by myself - the problem is in front of the screen:

    ...
    #ifndef TEENSY_AUDIO_BOARD
    for (uint8_t i = 0; i <= AUDIO_BLOCK_SAMPLES; i++)
    audio_buffer[i] *= vol;
    #endif
    queue1.playBuffer();
    ...

    Where is the problem? It is not the driver... It is the erroneous comparison in the for loop that triggers an access outside the allocated memory area! ARGH! And this part of the code is only used when not using the audio-board. The for-loop has to check "i < AUDIO_BLOCK_SAMPLES" instead of "i <= AUDIO_BLOCK_SAMPLES"...

    Now Micro-Dexed also works on the PT8211. Thanks so much for helping to all!!!!!!!!!!!

    Regards, Holger

  15. #15
    Senior Member+ Frank B's Avatar
    Join Date
    Apr 2014
    Location
    Germany NRW
    Posts
    5,065
    Quote Originally Posted by C0d3man View Post
    I GOT IT!!!
    I'm glad you found that little bug.

Posting Permissions

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