This commit is contained in:
2026-02-12 21:00:02 -08:00
parent 77f8236347
commit 8bdbf227ca
1141 changed files with 1010880 additions and 2 deletions

View File

@@ -0,0 +1,3 @@
# Basic API
Using the A2DP Callback directly is usually much more efficient then the A2DPStream which set up an additional buffer

View File

@@ -0,0 +1,55 @@
/**
* @file base-BufferRTOS.ino
* @author Phil Schatzmann
* @brief Data provider on core 0 with data consumer on core 1
* @version 0.1
* @date 2022-11-25
*
* @copyright Copyright (c) 2022
*
*/
#include "AudioTools.h"
#include "AudioTools/AudioLibs/Concurrency.h" // https://github.com/pschatzmann/arduino-freertos-addons
BufferRTOS<int16_t> buffer(1024);
void doWrite(); // forward declaration
Task writeTask("write",5000,10, 0); // FreeRTOS task from addons
// create data and write it to buffer
void doWrite() {
int16_t data[512];
for (int j=0;j<512;j++){
data[j]=j;
}
buffer.writeArray(data, 512);
}
void setup(){
// Setup logging
Serial.begin(115200);
AudioToolsLogger.begin(Serial, AudioToolsLogLevel::Info);
// start on core 0
writeTask.begin(doWrite);
}
// The loop runs on core 1: We read back the data
void loop(){
int16_t data[512];
uint64_t start = micros();
buffer.readArray(data, 512);
// process (verify) data
int error=0;
for (int j=0;j<512;j++){
if(data[j]!=j){
error++;
}
}
// write result
Serial.print("error: ");
Serial.print(error);
Serial.print(" runtime: ");
Serial.println(micros()-start);
}

View File

@@ -0,0 +1,86 @@
/**
* @file base-adc-average-mono-serial.ino
* @brief Attempts down sampling with binning of a mono audio signal by AVG_LEN
* @author Urs Utzinger
* @copyright GPLv3
**/
#include "Arduino.h"
#include "AudioTools.h"
// On board analog to digital converter
AnalogAudioStream analog_in;
// Serial terminal output
CsvOutput<int16_t> serial_out(Serial);
#define BAUD_RATE 500000
#define SAMPLE_RATE 44100
#define BUFFER_SIZE 256
#define AVG_LEN 64
#define BYTES_PER_SAMPLE sizeof(int16_t)
// buffer to read samples and store the average samples
int16_t buffer[BUFFER_SIZE];
void setup() {
delay(3000); // wait for serial to become available
// Serial Interface
Serial.begin(BAUD_RATE);
// Include logging to serial
AudioToolsLogger.begin(Serial, AudioToolsLogLevel::Error); // Debug, Warning, Info, Error
// Start ADC input
Serial.println("Starting ADC...");
auto adcConfig = analog_in.defaultConfig(RX_MODE);
adcConfig.sample_rate = SAMPLE_RATE;
adcConfig.channels = 1;
// For ESP32 by Espressif Systems version 3.0.0 and later:
// see examples/README_ESP32.md
// adcConfig.sample_rate = 44100;
// adcConfig.adc_bit_width = 12;
// adcConfig.adc_calibration_active = true;
// adcConfig.is_auto_center_read = false;
// adcConfig.adc_attenuation = ADC_ATTEN_DB_12;
// adcConfig.channels = 1;
// adcConfig.adc_channels[0] = ADC_CHANNEL_4;
analog_in.begin(adcConfig);
// Start Serial Output CSV
Serial.println("Starting Serial Out...");
auto csvConfig = serial_out.defaultConfig();
csvConfig.sample_rate = SAMPLE_RATE/AVG_LEN;
csvConfig.channels = 1;
csvConfig.bits_per_sample = 16;
serial_out.begin(csvConfig);
}
void loop() {
// Read the values from the ADC buffer to local buffer
size_t bytes_read = analog_in.readBytes((uint8_t*) buffer, BUFFER_SIZE * BYTES_PER_SAMPLE); // read byte stream and cast to destination type
size_t samples_read = bytes_read/BYTES_PER_SAMPLE;
size_t avg_samples = samples_read/AVG_LEN;
// Average the samples over AVG_LEN
int32_t sum; // register to hold summed values
int16_t *sample = (int16_t*) buffer; // sample pointer (input)
int16_t *avg = (int16_t*) buffer; // result pointer (output)
// each time we access a sample we increment sample pointer
for(uint16_t j=0; j<avg_samples; j++){
sum = *sample++; // initialize sum
for (uint16_t i=1; i<AVG_LEN; i++){
sum += *sample++; // sum the samples
}
// compute average and store in output buffer
*avg++ = (int16_t) (sum/AVG_LEN);
}
serial_out.write((uint8_t*)buffer, avg_samples*BYTES_PER_SAMPLE); // stream to output as byte type
}

View File

@@ -0,0 +1,60 @@
# ESP32 Analog to Digital Conversion Throughput using Continuous ADC API
Data is reported in bytes per second when using a single ADC unit and two A/D channels.
When each channel is measured with 4,000 samples per second the ADC is running at 8,000 samples per second as it multiplexes between the two channels.
The maximum sampling frequency depends on the ESP32 model.
The older ESP32 models can convert up to 2 Million samples per second, however there is discrepancy between the expected and effective throughput of about 20%.
The library creates int16_t datatype which is 2 bytes per sample.
## Adafruit Feather ESP32-S3 2MB PSRAM
```
SPS : expected, measured
150: error, sample rate eff: 300, range: 611 to 83,333
306: 1,224, 1,000
4,000: 16,000, 16,000
8,000: 32,000, 32,000
11,025: 44,100, 44,000
16,000: 64,000, 64,000
20,000: 80,000, 80,000
22,050: 88,200, 89,000
40,000: 160,000, 161,000
44,100: error, sample rate eff: 88,200, range: 611 to 83,333
```
## Sparkfun ESP32 WROOM Plus C
```
Data: bytes per second, single unit, two channels
SPS/CH expected, measured % of expected
5000: error, sample rate eff: 10000, range: 20000 to 2000000
10000: 40,000, 32,000
22050: 88,200, 72,000
44100: 176,400, 144,000
88200: 352,800, 157,000
500000: 2,000,000, 1,635,000
1000000: 4,000,000, 3,271,000
```
## DOIT ESP32 DEVKIT V1
```
Data: bytes per second, single unit, two channels
SPS : expected, measured 80% of expected
5000: error, sample rate: 5000, range: 10000 to 1000000
10000: 40,000, 32,000
20000: 80,000, 64,000
22050: 88,200, 72,000
44100: 176,400, 144,000
48000: 192,000, 156,000
88200: 352,800, 288,000
96000: 384,000, 313,000
176400: 705,600, 576,000
192200: 768,800, 628,000
352800: 1,411,200, 1,153,000
384000: 1,536,000, 1,256,000
500000: 2,000,000, 1,635,000
1000000: 4,000,000, 3,271,000
1500000: error, sample rate: 1500000, range: 10000 to 1000000
```

View File

@@ -0,0 +1,53 @@
/**
* Internal ADC: It depdens pretty much on our processor & arduino version if and how
* this is supported.
*/
#include "Arduino.h"
#include "AudioTools.h"
// On board analog to digital converter
AnalogAudioStream analog_in;
// Measure throughput
MeasuringStream measure(1000, &Serial);
// Copy input to output
StreamCopy copier(measure, analog_in);
void setup() {
delay(3000); // wait for serial to become available
// Serial Interface
Serial.begin(115200);
// Include logging to serial
AudioToolsLogger.begin(Serial, AudioToolsLogLevel::Info); //Warning, Info, Error, Debug
// Configure ADC input
auto adcConfig = analog_in.defaultConfig(RX_MODE);
// For ESP32 by Espressif Systems version 3.0.0 and later
// see examples/README_ESP32.md
// adcConfig.sample_rate = 22050;
// adcConfig.adc_bit_width = 12;
// adcConfig.adc_calibration_active = true;
// adcConfig.is_auto_center_read = false;
// adcConfig.adc_attenuation = ADC_ATTEN_DB_12;
// adcConfig.channels = 2;
// adcConfig.adc_channels[0] = ADC_CHANNEL_4;
// adcConfig.adc_channels[1] = ADC_CHANNEL_5;
adcConfig.sample_rate = 44100; // per channel
Serial.println("Starting ADC...");
analog_in.begin(adcConfig);
// Start Measurements
AudioToolsLogger.begin(Serial, AudioToolsLogLevel::Warning); //Warning, Debug, Info, Error
Serial.println("Starting through put measurement...");
}
void loop() {
copier.copy();
}

View File

@@ -0,0 +1,25 @@
# Stream Analog input to Serial
We can read an analog signal from a microphone and and write it out to Serial so that we can check the result in the __Arduino Serial Plotter__. To test the functionality I am using a MCP6022 microphone module.
![MCP6022](https://pschatzmann.github.io/Resources/img/mcp6022.jpeg)
![MCP6022](https://pschatzmann.github.io/Resources/img/mcp6022-1.jpeg)
The MCP6022 is a anlog microphone which operates at 3.3 V
We sample the sound signal with the help of the ESP32 I2S ADC input functionality.
### Pins:
| MCP6022 | ESP32
|---------|---------------
| VCC | 3.3
| GND | GND
| OUT | GPIO34
## Serial Plotter
![Serial](https://pschatzmann.github.io/Resources/img/serial_plotter.png)

View File

@@ -0,0 +1,62 @@
/**
* @file adc-serial.ino
* @author Phil Schatzmann
* @brief see https://github.com/pschatzmann/arduino-audio-tools/blob/main/examples/adc-serial/README.md
*
* @author Phil Schatzmann
* @copyright GPLv3
* #TODO retest is outstanding
*/
#include "Arduino.h"
#include "AudioTools.h"
/**
* @brief We use a mcp6022 analog microphone on GPIO34 and write it to Serial
*/
AnalogAudioStream adc;
const int32_t max_buffer_len = 1024;
uint8_t buffer[max_buffer_len];
// The data has a center of around 26427, so we we need to shift it down to bring the center to 0
ConverterScaler<int16_t> scaler(1.0, -26427, 32700 );
// Arduino Setup
void setup(void) {
delay(3000); // wait for serial to become available
Serial.begin(115200);
// Include logging to serial
AudioToolsLogger.begin(Serial, AudioToolsLogLevel::Info); //Warning, Info, Error, Debug
Serial.println("starting ADC...");
auto adcConfig = adc.defaultConfig(RX_MODE);
// For ESP32 by Espressif Systems version 3.0.0 and later:
// see examples/README_ESP32.md
// adcConfig.sample_rate = 44100;
// adcConfig.adc_bit_width = 12;
// adcConfig.adc_calibration_active = true;
// adcConfig.is_auto_center_read = false;
// adcConfig.adc_attenuation = ADC_ATTEN_DB_12;
// adcConfig.channels = 2;
// adcConfig.adc_channels[0] = ADC_CHANNEL_4;
// adcConfig.adc_channels[1] = ADC_CHANNEL_5;
adc.begin(adcConfig);
}
// Arduino loop - repeated processing
void loop() {
size_t len = adc.readBytes(buffer, max_buffer_len);
// move center to 0 and scale the values
scaler.convert(buffer, len);
int16_t *sample = (int16_t*) buffer;
int size = len / 4;
for (int j=0; j<size; j++){
Serial.print(*sample++);
Serial.print(", ");
Serial.println(*sample++);
}
}

View File

@@ -0,0 +1,37 @@
/**
* @file file_raw-serial.ino
* @author Phil Schatzmann
* @brief see https://github.com/pschatzmann/arduino-audio-tools/blob/main/examples/file_raw-serial/README.md
*
* @author Phil Schatzmann
* @copyright GPLv3
*/
#include <Arduino.h>
#include <SPI.h>
#include <SD.h>
File sound_file;
const char* file_name = "/audio.raw";
const int sd_ss_pin = 5;
const int32_t max_buffer_len = 512;
int32_t buffer[max_buffer_len][2];
// Arduino Setup
void setup(void) {
Serial.begin(115200);
// Setup SD and open file
SD.begin(sd_ss_pin);
sound_file = SD.open(file_name, FILE_READ);
}
// Arduino loop - repeated processing
void loop() {
size_t len = sound_file.read((uint8_t*)buffer, max_buffer_len * sizeof(int16_t) * 2 );
for (size_t j=0;j<len;j++){
Serial.print(buffer[j][0]);
Serial.print(", ");
Serial.println(buffer[j][1]);
}
}