Audio output other than 44100Hz

#1

Hi,

As I have stated in my project topic about the Audio Streamer, I have now output over the headphone Jack.
While this is great I have problems with audio other than 44100, 16bit stereo

My AudioPlay task is using a ringbuffer, filled via MQTT. Messages with wave files vary in samplerate from 22050 to 16000. They sound too fast.

My Task:

void AudioPlayTask(void * p){
  while(1) {
    xEventGroupWaitBits(audioGroup,PLAY,true,true,portMAX_DELAY); //Wait for the bit before updating
      if ( xSemaphoreTake( wbSemaphore, ( TickType_t ) 10000 ) == pdTRUE )
      {
        Serial.println("Play Audio");
        //devcfg.clock_speed_hz = 8 * 1000 * 1000; ==> not sure why sleep should be this????
        float sleep = 8000000 / kMaxWriteLength / 2;
        while(!audioData.isEmpty())
        {
            int frames = 1024;
            for (int i = 0; i < frames; i++) 
            {
              if (!audioData.isEmpty()) {
                audioData.pop(data[i]);
              }
            }
            wb.SpiWrite(hal::kDACBaseAddress,(const uint8_t *)data, sizeof(uint8_t) * frames);
            std::this_thread::sleep_for(std::chrono::microseconds((int)sleep));
        }
        if (asyncClient.connected()) {
          asyncClient.publish(playFinishedTopic.c_str(), 0, false, finishedMsg.c_str());
        }      
        uint8_t b = 0;
        for (int i = 0; i < kMaxWriteLength* 4;i++) {
          audioData.push(b);
        }
        audioData.clear();
        xEventGroupClearBits(audioGroup, PLAY);
        xSemaphoreGive( wbSemaphore ); //Free for all
      }
  }
  vTaskDelete(NULL);
}

Some of the code is not needed, but that is a result of me trying different things.
Can any of the dev’s help me out in understanding why I need the sleed after SpiWrite?
I think it has something to do with the devcfg.clock_speed_hz = 8 * 1000 * 1000; in the whisbonebus but I fail to see why.

Is it even possible to correctly output audio other than 44100?

0 Likes

#2

Just a little extra info.
In theory, I think this code:

    while(!audioData.isEmpty())
    {
        int frames = 1024;
        for (int i = 0; i < frames; i++) 
        {
          if (!audioData.isEmpty()) {
            audioData.pop(data[i]);
          }
        }
        wb.SpiWrite(hal::kDACBaseAddress,(const uint8_t *)data, sizeof(uint8_t) * frames);
        std::this_thread::sleep_for(std::chrono::microseconds((int)sleep));
    }

should be a bit different.

With a 44100, 16 bit stereo audio file, I think I should have 4 bytes per sample.
This means for 1 sample 1 / 44100 seconds ~ 23 microseconds.
1 sample has 4 bytes, since it is 16 bit and 2 channels

My first try was:

    while(!audioData.isEmpty())
    {
        int frames = 4;
        float sleep = 1 / 44100 * 2 * 2 * 1000 * 1000; //  ca 90 microsecs
        for (int i = 0; i < frames; i++) 
        {
          if (!audioData.isEmpty()) {
            audioData.pop(data[i]);
          }
        }
        wb.SpiWrite(hal::kDACBaseAddress,(const uint8_t *)data, sizeof(uint8_t) * frames);
        std::this_thread::sleep_for(std::chrono::microseconds((int)sleep));
    }

This produces way to slow audio however… so I am missing something here but I can’t figure out what. I also tried lower values for sleep, like 23 but still no luck

0 Likes

#3

Hi @Romkabouter,

How I can test this myself? Do you have this code on github?

I am also doing some additional test around this to see what is the best solution.

Will get back to you later with an answer on this.

-Yoel

0 Likes

#4

Hey yoel, it’s here:

I ran into an issue yesterday that audio output did not work anymore when the MV was attached to the Pi, but worked ok when running esp32.
FYI :slight_smile:

You can follow the instructions from the repo to get m going, adjust the code to whatever suits you.
The code connects to a MQTT broker and starts listening to the topics hermes/audioServer/matrixvoice/playBytes/#.
So you can inject a wave file to hermes/audioServer/matrixvoice/playBytes/test and the AudioPlay task should pick that up.
Sometime the audio is a big mess, probably an issue with the messages arriving or so, but I think you will figure it out :slight_smile:

Glad you can help, you can also PM me if you want.

Why I need different samplerates is that I am using the MV for Snips, which had some feedback sounds (22050) and plays Text To Speech at 16000. Some are mono and stereo as well, but that is another problem to tackle.
The code now plays the feedback sounds to fast and the speech way to fast

0 Likes