Matrix Voice and Raspberry Pi Zero Audio output

I think buying a respeaker and tell all friends they want to use matrix Voice that they never get the promised features.


Hi @joeduck

Sorry for the delay.

The Pull Request for audio output has been merged into our dev branch and should be officially released later today.

Thanks. But why you let the customers over one year waiting? However. now we have the feature and hope it works.

I do a update today, but have this error. So no updated Matrix Kernel Modules where installed. Can you tell me what is wrong?

Unpacking matrixio-kernel-modules (0.1.4) over (0.1.4) …
dpkg: error processing archive /var/cache/apt/archives/matrixio-kernel-modules_0.1.4_armhf.deb (–unpack):
unable to make backup link of ‘./boot/overlays/matrixio.dtbo’ before installing new version: Operation not permitted

Thanks, Jochen

@joeduck I’ve had this error in the past and yesterday while reinstalling the kernel module package.

In the used to rename the file and update the package…

sudo mv boot/overlays/matrixio.dtbo boot/overlays/matrixio.dtboold

But this didn’t work yesterday so I had to purge the kernel module, reboot and install the kernel module again.

There were several updates on GitHub so audio out is happening!


If you need any help testing audio out via the speaker connection on the marrix voice let me know. I bought the speaker connectors from digikey, updated the kernel modules and am curious about the configuration to get this going.

1 Like

Thanks! Now the Modules are loaded and the sound is working.
My Speaker config in the asound.conf:

pcm.speaker {
  type plug
  slave {
    pcm "hw:2,1"

Does the noice cancellation work? Can i Play music over the matrix and talk to the mic?

1 Like

Hi @joeduck,

Glad to hear that.

My guess is you are referring to AEC ( Acoustic Echo Cancellation). We currently dont offer any AEC examples but you could use 3rd party libraries for this like SpeexDSP or WebRTC.


Regarding the last update on the kernel module about the audio playback, we will share a more official guide on the documentation, but to test it you just need to install the kernel-modules package :

  • Follow steps for Option1: Package Installation.
  • After reboot download some audio in wav format:
    wget -O ./audio-sample.wav
  • Connect headphones or a peaker via the 3.5mm jack in the MATRIX Voice board.
  • and play it using:
    aplay -D "hw:2,1" ./audio-sample.wav

Let me how it goes.


Hi yoel, will this be implmented in the esp32 as well?
I am currently stuggling with bluetooth (more accurate the resampling of audio because of limitations in the esp framework)

Yes @Romkabouter, we will be also releasing a example/demo playing audio from the ESP32 based on this code. If you can’t wait for the official example, you can give it a try and share your feedback here if you want, that code should be almost working :). I think the use of HAL code is in the bt_app_av.cpp file.


Great! I will try it as soon as I can get my hands on it :smiley:
Nice to see you have a BT sink demo as well! I was referring to using the esp32 as a a2dp source by the way :slight_smile:

@yoelrc88 I bought the speaker connectors here…

Do you have any directions for outputting audio on this interface?

I remember that the audio_demo had an option to define either headphone or speaker before compiling.

FYI, audio out via the 3.5mm jack works well if the audio was recorded with the right sample rate.

Thanks for all the work you have done.

can play .wav files with aplay and mp3 files with mpg123. Have Output on the 3.5 mm Jack of the matrix voice. But no chance to adust the volume. and courios: no sound from snips output. But “sam test speaker” give sound. going back to the raspi Jack snips output works.

Canm i play music on the matrix audio jack an speak to the mic? On respeaker this works cause the internal AEC.

We currently don’t provide AEC for MATRIX Voice, you will have to use a 3rd party library or software, like SpeesDSP or WebRTC.


This is from your website. One Reason why I bought the matrix voice. What should I do with the audio jack when AEC is not working? Then I can use the raspi audio…

 Spartan-6 FPGA

Leverage fast audio processing and advanced algorithms for voice. Beamforming, AEC, de-reverberation and noise cancellation.

Hi Yoel,

I have worked my way through the code and I am stuck comprehending this:

void bt_app_a2d_data_cb(const uint8_t *data, uint32_t len)
static uint16_t buffer[2048];
int16_t p = (int16_t)data;

uint16_t diff;
uint16_t buffers_fifo[2];

for (int i = 0; i < len/4; i++)
    buffer[i] = p[i*2]/2+16768;
    /* code */


if(buffers_fifo[1] > buffers_fifo[0])
    diff = buffers_fifo[1] - buffers_fifo[0];
    diff = 4096 - buffers_fifo[0] + buffers_fifo[1];

if(diff > 2048){
    vTaskDelay(30 / portTICK_PERIOD_MS);
//    ESP_LOGI(BT_AV_TAG, "--- Diff %d Len:%d", diff,len/2);
wb->SpiWrite(hal::kDACBaseAddress, (uint8_t*)buffer, len/2);


I understand what it does, but I do not understand the SpiRead into buffers_fifo do?
I have chosen internal DAC in the config, assuming that the sound would come from the audio-jack.
Is that correct or should I choose external I2S?

This is because I get the buffer callback and all, but no sound is produced in the jack.
Should I upgrade firmware first?

Hi @Romkabouter,

Sorry about the code, it was meant to be a test and still requires some cleanup. A full example will be released in the coming weeks.

The audio data is sent from the ESP32 using SPI to the DAC implemented in the FPGA present in the board. So, that’s what SpiWrite does, is sending the audio.

Yes, you should use the latest version of matrix-creator-init package.


Yeah, I understand and that is no problem at all :slight_smile:
I was using that code as an example to output data but when I did not hear a sound I thought I’d made some mistake.

Code is fine to tinker with, no problems. I do not think I have the latest init code in place, so that will be my first action

update: yeuh, I could play my spotify playlist!
Although the buffers and such are not good (it’s a demo anyway), I could hear the music :slight_smile:
Lots of packets drops, but that is just a buffer problem.

For audio output I run into the same problem as bluetooth.
That is that the ESP framework only support 44100 16 bit for now, but I think I will just make this a requirement for incoming audio buffers instead of trying to resample on the fly.

Thanks for all the effort on the audio output :slight_smile:

Hi yoel,

I could use your help for a bit, because I can not seem to produce a correct sound.
My setup receives a wav file and puts the raw data part in a uint8_t buffer. For now I send a small 8bit 8kHz file, which fits in memory of the esp32.

Besides that, I have and task running which should be playing the buffer.
The code below is what I have to produce the audio, but all I got from various tries is between a ticking sound and a bit crushing sound.
Nothing is anything like it should be,

> void AudioPlayTask(void * p){
>   while(1) {
>     xEventGroupWaitBits(audioGroup,PLAY,true,true,portMAX_DELAY); //Wait for the bit before updating
>       if ( xSemaphoreTake( wbSemaphore, ( TickType_t ) 5000 ) == pdTRUE )
>       {
>         Serial.println("Play Audio");
>         //Serial.println(inRate);
>         int NUM = 512;
>         while (played < dataLength) {
>           uint8_t data[NUM];
>           for (int i = 0; i < NUM; i++) {
>             data[i] = Data[played+i];
>           }
>           played = played + NUM;         
>           wb.SpiWrite(hal::kDACBaseAddress, (uint8_t *) data, sizeof(data));
>          //delay: 1 000 000 microseconds in a second, 8000 samples / second (for a 8khz file)
>          //that will be 1 000 000 / 8000 microsecond per sample, we read NUM samples
>           delayMicroseconds( NUM *  ( 1000000 / inRate ) );
>         }
>         xEventGroupClearBits(audioGroup, PLAY);
>         xSemaphoreGive( wbSemaphore ); //Free for all
>       }
>   }
>   vTaskDelete(NULL);
> }

In this version I have a local buffer of 512, but I have also used 1 and other.
Since it is an 8bit mono file, I assumed that I could play the buffervalues as they come in.
My thoughts therefore were using NUM = 1, I would write the SPI with that data, then do a delay of 1 000 000 / 8000 microseconds and play the next value
This would result in playing 8000 samples per second, which matches the sample rate of the incoming file.
I am using an 8bit mono 8000Hz file to simplify the process for now.

  • dataLength is a global holding the length of the data, read from the wave header
  • inRate is the sample rate, read from the wav header
  • Data hold the whole raw data of the wav
  • please ignore xSemaphoreTake and other code, that works fine and I need it because this part is implemented in my Matrix Voice Audio Server. I want to output the incoming sound files to the audiojack.

I am misunderstanding the wb.SpiWrite(hal::kDACBaseAddress, (uint8_t *) data, sizeof(data)); part?