snapshot
This commit is contained in:
@@ -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
|
||||
@@ -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);
|
||||
}
|
||||
@@ -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
|
||||
}
|
||||
@@ -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
|
||||
```
|
||||
@@ -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();
|
||||
}
|
||||
@@ -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.
|
||||
|
||||

|
||||

|
||||
|
||||
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
|
||||
|
||||

|
||||
|
||||
|
||||
|
||||
@@ -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++);
|
||||
}
|
||||
}
|
||||
@@ -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]);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user