Code Monkey home page Code Monkey logo

esp32_audio's Introduction

This code is now pretty old

It's probably still useful, but I would recomment people check out the fantastic work here: https://github.com/pschatzmann/arduino-audio-tools

ESP32 I2S Audio

Explanatory video of the analog mic boards here (MAX9814 and MAX4466) here

Demo Video

And for the two I2S boards (SPH0645 and INMP441) here

Demo Video

For audio output we can use the MAX98357A boards - there's a explanatory video here

Demo Video

This project demonstrates how to use the ESP32 built-in Analog to Digital Converters and I2S for capturing audio data and for audio output..

There are four projects in this repository: loop_sampling, i2s_sampling, i2s_output and server.

server

This is a simple node server that writes the samples received from the ESP32 to a file.

Check the README.md file in the server folder for detailed instructsions.

You will need to have node and yarn. You may already have these on your system.

Check with:

node --version
yarn --version

Then just run:

cd server
yarn

To install the dependencies. And

cd server
yarn start

When you want to run the server.

loop_sampling

This project shows how to use the Arduino analogRead function and the Espressif adc1_get_raw function.

It also demonstrates how to get a calibrated value back from the ADC to give you the actual voltage at the input.

i2s_sampling

This project handles both analogue devices (such as the MAX4466 and the MAX9814) and I2S devices (such as the SPH0645 and INMP441).

This project demonstrates how to use the I2S peripheral for high-speed sampling using DMA to transfer samples directly to RAM.

We can read these samples from the internal ADC or from the I2S peripheral directly.

Samples are read from the DMA buffers and sent to a server running on your laptop/desktop machine.

The current set of pin assignment in the code are:

ADC

Function GPIO Pin Notes
Analogue input GPIO35 ADC_UNIT_1, ADC1_CHANNEL_7

I2S

Function GPIO Pin Notes
bck_io_num GPIO_NUM_32 I2S - Serial clock
ws_io_num GPIO_NUM_25 I2S - LRCLK - left right clock
data_in_num GPIO_NUM_33 I2S - Serial data

i2s_output

This example shows how to drive an I2S output device - I've tested this against the MAX98357 breakout board from Adafruit - https://learn.adafruit.com/adafruit-max98357-i2s-class-d-mono-amp

There is an example WAV file that can be played or you can play a simple sin wave through the output.

To play the WAV file you will need to download the file to the SPIFFS file system.

This is now annoyingly hard to find on platform.io - watch this video to see how to find it.

FS Upload

The pins currently configured are:

Function GPIO Pin Notes
bck_io_num GPIO_NUM_27 I2S - Serial clock
ws_io_num GPIO_NUM_14 I2S - LRCLK - left right clock
data_out_num GPIO_NUM_26 I2S - Serial data

esp32_audio's People

Contributors

cgreening avatar fluxxion82 avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

esp32_audio's Issues

Spiky audio capture

Hello!
I am trying to listen to the audio recorded by the ESP32, but it just sounds like a bunch of clicks. I looked at the raw audio data with Audacity and the audio waveform indeed is almost exclusively formed out of spikes. What could be causing this and how would one go about fixing it? I experimented with whether lowering the gain on the MAX9814 module by tying its gain pin high (40dB gain), but it did not help.

Waveform
The raw audio data in Audacity

ADC i2s sampling is not continuous

I am using MAX9814 mic with ESP32 38 pin board, and i2s_sampling project from this repository. Mic is connected to ADC7
However, audio recording is not continuous, between each audio sample, while ESP32 is sending data to the server, recording is not performed simultaniously. So final audio has missing audio. I am using the same parameters as in your repo code, I did not change sampling code.

I tried enumerating packets and time when they were sent and it seems that some not recorded time is missing:
27: 397959
28: 399442
29: 400861
30: 402280
31: 403699
32: 404926
33: 406151
34: 407634
35: 408860
36: 410280
37: 411699
38: 412923
39: 414343
40: 415568
41: 416794
42: 418085
43: 419504
44: 420923

It seems that your code is simpler and different from video explanation, and I don't quite understand how code knows when to read buffers. Maybe sending audio actually stops recording, ESP32 has two cores maybe tasks are not divided? I am rather new to ESP32 programing.

I also get a lot of static noise, but I think it is not related to this problem.

ffmpeg

I love this project thank you!

I did some testing and it's possible to get even cleaner audio by also applying a filter on your audio... for example a high pass and a low pass filter on the raw audio stream...

ffmpeg -f s16le -sample_rate 44100 -i audio.raw -af "highpass=f=200, lowpass=f=3000" -f wav file-out.wav

Mixing wav-files from SD-card

Hi!
Congratulations and thank you for your very useful work on ESP32-audio.
I wonder how it is possible to mix up to 6 different wavefiles (16-bit 44,1kHz) located on an sd-card and play them over MIDI with low latency. This should be possible with I2S and SD-MMC-mode. Could you PLEASE think of a solution?
Sorry for my English - I'm from Austria (not Australia... ;-)

A2DP source using adc dma (i2s) not working

Hi Chris,

Thanks for your wonderful video and nice explanation related to MAX9814 and ESP-32. I am trying to send digital audio from Max9814 to bluetooth headphone ( as sink).
Source esp-32 is able to connect to sink esp-32. I am able to run the basic example over classic bluetooth and send noise audio.
But when I connect data out from MAX9814( which I have confirmed to be working) on ADC channel 0 of source esp-32 after adding I2S code, I am not getting any audio on speaker connected to sink device.

Is it possible for you provide some pointers, if any.

thanks,
Rupak

Noise adjustment.

Hello! Your project helped me a lot. But I need to adjust the noise. The recording comes out paused and with a little noise.

My board:
ESP32 ---- MAX9814
3v3................Vdd
GND.............GND
GPIO35........Out
GND..............Gain - 40dB

Image of the audio output.
2020-09-13 174602

Video in zip.
ScreenRecorderProjectAudio.zip

WAV file to SD card

Hi!
First of all - your solution is magic, thanks for your work!))
Can you please provide an example of how I can write ADC samples as to *.wav file to SD card?

Streaming I2S data to a BT sink

Hi,

I'm trying to stream the audio of INMP441 w/ ESP32 to BT speakers/headphones, but I'm having a hard time figuring out how to stream the data continuously over Bluetooth to a BT sink. Do you have any tips/code? Thank you very much!

Regards,
rmond18

Noisy audio

Hello, I've been trying to capture audio and send it via wifi just as described in the project. But, as soon as I play the RAW file, it is just a noisy audio without a trace of any captured voice. I checked over the code but didn't see anything wrong, although I'm very new to programming in general. I'll be linking the audio acquired via wifi. I'll be very much appreciated for any help, thanks.

adc.zip

Advice on HTTP errno: 104 when using i2s_sampling and server

I've been playing around with your ICS43434 breakout board (it's pretty nice to get my builtin LED flashing along with volume as a test!) and am running into some HTTP issues when trying to use your i2s_sampling and server example. I hope you might have some suggestions as this server stuff is all brand new to me.

The error I'm seeing (as reported by my ESP32) is the following on every call of httpClient.post() within sendData() (the fd cycles from 54 through to 63, and then loops).

[E][WiFiClient.cpp:365] write(): fail on fd 54, errno: 104, "Connection reset by peer"

The Express server (no changes made there - I know nothing about TS / JS) gives me the below as it receives each POST request.

[2020-10-21T22:23:25.701Z]  "POST /i2s_samples" "ESP32HTTPClient"
[2020-10-21T22:23:28.877Z]  "POST /i2s_samples" Error (404): "Not found"

I'm not sure how the 104 and 404 relate, but again this is new to me. Is the issue that I'm somehow not sending bytes to the server?

I've made only minimal changes to your code (pinout for my board, some minor i2s_config stuff that I've verified works in other examples, fixing the thing seen in #4, etc)

Any advice greatly appreciated!

No audio Found

0after running the code, and converting the raw file to wave file, there is sound at all, knowing that some data are reaching the server and the raw file is being created.

I'm using I2S using the same code in the last commit

// Direct i2s input from INMP441 or the SPH0645
  i2sSampler = new I2SMEMSSampler(i2sPins, false);

  // set up the i2s sample writer task
  TaskHandle_t i2sMemsWriterTaskHandle;
  xTaskCreatePinnedToCore(i2sMemsWriterTask, "I2S Writer Task", 4096, i2sSampler, 1, &i2sMemsWriterTaskHandle, 1);

  // start sampling from i2s device
  i2sSampler->start(I2S_NUM_0, i2sMemsConfigBothChannels, 32768, i2sMemsWriterTaskHandle);
}

The component connectivity can be found here
raw data can be found here
wave file can be found here

Further Explanation

Hello, I am very new to programing. I am looking to create a wireless microphone system that works over a WIFI network for live sound reinforcement. I have everything downloaded, I am just not sure how to install everything and what parameters have to be modified to get it up and running. I was wondering if you could help walk me through how to get started. Ideally I would eventually like the received audio to come out of my server's speakers live.

Thanks in advance, I know those are a lot of questions.

-Caleb

Reading second ADC channel

Hello,

first of all I would like to thank you for this code! I'm using it to sample from an analog microphone (ADC sampler code path).

It works, although I'm not quite sure what the output data format is for the samples (MSB vs LSB), but the main proble I'm facing is that in another task I'm using Emon library to sample another sensor using ADC0 but on another channel.

Turns out this makes the I2S/ADCSampler give back a single value of 0. I tried using i2s_adc_enable and i2s_adc_disable around the i2s_read but it has no effect.

Even if I don't use the Emon library, and simply use adc1_get_raw() the same thing happens so that makes me think it's some sort of ADC config issue.

Do you have any thoughts or ideas why this may happen?

Thank you in advance,
Spiros

no audio / scope data OK

hi,

[env:pico32]
platform = espressif32
board = pico32
framework = arduino
upload_port = COM5
monitor_speed = 115200

.bck_io_num   = GPIO_NUM_26,             // bit clock
.ws_io_num    = GPIO_NUM_32,             // word select L/R
.data_out_num = GPIO_NUM_25,           // data

upload OK, no error messages.

adafruit MX98357
210208ESP32audio

danke aus österreich
rudi

WifiClient not connect

Hello, I found your project interesting, because I'll use a MAX9814 in the future, and I'm researching more about I2S too. However, I'm having problems connecting to my WIFI network. It's causing this error:
[E][WiFiClient.cpp:258] connect(): socket error on fd 54, errno: 113, "Software caused connection abort"
So far I don't know how I can solve it, if you can help I'll be grateful.

No Raw files saved?

Where does the raw file save? I looked at the folders and couldn't find any adc.raw

Connection reset by peer

I keep on getting this error even after starting the server. Any workaround to this thing?

[E][WiFiClient.cpp:258] connect(): socket error on fd 54, errno: 104, "Connection reset by peer"

Change frame buffer content for I2S Output

I am trying to port code from a M0 based system to ESP32 which includes an I2S buzzer output. The total project is fairly complex and I2S in the background is ideal. Your code using the dma event queue seems a good way to help achieve this. I have found getting to grips with esp32 I2s a lot harder than on the M0 platform!
I have added a simple square wave constructor to I2S Output and can change the tone and volume by re compiling code. I would like to be able to change the content of the frames buffer on the fly so that I can call something like:
buzz ( tone, duration_in_ms , volume) to re load the frames buffer and restart the i2s output for the given duration.
I have tried doing this by stopping / starting i2s and /or suspending the Output task. These tests don't give a clean restart to the output as any stop start may be at any point in the write cycle. A change in the frame buffer gives noise or no output and crashes from time to time. :-(
I would welcome any suggestions on how this might be achieved.
Thanks
Ted
ted at kitst dot co dot uk

Audio Issue: Audio file received from the ESP32 with INMP441 microphone is distorted

Hi,

I currently am using the INMP441 microphone connected to the ESP32 as per the wiring diagram on the github page. I have been able to get the esp32 to connect over wifi to stream the i2s data back. However, I am running into an issue with the quality of the audio received. I have been importing the audio into audacity with the setting.

  1. 16 bit signed PCM
  2. 16000hz sampling rate
  3. Mono channel.

While I am able to hear most of the high level features of the audio, the audio file is generally very distorted and has lots of hissing and popping noises in the background. From watching your previous videos, my first intuition was that it might be a power supply issue, so I added a 1mF capacitor between VCC and GND in order to try to smooth out the electrical noise but to no avail.

Here is sample of the audio received from the ESP32 in a raw format. I have recorded two samples, 1 at 44100hz and the other at 16000hz. The 44100hz sample is a little better but still heavily distorted.

audiosamples.zip

Very strange waveform Shape

Hello,
I have reduced your example to a minimum to investigate in details.
I changed output to Serial and observe the signals via SerialPlot SW.
Input signal was Sine 1kHz, 2V Amp, 1.7V offset.

#include "ADCSampler.h"

#define SAMPLE_RATE 32000 //16000
#define SAMPLES 16384

#define TPIN 2
#define t1 digitalWrite(TPIN, HIGH);
#define t0 digitalWrite(TPIN, LOW);
#define t digitalWrite(TPIN, !digitalRead(TPIN));

ADCSampler *adcSampler = NULL;
I2SSampler *i2sSampler = NULL;

// i2s config for using the internal ADC
i2s_config_t adcI2SConfig = {
.mode = (i2s_mode_t)(I2S_MODE_MASTER | I2S_MODE_RX | I2S_MODE_ADC_BUILT_IN),
.sample_rate = SAMPLE_RATE, //16000,
.bits_per_sample = I2S_BITS_PER_SAMPLE_16BIT, // I2S_BITS_PER_SAMPLE_16BIT,
.channel_format = I2S_CHANNEL_FMT_ONLY_LEFT,
.communication_format = I2S_COMM_FORMAT_I2S_LSB,
.intr_alloc_flags = ESP_INTR_FLAG_LEVEL1,
.dma_buf_count = 4,
.dma_buf_len = 1024,
.use_apll = false,
.tx_desc_auto_clear = false,
.fixed_mclk = 0
};

void adcWriterTask(void *param)
{
I2SSampler *sampler = (I2SSampler *)param;
const TickType_t xMaxBlockTime = pdMS_TO_TICKS(100);
while (true)
{
uint32_t ulNotificationValue = ulTaskNotifyTake(pdTRUE, xMaxBlockTime);
if (ulNotificationValue > 0){
int8_t buffptr = (int8_t)sampler->getCapturedAudioBuffer();

// for (int i = 0; i < sampler->getBufferSizeInBytes(); i=i+2) {
// Serial.printf("%d\n\r", buffptr[i] + buffptr[i+1]*256);
// }
Serial.write((char *) sampler->getCapturedAudioBuffer(), sampler->getBufferSizeInBytes());
}
}
}

void setup()
{
Serial.begin(115200);
pinMode(TPIN, OUTPUT);
while (!Serial);

adcSampler = new ADCSampler(ADC_UNIT_1, ADC1_CHANNEL_7);

TaskHandle_t adcWriterTaskHandle;
xTaskCreatePinnedToCore(adcWriterTask, "ADC Writer Task", 4096, adcSampler, 1, &adcWriterTaskHandle, 1);
adcSampler->start(I2S_NUM_0, adcI2SConfig, SAMPLES, adcWriterTaskHandle);
}

void loop()
{
}

Below are screenshorts of the various I2S settings.
Please, note how awful they looks. They should be smooth but they did not.
Only at 32Bit 100kHz it looks acceptable.
First time I met the problem on PDM example for M5 Core2.
Note, also, that signals aquired from analogRead function are ideal.
This sawtooth distortion leave no way to use FFT because they produce a lot of harmonics. Also, the same thing occured in you original code(Audacity picture).
16Bit_16kHz_1kHz_2V
16Bit_32kHz_1kHz_2V
)
32Bit_100kHz_1kHz_2V
Audacity

Play audio only once (dac i2s)

How could I play an audio file only once and not in a loop?
I tried to modify the code in DAC_i2S_OUTPUT to play a .wav file only once instead of in a loop.
My solution is rather radical, I´m simply killing the writer task and uninstall the i2s driver after a period of time (duration of the audio).

    delay(audio_length); //wait till audio is fully played
    if (writerTaskHandle != NULL) {
        vTaskDelete(writerTaskHandle);
        Serial.println("AudioTask killed!");
        i2s_driver_uninstall(I2S_NUM_0);  // stop & destroy i2s driver (audio ends)
    }

The solution works, but sometimes I get problems with the task, even though I wait long enough before killing it:

/home/runner/work/esp32-arduino-lib-builder/esp32-arduino-lib-builder/esp-idf/components/freertos/tasks.c:4101 (xTaskPriorityDisinherit)- assert failed!
abort() was called at PC 0x400880a7 on core 1

My final goal is to have several buttons which each play another .wav (not simultaneously).

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.