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 @@
# Stream Examples
Examples that show how to use the different audio classes

View File

@@ -0,0 +1,46 @@
# Stream Analog Input to I2S
## General Description:
In this sketch we get the data from via the ESP32 I2S ADC and send it to I2S
Since the ADC via I2S is using the i2s port 0, we use port 1 for the output.
### Analog Input:
| ADC | ESP32
| --------| ---------------
| VCC | 3.3V
| GND | GND
| OUT | GPIO34
For the input I was using a MCP6022 Microphone Sensor.
Plaese note that the signal that we receive from the ADC needs to be adjusted so that it is oscillating around 0.
![MCP6022](https://pschatzmann.github.io/Resources/img/mcp6022.jpeg)
### External DAC:
For my tests I am using the 24-bit PCM5102 PCM5102A Stereo DAC Digital-to-analog Converter PLL Voice Module pHAT
I am just using the default pins defined by the framework. However I could change them with the help of the config object. The mute pin can be defined in the constructor of the I2SStream - by not defining anything we use the default which is GPIO23
DAC | ESP32
-----|----------------
VCC | 5V
GND | GND
BCK | BCK (GPIO14)
DIN | OUT (GPIO22)
LCK | WS (GPIO15)
FMT | GND
XMT | 3V (or another GPIO PIN which is set to high)
- DMP - De-emphasis control for 44.1kHz sampling rate(1): Off (Low) / On (High)
- FLT - Filter select : Normal latency (Low) / Low latency (High)
- SCL - System clock input (probably SCL on your board).
- FMT - Audio format selection : I2S (Low) / Left justified (High)
- XMT - Soft mute control(1): Soft mute (Low) / soft un-mute (High)
![DAC](https://pschatzmann.github.io/Resources/img/dac.jpeg)

View File

@@ -0,0 +1,37 @@
/**
* @file streams-analog-i2s.ino
* @author Phil Schatzmann
* @brief see https://github.com/pschatzmann/arduino-audio-tools/blob/main/examples/examples-stream/streams-adc-i2s/README.md
*
* @author Phil Schatzmann
* @copyright GPLv3
*/
#include "AudioTools.h"
AudioInfo info(44100, 2, 16);
AnalogAudioStream in;
I2SStream out;
StreamCopy copier(out, in); // copy in to out
// Arduino Setup
void setup(void) {
Serial.begin(115200);
AudioToolsLogger.begin(Serial, AudioToolsLogLevel::Info);
// RX automatically uses port 0 with pin GPIO34
auto cfgRx = in.defaultConfig(RX_MODE);
cfgRx.copyFrom(info);
in.begin(cfgRx);
// TX on I2S_NUM_1
auto cfgTx = out.defaultConfig(TX_MODE);
cfgTx.port_no = 1;
cfgTx.copyFrom(info);
out.begin(cfgTx);
}
// Arduino loop - copy data
void loop() {
copier.copy();
}

View File

@@ -0,0 +1,24 @@
# Stream Analog Input to Serial Output
## General Description:
We just send the audio data that we receive from microphone the Serial output, so that we can monitor it in the Serial Plotter.
Here is the result on the Arduino Serial Plotter:
![serial-plotter](https://pschatzmann.github.io/Resources/img/serial-plotter-sine.png)
### Analog Input:
| ADC | ESP32 | UNO R4
| --------| --------|-------
| VCC | 3.3V | 3.3V
| GND | GND | GND
| OUT | GPIO34 | A0
For the input I was using a MCP6022 Microphone Sensor.
Plaese note that the signal that we receive from the ADC might need to be adjusted so that it is oscillating around 0.
![MCP6022](https://pschatzmann.github.io/Resources/img/mcp6022.jpeg)

View File

@@ -0,0 +1,36 @@
/**
* @file streams-analog-serial.ino
* @author Phil Schatzmann
* @brief see https://github.com/pschatzmann/arduino-audio-tools/blob/main/examples/examples-stream/streams-adc-serial/README.md
* @copyright GPLv3
* #TODO retest is outstanding
*/
#include "Arduino.h"
#include "AudioTools.h"
AnalogAudioStream in;
AudioInfo info(8000, 1, 16);
CsvOutput<int16_t> out(Serial); // ASCII output stream
StreamCopy copier(out, in);
// Arduino Setup
void setup(void) {
Serial.begin(115200);
AudioToolsLogger.begin(Serial, AudioToolsLogLevel::Warning);
auto cfgRx = in.defaultConfig(RX_MODE);
// cfgRx.start_pin = A1; // optinally define pin
// cfgRx.is_auto_center_read = true;
cfgRx.copyFrom(info);
in.begin(cfgRx);
// open output
out.begin(info);
}
// Arduino loop - copy data
void loop() {
copier.copy(); //
}

View File

@@ -0,0 +1,66 @@
/**
* @file streams-adsr-i2s.ino
* @author Phil Schatzmann
* @brief Simple example for AudioEffects with ADSR
* @copyright GPLv3
*
*/
#include "AudioTools.h"
//#include "AudioTools/AudioLibs/AudioBoardStream.h"
I2SStream i2s; //AudioBoardStream
SineWaveGenerator<int16_t> sine;
GeneratedSoundStream<int16_t> stream(sine);
AudioEffectStream effects(stream);
ADSRGain adsr(0.0001,0.0001, 0.9 , 0.0002);
StreamCopy copier(i2s, effects);
uint64_t time_on;
uint64_t time_off;
void actionKeyOn(float note){
Serial.println("KeyOn");
sine.setFrequency(note);
adsr.keyOn();
}
void actionKeyOff(){
Serial.println("KeyOff");
adsr.keyOff();
}
void setup() {
Serial.begin(115200);
AudioLogger::instance().begin(Serial,AudioLogger::Warning);
// setup effects
effects.addEffect(adsr);
// Setup output
auto cfg = i2s.defaultConfig(TX_MODE);
//i2s.setVolume(1.0);
i2s.begin(cfg);
// Setup sound generation based on AudioKit settins
sine.begin(cfg, 0);
stream.begin(cfg);
effects.begin(cfg);
}
// copy the data
void loop() {
copier.copy();
uint64_t time = millis();
if (time>time_off){
actionKeyOff();
time_on = time+1000;
time_off = time+2000;
}
if (time>time_on){
actionKeyOn(N_C3);
time_on = time+2000;
time_off = time+1000;
}
}

View File

@@ -0,0 +1,39 @@
# I2S Analog Output Test
This is a simple basic test for the ESP32 __analog output__ using I2S.
We just send a generated sine wave and expect to hear a clean signal.
Please note the log level should be set to Warning so that there is no disturbing output!
Make sure that you do not use any noisy power supply!
### Output Device: Earphones
You can also use some simple earphones
![DAC](https://pschatzmann.github.io/Resources/img/earphones.jpg)
On the ESP32 the stereo output is on the Pins GPIO25 and GPIO26
| Earphone| ESP32 | UNO R4 |
| --------| -----------------|---------|
| Left | GPIO25 | A0 |
| Righ | GPIO25 | GND |
| GND | GND | GND |
### Output Device: Piezo Electric Element
To test the output I am using a piezo electric element
![DAC](https://pschatzmann.github.io/Resources/img/piezo.jpeg)
On the ESP32 the stereo output is on the Pins GPIO25 and GPIO26
| PIEZO | ESP32 | UNO R4 |
| --------| -----------------|---------|
| + | GPIO25 | A0 |
| - | GND | GND |

View File

@@ -0,0 +1,36 @@
/**
* @file streams-generator-analog.ino
* @author Phil Schatzmann
* @brief see https://github.com/pschatzmann/arduino-audio-tools/blob/main/examples/examples-stream/streams-generator-analog/README.md
* @author Phil Schatzmann
* @copyright GPLv3
**/
#include "AudioTools.h"
AudioInfo info(8000, 1, 16);
SineWaveGenerator<int16_t> sineWave(32000); // subclass of SoundGenerator with max amplitude of 32000
GeneratedSoundStream<int16_t> sound(sineWave); // Stream generated from sine wave
AnalogAudioStream out;
StreamCopy copier(out, sound); // copies sound into i2s
// Arduino Setup
void setup(void) {
// Open Serial
Serial.begin(115200);
AudioToolsLogger.begin(Serial, AudioToolsLogLevel::Info);
// start the analog output
auto config = out.defaultConfig(TX_MODE);
config.copyFrom(info);
out.begin(config);
// Setup sine wave
sineWave.begin(info, N_B4);
Serial.println("started...");
}
// Arduino loop - copy sound to out
void loop() {
copier.copy();
}

View File

@@ -0,0 +1,34 @@
/**
* @file streams-generator-bin-serial.ino
* @author Urs Utzinger
* @brief Reduce samples by binning; which is summing consecutive samples and optionally dividing by the number of samples summed.
* @copyright GPLv3
**/
#include "AudioTools.h"
AudioInfo info(44100, 2, 16);
SineWaveGenerator<int16_t> sineWave(16000); // subclass of SoundGenerator with max amplitude of 32000
GeneratedSoundStream<int16_t> sound(sineWave); // stream generated from sine wave
Bin binner(64, 2, true, 16); // configure binning with binsize, channels, enable averaging, bits per channel
ConverterStream<int16_t> binning(sound, binner); // pipe the sound to the binner
CsvOutput<int16_t> out(Serial); // serial output
StreamCopy copier(out, binning); // stream the binner output to serial port
// Arduino Setup
void setup(void) {
// Open Serial
Serial.begin(115200);
AudioToolsLogger.begin(Serial, AudioToolsLogLevel::Warning);
// Define CSV Output
out.begin(info);
// Setup sine wave
sineWave.begin(info, N_B4);
}
// Arduino loop - copy sound to out with conversion
void loop() {
copier.copy();
}

View File

@@ -0,0 +1,46 @@
/**
* @file streams-generator-formatconverter-i2s.ino
* @brief Demonstrating FormatConverterStream: we can change the sample_rate, channels and bits_per_sample.
* This demo is using the converter on the input side. You can also use it on the output side as well, which
* consumes less memory!
* @author Phil Schatzmann
* @copyright GPLv3
*/
#include "AudioTools.h"
#include "AudioTools/AudioLibs/AudioBoardStream.h"
AudioInfo from(32000,2,32);
AudioInfo to(16000,1,16);
SineWaveGenerator<int32_t> sineWave;
GeneratedSoundStream<int32_t> sound(sineWave); // Stream generated from sine wave
I2SStream out; // or any other e.g. AudioBoardStream, CsvOutput<int16_t> out(Serial);
FormatConverterStream converter(sound); // or use converter(out)
StreamCopy copier(out, converter); // copier(converter, sound);
// Arduino Setup
void setup(void) {
// Open Serial
Serial.begin(115200);
AudioToolsLogger.begin(Serial, AudioToolsLogLevel::Warning);
// Setup Input
sineWave.begin(from, N_B4);
sound.begin(from);
// Define Converter
converter.begin(from, to);
// Start Output
Serial.println("starting I2S...");
auto config = out.defaultConfig(TX_MODE);
config.copyFrom(to);
out.begin(config);
Serial.println("started...");
}
// Arduino loop - copy sound to out
void loop() {
copier.copy();
}

View File

@@ -0,0 +1,32 @@
# I2S Digital Output Test
This is a simple basic test for the I2S output to an external DAC
We just send a generated sine wave and expect to hear a clean signal.
Please note the log level should be set so that there is no disturbing output!
### External DAC:
For my tests I am using the 24-bit PCM5102 PCM5102A Stereo DAC Digital-to-analog Converter PLL Voice Module pHAT
![DAC](https://pschatzmann.github.io/Resources/img/dac.jpeg)
I am just using the default pins defined by the framework. However I could change them with the help of the config object. The mute pin can be defined in the constructor of the I2SStream - by not defining anything we use the default which is GPIO23
DAC | ESP32
-----|----------------
VCC | 5V
GND | GND
BCK | BCK (GPIO14)
DIN | OUT (GPIO22)
LCK | BCK (GPIO15)
FMT | GND
XMT | 3V (or another GPIO PIN which is set to high)
- DMP - De-emphasis control for 44.1kHz sampling rate(1): Off (Low) / On (High)
- FLT - Filter select : Normal latency (Low) / Low latency (High)
- SCL - System clock input (probably SCL on your board).
- FMT - Audio format selection : I2S (Low) / Left justified (High)
- XMT - Soft mute control(1): Soft mute (Low) / soft un-mute (High)

View File

@@ -0,0 +1,37 @@
/**
* @file streams-generator-i2s.ino
* @author Phil Schatzmann
* @brief see https://github.com/pschatzmann/arduino-audio-tools/blob/main/examples/examples-stream/streams-generator-i2s/README.md
* @copyright GPLv3
*/
#include "AudioTools.h"
AudioInfo info(44100, 2, 16);
SineWaveGenerator<int16_t> sineWave(32000); // subclass of SoundGenerator with max amplitude of 32000
GeneratedSoundStream<int16_t> sound(sineWave); // Stream generated from sine wave
I2SStream out;
StreamCopy copier(out, sound); // copies sound into i2s
// Arduino Setup
void setup(void) {
// Open Serial
Serial.begin(115200);
while(!Serial);
AudioToolsLogger.begin(Serial, AudioToolsLogLevel::Info);
// start I2S
Serial.println("starting I2S...");
auto config = out.defaultConfig(TX_MODE);
config.copyFrom(info);
out.begin(config);
// Setup sine wave
sineWave.begin(info, N_B4);
Serial.println("started...");
}
// Arduino loop - copy sound to out
void loop() {
copier.copy();
}

View File

@@ -0,0 +1,50 @@
/**
* @file streams-generator-merge-pwm.ino
* @brief merge 2 mono signals into 1 stereo signal
* @author Phil Schatzmann
* @copyright GPLv3
*/
#include "AudioTools.h"
AudioInfo info_in(8000, 1, 16);
AudioInfo info_out(8000, 2, 16);
SineWaveGenerator<int16_t> sineWave1(32000); // subclass of SoundGenerator with max amplitude of 32000
GeneratedSoundStream<int16_t> sound1(sineWave1); // Stream generated from sine wave
SineWaveGenerator<int16_t> sineWave2(32000); // subclass of SoundGenerator with max amplitude of 32000
GeneratedSoundStream<int16_t> sound2(sineWave2); // Stream generated from sine wave
InputMerge<int16_t> imerge;
PWMAudioOutput pwm;
StreamCopy copier(pwm, imerge); // copy in to out
void setup() {
Serial.begin(115200);
AudioToolsLogger.begin(Serial, AudioToolsLogLevel::Warning);
// setup sine 2 mono sine waves
sineWave1.begin(info_in, N_B4);
sineWave2.begin(info_in, N_B5);
// merge input to stereo
imerge.add(sound1, 1);
imerge.add(sound2, 1);
imerge.begin(info_out);
// setup PWM output
auto config = pwm.defaultConfig();
config.copyFrom(info_out);
//config.resolution = 8; // must be between 8 and 11 -> drives pwm frequency (8 is default)
// alternative 1
//config.start_pin = 3;
// alternative 2
//int pins[] = {3};
// alternative 3
Pins pins = {3, 4};
config.setPins(pins);
pwm.begin(config);
}
void loop(){
copier.copy();
}

View File

@@ -0,0 +1,28 @@
# PWM Output Test
This is a simple basic test for the PWM output.
We just send a generated sine wave to some defined pins and expect to hear some audio signal.
### Output Device: Piezo Electric Element
To test the output I am using a piezo electric element
![DAC](https://pschatzmann.github.io/Resources/img/piezo.jpeg)
You can also use some simple earphones
![DAC](https://pschatzmann.github.io/Resources/img/earphones.jpg)
It should also be possible to connect a headphone to the output pins...
The pins depend on the Processor:
| PIEZO | ESP32 | RPI Pico | MBED | UNO R4 |
| --------| -------------|---------------|--------------|-------------|
| + | GPIO4/GPIO5 | GPIO2/GPIO3 | GPIO2/GPIO3 | GPIO2/GPIO4 |
| - | GND | GND | GND | GND |

View File

@@ -0,0 +1,41 @@
/**
* @file streams-generator-pwm.ino
* @author Phil Schatzmann
* @brief see https://github.com/pschatzmann/arduino-audio-tools/blob/main/examples/examples-stream/streams-generator-pwm/README.md
* @author Phil Schatzmann
* @copyright GPLv3
*/
#include "AudioTools.h"
AudioInfo info(8000, 1, 16);
SineWaveGenerator<int16_t> sineWave(32000); // subclass of SoundGenerator with max amplitude of 32000
GeneratedSoundStream<int16_t> sound(sineWave); // Stream generated from sine wave
PWMAudioOutput pwm;
StreamCopy copier(pwm, sound); // copy in to out
void setup() {
Serial.begin(115200);
AudioToolsLogger.begin(Serial, AudioToolsLogLevel::Warning);
// setup sine wave
sineWave.begin(info, N_B4);
// setup PWM output
auto config = pwm.defaultConfig();
config.copyFrom(info);
//config.resolution = 8; // must be between 8 and 11 -> drives pwm frequency (8 is default)
// alternative 1
//config.start_pin = 3;
// alternative 2
//int pins[] = {3};
// alternative 3
//Pins pins = {3};
//config.setPins(pins);
pwm.begin(config);
}
void loop(){
copier.copy();
}

View File

@@ -0,0 +1,42 @@
/**
* @file streams-generator-r2r.ino
* @author Phil Schatzmann
* @brief Example for a self built resistor ladder DAC
* @copyright GPLv3
*/
#include "AudioTools.h"
#include "AudioTools/AudioLibs/R2ROutput.h"
AudioInfo info(8000, 1, 16);
SineWaveGenerator<int16_t> sineWave; // subclass of SoundGenerator with max amplitude of 32000
GeneratedSoundStream<int16_t> sound(sineWave); // Stream generated from sine wave
R2ROutput out;
StreamCopy copier(out, sound); // copies sound into i2s
const int pins1[] = {12,14,27,26,25,33,32, 35}; // ESP32 pins
// Arduino Setup
void setup(void) {
// Open Serial
Serial.begin(115200);
while(!Serial);
AudioToolsLogger.begin(Serial, AudioToolsLogLevel::Info);
// start I2S
Serial.println("starting R2R...");
auto config = out.defaultConfig();
config.copyFrom(info);
// 8 pins for 8 bit DAC for channel 1
config.channel1_pins = pins1;
// channel 2 would be config.channel2_pins
out.begin(config);
// Setup sine wave
sineWave.begin(info, N_B4);
Serial.println("started...");
}
// Arduino loop - copy sound to out
void loop() {
copier.copy();
}

View File

@@ -0,0 +1,5 @@
# Serial Output Test as CSV
This is a simple basic test for any processor type
We just send a generated sine wave to the Serial Output

View File

@@ -0,0 +1,34 @@
/**
* @file streams-generator-serial.ino
* @author Phil Schatzmann
* @brief see https://github.com/pschatzmann/arduino-audio-tools/blob/main/examples/examples-stream/streams-generator-serial/README.md
* @copyright GPLv3
**/
#include "AudioTools.h"
AudioInfo audio_info(44100, 2, 16);
SineWaveGenerator<int16_t> sineWave(32000); // subclass of SoundGenerator with max amplitude of 32000
GeneratedSoundStream<int16_t> sound(sineWave); // Stream generated from sine wave
CsvOutput<int16_t> out(Serial);
StreamCopy copier(out, sound); // copies sound to out
// Arduino Setup
void setup(void) {
// Open Serial
Serial.begin(115200);
//AudioToolsLogger.begin(Serial, AudioToolsLogLevel::Warning);
// Define CSV Output
out.begin(audio_info);
// Setup sine wave
sineWave.begin(audio_info, N_B4);
Serial.println("started...");
}
// Arduino loop - copy sound to out
void loop() {
copier.copy();
}

View File

@@ -0,0 +1,4 @@
# Test Output to SPDIF
We use the sine generator to generate a test tone and output it as SPDIF dignals to the indicated pin.
If you encounter some quality issues you can increase the DEFAULT_BUFFER_SIZE (e.g. to 2048) and I2S_BUFFER_SIZE/I2S_BUFFER_COUNT

View File

@@ -0,0 +1,42 @@
/**
* @file streams-generator-i2s.ino
* @author Phil Schatzmann
* @brief see https://github.com/pschatzmann/arduino-audio-tools/blob/main/examples/examples-stream/streams-generator-spdif/README.md
* @author Phil Schatzmann
* @copyright GPLv3
*/
#include "AudioTools.h"
#include "AudioTools/AudioLibs/SPDIFOutput.h"
AudioInfo info(44100, 2, 16);
SineWaveGenerator<int16_t> sineWave(32000); // subclass of SoundGenerator with max amplitude of 32000
GeneratedSoundStream<int16_t> sound(sineWave); // Stream generated from sine wave
SPDIFOutput out;
StreamCopy copier(out, sound, 2048); // copies sound into i2s
// Arduino Setup
void setup(void) {
// Open Serial
Serial.begin(115200);
AudioToolsLogger.begin(Serial, AudioToolsLogLevel::Info);
// start I2S
Serial.println("starting SPDIF...");
auto config = out.defaultConfig();
config.copyFrom(info);
config.pin_data = 23;
config.buffer_size = 384;
config.buffer_count = 8;
out.begin(config);
// Setup sine wave
sineWave.begin(info, N_B4);
Serial.println("started...");
}
// Arduino loop - copy sound to out
void loop() {
copier.copy();
}

View File

@@ -0,0 +1,34 @@
/**
* @file streams-generator-serial.ino
* @author Phil Schatzmann
* @brief Example how to limit the output with a timed stream: generate audio for 1 second
* @copyright GPLv3
**/
#include "AudioTools.h"
AudioInfo info(8000, 1, 16);
SineWaveGenerator<int16_t> sineWave(32000);
GeneratedSoundStream<int16_t> sound(sineWave);
TimedStream timed(sound, 0, 1);
CsvOutput<int16_t> out(Serial);
StreamCopy copier(out, timed); // copies sound to out
// Arduino Setup
void setup(void) {
// Open Serial
Serial.begin(115200);
AudioToolsLogger.begin(Serial, AudioToolsLogLevel::Info);
sineWave.begin(info, N_B4);
timed.begin(info);
out.begin(info);
}
// Arduino loop - copy sound to out
void loop() {
copier.copy();
}

View File

@@ -0,0 +1,39 @@
/**
* @file streams-generator-volume.ino
* @author Phil Schatzmann
* @brief Determines the output volume (=amplitude)
* @copyright GPLv3
*/
#include "AudioTools.h"
AudioInfo info(44100, 2, 16);
SineWaveGenerator<int16_t> sineWave(32000); // subclass of SoundGenerator with max amplitude of 32000
GeneratedSoundStream<int16_t> sound(sineWave); // Stream generated from sine wave
VolumeMeter out;
StreamCopy copier(out, sound, 1024*2); // copies sound into VolumeMeter
// Arduino Setup
void setup(void) {
// Open Serial
Serial.begin(115200);
while(!Serial);
AudioToolsLogger.begin(Serial, AudioToolsLogLevel::Warning);
// start Volume Meter
out.begin(info);
// Setup sine wave
sineWave.begin(info, N_B4);
Serial.println("started...");
}
// Arduino loop - copy sound to out
void loop() {
copier.copy();
Serial.print(out.volume()); // overall
Serial.print(" ");
Serial.print(out.volume(0)); // left
Serial.print(" ");
Serial.println(out.volume(1)); // right
}

View File

@@ -0,0 +1,51 @@
/**
* @file streams-generator-wm8990.ino
* @author Phil Schatzmann
* @brief Test sketch for wm8990
* @copyright GPLv3
*/
#include "AudioTools.h"
#include "AudioTools/AudioLibs/WM8960Stream.h"
AudioInfo info(44100, 2, 16);
SineWaveGenerator<int16_t> sineWave(32000); // subclass of SoundGenerator with max amplitude of 32000
GeneratedSoundStream<int16_t> sound(sineWave); // Stream generated from sine wave
WM8960Stream out;
StreamCopy copier(out, sound); // copies sound into i2s
// Arduino Setup
void setup(void) {
// Open Serial
Serial.begin(115200);
while(!Serial);
AudioToolsLogger.begin(Serial, AudioToolsLogLevel::Warning);
// setup wire on pins 19 and 21
Wire.begin(19, 21);
Wire.setClock(10000);
// start I2S
Serial.println("starting I2S...");
auto config = out.defaultConfig(TX_MODE);
config.copyFrom(info);
config.wire = &Wire;
// use default i2s pins
//config.pin_bck = 14;
//config.pin_ws = 15;
//config.pin_data = 22;
if (!out.begin(config)){
stop();
}
// Setup sine wave
sineWave.begin(info, N_B4);
Serial.println("started...");
}
// Arduino loop - copy sound to out
void loop() {
copier.copy();
}

View File

@@ -0,0 +1,25 @@
# I2S Analog Output Test
This is a simple basic test for the ESP32 __analog output__ using I2S.
We just send a generated sine wave and expect to hear a clean signal.
Please note the log level should be set so that there is no disturbing output!
### Output Device: Piezo Electric Element
To test the output I am using a piezo electric element
![DAC](https://pschatzmann.github.io/Resources/img/piezo.jpeg)
It should also be possible to connect a headphone to the output pins...
On the ESP32 the output is on the Pins GPIO26 and GPIO27
| PIEZO | ESP32
| --------| ---------------
| + | GPIO25 / GPIO26
| - | GND

View File

@@ -0,0 +1,41 @@
/**
* @file streams-generator_fromarray-analog.ino
* @author Phil Schatzmann
* @brief Example for GeneratorFromArray
* @version 0.1
* @date 2022-03-22
*
* @copyright Copyright (c) 2022
*
*/
#include "AudioTools.h"
#include "AudioTools/AudioLibs/AudioBoardStream.h"
AudioInfo info(44100, 1, 16);
int16_t sine_array[] = {0, 4560, 9031, 13327, 17363, 21062, 24350, 27165, 29450, 31163, 32269, 32747, 32587, 31793, 30381, 28377, 25820, 22761, 19259, 15383, 11206, 6812, 2285, -2285, -6812, -11206, -15383, -19259, -22761, -25820, -28377, -30381, -31793, -32587, -32747, -32269, -31163, -29450, -27165, -24350, -21062, -17363, -13327, -9031, -4560 };
GeneratorFromArray<int16_t> sineWave(sine_array,0,false);
GeneratedSoundStream<int16_t> sound(sineWave); // Stream generated from sine wave
AnalogAudioStream out;
StreamCopy copier(out, sound); // copies sound into i2s
// Arduino Setup
void setup(void) {
// Open Serial
Serial.begin(115200);
AudioToolsLogger.begin(Serial, AudioToolsLogLevel::Warning);
// start I2S
Serial.println("starting I2S...");
auto config = out.defaultConfig(TX_MODE);
config.copyFrom(info);
out.begin(config);
// Setup sine wave
sineWave.begin(info);
Serial.println("started...");
}
// Arduino loop - copy sound to out
void loop() {
copier.copy();
}

View File

@@ -0,0 +1,65 @@
/**
* @file streams-i2s-filter-i2s.ino
* @brief Copy audio from I2S to I2S using an FIR filter
* @author Phil Schatzmann
* @copyright GPLv3
*/
#include "AudioTools.h"
AudioInfo info(44100, 2, 16);
I2SStream in;
I2SStream out;
// copy filtered values
FilteredStream<int16_t, float> filtered(in, info.channels); // Defiles the filter as BaseConverter
StreamCopy copier(out, filtered); // copies sound into i2s
// define FIR filter parameters
float coef[] = { 0.021, 0.096, 0.146, 0.096, 0.021};
// Arduino Setup
void setup(void) {
// Open Serial
Serial.begin(115200);
// change to Warning to improve the quality
AudioToolsLogger.begin(Serial, AudioToolsLogLevel::Info);
// setup filters for all available channels
filtered.setFilter(0, new FIR<float>(coef));
filtered.setFilter(1, new FIR<float>(coef));
// start I2S in
Serial.println("starting I2S...");
auto config_in = in.defaultConfig(RX_MODE);
config_in.copyFrom(info);
config_in.i2s_format = I2S_STD_FORMAT;
config_in.is_master = true;
config_in.port_no = 0;
config_in.pin_ws = 14;
config_in.pin_bck = 15;
config_in.pin_data = 16;
// config_in.fixed_mclk = sample_rate * 256
// config_in.pin_mck = 3
in.begin(config_in);
// start I2S out
auto config_out = out.defaultConfig(TX_MODE);
config_out.copyFrom(info);
config_out.i2s_format = I2S_STD_FORMAT;
config_out.is_master = true;
config_out.port_no = 1;
config_out.pin_ws = 17;
config_out.pin_bck = 18;
config_out.pin_data = 19;
out.begin(config_out);
Serial.println("I2S started...");
}
// Arduino loop - copy sound to out
void loop() {
copier.copy();
}

View File

@@ -0,0 +1,14 @@
# I2S input and I2S Output with separate Ports
We use 2 separate I2S Ports to input data from an I2S device and output the data to another I2S Device:
| In | ESP32 | Out |
|------|-------|------|
| BCK | G14 | - |
| WS | G15 | - |
| DATA | G22 | - |
| - | G18 | BCK |
| - | G19 | WS |
| - | G23 | DATA |
| VIN | VIN | VIN |
| GND | GND | GND |

View File

@@ -0,0 +1,54 @@
/**
* @file streams-i2s-i2s-2.ino
* @brief Copy audio from I2S to I2S: We use 2 different i2s ports!
* @author Phil Schatzmann
* @copyright GPLv3
*/
#include "AudioTools.h"
AudioInfo info(44100, 2, 16);
I2SStream in;
I2SStream out;
StreamCopy copier(out, in); // copies sound into i2s
// Arduino Setup
void setup(void) {
// Open Serial
Serial.begin(115200);
// change to Warning to improve the quality
AudioToolsLogger.begin(Serial, AudioToolsLogLevel::Info);
// start I2S in
Serial.println("starting I2S...");
auto config_in = in.defaultConfig(RX_MODE);
config_in.copyFrom(info);
config_in.i2s_format = I2S_STD_FORMAT;
config_in.is_master = true;
config_in.port_no = 0;
config_in.pin_bck = 14;
config_in.pin_ws = 15;
config_in.pin_data = 22;
// config_in.fixed_mclk = sample_rate * 256
// config_in.pin_mck = 2
in.begin(config_in);
// start I2S out
auto config_out = out.defaultConfig(TX_MODE);
config_out.copyFrom(info);
config_out.i2s_format = I2S_STD_FORMAT;
config_out.is_master = true;
config_out.port_no = 1;
config_out.pin_bck = 18;
config_out.pin_ws = 19;
config_out.pin_data = 23;
out.begin(config_out);
Serial.println("I2S started...");
}
// Arduino loop - copy sound to out
void loop() {
copier.copy();
}

View File

@@ -0,0 +1,12 @@
# I2S input and I2S Output with One Port
We use the same I2S Port to input data from an I2S device and output data to another I2S Device. This means that the WS and BCK pins are shared:
| In | ESP32 | Out |
|------|-------|------|
| WS | G14 | WS |
| BCK | G15 | BCK |
| DATA | G19 | - |
| - | G18 | DATA |
| VIN | VIN | VIN |
| GND | GND | GND |

View File

@@ -0,0 +1,41 @@
/**
* @file streams-i2s-i2s.ino
* @brief Copy audio from I2S to I2S - I2S uses 1 i2s port
* @author Phil Schatzmann
* @copyright GPLv3
*/
#include "AudioTools.h"
AudioInfo info(44100, 2, 16);
I2SStream i2s;
StreamCopy copier(i2s, i2s); // copies sound into i2s
// Arduino Setup
void setup(void) {
// Open Serial
Serial.begin(115200);
// change to Warning to improve the quality
AudioToolsLogger.begin(Serial, AudioToolsLogLevel::Info);
// start I2S in
Serial.println("starting I2S...");
auto config = i2s.defaultConfig(RXTX_MODE);
config.copyFrom(info);
config.i2s_format = I2S_STD_FORMAT;
config.pin_ws = 14;
config.pin_bck = 15;
config.pin_data = 18;
config.pin_data_rx = 19;
//config.fixed_mclk = sample_rate * 256;
// config.pin_mck = 3; // must be 0,1 or 3 - only for ESP_IDF_VERSION_MAJOR >= 4
i2s.begin(config);
Serial.println("I2S started...");
}
// Arduino loop - copy sound to out
void loop() {
copier.copy();
}

View File

@@ -0,0 +1,36 @@
# Stream I2S Input to CSV Output
## General Description:
We implement a I2S source: We stream the sound input which we read in from the I2S interface and displays it on the Arduino Serial Plotter.
We can use any device which provides the sound data via I2S. In this case it is a 'I2S ADC Audio I2S Capture Card Module'
Usually you do not need any master clock, but unfortunatly we need to feed this module with a master clock signal from the ESP32, if
the ESP32 is acting as master.
## Pins
![i2s-adc](https://pschatzmann.github.io/Resources/img/I2S-ADC.jpg)
| i2s-ADC | ESP32
| ---------| ---------------
| MCCLK_IN | RX_0 (GPIO3)
| BICK | BCK (GPIO14)
| DATA | IN (GPIO32)
| RLCLK | WS (GPIO15)
| GND | GND
| MUTE | -
| VCC | VIN 5V
## Additional Comments
I recommend this sketch as a starting point for all I2S input. Just leave the masterclock out, because this is not needed for most input devices.
If it is working with 32 bit you can try to change it to 16bits which most of the time works as well:
- CsvOutput<int16_t> csvOutput(Serial);
- cfg.bits_per_sample = 16;
see streams-12s-serial_16_bit

View File

@@ -0,0 +1,40 @@
/**
* @file streams-i2s-serial.ino
* @author Phil Schatzmann
* @brief see https://github.com/pschatzmann/arduino-audio-tools/blob/main/examples/examples-stream/streams-i2s-serial/README.md
*
* @author Phil Schatzmann
* @copyright GPLv3
*/
#include "AudioTools.h"
AudioInfo info(44100, 2, 32);
I2SStream i2sStream; // Access I2S as stream
CsvOutput<int32_t> csvOutput(Serial);
StreamCopy copier(csvOutput, i2sStream); // copy i2sStream to csvOutput
// Arduino Setup
void setup(void) {
Serial.begin(115200);
AudioToolsLogger.begin(Serial, AudioToolsLogLevel::Info);
auto cfg = i2sStream.defaultConfig(RX_MODE);
cfg.copyFrom(info);
cfg.i2s_format = I2S_STD_FORMAT; // or try with I2S_LSB_FORMAT
cfg.is_master = true;
// this module nees a master clock if the ESP32 is master
cfg.use_apll = false; // try with yes
cfg.pin_mck = 3;
i2sStream.begin(cfg);
// make sure that we have the correct channels set up
csvOutput.begin(info);
}
// Arduino loop - copy data
void loop() {
copier.copy();
}

View File

@@ -0,0 +1,21 @@
# Stream I2S Input to CSV Output
## General Description:
We implement a I2S source: We stream the sound input which we read in from the I2S interface and displays it on the Arduino Serial Plotter.
We use only 16bits!
## Pins
| i2s-device | ESP32
| -----------| ---------------
| BCK | BCK (GPIO14)
| WS | WS (GPIO15)
| DATA | IN (GPIO32)
| GND | GND
| VCC | VIN 5V

View File

@@ -0,0 +1,40 @@
/**
* @file streams-i2s-serial_16bit.ino
* @author Phil Schatzmann
* @brief see https://github.com/pschatzmann/arduino-audio-tools/blob/main/examples/examples-stream/streams-i2s-serial_16bit/README.md
*
* @author Phil Schatzmann
* @copyright GPLv3
*/
#include "AudioTools.h"
AudioInfo info(44100, 2, 16);
I2SStream i2sStream; // Access I2S as stream
CsvOutput<int16_t> csvOutput(Serial);
StreamCopy copier(csvOutput, i2sStream); // copy i2sStream to csvOutput
// Arduino Setup
void setup(void) {
Serial.begin(115200);
AudioToolsLogger.begin(Serial, AudioToolsLogLevel::Info);
auto cfg = i2sStream.defaultConfig(RX_MODE);
cfg.copyFrom(info);
cfg.i2s_format = I2S_STD_FORMAT; // or try with I2S_LSB_FORMAT
cfg.is_master = true;
// this module nees a master clock if the ESP32 is master
cfg.use_apll = false; // try with yes
//cfg.pin_mck = 3;
i2sStream.begin(cfg);
// make sure that we have the correct channels set up
csvOutput.begin(info);
}
// Arduino loop - copy data
void loop() {
copier.copy();
}

View File

@@ -0,0 +1,47 @@
## Micro Speech
The staring point for doing speech recognition on an Arduino based board is TensorFlow Light For Microcontrollers with the example sketch called micro_speech!
I have adapted the MicroSpeech example from TensorFlow Lite to follow the philosophy of this framework. The example uses a Tensorflow model which can recognise the words 'yes' and 'no'. The output stream class is TfLiteAudioOutput. In the example I am using an ESP32 AudioKit board, but you can replace this with any type of processor with a microphone.
Further information can be found in the [Wiki](https://github.com/pschatzmann/arduino-audio-tools/wiki/TensorFlow-Lite---MicroSpeech).
To capture the Audio we use an INMP441 Microphone:
![INMP441](https://pschatzmann.github.io/Resources/img/inmp441.jpeg)
The INMP441 is a high-performance, low power, digital-output, omnidirectional MEMS microphone with a bottom port. The complete INMP441 solution consists of a MEMS sensor, signal conditioning, an analog-to-digital converter, anti-aliasing filters, power management, and an industry-standard 24-bit I²S interface. The I²S interface allows the INMP441 to connect directly to digital processors, such as DSPs and microcontrollers, without the need for an audio codec in the system.
## Pins
| INMP441 | ESP32
| --------| ---------------
| VDD | 3.3
| GND | GND
| SD | IN (GPIO32)
| L/R | GND
| WS | WS (GPIO15)
| SCK | BCK (GPIO14)
- SCK: Serial data clock for I²S interface
- WS: Select serial data words for the I²S interface
- L/R: Left / right channel selection
When set to low, the microphone emits signals on the left channel of the I²S frame.
When the high level is set, the microphone will send signals on the right channel.
- ExSD: Serial data output of the I²S interface
- VCC: input power 1.8V to 3.3V
- GND: Power groundHigh PSR: -75 dBFS.
### Note
The log level has been set to Info to help you to identify any problems. Please change it to AudioLogger::Warning to get the best sound quality!
## Dependencies
You need to install the following libraries:
- https://github.com/pschatzmann/arduino-audio-tools
- https://github.com/pschatzmann/tflite-micro-arduino-examples

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,63 @@
/**
* @file streams-i2s-tf.ino
* @author Phil Schatzmann
* @brief We read audio data from a I2S Microphone and send it to Tensorflow Lite to recognize the words yes and no
* @version 0.1
* @date 2022-04-07
*
* @copyright Copyright (c) 2022
*
*/
#include "AudioTools.h"
#include "AudioTools/AudioLibs/TfLiteAudioStream.h"
#include "model.h" // tensorflow model
I2SStream i2s; // Audio source
TfLiteAudioStream tfl; // Audio sink
const char* kCategoryLabels[4] = {
"silence",
"unknown",
"yes",
"no",
};
StreamCopy copier(tfl, i2s); // copy mic to tfl
int channels = 1;
int samples_per_second = 16000;
void respondToCommand(const char* found_command, uint8_t score,
bool is_new_command) {
if (is_new_command) {
char buffer[80];
sprintf(buffer, "Result: %s, score: %d, is_new: %s", found_command, score,
is_new_command ? "true" : "false");
Serial.println(buffer);
}
}
void setup() {
Serial.begin(115200);
AudioToolsLogger.begin(Serial, AudioToolsLogLevel::Warning);
// setup Audioi2s input
auto cfg = i2s.defaultConfig(RX_MODE);
cfg.channels = channels;
cfg.sample_rate = samples_per_second;
cfg.use_apll = false;
//cfg.auto_clear = true;
cfg.buffer_size = 512;
cfg.buffer_count = 16;
i2s.begin(cfg);
// Setup tensorflow output
auto tcfg = tfl.defaultConfig();
tcfg.setCategories(kCategoryLabels);
tcfg.channels = channels;
tcfg.sample_rate = samples_per_second;
tcfg.kTensorArenaSize = 10 * 1024;
tcfg.respondToCommand = respondToCommand;
tcfg.model = g_model;
tfl.begin(tcfg);
}
void loop() { copier.copy(); }

View File

@@ -0,0 +1,30 @@
# Stream PDM Input to CSV Output
## General Description:
To use a PDM microphone you need to have a microcontroller that supports PDM input or a dedicated library.
The ESP32 supports PDM via the I2S API: We stream the sound input from a PDM microphone (PDM Digital MEMS MP34DT01) which we read in from the I2S interface and displays it on the Arduino Serial Plotter.
## Pins
![i2s-adc](https://pschatzmann.github.io/Resources/img/pdm-mic.jpg)
| i2s-mic | ESP32
| ---------| ---------------
| 3V | 3V
| GND | GND
| SEL | GND (GND or 3.3V)
| CLK | WS (GPIO15)
| DAT | IN (GPIO32)
| - | BCK (GPIO14)
## Additional Comments
You can select if you receive only data on the left or right by setting SEL to high or low.
Please note that in the 2.x realease of the Arduino ESP core, the WS pin is used as CLK. Prior to this it was BCK

View File

@@ -0,0 +1,39 @@
/**
* @file streams-i2s_pdm-serial.ino
* @author Phil Schatzmann
* @brief see https://github.com/pschatzmann/arduino-audio-tools/blob/main/examples/examples-stream/streams-i2s_pdm-serial/README.md
*
* @author Phil Schatzmann
* @copyright GPLv3
*/
#include "AudioTools.h"
AudioInfo info(44100, 1, 16);
I2SStream i2sStream; // Access I2S as stream
CsvOutput<int16_t> csvOutput(Serial);
StreamCopy copier(csvOutput, i2sStream); // copy i2sStream to csvOutput
// Arduino Setup
void setup(void) {
Serial.begin(115200);
AudioToolsLogger.begin(Serial, AudioToolsLogLevel::Info);
auto cfg = i2sStream.defaultConfig(RX_MODE);
cfg.copyFrom(info);
cfg.signal_type = PDM;
//cfg.use_apll = false;
//cfg.auto_clear = false;
cfg.pin_bck = -1; // not used depending on ESP32 core version
i2sStream.begin(cfg);
// make sure that we have the correct channels set up
csvOutput.begin(info);
}
// Arduino loop - copy data
void loop() {
copier.copy();
}

View File

@@ -0,0 +1,28 @@
# Decoding a MP3 file
In this example we decode a MP3 file into RAW output and send it the analog output pins.
Currently we provide multiple mp3 decoders
- libhelix
- tinymp3
Unfortunatly non of those are currently stable in all environments....
### Output Device: Piezo Electric Element
To test the output I am using piezo electric elements
![DAC](https://pschatzmann.github.io/Resources/img/piezo.jpeg)
It should also be possible to connect a headphone to the output pins.
| PIEZO Left | ESP32
| ------------| --------------
| + | GPIO25
| - | GND
| PIEZO2 Rigt | ESP32
| ------------| --------------
| + | GPIO26
| - | GND

View File

@@ -0,0 +1,44 @@
/**
* @file stream-memory_mp3-analog.ino
* @author Phil Schatzmann
* @brief decode MP3 stream and output as out signal
* @version 0.1
* @date 2021-01-24
*
* @copyright Copyright (c) 2021
*/
// install https://github.com/pschatzmann/arduino-libhelix.git
#include "AudioTools.h"
#include "AudioTools/AudioCodecs/CodecMP3Helix.h"
#include "BabyElephantWalk60_mp3.h"
MemoryStream mp3(BabyElephantWalk60_mp3, BabyElephantWalk60_mp3_len);
AnalogAudioStream analog; // Analog output
EncodedAudioStream out(&analog, new MP3DecoderHelix()); // output to decoder
StreamCopy copier(out, mp3); // copy in to out
void setup(){
Serial.begin(115200);
AudioToolsLogger.begin(Serial, AudioToolsLogLevel::Info);
analog.begin(analog.defaultConfig(TX_MODE));
// begin processing
out.begin();
}
void loop(){
if (mp3) {
copier.copy();
} else {
auto info = out.decoder().audioInfo();
LOGI("The audio rate from the mp3 file is %d", info.sample_rate);
LOGI("The channels from the mp3 file is %d", info.channels);
out.end();
stop();
}
}

View File

@@ -0,0 +1,5 @@
# Decoding a MP3 file with Metadata
In this example we provide the ID3 metadata from a MP3 file. We support the old ID3V1 and the newer ID3V2.
The MetaDataID3 class is used as stream output destination.
You register your callback method with setCallback().

View File

@@ -0,0 +1,41 @@
/**
* @file streams-memory_mp3-metadata.ino
* @brief In this example we provide the metadata from a MP3 file.
* @author Phil Schatzmann
* @copyright GPLv3
*/
#include "AudioTools.h"
#include "sample-12s.h"
MemoryStream mp3(sample_12s_mp3, sample_12s_mp3_len);
MetaDataOutput out;
StreamCopy copier(out, mp3); // copy in to out
// callback for meta data
void printMetaData(MetaDataType type, const char* str, int len){
Serial.print("==> ");
Serial.print(toStr(type));
Serial.print(": ");
Serial.println(str);
}
void setup(){
Serial.begin(115200);
AudioToolsLogger.begin(Serial, AudioToolsLogLevel::Info);
mp3.begin();
out.setCallback(printMetaData);
out.begin();
}
void loop(){
if (mp3) {
copier.copy();
} else {
stop();
}
}

View File

@@ -0,0 +1,29 @@
# Decoding a MP3 file
In this example we decode a MP3 file into RAW output and write the output with the help of a PWM signal to the pins.
Currently we provide multiple mp3 decoders
- libhelix
- tinymp3
Unfortunatly non of those are currently stable in all environments....
### Output Device: Earphone
To test the output I am using an earphone from a mobile phone.
We get 2 signals one for the left and the other for the right channel.
![DAC](https://pschatzmann.github.io/Resources/img/earphones.jpg)
The pins depend on the Processor:
| EarPhone | ESP32 | RPI Pico | MBED |
| -----------| -------------|---------------|--------------|
| Left | GPI2 | GPI2 | GPI2 |
| Right | GPI3 | GPIO3 | GPI3 |
| GND | GND | GND | GND |
To verify check the PIN_PWM_START in AudioConfig.h or you can set the pins by calling setPins() method on the PWMConfig object.

View File

@@ -0,0 +1,44 @@
/**
* @file stream-memory_mp3-analog.ino
* @author Phil Schatzmann
* @brief decode MP3 stream and output as analog signal
* @version 0.1
* @date 2021-01-24
*
* @copyright Copyright (c) 2021
*/
#include "AudioTools.h"
#include "AudioTools/AudioCodecs/CodecMP3Helix.h"
#include "BabyElephantWalk60_mp3.h"
MemoryStream mp3(BabyElephantWalk60_mp3, BabyElephantWalk60_mp3_len);
PWMAudioOutput out; // PWM output
EncodedAudioStream decoded(&out, new MP3DecoderHelix()); // output to decoder
StreamCopy copier(decoded, mp3); // copy in to out
void setup(){
Serial.begin(115200);
AudioToolsLogger.begin(Serial, AudioToolsLogLevel::Info);
// begin processing
auto cfg = out.defaultConfig();
out.begin(cfg);
decoded.begin();
}
void loop(){
if (mp3) {
copier.copy();
} else {
auto info = decoded.decoder().audioInfo();
LOGI("The audio rate from the mp3 file is %d", info.sample_rate);
LOGI("The channels from the mp3 file is %d", info.channels);
out.end();
stop();
}
}

View File

@@ -0,0 +1,28 @@
# Decoding a MP3 file
In this example we decode a very short MP3 file using lebhelix
### External DAC:
![DAC](https://pschatzmann.github.io/Resources/img/dac.jpeg)
For my tests I am using the 24-bit PCM5102 PCM5102A Stereo DAC Digital-to-analog Converter PLL Voice Module pHAT
I am just using the default pins defined by the framework. However I could change them with the help of the config object. The mute pin can be defined in the constructor of the I2SStream - by not defining anything we use the default which is GPIO23
DAC | ESP32
-----|----------------
VCC | 5V
GND | GND
BCK | BCK (GPIO14)
DIN | OUT (GPIO22)
LCK | BCK (GPIO15)
FMT | GND
XMT | 3V (or another GPIO PIN which is set to high)
- DMP - De-emphasis control for 44.1kHz sampling rate(1): Off (Low) / On (High)
- FLT - Filter select : Normal latency (Low) / Low latency (High)
- SCL - System clock input (probably SCL on your board).
- FMT - Audio format selection : I2S (Low) / Left justified (High)
- XMT - Soft mute control(1): Soft mute (Low) / soft un-mute (High)

View File

@@ -0,0 +1,48 @@
/**
* @file streams-memory_mp3_short-i2s-2.ino
* @author Phil Schatzmann
* @brief decode MP3 stream and output as i2s signal
* @version 0.1
* @date 2021-01-24
*
* @copyright Copyright (c) 2021
*/
#include "AudioTools.h"
#include "AudioTools/AudioCodecs/CodecMP3Helix.h"
#include "zero.h"
MemoryStream mp3(zero_mp3, zero_mp3_len);
I2SStream i2s; // PWM output
MP3DecoderHelix helix;
EncodedAudioStream out(&i2s, &helix); // output to decoder
StreamCopy copier(out, mp3); // copy in to out
void setup(){
Serial.begin(115200);
AudioToolsLogger.begin(Serial, AudioToolsLogLevel::Info);
// begin processing
auto cfg = i2s.defaultConfig();
cfg.sample_rate = 24000;
cfg.channels = 1;
i2s.begin(cfg);
out.begin();
sayWord();
}
void sayWord() {
Serial.println("Saying word...");
mp3.begin(); // restart source
helix.begin(); // so that we can repeatedly call this method
copier.copyAll();
helix.end(); // flush output
}
void loop(){
}

View File

@@ -0,0 +1,365 @@
#pragma once
const unsigned char zero_mp3[] = {
0xff, 0xf3, 0x44, 0xc4, 0x00, 0x11, 0x20, 0x6a, 0x1c, 0x00, 0x7b, 0x0c,
0x28, 0x52, 0x24, 0x4c, 0x22, 0xb4, 0xe2, 0x18, 0x80, 0x0e, 0x52, 0x2f,
0xa0, 0x17, 0x07, 0xc5, 0x62, 0x21, 0xd8, 0x83, 0x56, 0x4c, 0xc3, 0x52,
0x51, 0x38, 0x3c, 0xdb, 0x82, 0x33, 0xf8, 0x9c, 0xb9, 0x47, 0x1c, 0x20,
0x8b, 0x2b, 0x79, 0xcf, 0x97, 0x1e, 0xf0, 0x83, 0xb2, 0x8a, 0xa5, 0x1f,
0xff, 0xfe, 0xc4, 0x27, 0xc4, 0x00, 0x83, 0xb9, 0x75, 0xa8, 0x10, 0x0c,
0x10, 0x28, 0x5c, 0x78, 0x5c, 0x2e, 0x0e, 0x02, 0x01, 0x85, 0x83, 0x18,
0x82, 0xec, 0x5c, 0x86, 0x25, 0x21, 0x6a, 0x00, 0xe4, 0x4b, 0xcd, 0x35,
0xff, 0xf3, 0x44, 0xc4, 0x0e, 0x11, 0x98, 0xca, 0x80, 0x00, 0xc3, 0xc6,
0x70, 0x11, 0x90, 0xd0, 0x41, 0xfa, 0x58, 0xd8, 0x1e, 0x45, 0x57, 0xc4,
0xd4, 0x3d, 0xe1, 0xe5, 0x35, 0x7a, 0x6b, 0xfc, 0x6a, 0x9f, 0xbe, 0x95,
0xdd, 0xe3, 0xee, 0xe0, 0x60, 0x41, 0x38, 0x20, 0x27, 0xa9, 0xc4, 0xd4,
0x08, 0x09, 0xc4, 0xeb, 0x3f, 0xff, 0xd4, 0x18, 0x13, 0xc9, 0xed, 0xff,
0xff, 0xff, 0x59, 0xfa, 0xa5, 0xfe, 0x73, 0x07, 0xc3, 0xea, 0x86, 0x70,
0xa7, 0x72, 0xa0, 0xc0, 0x2c, 0x54, 0x47, 0x5f, 0xd2, 0x3a, 0x52, 0xea,
0x18, 0x93, 0xb1, 0x97, 0xee, 0xcd, 0xba, 0x78, 0x00, 0x1c, 0x7a, 0xb1,
0xff, 0xf3, 0x44, 0xc4, 0x1a, 0x17, 0x62, 0xea, 0x94, 0x00, 0xd1, 0x44,
0xb9, 0x45, 0x9e, 0x5f, 0xda, 0xd2, 0x92, 0xb6, 0xa4, 0x58, 0x81, 0xa2,
0x82, 0x42, 0x8c, 0x2c, 0xca, 0xea, 0xf2, 0x2d, 0x5e, 0xe9, 0x73, 0x91,
0xb3, 0xff, 0xd2, 0xb6, 0xe8, 0xaf, 0xe8, 0x22, 0x88, 0x9e, 0x8d, 0x92,
0xfd, 0xe8, 0xcb, 0xfd, 0xbb, 0x1d, 0xda, 0xf3, 0xab, 0x93, 0x6e, 0xcf,
0xa9, 0xc8, 0xd5, 0x33, 0x9d, 0xd1, 0x9d, 0x64, 0x20, 0x37, 0x41, 0x0d,
0x75, 0x0e, 0x06, 0xe0, 0x9d, 0xc2, 0x23, 0xf7, 0xda, 0xa6, 0xbd, 0xf6,
0x23, 0x80, 0x45, 0x8d, 0x19, 0xf4, 0x9c, 0xe3, 0xb4, 0x84, 0x98, 0x6a,
0xff, 0xf3, 0x44, 0xc4, 0x0f, 0x16, 0x3b, 0x1a, 0xa4, 0x00, 0xc1, 0x4a,
0xbd, 0x59, 0x63, 0x3a, 0xd4, 0xe0, 0xcc, 0x9a, 0xb7, 0x6f, 0xd6, 0xdf,
0xce, 0x86, 0x2d, 0x8d, 0xf6, 0xfd, 0x29, 0xea, 0x95, 0x7f, 0xff, 0x4a,
0x67, 0xfa, 0x7f, 0xdd, 0x7d, 0x74, 0xcd, 0xdf, 0x7c, 0x8e, 0xcf, 0xb1,
0x1d, 0x6d, 0x98, 0x85, 0x54, 0x7a, 0x3b, 0x9f, 0x41, 0x8c, 0xe4, 0x55,
0x33, 0x0d, 0x1c, 0xe4, 0x14, 0x17, 0x45, 0x40, 0xfb, 0x9c, 0x38, 0x38,
0x44, 0x79, 0x1c, 0x39, 0x28, 0x38, 0x9b, 0x04, 0xce, 0x01, 0x98, 0x3e,
0x20, 0x1c, 0x11, 0x9f, 0x71, 0x54, 0x82, 0x0a, 0xc2, 0x5d, 0x96, 0x26,
0xff, 0xf3, 0x44, 0xc4, 0x09, 0x14, 0x63, 0x22, 0xa8, 0x00, 0x78, 0x4e,
0xbc, 0x99, 0xeb, 0x85, 0x6b, 0xf1, 0x6e, 0x4b, 0xff, 0xaf, 0xff, 0xcd,
0x13, 0xf6, 0xbf, 0x2b, 0xfa, 0xfc, 0xba, 0xbf, 0x7f, 0xb6, 0xbf, 0x45,
0xa7, 0xbe, 0xfa, 0xe7, 0x53, 0xeb, 0x31, 0xb5, 0xa1, 0x8a, 0xb9, 0x95,
0x44, 0x9f, 0x53, 0x19, 0xdc, 0xd9, 0xa5, 0x56, 0x61, 0xf4, 0x66, 0xa9,
0x76, 0x1c, 0xa9, 0xa6, 0x98, 0x92, 0x6c, 0x5c, 0x78, 0xf2, 0x43, 0xe3,
0xae, 0xa7, 0x16, 0x1c, 0x2e, 0x4c, 0xb8, 0x8c, 0x38, 0x70, 0x46, 0x54,
0xb9, 0x75, 0xa6, 0x9b, 0xe6, 0x1c, 0x46, 0x91, 0x30, 0x6b, 0x89, 0xef,
0xff, 0xf3, 0x44, 0xc4, 0x0a, 0x14, 0xfb, 0x22, 0xa4, 0x00, 0x78, 0x4a,
0xbc, 0x4b, 0x7f, 0xbf, 0x9f, 0xf9, 0xaf, 0xff, 0xff, 0xc8, 0x8c, 0xf0,
0x65, 0xd5, 0xf6, 0xc8, 0xbf, 0x57, 0xbd, 0x5e, 0xb6, 0xcf, 0xfa, 0xf3,
0x76, 0x6f, 0xc8, 0xee, 0x8f, 0xad, 0x59, 0xfe, 0x87, 0x91, 0x5c, 0xee,
0xa8, 0xa6, 0x32, 0x14, 0x91, 0x85, 0xa0, 0xa2, 0x65, 0x67, 0x22, 0x5d,
0x48, 0x64, 0x62, 0x89, 0x87, 0xca, 0x34, 0x83, 0x06, 0x07, 0x43, 0x82,
0x63, 0xc7, 0x09, 0x8b, 0x1d, 0x86, 0x80, 0xe3, 0x82, 0xd4, 0xa8, 0x42,
0x00, 0xe2, 0xec, 0x2d, 0x44, 0x22, 0x10, 0x89, 0x03, 0x0a, 0x38, 0xab,
0xff, 0xf3, 0x44, 0xc4, 0x09, 0x14, 0xcb, 0x1e, 0xa8, 0x00, 0x38, 0x50,
0xbc, 0x6f, 0xff, 0xff, 0xff, 0xfe, 0xdc, 0xa2, 0x07, 0x4e, 0x82, 0x6e,
0x68, 0x98, 0xcf, 0x4f, 0xee, 0xbf, 0xf8, 0xfe, 0xa7, 0xfa, 0xbd, 0x3b,
0x4b, 0xef, 0xfe, 0x3f, 0xff, 0xa9, 0x5e, 0x9b, 0xee, 0x5e, 0x23, 0xae,
0xe6, 0xdd, 0xe2, 0x21, 0x9a, 0x51, 0xd2, 0x5e, 0xee, 0x10, 0xb2, 0xee,
0xfb, 0x52, 0x39, 0x20, 0x93, 0x11, 0xec, 0x54, 0x98, 0x10, 0x58, 0xed,
0x49, 0xab, 0xa6, 0x30, 0xac, 0xf2, 0x06, 0x0b, 0x1c, 0x27, 0x41, 0x10,
0x21, 0xa3, 0xc6, 0xd5, 0x5d, 0x10, 0x1c, 0x14, 0x3c, 0xcb, 0xd3, 0xe6,
0xff, 0xf3, 0x44, 0xc4, 0x08, 0x13, 0x8b, 0x22, 0xb0, 0x00, 0x40, 0x4a,
0xbc, 0xff, 0xff, 0xe5, 0xf2, 0xff, 0xff, 0x54, 0x66, 0x4e, 0xdf, 0x59,
0xd6, 0x02, 0xcb, 0x32, 0x22, 0xff, 0xef, 0xbf, 0xb6, 0x8c, 0x9b, 0xd2,
0x8d, 0x44, 0x6c, 0x8c, 0xcd, 0xbc, 0x94, 0xb2, 0xa7, 0x64, 0x89, 0x4a,
0xe3, 0x19, 0x95, 0xa6, 0x79, 0xca, 0x2e, 0x47, 0x55, 0x2d, 0xd4, 0xf1,
0xe2, 0x51, 0x67, 0x17, 0xb2, 0x91, 0x8a, 0x2e, 0x16, 0x0c, 0x71, 0x61,
0x53, 0x9c, 0x38, 0xcc, 0x2e, 0xa2, 0x01, 0xc1, 0x10, 0xe0, 0xa3, 0xaa,
0xd7, 0xf6, 0xee, 0xa9, 0x8c, 0x8c, 0x51, 0x08, 0x7e, 0x57, 0x62, 0x26,
0xff, 0xf3, 0x44, 0xc4, 0x0c, 0x13, 0xc3, 0x0e, 0xb8, 0x00, 0xc0, 0x84,
0xb9, 0xdc, 0xd7, 0x5d, 0x1f, 0xff, 0x14, 0x39, 0xfd, 0x4f, 0xff, 0xc8,
0x4f, 0xaa, 0xec, 0xc6, 0x2a, 0xb0, 0x4d, 0x92, 0xba, 0x12, 0x8e, 0x62,
0x33, 0xb3, 0x5d, 0xdd, 0x57, 0xd1, 0x2b, 0xff, 0xf4, 0x4d, 0xea, 0xa9,
0xff, 0xba, 0x74, 0xfc, 0xed, 0xd9, 0xa9, 0x4d, 0x26, 0x7d, 0x51, 0x76,
0xb1, 0xca, 0xe9, 0x4b, 0x83, 0x50, 0x45, 0x80, 0xb3, 0x21, 0x90, 0xea,
0xcf, 0xa1, 0x5b, 0x31, 0x8a, 0x15, 0x32, 0x09, 0xb1, 0xfc, 0xe6, 0x53,
0x27, 0x48, 0x65, 0x60, 0x4f, 0xda, 0x97, 0x4e, 0x15, 0x53, 0x1f, 0xaa,
0xff, 0xf3, 0x44, 0xc4, 0x10, 0x15, 0x39, 0xba, 0xac, 0x00, 0xc9, 0xda,
0x94, 0x14, 0xcb, 0x80, 0xc1, 0x9f, 0x34, 0x69, 0xe8, 0x51, 0xfc, 0xe1,
0x3b, 0xf4, 0x10, 0x9c, 0x6b, 0x52, 0x71, 0x0e, 0xb4, 0x8d, 0x93, 0x40,
0x97, 0x06, 0xd9, 0x71, 0x05, 0x58, 0x4f, 0xcb, 0x88, 0x3a, 0x2e, 0x49,
0x09, 0x73, 0x1f, 0x42, 0x99, 0x82, 0xfd, 0x34, 0xfd, 0x54, 0x3d, 0x33,
0x7f, 0x44, 0xc5, 0x4b, 0xa4, 0x6c, 0x07, 0x67, 0xff, 0xff, 0x53, 0xc6,
0x9d, 0x59, 0xaa, 0xd7, 0xcf, 0x48, 0x05, 0x65, 0xec, 0x1b, 0xe7, 0x72,
0xff, 0x8e, 0x02, 0xc9, 0xa5, 0xd7, 0x2d, 0x4a, 0x41, 0x3a, 0xa0, 0x77,
0xff, 0xf3, 0x44, 0xc4, 0x0e, 0x12, 0x99, 0xc2, 0xb4, 0x00, 0xc9, 0xd6,
0x94, 0xf5, 0x09, 0x9f, 0xcf, 0x23, 0xf7, 0xf4, 0x1a, 0x12, 0xf5, 0x16,
0xff, 0x0d, 0x36, 0xbf, 0x61, 0x40, 0x30, 0x3f, 0x27, 0x30, 0x7c, 0x12,
0xce, 0xcf, 0x29, 0x8d, 0xe1, 0xf8, 0xeb, 0x6d, 0x83, 0x61, 0x08, 0x3f,
0x44, 0xd4, 0xdd, 0x7f, 0xb2, 0xdb, 0xfb, 0xf3, 0xbf, 0x37, 0x27, 0xcd,
0x5b, 0xbf, 0x41, 0x1a, 0xa9, 0x7f, 0xff, 0xfe, 0xaa, 0x3b, 0x17, 0x77,
0xfd, 0x4a, 0xe6, 0xbf, 0x55, 0x60, 0x21, 0xb5, 0xcb, 0xbf, 0x2b, 0x30,
0x31, 0xb3, 0xe5, 0x63, 0x9d, 0x76, 0x8d, 0x1f, 0xf1, 0x5f, 0x93, 0xc8,
0xff, 0xf3, 0x44, 0xc4, 0x16, 0x10, 0x51, 0xba, 0xb8, 0x00, 0xc1, 0x50,
0x94, 0x10, 0x7e, 0xa2, 0x62, 0x4d, 0xe5, 0x94, 0xdf, 0x96, 0x2c, 0x0b,
0x47, 0x59, 0x82, 0x80, 0x08, 0x02, 0x42, 0xd7, 0x14, 0x30, 0x45, 0x7d,
0x11, 0xc0, 0x60, 0x9e, 0xfb, 0x22, 0xcd, 0xfe, 0x3b, 0x5f, 0xe9, 0xcd,
0xae, 0x52, 0x59, 0xb7, 0x17, 0xb3, 0x09, 0xaa, 0xaa, 0xe7, 0xff, 0xf1,
0x1d, 0xc4, 0x8e, 0xaf, 0x96, 0x56, 0x42, 0xe5, 0x9f, 0x2f, 0x2c, 0xeb,
0x2f, 0x21, 0x9f, 0xce, 0xdc, 0xe7, 0x6e, 0x41, 0x45, 0xf0, 0x7e, 0x75,
0xf3, 0xfe, 0xa3, 0x62, 0x98, 0xed, 0x06, 0x01, 0x01, 0x59, 0xed, 0xa4,
0xff, 0xf3, 0x44, 0xc4, 0x27, 0x10, 0x49, 0xaa, 0xb8, 0x00, 0xc8, 0x92,
0x95, 0x04, 0x05, 0xcc, 0xd6, 0xa3, 0x24, 0x2e, 0x25, 0xcd, 0x5e, 0x69,
0x6d, 0xfb, 0xda, 0x97, 0xf5, 0xf2, 0x5b, 0xfd, 0xea, 0xbf, 0x7d, 0xeb,
0x3a, 0x6e, 0xc4, 0xd5, 0xe7, 0xf7, 0x94, 0xe3, 0x81, 0xd1, 0x8e, 0x93,
0x74, 0xaf, 0xd9, 0x04, 0x56, 0xca, 0xf2, 0xcf, 0x30, 0x8e, 0x01, 0xef,
0xca, 0x88, 0xde, 0x3e, 0x51, 0xfb, 0x0b, 0x8d, 0xb9, 0x84, 0x09, 0x3e,
0x60, 0xe9, 0x2b, 0x4d, 0xc2, 0x4b, 0x5a, 0x17, 0x01, 0xe0, 0x06, 0x0e,
0x4c, 0x48, 0x2c, 0x2c, 0x69, 0x8a, 0x58, 0x8c, 0x10, 0xc5, 0x6e, 0x79,
0xff, 0xf3, 0x44, 0xc4, 0x38, 0x12, 0x91, 0x9a, 0xb4, 0x00, 0xd1, 0xd0,
0x95, 0x97, 0xd2, 0x5d, 0x7e, 0x93, 0x1d, 0x42, 0x4c, 0x5d, 0xc9, 0x6a,
0xc7, 0x04, 0x46, 0x05, 0x28, 0xaf, 0xfe, 0xd5, 0xc3, 0x9f, 0xb8, 0xe0,
0x31, 0xcd, 0xf4, 0xb2, 0xcc, 0x64, 0x47, 0x13, 0x9e, 0x0c, 0x77, 0x0b,
0xa4, 0xc7, 0x3b, 0x96, 0x6f, 0x86, 0x03, 0xa6, 0xba, 0xf8, 0x7e, 0xe3,
0x5f, 0xf2, 0xa3, 0x5e, 0xe6, 0x99, 0x34, 0xbc, 0xd7, 0x15, 0x9a, 0x95,
0x20, 0x10, 0x10, 0xb2, 0xe7, 0x2e, 0x03, 0x90, 0x34, 0x9f, 0x99, 0xa1,
0x4a, 0xd5, 0x63, 0x02, 0x12, 0x54, 0x31, 0xdb, 0x73, 0xe7, 0xb7, 0xa9,
0xff, 0xf3, 0x44, 0xc4, 0x40, 0x11, 0xd9, 0x2a, 0xb4, 0x00, 0xc3, 0xd2,
0x70, 0x74, 0x95, 0x36, 0x48, 0x58, 0xb1, 0xe2, 0x4a, 0xb3, 0xac, 0x2e,
0xc9, 0xc0, 0x22, 0xdc, 0x93, 0x4b, 0x21, 0xf0, 0x45, 0x2b, 0x16, 0x4d,
0x1e, 0x58, 0x00, 0xe4, 0x24, 0x75, 0x8b, 0xf4, 0x8e, 0xc4, 0x35, 0x2c,
0xdf, 0xd7, 0x8d, 0x52, 0x59, 0xef, 0xd3, 0xd2, 0xf8, 0x45, 0x51, 0xa3,
0xf2, 0xc9, 0xb2, 0x8b, 0x20, 0xa9, 0x12, 0x68, 0x15, 0x2e, 0x90, 0x0e,
0x26, 0x6b, 0xa3, 0xb1, 0x52, 0xda, 0xa1, 0xf1, 0x0a, 0x12, 0x59, 0x24,
0x42, 0xe3, 0xa3, 0x02, 0x8f, 0xfa, 0xfa, 0x95, 0x45, 0xef, 0x32, 0xf4,
0xff, 0xf3, 0x44, 0xc4, 0x4b, 0x11, 0xe9, 0x1e, 0xb0, 0x00, 0xce, 0x12,
0x70, 0x97, 0x43, 0x6a, 0x7b, 0xd9, 0x32, 0x80, 0xf2, 0xcd, 0xce, 0xc4,
0x50, 0x16, 0x03, 0x7a, 0x5c, 0xce, 0xed, 0xdb, 0x6d, 0xa5, 0xb6, 0x72,
0xa9, 0x1f, 0xb1, 0x8e, 0xe5, 0x72, 0xf9, 0xde, 0xd2, 0x04, 0xc5, 0x2c,
0xed, 0x93, 0xa4, 0x69, 0x40, 0x40, 0x26, 0x48, 0x2a, 0x80, 0xa0, 0x48,
0x46, 0x66, 0x64, 0x88, 0x5e, 0x4a, 0x99, 0xb5, 0x99, 0x22, 0xd6, 0xd6,
0x65, 0xf1, 0x01, 0x9e, 0x1f, 0xfd, 0x8e, 0x39, 0x4a, 0xfe, 0xe1, 0x4e,
0x31, 0x55, 0x27, 0x45, 0x2a, 0x80, 0x8d, 0x63, 0x28, 0x4b, 0xfd, 0x13,
0xff, 0xf3, 0x44, 0xc4, 0x56, 0x11, 0xa9, 0x16, 0xb4, 0x00, 0xc6, 0x12,
0x70, 0x43, 0x81, 0xe9, 0x50, 0xf2, 0xce, 0x4e, 0xa1, 0x84, 0x60, 0x95,
0xde, 0xdb, 0xee, 0xa5, 0xd2, 0xec, 0x6e, 0xbc, 0x6e, 0xd5, 0xfc, 0x72,
0x56, 0x1c, 0x51, 0xa5, 0x90, 0xb0, 0x12, 0x68, 0xd0, 0x49, 0x18, 0x4f,
0x0f, 0xd8, 0x6f, 0x1c, 0x89, 0xf9, 0x61, 0xd5, 0x98, 0x10, 0x38, 0xb5,
0xf2, 0x70, 0xbd, 0x7b, 0xaa, 0x32, 0xbd, 0x8b, 0xaf, 0x18, 0x3a, 0xb2,
0x36, 0x7b, 0xe5, 0xbf, 0xff, 0xff, 0xff, 0xeb, 0x4f, 0xff, 0xa1, 0x15,
0xc3, 0xb5, 0x60, 0x23, 0x19, 0x04, 0x4a, 0xa5, 0xac, 0xe9, 0x80, 0xe5,
0xff, 0xf3, 0x44, 0xc4, 0x62, 0x15, 0x59, 0x16, 0xa4, 0x00, 0xc6, 0x5e,
0x70, 0x87, 0x6c, 0xcf, 0x81, 0x38, 0x34, 0xc1, 0x70, 0xad, 0xf1, 0x47,
0xaf, 0x5a, 0xce, 0x20, 0xc1, 0x67, 0xec, 0xfc, 0x61, 0x8a, 0xd5, 0xab,
0x40, 0xd6, 0x0c, 0x68, 0xd9, 0x5d, 0x83, 0xd1, 0x5c, 0xfb, 0xa2, 0xc6,
0x6a, 0xfb, 0x43, 0xf4, 0x5a, 0xf4, 0x7d, 0x4a, 0x9e, 0x7b, 0x25, 0x9f,
0x2e, 0xd9, 0x46, 0x8b, 0x1e, 0x59, 0x1f, 0xf6, 0xae, 0xcf, 0xff, 0xff,
0xff, 0xfa, 0xbf, 0xfd, 0x6a, 0xca, 0xd6, 0x51, 0x10, 0x3b, 0x52, 0xcb,
0xf1, 0x40, 0xbd, 0xab, 0xfa, 0x35, 0x2b, 0x49, 0x53, 0x73, 0x40, 0x14,
0xff, 0xf3, 0x44, 0xc4, 0x5f, 0x12, 0xd8, 0xea, 0xa0, 0x00, 0xce, 0x5e,
0x70, 0x59, 0xbf, 0x9c, 0xa7, 0x62, 0x31, 0x4c, 0xf1, 0x4e, 0xe8, 0x7b,
0x2b, 0x0e, 0x9b, 0x93, 0x45, 0x5f, 0xa4, 0x00, 0xa7, 0xa2, 0x52, 0x69,
0x48, 0x2a, 0x2b, 0x56, 0x04, 0xbb, 0x36, 0xe4, 0xd8, 0xe7, 0x67, 0x75,
0x7b, 0x39, 0x5b, 0xfb, 0x4b, 0xcd, 0x6a, 0x98, 0xf3, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xe9, 0x8d, 0xef, 0x6d, 0x10, 0xeb, 0x05,
0x7e, 0x74, 0xfb, 0x8e, 0xd7, 0x4c, 0x48, 0xb3, 0x67, 0x10, 0x0a, 0x1c,
0x90, 0xb8, 0xd0, 0x0c, 0xbe, 0xf3, 0x38, 0x96, 0xd3, 0x54, 0x5f, 0x08,
0xff, 0xf3, 0x44, 0xc4, 0x66, 0x12, 0x00, 0xe2, 0x98, 0x00, 0xce, 0xb0,
0x70, 0xd3, 0x8f, 0xc1, 0x49, 0xab, 0x62, 0x9a, 0x61, 0x6d, 0x0d, 0x10,
0xc3, 0xaf, 0x23, 0xf0, 0x14, 0x15, 0x8b, 0x31, 0xb6, 0x97, 0xf8, 0xde,
0x8f, 0xca, 0xb3, 0xce, 0x9a, 0x19, 0xb7, 0xf7, 0x71, 0xbf, 0xc2, 0x8e,
0xa7, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfa, 0xbf, 0xfe, 0x9a, 0xc3, 0x7d,
0x80, 0x87, 0xef, 0xca, 0xc2, 0xf3, 0x1c, 0x44, 0x6a, 0x0d, 0x2d, 0x30,
0x4b, 0x47, 0xa9, 0xee, 0x73, 0xec, 0xa9, 0x16, 0x93, 0x6f, 0x2a, 0x96,
0xad, 0x79, 0x9c, 0xaf, 0xac, 0x03, 0xb5, 0x95, 0x78, 0xe2, 0xf9, 0x6c,
0xff, 0xf3, 0x44, 0xc4, 0x71, 0x12, 0xa0, 0xde, 0x90, 0x00, 0xd6, 0xf0,
0x70, 0xd1, 0xaa, 0x91, 0xe1, 0x62, 0xe6, 0xec, 0x3d, 0x90, 0x65, 0x14,
0xcc, 0x6e, 0x0d, 0x9f, 0x95, 0xca, 0xef, 0xbc, 0xf7, 0x2f, 0x61, 0x1c,
0xbc, 0xe0, 0x62, 0x73, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xe3, 0x3e,
0x8a, 0xb3, 0xdd, 0x37, 0x13, 0x88, 0x08, 0x77, 0x74, 0x06, 0x30, 0x4b,
0x56, 0x1e, 0x70, 0x45, 0x69, 0x4e, 0x1b, 0xb1, 0x48, 0x6c, 0x1d, 0x5b,
0xf7, 0x4d, 0x01, 0xb0, 0x29, 0x16, 0xa4, 0xad, 0x3a, 0x1d, 0xca, 0x48,
0xca, 0x1b, 0x6b, 0x3c, 0x2f, 0x87, 0x69, 0xe2, 0xca, 0x55, 0x89, 0x98,
0xff, 0xf3, 0x44, 0xc4, 0x79, 0x12, 0x60, 0xda, 0x9c, 0x00, 0xce, 0x70,
0x70, 0x6a, 0x55, 0x94, 0x27, 0xe5, 0xea, 0x3b, 0x79, 0xcf, 0x11, 0xf4,
0xaa, 0x74, 0xf4, 0x77, 0xaa, 0x43, 0xa2, 0x7a, 0xe2, 0x04, 0x5c, 0xde,
0x98, 0xfe, 0x01, 0x85, 0x3e, 0xfb, 0xec, 0xff, 0xff, 0xff, 0xff, 0xef,
0x5a, 0x7f, 0xf6, 0xb3, 0xa5, 0x15, 0xee, 0xab, 0x90, 0x00, 0x06, 0x19,
0x05, 0xd9, 0x81, 0x29, 0xd2, 0x56, 0x8b, 0x11, 0x62, 0x45, 0x72, 0x5c,
0x8a, 0x82, 0x5a, 0x8f, 0xfa, 0x47, 0x94, 0x56, 0xae, 0x56, 0xd3, 0xc6,
0x73, 0xe5, 0x29, 0xc5, 0x47, 0xba, 0x56, 0x9d, 0x96, 0xe5, 0x4d, 0x26,
0xff, 0xf3, 0x44, 0xc4, 0x82, 0x15, 0xd9, 0x12, 0xa0, 0x00, 0xce, 0x5e,
0x70, 0x4f, 0x94, 0xba, 0x22, 0x92, 0x52, 0x2d, 0x3b, 0x6d, 0xa6, 0xf3,
0xc2, 0x4a, 0x84, 0x87, 0x2d, 0x74, 0x93, 0x81, 0x15, 0x16, 0x9e, 0x19,
0x72, 0xb1, 0x0f, 0xed, 0x2f, 0xf7, 0x1c, 0xf7, 0x55, 0xf3, 0x0d, 0xf8,
0x6b, 0x76, 0xae, 0x7d, 0x2d, 0xff, 0x57, 0xff, 0xff, 0xd8, 0x5b, 0xce,
0xce, 0xda, 0x65, 0x8d, 0x4d, 0x03, 0x90, 0xde, 0xaa, 0xa6, 0xf0, 0xb2,
0xe7, 0xb9, 0x42, 0xa1, 0x96, 0xf9, 0x50, 0xb7, 0xd6, 0x3f, 0x02, 0xab,
0xa2, 0x5a, 0xd0, 0xe8, 0x48, 0x8b, 0x86, 0x33, 0x4c, 0x72, 0xf6, 0xa6,
0xff, 0xf3, 0x44, 0xc4, 0x7d, 0x17, 0xf9, 0x76, 0xa0, 0x00, 0xc6, 0x16,
0x94, 0xda, 0xe5, 0xef, 0xf3, 0x47, 0x7f, 0x23, 0x41, 0xf5, 0x67, 0x44,
0x11, 0xed, 0x73, 0xae, 0x46, 0xa3, 0x85, 0xf0, 0xdb, 0x9f, 0x46, 0x5f,
0xbe, 0xb9, 0x83, 0x8d, 0x37, 0xb4, 0xcf, 0x48, 0xa8, 0x38, 0xf8, 0xcc,
0x2c, 0xfc, 0x47, 0xbc, 0x29, 0x24, 0xb6, 0x44, 0x90, 0x2c, 0x4c, 0xc5,
0x7e, 0xef, 0xff, 0xff, 0xff, 0x7f, 0x7b, 0x19, 0xb1, 0x35, 0xb7, 0xbd,
0x40, 0x62, 0xee, 0x8b, 0xf2, 0x00, 0x2f, 0xec, 0xc5, 0x5a, 0xe1, 0x65,
0xd3, 0xcc, 0x49, 0x44, 0x22, 0x1e, 0x04, 0x7a, 0xb8, 0xe8, 0xc9, 0xa9,
0xff, 0xf3, 0x44, 0xc4, 0x70, 0x15, 0x59, 0x36, 0xa8, 0x00, 0xc6, 0x1e,
0x70, 0x14, 0xd4, 0x18, 0xed, 0xff, 0x28, 0x1a, 0x3d, 0xde, 0xf4, 0xce,
0x77, 0x7a, 0x1b, 0x0e, 0x36, 0xdc, 0xe1, 0xa5, 0x37, 0xc1, 0x9f, 0xad,
0xf5, 0xd6, 0xf3, 0xb5, 0xd4, 0x7f, 0xb6, 0xb9, 0x31, 0xad, 0x28, 0xbc,
0xd7, 0x56, 0x4f, 0x7e, 0xdb, 0x6f, 0xe0, 0xed, 0x9d, 0x9e, 0x61, 0x28,
0x35, 0x15, 0x72, 0x7d, 0xff, 0xff, 0xff, 0xeb, 0xe8, 0xc3, 0x7b, 0x68,
0x82, 0xd8, 0xb5, 0x83, 0x72, 0x4c, 0x76, 0xd6, 0xd5, 0x00, 0xa3, 0xa7,
0xf8, 0xec, 0x85, 0x0c, 0x24, 0x59, 0x87, 0xdc, 0x44, 0x16, 0x9f, 0x02,
0xff, 0xf3, 0x44, 0xc4, 0x6d, 0x14, 0x81, 0x32, 0xa4, 0x00, 0xc6, 0x1e,
0x70, 0x5b, 0xaf, 0x0f, 0x5e, 0xb1, 0x2a, 0x9b, 0xa3, 0xb3, 0xd4, 0x32,
0xd4, 0x2c, 0x97, 0x0e, 0x1e, 0xa2, 0x41, 0x14, 0xe6, 0x27, 0xc3, 0xff,
0xdb, 0xdf, 0x2f, 0x6d, 0x7e, 0x97, 0x85, 0xf6, 0x33, 0x54, 0x6e, 0x79,
0x82, 0x4a, 0x1a, 0xec, 0xfd, 0x11, 0x1a, 0x48, 0xaa, 0xd5, 0x25, 0x0a,
0x40, 0x21, 0xc9, 0xa4, 0xc8, 0x5a, 0x9a, 0x34, 0x89, 0x0e, 0xbc, 0x57,
0x6e, 0x88, 0x72, 0x9e, 0x49, 0x44, 0x49, 0x44, 0xe4, 0x7c, 0xb9, 0x13,
0x73, 0x70, 0xf9, 0xb7, 0x6a, 0xd7, 0xf8, 0x92, 0x5b, 0x10, 0x7a, 0xbe,
0xff, 0xf3, 0x44, 0xc4, 0x6e, 0x11, 0x89, 0x12, 0xa8, 0x00, 0xc6, 0x18,
0x70, 0x82, 0x80, 0x51, 0x3a, 0x10, 0x0e, 0x40, 0xb7, 0x48, 0x4b, 0x7b,
0x04, 0x9a, 0xe9, 0x31, 0xdf, 0x02, 0x38, 0xa1, 0xa1, 0x41, 0x2c, 0x4a,
0x3d, 0x41, 0xaf, 0xb5, 0x62, 0x68, 0xb0, 0xe4, 0xb9, 0x3f, 0xff, 0xff,
0xff, 0x65, 0x35, 0x9d, 0xee, 0x0e, 0xf1, 0x39, 0x52, 0x3e, 0x44, 0x03,
0x9d, 0x97, 0xe3, 0x50, 0x3c, 0x09, 0xaa, 0xf7, 0x4c, 0x84, 0xe2, 0xd8,
0xcf, 0xd1, 0x34, 0x2c, 0x7e, 0x0d, 0x6f, 0x75, 0xa9, 0x2b, 0xe5, 0xf9,
0xdc, 0x63, 0xf8, 0xd9, 0xbb, 0x4b, 0x69, 0x0e, 0xad, 0x30, 0x27, 0x7a,
0xff, 0xf3, 0x44, 0xc4, 0x7a, 0x13, 0x19, 0x16, 0xa4, 0x00, 0x7e, 0x12,
0x70, 0x7d, 0x37, 0x65, 0xf7, 0xb2, 0xa7, 0x77, 0xc3, 0x95, 0x29, 0x85,
0xd3, 0x83, 0x76, 0x59, 0xfd, 0xb7, 0x25, 0x5b, 0xef, 0xe4, 0x61, 0x25,
0x8a, 0x18, 0xbf, 0xef, 0xff, 0xff, 0xff, 0xfe, 0xdf, 0xa1, 0xc7, 0x95,
0x07, 0x52, 0x1b, 0x2b, 0x77, 0x9d, 0x20, 0x76, 0xe8, 0xad, 0x57, 0x03,
0x62, 0x24, 0x7a, 0x97, 0x00, 0xc0, 0x90, 0x1d, 0xc8, 0x97, 0x04, 0x48,
0x7a, 0xc7, 0xc8, 0xde, 0xd8, 0x6c, 0xf2, 0x77, 0xc0, 0xdc, 0xde, 0x45,
0x17, 0x1e, 0x50, 0x00, 0x46, 0x6e, 0x65, 0x91, 0xbe, 0x4e, 0xfa, 0xa6,
0xff, 0xf3, 0x44, 0xc4, 0x80, 0x13, 0x71, 0x1e, 0x9c, 0x00, 0xce, 0x5e,
0x70, 0xd5, 0x70, 0x3c, 0x9d, 0xb6, 0x91, 0x8c, 0xff, 0x5b, 0xbb, 0xed,
0x48, 0x78, 0xa0, 0x8d, 0x22, 0xb5, 0x7d, 0x5f, 0xff, 0xff, 0xaf, 0xfe,
0x9f, 0xa9, 0xbd, 0x8c, 0x78, 0x72, 0xe7, 0x81, 0x43, 0x35, 0x98, 0x58,
0x85, 0xd4, 0x92, 0xc8, 0xa1, 0xcc, 0x49, 0x0d, 0xda, 0x94, 0xa1, 0xc6,
0x11, 0x85, 0x32, 0x8f, 0x6b, 0xf7, 0x42, 0xf6, 0xff, 0xdc, 0x9b, 0xc3,
0x78, 0x96, 0xf5, 0x21, 0xf6, 0xad, 0x80, 0x80, 0x5f, 0x27, 0x40, 0xb0,
0xca, 0xaf, 0x3b, 0x1c, 0xdf, 0xc9, 0xad, 0xf0, 0x3d, 0x46, 0x70, 0x7a,
0xff, 0xf3, 0x44, 0xc4, 0x85, 0x12, 0xb1, 0x26, 0x98, 0x00, 0xc5, 0x16,
0x70, 0x3d, 0x0d, 0x7f, 0xd7, 0x50, 0x75, 0x4f, 0xbb, 0xff, 0xff, 0xff,
0xf2, 0x32, 0xcc, 0x4f, 0xfa, 0x95, 0x7b, 0x2c, 0xd7, 0x56, 0x02, 0x7f,
0x8b, 0x32, 0x15, 0x0e, 0x9a, 0x43, 0x71, 0xe8, 0x64, 0x70, 0x31, 0xc5,
0x73, 0xc8, 0x7a, 0x7a, 0x9a, 0x7b, 0x76, 0x5b, 0xb4, 0xb7, 0x77, 0x6e,
0xc3, 0xbf, 0xf9, 0x45, 0xb9, 0xcf, 0x7c, 0x68, 0xd9, 0x10, 0xfa, 0x0a,
0x0d, 0x22, 0x4e, 0x88, 0x8f, 0xfb, 0xdd, 0xff, 0xd6, 0xfb, 0xad, 0xc8,
0xd7, 0xd7, 0xf6, 0xf4, 0xff, 0xcb, 0xb8, 0xd7, 0xff, 0xff, 0xff, 0xe2,
0xff, 0xf3, 0x44, 0xc4, 0x8d, 0x12, 0x91, 0x12, 0x90, 0x00, 0xc6, 0x96,
0x70, 0xb0, 0xef, 0xfa, 0x49, 0xa5, 0xca, 0xa8, 0x88, 0xf5, 0x96, 0xc7,
0x1f, 0xc0, 0xa3, 0xc0, 0xa4, 0x34, 0x2f, 0x65, 0xee, 0x51, 0x8b, 0x41,
0x0d, 0x39, 0x6e, 0xb9, 0x90, 0xc1, 0x07, 0x8a, 0xcb, 0xe1, 0x8a, 0xd5,
0xf5, 0x2a, 0x8b, 0x34, 0x91, 0xd1, 0x52, 0xc8, 0xec, 0xed, 0xa9, 0xd5,
0x46, 0x61, 0x60, 0xd0, 0x52, 0x4a, 0x41, 0x6d, 0x23, 0x74, 0x56, 0xf7,
0x4b, 0x80, 0xc0, 0x3f, 0xfe, 0xa7, 0xae, 0xdb, 0x7f, 0xff, 0xff, 0xff,
0xfa, 0x7a, 0xfa, 0x55, 0x46, 0x63, 0x12, 0x28, 0xc1, 0x86, 0x35, 0x34,
0xff, 0xf3, 0x44, 0xc4, 0x95, 0x12, 0xa1, 0x12, 0x84, 0x00, 0xd6, 0x92,
0x70, 0x0f, 0x2d, 0x43, 0x56, 0x10, 0xbb, 0xcb, 0x7a, 0x04, 0x43, 0x12,
0xca, 0x82, 0x82, 0x4a, 0x23, 0x58, 0x18, 0x33, 0x5a, 0x72, 0x98, 0x73,
0x93, 0x0e, 0xe1, 0x4c, 0xb0, 0x58, 0x0a, 0x5d, 0x98, 0xc6, 0x28, 0x5c,
0x58, 0x35, 0x35, 0x08, 0x40, 0x08, 0x97, 0xc6, 0x9a, 0xd6, 0xc1, 0x51,
0xa0, 0xa8, 0x35, 0x12, 0xd4, 0x0d, 0x05, 0x4e, 0xea, 0x3d, 0xd4, 0x7b,
0xff, 0xff, 0xff, 0xff, 0xfd, 0x2a, 0x10, 0xa4, 0x12, 0x54, 0x7c, 0x38,
0xa8, 0x43, 0x2e, 0x16, 0x5e, 0x60, 0x17, 0x0d, 0xad, 0x9d, 0xa6, 0x2d,
0xff, 0xf3, 0x44, 0xc4, 0x9d, 0x10, 0x50, 0xaa, 0x7c, 0x00, 0xd6, 0x12,
0x4c, 0x55, 0x7e, 0x1c, 0x55, 0x55, 0xb6, 0x06, 0x70, 0x54, 0x32, 0xd6,
0x00, 0xa3, 0x5a, 0x59, 0x01, 0x38, 0x44, 0x79, 0x24, 0xce, 0xd2, 0xd6,
0x15, 0x0c, 0x99, 0x85, 0x5d, 0x88, 0x81, 0xa5, 0x07, 0x5a, 0x74, 0x4b,
0xb4, 0x96, 0xf4, 0xce, 0x86, 0xb5, 0x3e, 0xe5, 0x3d, 0x6b, 0xf7, 0xfc,
0x97, 0xd7, 0xfe, 0xaa, 0x02, 0x74, 0x4e, 0x08, 0x59, 0x78, 0x47, 0xa5,
0x11, 0xc5, 0xc4, 0x95, 0x13, 0x23, 0x0c, 0xe4, 0x51, 0xb2, 0x39, 0xa0,
0x9c, 0x47, 0xf9, 0xb2, 0x71, 0xa2, 0x80, 0x8f, 0x8b, 0x87, 0x8d, 0x93,
0xff, 0xf3, 0x44, 0xc4, 0xae, 0x12, 0x18, 0xb2, 0x5c, 0x00, 0xd6, 0x12,
0x4c, 0x4e, 0x2e, 0x37, 0x3b, 0x3b, 0xb3, 0xfc, 0xb2, 0xd4, 0x3f, 0xd6,
0x5b, 0x3f, 0x96, 0x19, 0xac, 0xbd, 0x60, 0xa0, 0x81, 0x03, 0x8f, 0x8b,
0x33, 0xff, 0x82, 0xc2, 0xe2, 0x37, 0x7d, 0x4d, 0xfe, 0x2a, 0x28, 0xdf,
0xff, 0x16, 0xd4, 0x2f, 0x4c, 0x41, 0x4d, 0x45, 0x33, 0x2e, 0x31, 0x30,
0x30, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55,
0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55,
0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x4c, 0x41, 0x4d, 0x45, 0x33, 0x2e,
0xff, 0xf3, 0x44, 0xc4, 0xb8, 0x11, 0x20, 0xda, 0x00, 0x00, 0x62, 0x06,
0x70, 0x31, 0x30, 0x30, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55,
0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55,
0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55,
0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55,
0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55,
0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55,
0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x4c, 0x41, 0x4d, 0x45, 0x33, 0x2e,
0xff, 0xf3, 0x44, 0xc4, 0xc6, 0x11, 0xb9, 0x49, 0x90, 0x00, 0x79, 0x86,
0x94, 0x31, 0x30, 0x30, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55,
0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55,
0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55,
0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55,
0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55,
0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55,
0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x4c, 0x41, 0x4d, 0x45, 0x33, 0x2e,
0xff, 0xf3, 0x44, 0xc4, 0xac, 0x00, 0x00, 0x03, 0x48, 0x00, 0x00, 0x00,
0x00, 0x31, 0x30, 0x30, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55,
0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55,
0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55,
0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55,
0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55,
0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55,
0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x4c, 0x41, 0x4d, 0x45, 0x33, 0x2e,
0xff, 0xf3, 0x44, 0xc4, 0xac, 0x00, 0x00, 0x03, 0x48, 0x00, 0x00, 0x00,
0x00, 0x31, 0x30, 0x30, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55,
0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55,
0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55,
0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55,
0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55,
0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55,
0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x4c, 0x41, 0x4d, 0x45, 0x33, 0x2e,
0xff, 0xf3, 0x44, 0xc4, 0xac, 0x00, 0x00, 0x03, 0x48, 0x00, 0x00, 0x00,
0x00, 0x31, 0x30, 0x30, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55,
0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55,
0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55,
0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55,
0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55,
0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55,
0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x1c, 0xe0, 0x43, 0x42, 0x88, 0x20,
0xff, 0xf3, 0x44, 0xc4, 0xac, 0x00, 0x00, 0x03, 0x48, 0x00, 0x00, 0x00,
0x00, 0x9a, 0x09, 0xa0, 0x5e, 0x03, 0x90, 0x30, 0x02, 0x46, 0x3f, 0xd7,
0x8b, 0x61, 0x38, 0x2e, 0x04, 0x81, 0x40, 0x30, 0x05, 0x93, 0xec, 0x2c,
0x8c, 0x13, 0x3f, 0x0c, 0x23, 0x36, 0x81, 0xc8, 0xd1, 0xa3, 0xa6, 0xc4,
0x00, 0x80, 0x20, 0x18, 0x8a, 0xe2, 0xb2, 0x7b, 0xeb, 0x8b, 0x34, 0x00,
0x00, 0x00, 0x03, 0x17, 0xf1, 0x02, 0x00, 0x23, 0xff, 0x10, 0x00, 0x00,
0xbf, 0x40, 0x80, 0x00, 0x02, 0x3d, 0x11, 0x11, 0x13, 0x74, 0xc3, 0x81,
0x99, 0x71, 0xc0, 0xf8, 0x3e, 0xc0, 0xf9, 0x70, 0x7c, 0x40, 0x08, 0x41,
0xff, 0xf3, 0x44, 0xc4, 0xac, 0x00, 0x00, 0x03, 0x48, 0x00, 0x00, 0x00,
0x00, 0x01, 0x87, 0x1f, 0xc9, 0x88, 0x1f, 0x39, 0xf0, 0xc1, 0x0d, 0x43,
0x1d, 0xfc, 0x49, 0x59, 0xf5, 0x9c, 0x89, 0xc3, 0xea, 0x2d, 0xc9, 0x54,
0x40, 0xa7, 0x2a, 0x65, 0xd5, 0x2a, 0x58, 0x67, 0xdd, 0xc5, 0x7a, 0x8b,
0x54, 0x86, 0xcd, 0x79, 0xc6, 0x92, 0xce, 0x39, 0x51, 0x30, 0x49, 0x10,
0xa9, 0xb6, 0x4a, 0xa0, 0x00, 0x48, 0xcb, 0x81, 0x22, 0x23, 0x60, 0x8b,
0xad, 0x23, 0x40, 0x30, 0x15, 0x19, 0x00, 0xa0, 0x4a, 0x12, 0x51, 0xa3,
0x3a, 0xca, 0xc4, 0xc8, 0x91, 0x6c, 0x56, 0x44, 0xd4, 0x91, 0x6c, 0xa6,
0xff, 0xf3, 0x44, 0xc4, 0xac, 0x00, 0x00, 0x03, 0x48, 0x00, 0x00, 0x00,
0x00, 0xcd, 0x22, 0x9a, 0x4d, 0x7a, 0x35, 0x16, 0xaa, 0x25, 0xa7, 0x58,
0x05, 0x4c, 0x95, 0x6f, 0xef, 0x39, 0x26, 0xa2, 0x52, 0x4e, 0xd5, 0x53,
0xe5, 0x92, 0x98, 0xaa, 0xce, 0xc4, 0xb6, 0x5e, 0x73, 0xef, 0x67, 0x96,
0xdf, 0xfc, 0xb6, 0xcd, 0x56, 0x9d, 0xb2, 0x75, 0x82, 0xcd, 0x23, 0x9e,
0x13, 0x12, 0x7c, 0x54, 0x19, 0x11, 0x80, 0xb9, 0x29, 0x22, 0x4b, 0x3b,
0x59, 0xd1, 0x2b, 0x83, 0xb5, 0x08, 0x70, 0xc9, 0x27, 0x87, 0x5a, 0x81,
0x8d, 0x74, 0x7a, 0x9b, 0x07, 0xb2, 0x2d, 0x38, 0x27, 0x30, 0x7c, 0x95,
0xff, 0xf3, 0x44, 0xc4, 0xff, 0x1b, 0x19, 0x7d, 0xf0, 0x00, 0x7a, 0x46,
0x94, 0x12, 0xa9, 0xa9, 0x3a, 0xb9, 0x2a, 0x58, 0xe9, 0xd4, 0x97, 0x84,
0xe0, 0xed, 0xfd, 0xca, 0x88, 0xa8, 0xa9, 0xfe, 0xe5, 0x30, 0x50, 0x40,
0x8e, 0x47, 0xcc, 0x50, 0x40, 0x84, 0x86, 0x9f, 0xfe, 0x02, 0x09, 0x0a,
0x86, 0x6b, 0x14, 0x6f, 0xeb, 0x14, 0xe2, 0xc2, 0xba, 0xc5, 0x1a, 0x81,
0xe2, 0xa2, 0xd8, 0x48, 0x5c, 0x46, 0xe8, 0xa8, 0xb2, 0x4c, 0x41, 0x4d,
0x45, 0x33, 0x2e, 0x31, 0x30, 0x30, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
0xff, 0xf3, 0x44, 0xc4, 0xe5, 0x1f, 0x9a, 0x31, 0xf8, 0x00, 0xc2, 0x4c,
0xb8, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
0xff, 0xf3, 0x44, 0xc4, 0xb9, 0x12, 0xa9, 0x25, 0x88, 0x00, 0x7a, 0x44,
0x70, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa
};
unsigned int zero_mp3_len = 4320;

View File

@@ -0,0 +1,28 @@
# Decoding a MP3 file
In this example we decode a very short MP3 file using lebhelix
### External DAC:
![DAC](https://pschatzmann.github.io/Resources/img/dac.jpeg)
For my tests I am using the 24-bit PCM5102 PCM5102A Stereo DAC Digital-to-analog Converter PLL Voice Module pHAT
I am just using the default pins defined by the framework. However I could change them with the help of the config object. The mute pin can be defined in the constructor of the I2SStream - by not defining anything we use the default which is GPIO23
DAC | ESP32
-----|----------------
VCC | 5V
GND | GND
BCK | BCK (GPIO14)
DIN | OUT (GPIO22)
LCK | BCK (GPIO15)
FMT | GND
XMT | 3V (or another GPIO PIN which is set to high)
- DMP - De-emphasis control for 44.1kHz sampling rate(1): Off (Low) / On (High)
- FLT - Filter select : Normal latency (Low) / Low latency (High)
- SCL - System clock input (probably SCL on your board).
- FMT - Audio format selection : I2S (Low) / Left justified (High)
- XMT - Soft mute control(1): Soft mute (Low) / soft un-mute (High)

View File

@@ -0,0 +1,45 @@
/**
* @file streams-memory_mp3_short-i2s.ino
* @author Phil Schatzmann
* @brief decode MP3 stream and output as i2s signal
* @version 0.1
* @date 2021-01-24
*
* @copyright Copyright (c) 2021
*/
#include "AudioTools.h"
#include "AudioTools/AudioCodecs/CodecMP3Helix.h"
#include "zero.h"
MemoryStream mp3(zero_mp3, zero_mp3_len);
I2SStream i2s;
MP3DecoderHelix helix;
EncodedAudioStream out(&i2s, &helix); // output to decoder
StreamCopy copier(out, mp3); // copy in to i2s
void setup(){
Serial.begin(115200);
AudioToolsLogger.begin(Serial, AudioToolsLogLevel::Info);
// begin processing
auto cfg = i2s.defaultConfig();
cfg.sample_rate = 24000;
cfg.channels = 1;
i2s.begin(cfg);
out.begin();
}
void loop(){
if (mp3.available()) {
copier.copy();
} else {
helix.end(); // flush output
auto info = out.decoder().audioInfo();
LOGI("The audio rate from the mp3 file is %d", info.sample_rate);
LOGI("The channels from the mp3 file is %d", info.channels);
i2s.end();
stop();
}
}

View File

@@ -0,0 +1,365 @@
#pragma once
const unsigned char zero_mp3[] = {
0xff, 0xf3, 0x44, 0xc4, 0x00, 0x11, 0x20, 0x6a, 0x1c, 0x00, 0x7b, 0x0c,
0x28, 0x52, 0x24, 0x4c, 0x22, 0xb4, 0xe2, 0x18, 0x80, 0x0e, 0x52, 0x2f,
0xa0, 0x17, 0x07, 0xc5, 0x62, 0x21, 0xd8, 0x83, 0x56, 0x4c, 0xc3, 0x52,
0x51, 0x38, 0x3c, 0xdb, 0x82, 0x33, 0xf8, 0x9c, 0xb9, 0x47, 0x1c, 0x20,
0x8b, 0x2b, 0x79, 0xcf, 0x97, 0x1e, 0xf0, 0x83, 0xb2, 0x8a, 0xa5, 0x1f,
0xff, 0xfe, 0xc4, 0x27, 0xc4, 0x00, 0x83, 0xb9, 0x75, 0xa8, 0x10, 0x0c,
0x10, 0x28, 0x5c, 0x78, 0x5c, 0x2e, 0x0e, 0x02, 0x01, 0x85, 0x83, 0x18,
0x82, 0xec, 0x5c, 0x86, 0x25, 0x21, 0x6a, 0x00, 0xe4, 0x4b, 0xcd, 0x35,
0xff, 0xf3, 0x44, 0xc4, 0x0e, 0x11, 0x98, 0xca, 0x80, 0x00, 0xc3, 0xc6,
0x70, 0x11, 0x90, 0xd0, 0x41, 0xfa, 0x58, 0xd8, 0x1e, 0x45, 0x57, 0xc4,
0xd4, 0x3d, 0xe1, 0xe5, 0x35, 0x7a, 0x6b, 0xfc, 0x6a, 0x9f, 0xbe, 0x95,
0xdd, 0xe3, 0xee, 0xe0, 0x60, 0x41, 0x38, 0x20, 0x27, 0xa9, 0xc4, 0xd4,
0x08, 0x09, 0xc4, 0xeb, 0x3f, 0xff, 0xd4, 0x18, 0x13, 0xc9, 0xed, 0xff,
0xff, 0xff, 0x59, 0xfa, 0xa5, 0xfe, 0x73, 0x07, 0xc3, 0xea, 0x86, 0x70,
0xa7, 0x72, 0xa0, 0xc0, 0x2c, 0x54, 0x47, 0x5f, 0xd2, 0x3a, 0x52, 0xea,
0x18, 0x93, 0xb1, 0x97, 0xee, 0xcd, 0xba, 0x78, 0x00, 0x1c, 0x7a, 0xb1,
0xff, 0xf3, 0x44, 0xc4, 0x1a, 0x17, 0x62, 0xea, 0x94, 0x00, 0xd1, 0x44,
0xb9, 0x45, 0x9e, 0x5f, 0xda, 0xd2, 0x92, 0xb6, 0xa4, 0x58, 0x81, 0xa2,
0x82, 0x42, 0x8c, 0x2c, 0xca, 0xea, 0xf2, 0x2d, 0x5e, 0xe9, 0x73, 0x91,
0xb3, 0xff, 0xd2, 0xb6, 0xe8, 0xaf, 0xe8, 0x22, 0x88, 0x9e, 0x8d, 0x92,
0xfd, 0xe8, 0xcb, 0xfd, 0xbb, 0x1d, 0xda, 0xf3, 0xab, 0x93, 0x6e, 0xcf,
0xa9, 0xc8, 0xd5, 0x33, 0x9d, 0xd1, 0x9d, 0x64, 0x20, 0x37, 0x41, 0x0d,
0x75, 0x0e, 0x06, 0xe0, 0x9d, 0xc2, 0x23, 0xf7, 0xda, 0xa6, 0xbd, 0xf6,
0x23, 0x80, 0x45, 0x8d, 0x19, 0xf4, 0x9c, 0xe3, 0xb4, 0x84, 0x98, 0x6a,
0xff, 0xf3, 0x44, 0xc4, 0x0f, 0x16, 0x3b, 0x1a, 0xa4, 0x00, 0xc1, 0x4a,
0xbd, 0x59, 0x63, 0x3a, 0xd4, 0xe0, 0xcc, 0x9a, 0xb7, 0x6f, 0xd6, 0xdf,
0xce, 0x86, 0x2d, 0x8d, 0xf6, 0xfd, 0x29, 0xea, 0x95, 0x7f, 0xff, 0x4a,
0x67, 0xfa, 0x7f, 0xdd, 0x7d, 0x74, 0xcd, 0xdf, 0x7c, 0x8e, 0xcf, 0xb1,
0x1d, 0x6d, 0x98, 0x85, 0x54, 0x7a, 0x3b, 0x9f, 0x41, 0x8c, 0xe4, 0x55,
0x33, 0x0d, 0x1c, 0xe4, 0x14, 0x17, 0x45, 0x40, 0xfb, 0x9c, 0x38, 0x38,
0x44, 0x79, 0x1c, 0x39, 0x28, 0x38, 0x9b, 0x04, 0xce, 0x01, 0x98, 0x3e,
0x20, 0x1c, 0x11, 0x9f, 0x71, 0x54, 0x82, 0x0a, 0xc2, 0x5d, 0x96, 0x26,
0xff, 0xf3, 0x44, 0xc4, 0x09, 0x14, 0x63, 0x22, 0xa8, 0x00, 0x78, 0x4e,
0xbc, 0x99, 0xeb, 0x85, 0x6b, 0xf1, 0x6e, 0x4b, 0xff, 0xaf, 0xff, 0xcd,
0x13, 0xf6, 0xbf, 0x2b, 0xfa, 0xfc, 0xba, 0xbf, 0x7f, 0xb6, 0xbf, 0x45,
0xa7, 0xbe, 0xfa, 0xe7, 0x53, 0xeb, 0x31, 0xb5, 0xa1, 0x8a, 0xb9, 0x95,
0x44, 0x9f, 0x53, 0x19, 0xdc, 0xd9, 0xa5, 0x56, 0x61, 0xf4, 0x66, 0xa9,
0x76, 0x1c, 0xa9, 0xa6, 0x98, 0x92, 0x6c, 0x5c, 0x78, 0xf2, 0x43, 0xe3,
0xae, 0xa7, 0x16, 0x1c, 0x2e, 0x4c, 0xb8, 0x8c, 0x38, 0x70, 0x46, 0x54,
0xb9, 0x75, 0xa6, 0x9b, 0xe6, 0x1c, 0x46, 0x91, 0x30, 0x6b, 0x89, 0xef,
0xff, 0xf3, 0x44, 0xc4, 0x0a, 0x14, 0xfb, 0x22, 0xa4, 0x00, 0x78, 0x4a,
0xbc, 0x4b, 0x7f, 0xbf, 0x9f, 0xf9, 0xaf, 0xff, 0xff, 0xc8, 0x8c, 0xf0,
0x65, 0xd5, 0xf6, 0xc8, 0xbf, 0x57, 0xbd, 0x5e, 0xb6, 0xcf, 0xfa, 0xf3,
0x76, 0x6f, 0xc8, 0xee, 0x8f, 0xad, 0x59, 0xfe, 0x87, 0x91, 0x5c, 0xee,
0xa8, 0xa6, 0x32, 0x14, 0x91, 0x85, 0xa0, 0xa2, 0x65, 0x67, 0x22, 0x5d,
0x48, 0x64, 0x62, 0x89, 0x87, 0xca, 0x34, 0x83, 0x06, 0x07, 0x43, 0x82,
0x63, 0xc7, 0x09, 0x8b, 0x1d, 0x86, 0x80, 0xe3, 0x82, 0xd4, 0xa8, 0x42,
0x00, 0xe2, 0xec, 0x2d, 0x44, 0x22, 0x10, 0x89, 0x03, 0x0a, 0x38, 0xab,
0xff, 0xf3, 0x44, 0xc4, 0x09, 0x14, 0xcb, 0x1e, 0xa8, 0x00, 0x38, 0x50,
0xbc, 0x6f, 0xff, 0xff, 0xff, 0xfe, 0xdc, 0xa2, 0x07, 0x4e, 0x82, 0x6e,
0x68, 0x98, 0xcf, 0x4f, 0xee, 0xbf, 0xf8, 0xfe, 0xa7, 0xfa, 0xbd, 0x3b,
0x4b, 0xef, 0xfe, 0x3f, 0xff, 0xa9, 0x5e, 0x9b, 0xee, 0x5e, 0x23, 0xae,
0xe6, 0xdd, 0xe2, 0x21, 0x9a, 0x51, 0xd2, 0x5e, 0xee, 0x10, 0xb2, 0xee,
0xfb, 0x52, 0x39, 0x20, 0x93, 0x11, 0xec, 0x54, 0x98, 0x10, 0x58, 0xed,
0x49, 0xab, 0xa6, 0x30, 0xac, 0xf2, 0x06, 0x0b, 0x1c, 0x27, 0x41, 0x10,
0x21, 0xa3, 0xc6, 0xd5, 0x5d, 0x10, 0x1c, 0x14, 0x3c, 0xcb, 0xd3, 0xe6,
0xff, 0xf3, 0x44, 0xc4, 0x08, 0x13, 0x8b, 0x22, 0xb0, 0x00, 0x40, 0x4a,
0xbc, 0xff, 0xff, 0xe5, 0xf2, 0xff, 0xff, 0x54, 0x66, 0x4e, 0xdf, 0x59,
0xd6, 0x02, 0xcb, 0x32, 0x22, 0xff, 0xef, 0xbf, 0xb6, 0x8c, 0x9b, 0xd2,
0x8d, 0x44, 0x6c, 0x8c, 0xcd, 0xbc, 0x94, 0xb2, 0xa7, 0x64, 0x89, 0x4a,
0xe3, 0x19, 0x95, 0xa6, 0x79, 0xca, 0x2e, 0x47, 0x55, 0x2d, 0xd4, 0xf1,
0xe2, 0x51, 0x67, 0x17, 0xb2, 0x91, 0x8a, 0x2e, 0x16, 0x0c, 0x71, 0x61,
0x53, 0x9c, 0x38, 0xcc, 0x2e, 0xa2, 0x01, 0xc1, 0x10, 0xe0, 0xa3, 0xaa,
0xd7, 0xf6, 0xee, 0xa9, 0x8c, 0x8c, 0x51, 0x08, 0x7e, 0x57, 0x62, 0x26,
0xff, 0xf3, 0x44, 0xc4, 0x0c, 0x13, 0xc3, 0x0e, 0xb8, 0x00, 0xc0, 0x84,
0xb9, 0xdc, 0xd7, 0x5d, 0x1f, 0xff, 0x14, 0x39, 0xfd, 0x4f, 0xff, 0xc8,
0x4f, 0xaa, 0xec, 0xc6, 0x2a, 0xb0, 0x4d, 0x92, 0xba, 0x12, 0x8e, 0x62,
0x33, 0xb3, 0x5d, 0xdd, 0x57, 0xd1, 0x2b, 0xff, 0xf4, 0x4d, 0xea, 0xa9,
0xff, 0xba, 0x74, 0xfc, 0xed, 0xd9, 0xa9, 0x4d, 0x26, 0x7d, 0x51, 0x76,
0xb1, 0xca, 0xe9, 0x4b, 0x83, 0x50, 0x45, 0x80, 0xb3, 0x21, 0x90, 0xea,
0xcf, 0xa1, 0x5b, 0x31, 0x8a, 0x15, 0x32, 0x09, 0xb1, 0xfc, 0xe6, 0x53,
0x27, 0x48, 0x65, 0x60, 0x4f, 0xda, 0x97, 0x4e, 0x15, 0x53, 0x1f, 0xaa,
0xff, 0xf3, 0x44, 0xc4, 0x10, 0x15, 0x39, 0xba, 0xac, 0x00, 0xc9, 0xda,
0x94, 0x14, 0xcb, 0x80, 0xc1, 0x9f, 0x34, 0x69, 0xe8, 0x51, 0xfc, 0xe1,
0x3b, 0xf4, 0x10, 0x9c, 0x6b, 0x52, 0x71, 0x0e, 0xb4, 0x8d, 0x93, 0x40,
0x97, 0x06, 0xd9, 0x71, 0x05, 0x58, 0x4f, 0xcb, 0x88, 0x3a, 0x2e, 0x49,
0x09, 0x73, 0x1f, 0x42, 0x99, 0x82, 0xfd, 0x34, 0xfd, 0x54, 0x3d, 0x33,
0x7f, 0x44, 0xc5, 0x4b, 0xa4, 0x6c, 0x07, 0x67, 0xff, 0xff, 0x53, 0xc6,
0x9d, 0x59, 0xaa, 0xd7, 0xcf, 0x48, 0x05, 0x65, 0xec, 0x1b, 0xe7, 0x72,
0xff, 0x8e, 0x02, 0xc9, 0xa5, 0xd7, 0x2d, 0x4a, 0x41, 0x3a, 0xa0, 0x77,
0xff, 0xf3, 0x44, 0xc4, 0x0e, 0x12, 0x99, 0xc2, 0xb4, 0x00, 0xc9, 0xd6,
0x94, 0xf5, 0x09, 0x9f, 0xcf, 0x23, 0xf7, 0xf4, 0x1a, 0x12, 0xf5, 0x16,
0xff, 0x0d, 0x36, 0xbf, 0x61, 0x40, 0x30, 0x3f, 0x27, 0x30, 0x7c, 0x12,
0xce, 0xcf, 0x29, 0x8d, 0xe1, 0xf8, 0xeb, 0x6d, 0x83, 0x61, 0x08, 0x3f,
0x44, 0xd4, 0xdd, 0x7f, 0xb2, 0xdb, 0xfb, 0xf3, 0xbf, 0x37, 0x27, 0xcd,
0x5b, 0xbf, 0x41, 0x1a, 0xa9, 0x7f, 0xff, 0xfe, 0xaa, 0x3b, 0x17, 0x77,
0xfd, 0x4a, 0xe6, 0xbf, 0x55, 0x60, 0x21, 0xb5, 0xcb, 0xbf, 0x2b, 0x30,
0x31, 0xb3, 0xe5, 0x63, 0x9d, 0x76, 0x8d, 0x1f, 0xf1, 0x5f, 0x93, 0xc8,
0xff, 0xf3, 0x44, 0xc4, 0x16, 0x10, 0x51, 0xba, 0xb8, 0x00, 0xc1, 0x50,
0x94, 0x10, 0x7e, 0xa2, 0x62, 0x4d, 0xe5, 0x94, 0xdf, 0x96, 0x2c, 0x0b,
0x47, 0x59, 0x82, 0x80, 0x08, 0x02, 0x42, 0xd7, 0x14, 0x30, 0x45, 0x7d,
0x11, 0xc0, 0x60, 0x9e, 0xfb, 0x22, 0xcd, 0xfe, 0x3b, 0x5f, 0xe9, 0xcd,
0xae, 0x52, 0x59, 0xb7, 0x17, 0xb3, 0x09, 0xaa, 0xaa, 0xe7, 0xff, 0xf1,
0x1d, 0xc4, 0x8e, 0xaf, 0x96, 0x56, 0x42, 0xe5, 0x9f, 0x2f, 0x2c, 0xeb,
0x2f, 0x21, 0x9f, 0xce, 0xdc, 0xe7, 0x6e, 0x41, 0x45, 0xf0, 0x7e, 0x75,
0xf3, 0xfe, 0xa3, 0x62, 0x98, 0xed, 0x06, 0x01, 0x01, 0x59, 0xed, 0xa4,
0xff, 0xf3, 0x44, 0xc4, 0x27, 0x10, 0x49, 0xaa, 0xb8, 0x00, 0xc8, 0x92,
0x95, 0x04, 0x05, 0xcc, 0xd6, 0xa3, 0x24, 0x2e, 0x25, 0xcd, 0x5e, 0x69,
0x6d, 0xfb, 0xda, 0x97, 0xf5, 0xf2, 0x5b, 0xfd, 0xea, 0xbf, 0x7d, 0xeb,
0x3a, 0x6e, 0xc4, 0xd5, 0xe7, 0xf7, 0x94, 0xe3, 0x81, 0xd1, 0x8e, 0x93,
0x74, 0xaf, 0xd9, 0x04, 0x56, 0xca, 0xf2, 0xcf, 0x30, 0x8e, 0x01, 0xef,
0xca, 0x88, 0xde, 0x3e, 0x51, 0xfb, 0x0b, 0x8d, 0xb9, 0x84, 0x09, 0x3e,
0x60, 0xe9, 0x2b, 0x4d, 0xc2, 0x4b, 0x5a, 0x17, 0x01, 0xe0, 0x06, 0x0e,
0x4c, 0x48, 0x2c, 0x2c, 0x69, 0x8a, 0x58, 0x8c, 0x10, 0xc5, 0x6e, 0x79,
0xff, 0xf3, 0x44, 0xc4, 0x38, 0x12, 0x91, 0x9a, 0xb4, 0x00, 0xd1, 0xd0,
0x95, 0x97, 0xd2, 0x5d, 0x7e, 0x93, 0x1d, 0x42, 0x4c, 0x5d, 0xc9, 0x6a,
0xc7, 0x04, 0x46, 0x05, 0x28, 0xaf, 0xfe, 0xd5, 0xc3, 0x9f, 0xb8, 0xe0,
0x31, 0xcd, 0xf4, 0xb2, 0xcc, 0x64, 0x47, 0x13, 0x9e, 0x0c, 0x77, 0x0b,
0xa4, 0xc7, 0x3b, 0x96, 0x6f, 0x86, 0x03, 0xa6, 0xba, 0xf8, 0x7e, 0xe3,
0x5f, 0xf2, 0xa3, 0x5e, 0xe6, 0x99, 0x34, 0xbc, 0xd7, 0x15, 0x9a, 0x95,
0x20, 0x10, 0x10, 0xb2, 0xe7, 0x2e, 0x03, 0x90, 0x34, 0x9f, 0x99, 0xa1,
0x4a, 0xd5, 0x63, 0x02, 0x12, 0x54, 0x31, 0xdb, 0x73, 0xe7, 0xb7, 0xa9,
0xff, 0xf3, 0x44, 0xc4, 0x40, 0x11, 0xd9, 0x2a, 0xb4, 0x00, 0xc3, 0xd2,
0x70, 0x74, 0x95, 0x36, 0x48, 0x58, 0xb1, 0xe2, 0x4a, 0xb3, 0xac, 0x2e,
0xc9, 0xc0, 0x22, 0xdc, 0x93, 0x4b, 0x21, 0xf0, 0x45, 0x2b, 0x16, 0x4d,
0x1e, 0x58, 0x00, 0xe4, 0x24, 0x75, 0x8b, 0xf4, 0x8e, 0xc4, 0x35, 0x2c,
0xdf, 0xd7, 0x8d, 0x52, 0x59, 0xef, 0xd3, 0xd2, 0xf8, 0x45, 0x51, 0xa3,
0xf2, 0xc9, 0xb2, 0x8b, 0x20, 0xa9, 0x12, 0x68, 0x15, 0x2e, 0x90, 0x0e,
0x26, 0x6b, 0xa3, 0xb1, 0x52, 0xda, 0xa1, 0xf1, 0x0a, 0x12, 0x59, 0x24,
0x42, 0xe3, 0xa3, 0x02, 0x8f, 0xfa, 0xfa, 0x95, 0x45, 0xef, 0x32, 0xf4,
0xff, 0xf3, 0x44, 0xc4, 0x4b, 0x11, 0xe9, 0x1e, 0xb0, 0x00, 0xce, 0x12,
0x70, 0x97, 0x43, 0x6a, 0x7b, 0xd9, 0x32, 0x80, 0xf2, 0xcd, 0xce, 0xc4,
0x50, 0x16, 0x03, 0x7a, 0x5c, 0xce, 0xed, 0xdb, 0x6d, 0xa5, 0xb6, 0x72,
0xa9, 0x1f, 0xb1, 0x8e, 0xe5, 0x72, 0xf9, 0xde, 0xd2, 0x04, 0xc5, 0x2c,
0xed, 0x93, 0xa4, 0x69, 0x40, 0x40, 0x26, 0x48, 0x2a, 0x80, 0xa0, 0x48,
0x46, 0x66, 0x64, 0x88, 0x5e, 0x4a, 0x99, 0xb5, 0x99, 0x22, 0xd6, 0xd6,
0x65, 0xf1, 0x01, 0x9e, 0x1f, 0xfd, 0x8e, 0x39, 0x4a, 0xfe, 0xe1, 0x4e,
0x31, 0x55, 0x27, 0x45, 0x2a, 0x80, 0x8d, 0x63, 0x28, 0x4b, 0xfd, 0x13,
0xff, 0xf3, 0x44, 0xc4, 0x56, 0x11, 0xa9, 0x16, 0xb4, 0x00, 0xc6, 0x12,
0x70, 0x43, 0x81, 0xe9, 0x50, 0xf2, 0xce, 0x4e, 0xa1, 0x84, 0x60, 0x95,
0xde, 0xdb, 0xee, 0xa5, 0xd2, 0xec, 0x6e, 0xbc, 0x6e, 0xd5, 0xfc, 0x72,
0x56, 0x1c, 0x51, 0xa5, 0x90, 0xb0, 0x12, 0x68, 0xd0, 0x49, 0x18, 0x4f,
0x0f, 0xd8, 0x6f, 0x1c, 0x89, 0xf9, 0x61, 0xd5, 0x98, 0x10, 0x38, 0xb5,
0xf2, 0x70, 0xbd, 0x7b, 0xaa, 0x32, 0xbd, 0x8b, 0xaf, 0x18, 0x3a, 0xb2,
0x36, 0x7b, 0xe5, 0xbf, 0xff, 0xff, 0xff, 0xeb, 0x4f, 0xff, 0xa1, 0x15,
0xc3, 0xb5, 0x60, 0x23, 0x19, 0x04, 0x4a, 0xa5, 0xac, 0xe9, 0x80, 0xe5,
0xff, 0xf3, 0x44, 0xc4, 0x62, 0x15, 0x59, 0x16, 0xa4, 0x00, 0xc6, 0x5e,
0x70, 0x87, 0x6c, 0xcf, 0x81, 0x38, 0x34, 0xc1, 0x70, 0xad, 0xf1, 0x47,
0xaf, 0x5a, 0xce, 0x20, 0xc1, 0x67, 0xec, 0xfc, 0x61, 0x8a, 0xd5, 0xab,
0x40, 0xd6, 0x0c, 0x68, 0xd9, 0x5d, 0x83, 0xd1, 0x5c, 0xfb, 0xa2, 0xc6,
0x6a, 0xfb, 0x43, 0xf4, 0x5a, 0xf4, 0x7d, 0x4a, 0x9e, 0x7b, 0x25, 0x9f,
0x2e, 0xd9, 0x46, 0x8b, 0x1e, 0x59, 0x1f, 0xf6, 0xae, 0xcf, 0xff, 0xff,
0xff, 0xfa, 0xbf, 0xfd, 0x6a, 0xca, 0xd6, 0x51, 0x10, 0x3b, 0x52, 0xcb,
0xf1, 0x40, 0xbd, 0xab, 0xfa, 0x35, 0x2b, 0x49, 0x53, 0x73, 0x40, 0x14,
0xff, 0xf3, 0x44, 0xc4, 0x5f, 0x12, 0xd8, 0xea, 0xa0, 0x00, 0xce, 0x5e,
0x70, 0x59, 0xbf, 0x9c, 0xa7, 0x62, 0x31, 0x4c, 0xf1, 0x4e, 0xe8, 0x7b,
0x2b, 0x0e, 0x9b, 0x93, 0x45, 0x5f, 0xa4, 0x00, 0xa7, 0xa2, 0x52, 0x69,
0x48, 0x2a, 0x2b, 0x56, 0x04, 0xbb, 0x36, 0xe4, 0xd8, 0xe7, 0x67, 0x75,
0x7b, 0x39, 0x5b, 0xfb, 0x4b, 0xcd, 0x6a, 0x98, 0xf3, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xe9, 0x8d, 0xef, 0x6d, 0x10, 0xeb, 0x05,
0x7e, 0x74, 0xfb, 0x8e, 0xd7, 0x4c, 0x48, 0xb3, 0x67, 0x10, 0x0a, 0x1c,
0x90, 0xb8, 0xd0, 0x0c, 0xbe, 0xf3, 0x38, 0x96, 0xd3, 0x54, 0x5f, 0x08,
0xff, 0xf3, 0x44, 0xc4, 0x66, 0x12, 0x00, 0xe2, 0x98, 0x00, 0xce, 0xb0,
0x70, 0xd3, 0x8f, 0xc1, 0x49, 0xab, 0x62, 0x9a, 0x61, 0x6d, 0x0d, 0x10,
0xc3, 0xaf, 0x23, 0xf0, 0x14, 0x15, 0x8b, 0x31, 0xb6, 0x97, 0xf8, 0xde,
0x8f, 0xca, 0xb3, 0xce, 0x9a, 0x19, 0xb7, 0xf7, 0x71, 0xbf, 0xc2, 0x8e,
0xa7, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfa, 0xbf, 0xfe, 0x9a, 0xc3, 0x7d,
0x80, 0x87, 0xef, 0xca, 0xc2, 0xf3, 0x1c, 0x44, 0x6a, 0x0d, 0x2d, 0x30,
0x4b, 0x47, 0xa9, 0xee, 0x73, 0xec, 0xa9, 0x16, 0x93, 0x6f, 0x2a, 0x96,
0xad, 0x79, 0x9c, 0xaf, 0xac, 0x03, 0xb5, 0x95, 0x78, 0xe2, 0xf9, 0x6c,
0xff, 0xf3, 0x44, 0xc4, 0x71, 0x12, 0xa0, 0xde, 0x90, 0x00, 0xd6, 0xf0,
0x70, 0xd1, 0xaa, 0x91, 0xe1, 0x62, 0xe6, 0xec, 0x3d, 0x90, 0x65, 0x14,
0xcc, 0x6e, 0x0d, 0x9f, 0x95, 0xca, 0xef, 0xbc, 0xf7, 0x2f, 0x61, 0x1c,
0xbc, 0xe0, 0x62, 0x73, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xe3, 0x3e,
0x8a, 0xb3, 0xdd, 0x37, 0x13, 0x88, 0x08, 0x77, 0x74, 0x06, 0x30, 0x4b,
0x56, 0x1e, 0x70, 0x45, 0x69, 0x4e, 0x1b, 0xb1, 0x48, 0x6c, 0x1d, 0x5b,
0xf7, 0x4d, 0x01, 0xb0, 0x29, 0x16, 0xa4, 0xad, 0x3a, 0x1d, 0xca, 0x48,
0xca, 0x1b, 0x6b, 0x3c, 0x2f, 0x87, 0x69, 0xe2, 0xca, 0x55, 0x89, 0x98,
0xff, 0xf3, 0x44, 0xc4, 0x79, 0x12, 0x60, 0xda, 0x9c, 0x00, 0xce, 0x70,
0x70, 0x6a, 0x55, 0x94, 0x27, 0xe5, 0xea, 0x3b, 0x79, 0xcf, 0x11, 0xf4,
0xaa, 0x74, 0xf4, 0x77, 0xaa, 0x43, 0xa2, 0x7a, 0xe2, 0x04, 0x5c, 0xde,
0x98, 0xfe, 0x01, 0x85, 0x3e, 0xfb, 0xec, 0xff, 0xff, 0xff, 0xff, 0xef,
0x5a, 0x7f, 0xf6, 0xb3, 0xa5, 0x15, 0xee, 0xab, 0x90, 0x00, 0x06, 0x19,
0x05, 0xd9, 0x81, 0x29, 0xd2, 0x56, 0x8b, 0x11, 0x62, 0x45, 0x72, 0x5c,
0x8a, 0x82, 0x5a, 0x8f, 0xfa, 0x47, 0x94, 0x56, 0xae, 0x56, 0xd3, 0xc6,
0x73, 0xe5, 0x29, 0xc5, 0x47, 0xba, 0x56, 0x9d, 0x96, 0xe5, 0x4d, 0x26,
0xff, 0xf3, 0x44, 0xc4, 0x82, 0x15, 0xd9, 0x12, 0xa0, 0x00, 0xce, 0x5e,
0x70, 0x4f, 0x94, 0xba, 0x22, 0x92, 0x52, 0x2d, 0x3b, 0x6d, 0xa6, 0xf3,
0xc2, 0x4a, 0x84, 0x87, 0x2d, 0x74, 0x93, 0x81, 0x15, 0x16, 0x9e, 0x19,
0x72, 0xb1, 0x0f, 0xed, 0x2f, 0xf7, 0x1c, 0xf7, 0x55, 0xf3, 0x0d, 0xf8,
0x6b, 0x76, 0xae, 0x7d, 0x2d, 0xff, 0x57, 0xff, 0xff, 0xd8, 0x5b, 0xce,
0xce, 0xda, 0x65, 0x8d, 0x4d, 0x03, 0x90, 0xde, 0xaa, 0xa6, 0xf0, 0xb2,
0xe7, 0xb9, 0x42, 0xa1, 0x96, 0xf9, 0x50, 0xb7, 0xd6, 0x3f, 0x02, 0xab,
0xa2, 0x5a, 0xd0, 0xe8, 0x48, 0x8b, 0x86, 0x33, 0x4c, 0x72, 0xf6, 0xa6,
0xff, 0xf3, 0x44, 0xc4, 0x7d, 0x17, 0xf9, 0x76, 0xa0, 0x00, 0xc6, 0x16,
0x94, 0xda, 0xe5, 0xef, 0xf3, 0x47, 0x7f, 0x23, 0x41, 0xf5, 0x67, 0x44,
0x11, 0xed, 0x73, 0xae, 0x46, 0xa3, 0x85, 0xf0, 0xdb, 0x9f, 0x46, 0x5f,
0xbe, 0xb9, 0x83, 0x8d, 0x37, 0xb4, 0xcf, 0x48, 0xa8, 0x38, 0xf8, 0xcc,
0x2c, 0xfc, 0x47, 0xbc, 0x29, 0x24, 0xb6, 0x44, 0x90, 0x2c, 0x4c, 0xc5,
0x7e, 0xef, 0xff, 0xff, 0xff, 0x7f, 0x7b, 0x19, 0xb1, 0x35, 0xb7, 0xbd,
0x40, 0x62, 0xee, 0x8b, 0xf2, 0x00, 0x2f, 0xec, 0xc5, 0x5a, 0xe1, 0x65,
0xd3, 0xcc, 0x49, 0x44, 0x22, 0x1e, 0x04, 0x7a, 0xb8, 0xe8, 0xc9, 0xa9,
0xff, 0xf3, 0x44, 0xc4, 0x70, 0x15, 0x59, 0x36, 0xa8, 0x00, 0xc6, 0x1e,
0x70, 0x14, 0xd4, 0x18, 0xed, 0xff, 0x28, 0x1a, 0x3d, 0xde, 0xf4, 0xce,
0x77, 0x7a, 0x1b, 0x0e, 0x36, 0xdc, 0xe1, 0xa5, 0x37, 0xc1, 0x9f, 0xad,
0xf5, 0xd6, 0xf3, 0xb5, 0xd4, 0x7f, 0xb6, 0xb9, 0x31, 0xad, 0x28, 0xbc,
0xd7, 0x56, 0x4f, 0x7e, 0xdb, 0x6f, 0xe0, 0xed, 0x9d, 0x9e, 0x61, 0x28,
0x35, 0x15, 0x72, 0x7d, 0xff, 0xff, 0xff, 0xeb, 0xe8, 0xc3, 0x7b, 0x68,
0x82, 0xd8, 0xb5, 0x83, 0x72, 0x4c, 0x76, 0xd6, 0xd5, 0x00, 0xa3, 0xa7,
0xf8, 0xec, 0x85, 0x0c, 0x24, 0x59, 0x87, 0xdc, 0x44, 0x16, 0x9f, 0x02,
0xff, 0xf3, 0x44, 0xc4, 0x6d, 0x14, 0x81, 0x32, 0xa4, 0x00, 0xc6, 0x1e,
0x70, 0x5b, 0xaf, 0x0f, 0x5e, 0xb1, 0x2a, 0x9b, 0xa3, 0xb3, 0xd4, 0x32,
0xd4, 0x2c, 0x97, 0x0e, 0x1e, 0xa2, 0x41, 0x14, 0xe6, 0x27, 0xc3, 0xff,
0xdb, 0xdf, 0x2f, 0x6d, 0x7e, 0x97, 0x85, 0xf6, 0x33, 0x54, 0x6e, 0x79,
0x82, 0x4a, 0x1a, 0xec, 0xfd, 0x11, 0x1a, 0x48, 0xaa, 0xd5, 0x25, 0x0a,
0x40, 0x21, 0xc9, 0xa4, 0xc8, 0x5a, 0x9a, 0x34, 0x89, 0x0e, 0xbc, 0x57,
0x6e, 0x88, 0x72, 0x9e, 0x49, 0x44, 0x49, 0x44, 0xe4, 0x7c, 0xb9, 0x13,
0x73, 0x70, 0xf9, 0xb7, 0x6a, 0xd7, 0xf8, 0x92, 0x5b, 0x10, 0x7a, 0xbe,
0xff, 0xf3, 0x44, 0xc4, 0x6e, 0x11, 0x89, 0x12, 0xa8, 0x00, 0xc6, 0x18,
0x70, 0x82, 0x80, 0x51, 0x3a, 0x10, 0x0e, 0x40, 0xb7, 0x48, 0x4b, 0x7b,
0x04, 0x9a, 0xe9, 0x31, 0xdf, 0x02, 0x38, 0xa1, 0xa1, 0x41, 0x2c, 0x4a,
0x3d, 0x41, 0xaf, 0xb5, 0x62, 0x68, 0xb0, 0xe4, 0xb9, 0x3f, 0xff, 0xff,
0xff, 0x65, 0x35, 0x9d, 0xee, 0x0e, 0xf1, 0x39, 0x52, 0x3e, 0x44, 0x03,
0x9d, 0x97, 0xe3, 0x50, 0x3c, 0x09, 0xaa, 0xf7, 0x4c, 0x84, 0xe2, 0xd8,
0xcf, 0xd1, 0x34, 0x2c, 0x7e, 0x0d, 0x6f, 0x75, 0xa9, 0x2b, 0xe5, 0xf9,
0xdc, 0x63, 0xf8, 0xd9, 0xbb, 0x4b, 0x69, 0x0e, 0xad, 0x30, 0x27, 0x7a,
0xff, 0xf3, 0x44, 0xc4, 0x7a, 0x13, 0x19, 0x16, 0xa4, 0x00, 0x7e, 0x12,
0x70, 0x7d, 0x37, 0x65, 0xf7, 0xb2, 0xa7, 0x77, 0xc3, 0x95, 0x29, 0x85,
0xd3, 0x83, 0x76, 0x59, 0xfd, 0xb7, 0x25, 0x5b, 0xef, 0xe4, 0x61, 0x25,
0x8a, 0x18, 0xbf, 0xef, 0xff, 0xff, 0xff, 0xfe, 0xdf, 0xa1, 0xc7, 0x95,
0x07, 0x52, 0x1b, 0x2b, 0x77, 0x9d, 0x20, 0x76, 0xe8, 0xad, 0x57, 0x03,
0x62, 0x24, 0x7a, 0x97, 0x00, 0xc0, 0x90, 0x1d, 0xc8, 0x97, 0x04, 0x48,
0x7a, 0xc7, 0xc8, 0xde, 0xd8, 0x6c, 0xf2, 0x77, 0xc0, 0xdc, 0xde, 0x45,
0x17, 0x1e, 0x50, 0x00, 0x46, 0x6e, 0x65, 0x91, 0xbe, 0x4e, 0xfa, 0xa6,
0xff, 0xf3, 0x44, 0xc4, 0x80, 0x13, 0x71, 0x1e, 0x9c, 0x00, 0xce, 0x5e,
0x70, 0xd5, 0x70, 0x3c, 0x9d, 0xb6, 0x91, 0x8c, 0xff, 0x5b, 0xbb, 0xed,
0x48, 0x78, 0xa0, 0x8d, 0x22, 0xb5, 0x7d, 0x5f, 0xff, 0xff, 0xaf, 0xfe,
0x9f, 0xa9, 0xbd, 0x8c, 0x78, 0x72, 0xe7, 0x81, 0x43, 0x35, 0x98, 0x58,
0x85, 0xd4, 0x92, 0xc8, 0xa1, 0xcc, 0x49, 0x0d, 0xda, 0x94, 0xa1, 0xc6,
0x11, 0x85, 0x32, 0x8f, 0x6b, 0xf7, 0x42, 0xf6, 0xff, 0xdc, 0x9b, 0xc3,
0x78, 0x96, 0xf5, 0x21, 0xf6, 0xad, 0x80, 0x80, 0x5f, 0x27, 0x40, 0xb0,
0xca, 0xaf, 0x3b, 0x1c, 0xdf, 0xc9, 0xad, 0xf0, 0x3d, 0x46, 0x70, 0x7a,
0xff, 0xf3, 0x44, 0xc4, 0x85, 0x12, 0xb1, 0x26, 0x98, 0x00, 0xc5, 0x16,
0x70, 0x3d, 0x0d, 0x7f, 0xd7, 0x50, 0x75, 0x4f, 0xbb, 0xff, 0xff, 0xff,
0xf2, 0x32, 0xcc, 0x4f, 0xfa, 0x95, 0x7b, 0x2c, 0xd7, 0x56, 0x02, 0x7f,
0x8b, 0x32, 0x15, 0x0e, 0x9a, 0x43, 0x71, 0xe8, 0x64, 0x70, 0x31, 0xc5,
0x73, 0xc8, 0x7a, 0x7a, 0x9a, 0x7b, 0x76, 0x5b, 0xb4, 0xb7, 0x77, 0x6e,
0xc3, 0xbf, 0xf9, 0x45, 0xb9, 0xcf, 0x7c, 0x68, 0xd9, 0x10, 0xfa, 0x0a,
0x0d, 0x22, 0x4e, 0x88, 0x8f, 0xfb, 0xdd, 0xff, 0xd6, 0xfb, 0xad, 0xc8,
0xd7, 0xd7, 0xf6, 0xf4, 0xff, 0xcb, 0xb8, 0xd7, 0xff, 0xff, 0xff, 0xe2,
0xff, 0xf3, 0x44, 0xc4, 0x8d, 0x12, 0x91, 0x12, 0x90, 0x00, 0xc6, 0x96,
0x70, 0xb0, 0xef, 0xfa, 0x49, 0xa5, 0xca, 0xa8, 0x88, 0xf5, 0x96, 0xc7,
0x1f, 0xc0, 0xa3, 0xc0, 0xa4, 0x34, 0x2f, 0x65, 0xee, 0x51, 0x8b, 0x41,
0x0d, 0x39, 0x6e, 0xb9, 0x90, 0xc1, 0x07, 0x8a, 0xcb, 0xe1, 0x8a, 0xd5,
0xf5, 0x2a, 0x8b, 0x34, 0x91, 0xd1, 0x52, 0xc8, 0xec, 0xed, 0xa9, 0xd5,
0x46, 0x61, 0x60, 0xd0, 0x52, 0x4a, 0x41, 0x6d, 0x23, 0x74, 0x56, 0xf7,
0x4b, 0x80, 0xc0, 0x3f, 0xfe, 0xa7, 0xae, 0xdb, 0x7f, 0xff, 0xff, 0xff,
0xfa, 0x7a, 0xfa, 0x55, 0x46, 0x63, 0x12, 0x28, 0xc1, 0x86, 0x35, 0x34,
0xff, 0xf3, 0x44, 0xc4, 0x95, 0x12, 0xa1, 0x12, 0x84, 0x00, 0xd6, 0x92,
0x70, 0x0f, 0x2d, 0x43, 0x56, 0x10, 0xbb, 0xcb, 0x7a, 0x04, 0x43, 0x12,
0xca, 0x82, 0x82, 0x4a, 0x23, 0x58, 0x18, 0x33, 0x5a, 0x72, 0x98, 0x73,
0x93, 0x0e, 0xe1, 0x4c, 0xb0, 0x58, 0x0a, 0x5d, 0x98, 0xc6, 0x28, 0x5c,
0x58, 0x35, 0x35, 0x08, 0x40, 0x08, 0x97, 0xc6, 0x9a, 0xd6, 0xc1, 0x51,
0xa0, 0xa8, 0x35, 0x12, 0xd4, 0x0d, 0x05, 0x4e, 0xea, 0x3d, 0xd4, 0x7b,
0xff, 0xff, 0xff, 0xff, 0xfd, 0x2a, 0x10, 0xa4, 0x12, 0x54, 0x7c, 0x38,
0xa8, 0x43, 0x2e, 0x16, 0x5e, 0x60, 0x17, 0x0d, 0xad, 0x9d, 0xa6, 0x2d,
0xff, 0xf3, 0x44, 0xc4, 0x9d, 0x10, 0x50, 0xaa, 0x7c, 0x00, 0xd6, 0x12,
0x4c, 0x55, 0x7e, 0x1c, 0x55, 0x55, 0xb6, 0x06, 0x70, 0x54, 0x32, 0xd6,
0x00, 0xa3, 0x5a, 0x59, 0x01, 0x38, 0x44, 0x79, 0x24, 0xce, 0xd2, 0xd6,
0x15, 0x0c, 0x99, 0x85, 0x5d, 0x88, 0x81, 0xa5, 0x07, 0x5a, 0x74, 0x4b,
0xb4, 0x96, 0xf4, 0xce, 0x86, 0xb5, 0x3e, 0xe5, 0x3d, 0x6b, 0xf7, 0xfc,
0x97, 0xd7, 0xfe, 0xaa, 0x02, 0x74, 0x4e, 0x08, 0x59, 0x78, 0x47, 0xa5,
0x11, 0xc5, 0xc4, 0x95, 0x13, 0x23, 0x0c, 0xe4, 0x51, 0xb2, 0x39, 0xa0,
0x9c, 0x47, 0xf9, 0xb2, 0x71, 0xa2, 0x80, 0x8f, 0x8b, 0x87, 0x8d, 0x93,
0xff, 0xf3, 0x44, 0xc4, 0xae, 0x12, 0x18, 0xb2, 0x5c, 0x00, 0xd6, 0x12,
0x4c, 0x4e, 0x2e, 0x37, 0x3b, 0x3b, 0xb3, 0xfc, 0xb2, 0xd4, 0x3f, 0xd6,
0x5b, 0x3f, 0x96, 0x19, 0xac, 0xbd, 0x60, 0xa0, 0x81, 0x03, 0x8f, 0x8b,
0x33, 0xff, 0x82, 0xc2, 0xe2, 0x37, 0x7d, 0x4d, 0xfe, 0x2a, 0x28, 0xdf,
0xff, 0x16, 0xd4, 0x2f, 0x4c, 0x41, 0x4d, 0x45, 0x33, 0x2e, 0x31, 0x30,
0x30, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55,
0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55,
0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x4c, 0x41, 0x4d, 0x45, 0x33, 0x2e,
0xff, 0xf3, 0x44, 0xc4, 0xb8, 0x11, 0x20, 0xda, 0x00, 0x00, 0x62, 0x06,
0x70, 0x31, 0x30, 0x30, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55,
0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55,
0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55,
0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55,
0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55,
0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55,
0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x4c, 0x41, 0x4d, 0x45, 0x33, 0x2e,
0xff, 0xf3, 0x44, 0xc4, 0xc6, 0x11, 0xb9, 0x49, 0x90, 0x00, 0x79, 0x86,
0x94, 0x31, 0x30, 0x30, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55,
0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55,
0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55,
0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55,
0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55,
0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55,
0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x4c, 0x41, 0x4d, 0x45, 0x33, 0x2e,
0xff, 0xf3, 0x44, 0xc4, 0xac, 0x00, 0x00, 0x03, 0x48, 0x00, 0x00, 0x00,
0x00, 0x31, 0x30, 0x30, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55,
0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55,
0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55,
0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55,
0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55,
0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55,
0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x4c, 0x41, 0x4d, 0x45, 0x33, 0x2e,
0xff, 0xf3, 0x44, 0xc4, 0xac, 0x00, 0x00, 0x03, 0x48, 0x00, 0x00, 0x00,
0x00, 0x31, 0x30, 0x30, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55,
0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55,
0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55,
0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55,
0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55,
0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55,
0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x4c, 0x41, 0x4d, 0x45, 0x33, 0x2e,
0xff, 0xf3, 0x44, 0xc4, 0xac, 0x00, 0x00, 0x03, 0x48, 0x00, 0x00, 0x00,
0x00, 0x31, 0x30, 0x30, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55,
0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55,
0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55,
0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55,
0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55,
0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55,
0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x1c, 0xe0, 0x43, 0x42, 0x88, 0x20,
0xff, 0xf3, 0x44, 0xc4, 0xac, 0x00, 0x00, 0x03, 0x48, 0x00, 0x00, 0x00,
0x00, 0x9a, 0x09, 0xa0, 0x5e, 0x03, 0x90, 0x30, 0x02, 0x46, 0x3f, 0xd7,
0x8b, 0x61, 0x38, 0x2e, 0x04, 0x81, 0x40, 0x30, 0x05, 0x93, 0xec, 0x2c,
0x8c, 0x13, 0x3f, 0x0c, 0x23, 0x36, 0x81, 0xc8, 0xd1, 0xa3, 0xa6, 0xc4,
0x00, 0x80, 0x20, 0x18, 0x8a, 0xe2, 0xb2, 0x7b, 0xeb, 0x8b, 0x34, 0x00,
0x00, 0x00, 0x03, 0x17, 0xf1, 0x02, 0x00, 0x23, 0xff, 0x10, 0x00, 0x00,
0xbf, 0x40, 0x80, 0x00, 0x02, 0x3d, 0x11, 0x11, 0x13, 0x74, 0xc3, 0x81,
0x99, 0x71, 0xc0, 0xf8, 0x3e, 0xc0, 0xf9, 0x70, 0x7c, 0x40, 0x08, 0x41,
0xff, 0xf3, 0x44, 0xc4, 0xac, 0x00, 0x00, 0x03, 0x48, 0x00, 0x00, 0x00,
0x00, 0x01, 0x87, 0x1f, 0xc9, 0x88, 0x1f, 0x39, 0xf0, 0xc1, 0x0d, 0x43,
0x1d, 0xfc, 0x49, 0x59, 0xf5, 0x9c, 0x89, 0xc3, 0xea, 0x2d, 0xc9, 0x54,
0x40, 0xa7, 0x2a, 0x65, 0xd5, 0x2a, 0x58, 0x67, 0xdd, 0xc5, 0x7a, 0x8b,
0x54, 0x86, 0xcd, 0x79, 0xc6, 0x92, 0xce, 0x39, 0x51, 0x30, 0x49, 0x10,
0xa9, 0xb6, 0x4a, 0xa0, 0x00, 0x48, 0xcb, 0x81, 0x22, 0x23, 0x60, 0x8b,
0xad, 0x23, 0x40, 0x30, 0x15, 0x19, 0x00, 0xa0, 0x4a, 0x12, 0x51, 0xa3,
0x3a, 0xca, 0xc4, 0xc8, 0x91, 0x6c, 0x56, 0x44, 0xd4, 0x91, 0x6c, 0xa6,
0xff, 0xf3, 0x44, 0xc4, 0xac, 0x00, 0x00, 0x03, 0x48, 0x00, 0x00, 0x00,
0x00, 0xcd, 0x22, 0x9a, 0x4d, 0x7a, 0x35, 0x16, 0xaa, 0x25, 0xa7, 0x58,
0x05, 0x4c, 0x95, 0x6f, 0xef, 0x39, 0x26, 0xa2, 0x52, 0x4e, 0xd5, 0x53,
0xe5, 0x92, 0x98, 0xaa, 0xce, 0xc4, 0xb6, 0x5e, 0x73, 0xef, 0x67, 0x96,
0xdf, 0xfc, 0xb6, 0xcd, 0x56, 0x9d, 0xb2, 0x75, 0x82, 0xcd, 0x23, 0x9e,
0x13, 0x12, 0x7c, 0x54, 0x19, 0x11, 0x80, 0xb9, 0x29, 0x22, 0x4b, 0x3b,
0x59, 0xd1, 0x2b, 0x83, 0xb5, 0x08, 0x70, 0xc9, 0x27, 0x87, 0x5a, 0x81,
0x8d, 0x74, 0x7a, 0x9b, 0x07, 0xb2, 0x2d, 0x38, 0x27, 0x30, 0x7c, 0x95,
0xff, 0xf3, 0x44, 0xc4, 0xff, 0x1b, 0x19, 0x7d, 0xf0, 0x00, 0x7a, 0x46,
0x94, 0x12, 0xa9, 0xa9, 0x3a, 0xb9, 0x2a, 0x58, 0xe9, 0xd4, 0x97, 0x84,
0xe0, 0xed, 0xfd, 0xca, 0x88, 0xa8, 0xa9, 0xfe, 0xe5, 0x30, 0x50, 0x40,
0x8e, 0x47, 0xcc, 0x50, 0x40, 0x84, 0x86, 0x9f, 0xfe, 0x02, 0x09, 0x0a,
0x86, 0x6b, 0x14, 0x6f, 0xeb, 0x14, 0xe2, 0xc2, 0xba, 0xc5, 0x1a, 0x81,
0xe2, 0xa2, 0xd8, 0x48, 0x5c, 0x46, 0xe8, 0xa8, 0xb2, 0x4c, 0x41, 0x4d,
0x45, 0x33, 0x2e, 0x31, 0x30, 0x30, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
0xff, 0xf3, 0x44, 0xc4, 0xe5, 0x1f, 0x9a, 0x31, 0xf8, 0x00, 0xc2, 0x4c,
0xb8, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
0xff, 0xf3, 0x44, 0xc4, 0xb9, 0x12, 0xa9, 0x25, 0x88, 0x00, 0x7a, 0x44,
0x70, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa
};
unsigned int zero_mp3_len = 4320;

View File

@@ -0,0 +1,35 @@
# Digital output via I2S to a external DAC
Somtimes we want to store the sound file in memory. [Audacity](https://www.audacityteam.org/) might help you out here: export with the file name audio.raw as RAW signed 16 bit PCM and copy it to the SD card. In the example I was just using one channel to save memory!.
Then you can convert the file with xxd into a C file that contains the data in an array. In the Sketch I am using the __MemoryStream class__ which turns the array into a Stream.
Please note that you must compile this sketch with the __Partition Scheme: Huge App__!
### External DAC:
![DAC](https://pschatzmann.github.io/Resources/img/dac.jpeg)
For my tests I am using the 24-bit PCM5102 PCM5102A Stereo DAC Digital-to-analog Converter PLL Voice Module pHAT
I am just using the default pins defined by the framework. However I could change them with the help of the config object. The mute pin can be defined in the constructor of the I2SStream - by not defining anything we use the default which is GPIO23
DAC | ESP32
-----|----------------
VCC | 5V
GND | GND
BCK | BCK (GPIO14)
DIN | OUT (GPIO22)
LCK | BCK (GPIO15)
FMT | GND
XMT | 3V (or another GPIO PIN which is set to high)
- DMP - De-emphasis control for 44.1kHz sampling rate(1): Off (Low) / On (High)
- FLT - Filter select : Normal latency (Low) / Low latency (High)
- SCL - System clock input (probably SCL on your board).
- FMT - Audio format selection : I2S (Low) / Left justified (High)
- XMT - Soft mute control(1): Soft mute (Low) / soft un-mute (High)

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,33 @@
/**
* @file streams-memory_raw-i2s.ino
* @author Phil Schatzmann
* @brief Compile with Partition Scheme Hughe APP!
* @version 0.1
* @date 2021-01-24
*
* @copyright Copyright (c) 2021
*
*/
#include "AudioTools.h"
#include "StarWars30.h"
AudioInfo info(22050, 1, 16);
I2SStream i2s; // Output to I2S
MemoryStream music(StarWars30_raw, StarWars30_raw_len);
StreamCopy copier(i2s, music); // copies sound into i2s
void setup(){
Serial.begin(115200);
AudioToolsLogger.begin(Serial, AudioToolsLogLevel::Info);
auto config = i2s.defaultConfig(TX_MODE);
config.copyFrom(info);
i2s.begin(config);
}
void loop(){
if (!copier.copy()){
i2s.end();
stop();
}
}

View File

@@ -0,0 +1,19 @@
# Decoding a WAV file
In this example we decode a WAV file into RAW output and send it to a PWM pins (on a Raspberry Pico or ESP32)
The WAV file has been down sampled with the help of __Audacity__ and then converted into an array with __xxd__.
Please note that this example is still using the more confusing old api which uses the following processing chain:
MemoryStream -> AudioOutputStream -> WAVDecoder -> AudioPWM
The pins depend on the Processor:
| PIEZO | ESP32 | RPI Pico | MBED |
| --------| -------------|---------------|--------------|
| + | GPIO4 | GPIO2 | GPIO2 |
| - | GND | | |
Complie with Partition Scheme Huge APP!

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,52 @@
/**
* @file stream-memory_wav-pwm.ino
* @author Phil Schatzmann
* @brief decode WAV stream and output to PWM pins
* @version 0.1
* @date 2021-01-24
*
* @copyright Copyright (c) 2021
*/
#include "AudioTools.h"
//#include "knghtsng.h"
#include "alice.h"
//Data Flow: MemoryStream -> EncodedAudioStream -> PWMAudioOutput
//Use 8000 for alice_wav and 11025 for knghtsng_wav
AudioInfo info(8000, 1, 16);
//MemoryStream wav(knghtsng_wav, knghtsng_wav_len);
MemoryStream wav(alice_wav, alice_wav_len);
PWMAudioOutput pwm; // PWM output
EncodedAudioStream out(&pwm, new WAVDecoder()); // Decoder stream
StreamCopy copier(out, wav); // copy in to out
void setup(){
Serial.begin(115200);
AudioToolsLogger.begin(Serial, AudioToolsLogLevel::Info);
wav.begin();
out.begin();
auto config = pwm.defaultConfig();
config.copyFrom(info);
pwm.begin(config);
}
void loop(){
if (wav) {
copier.copy();
} else {
// after we are done we just print some info form the wav file
auto info = out.audioInfo();
LOGI("The audio rate from the wav file is %d", info.sample_rate);
LOGI("The channels from the wav file is %d", info.channels);
// restart from the beginning
Serial.println("Restarting...");
delay(5000);
out.begin(); // indicate that we process the WAV header
wav.begin(); // reset actual position to 0
pwm.begin(); // reset counters
}
}

View File

@@ -0,0 +1,7 @@
# Decoding a WAV file
In this example we decode a WAV file into RAW output and send it to the Serial output.
This example uses the preferred EncodedAudioStream class.
Complie with Partition Scheme Huge APP!

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,39 @@
/**
* @file stream-memory_wav-serial.ino
* @author Phil Schatzmann
* @brief decode WAV strea
* @version 0.1
* @date 2021-01-24
*
* @copyright Copyright (c) 2021
*/
#include "AudioTools.h"
#include "knghtsng.h"
// MemoryStream -> EncodedAudioStream -> CsvOutput
MemoryStream wav(knghtsng_wav, knghtsng_wav_len);
CsvOutput<int16_t> out(Serial, 1); // ASCII stream
EncodedAudioStream enc(&out, new WAVDecoder());
StreamCopy copier(enc, wav); // copy in to out
void setup(){
Serial.begin(115200);
AudioToolsLogger.begin(Serial, AudioToolsLogLevel::Info);
// update number of channels from wav file
enc.begin();
out.begin();
wav.begin();
}
void loop(){
if (wav) {
copier.copy();
} else {
auto info = enc.decoder().audioInfo();
LOGI("The audio rate from the wav file is %d", info.sample_rate);
LOGI("The channels from the wav file is %d", info.channels);
stop();
}
}

View File

@@ -0,0 +1,43 @@
/**
* @file streams-mp34dt05-csv.ino
* @author Phil Schatzmann
* @brief Microphone test for Nano BLE Sense which has a MP34DT05 microphone
*
* @author Phil Schatzmann
* @copyright GPLv3
*/
#include "AudioTools.h"
#include "AudioTools/AudioLibs/AudioMP34DT05.h"
AudioMP34DT05 mic; // Access I2S as stream
CsvOutput<int16_t> csvOutput(Serial);
StreamCopy copier(csvOutput, mic); // copy mic to csvOutput
// Arduino Setup
void setup(void) {
Serial.begin(115200);
AudioToolsLogger.begin(Serial, AudioToolsLogLevel::Debug);
while(!Serial);
Serial.println("starting...");
auto cfg = mic.defaultConfig(RX_MODE);
cfg.bits_per_sample = 16;
cfg.channels = 1;
cfg.sample_rate = 16000;
mic.begin(cfg);
// make sure that we have the correct channels set up
csvOutput.begin(cfg);
Serial.println("started");
}
// Arduino loop - copy data
void loop() {
copier.copy();
}

View File

@@ -0,0 +1,28 @@
# SD Player
We just play a mp3 file (using the Arduino SD library) and output the result via I2S to an external DAC.
An ESP32 was used to test this sketch.
### External DAC:
![DAC](https://pschatzmann.github.io/Resources/img/dac.jpeg)
I am just using the default pins defined by the framework. However I could change them with the help of the config object. The mute pin can be defined in the constructor of the I2SStream - by not defining anything we use the default which is GPIO23
DAC | ESP32
-----|----------------
VCC | 5V
GND | GND
BCK | BCK (GPIO14)
DIN | OUT (GPIO22)
LCK | BCK (GPIO15)
FMT | GND
XMT | 3V (or another GPIO PIN which is set to high)
- DMP - De-emphasis control for 44.1kHz sampling rate(1): Off (Low) / On (High)
- FLT - Filter select : Normal latency (Low) / Low latency (High)
- SCL - System clock input (probably SCL on your board).
- FMT - Audio format selection : I2S (Low) / Left justified (High)
- XMT - Soft mute control(1): Soft mute (Low) / soft un-mute (High)

View File

@@ -0,0 +1,48 @@
/**
* @file streams-sd_mp3-i2s.ino
* @author Phil Schatzmann
* @brief decode MP3 file and output it on I2S
* @version 0.1
* @date 2021-96-25
*
* @copyright Copyright (c) 2021
*/
#include <SPI.h>
#include <SD.h>
#include "AudioTools.h"
#include "AudioTools/AudioCodecs/CodecMP3Helix.h"
const int chipSelect=10;
I2SStream i2s; // final output of decoded stream
EncodedAudioStream decoder(&i2s, new MP3DecoderHelix()); // Decoding stream
StreamCopy copier;
File audioFile;
void setup(){
Serial.begin(115200);
AudioToolsLogger.begin(Serial, AudioToolsLogLevel::Info);
// setup file
SD.begin(chipSelect);
audioFile = SD.open("/Music/Conquistadores.mp3");
// setup i2s
auto config = i2s.defaultConfig(TX_MODE);
i2s.begin(config);
// setup I2S based on sampling rate provided by decoder
decoder.begin();
// begin copy
copier.begin(decoder, audioFile);
}
void loop(){
if (!copier.copy()) {
stop();
}
}

View File

@@ -0,0 +1,69 @@
/**
* @file streams-sd_wav4-i2s.ino
* @author Phil Schatzmann
* @brief decode WAV file with 4 channels and output it on 2 I2S ports
* @version 0.1
* @date 2021-96-25
*
* @copyright Copyright (c) 2021
*/
#include <SD.h>
#include <SPI.h>
#include "AudioTools.h"
#include "AudioTools/AudioCodecs/CodecMP3Helix.h"
const int chipSelect = 10;
AudioInfo info(44100, 2, 16);
AudioInfo info4(44100, 4, 16);
I2SStream i2s_1; // final output port 0
I2SStream i2s_2; // final output port 1
ChannelsSelectOutput out;
WAVDecoder wav;
EncodedAudioOutput decoder(&out, &wav); // Decoding stream
StreamCopy copier;
File audioFile;
void setup() {
Serial.begin(115200);
AudioToolsLogger.begin(Serial, AudioToolsLogLevel::Info);
// setup file
SD.begin(chipSelect);
audioFile = SD.open("/Music/ch4.wav");
// setup i2s
auto config1 = i2s_1.defaultConfig(TX_MODE);
config1.copyFrom(info);
// config1.port_no = 0; // 0 is default port
i2s_1.begin(config1);
auto config2 = i2s_2.defaultConfig(TX_MODE);
config2.copyFrom(info);
// use separate pins
config2.pin_ws = 4;
config2.pin_bck = 5;
config2.pin_data = 6;
// use port 1
config2.port_no = 1;
i2s_2.begin(config2);
// split channels to different i2s ports
out.addOutput(i2s_1, 0, 1);
out.addOutput(i2s_2, 2, 3);
// 4 channels
out.begin(info4);
// setup decoder
decoder.begin();
// begin copy
copier.begin(decoder, audioFile);
}
void loop() {
if (!copier.copy()) {
stop();
}
}

View File

@@ -0,0 +1,69 @@
/**
* @file streams-sd_mp3-metadata.ino
* @author Phil Schatzmann
* @brief read MP3 stream from a SD drive and output metadata and audio!
* The used mp3 file contains ID3 Metadata!
* @date 2021-11-07
*
* @copyright Copyright (c) 2021
*/
// install https://github.com/pschatzmann/arduino-libhelix.git
// install https://github.com/greiman/SdFat.git
#include <SPI.h>
#include <SdFat.h>
#include "AudioTools.h"
#include "AudioTools/AudioCodecs/CodecMP3Helix.h"
#include "AudioTools/Communication/AudioHttp.h"
// -> EncodedAudioStream -> I2SStream
// URLStream -> MultiOutput -|
// -> MetaDataOutput
File audioFile;
SdFs SD;
MetaDataOutput outMeta; // final output of metadata
I2SStream i2s; // I2S output
EncodedAudioStream out2dec(&i2s, new MP3DecoderHelix()); // Decoding stream
MultiOutput out;
StreamCopy copier(out, audioFile); // copy url to decoder
// callback for meta data
void printMetaData(MetaDataType type, const char* str, int len){
Serial.print("==> ");
Serial.print(toStr(type));
Serial.print(": ");
Serial.println(str);
}
void setup(){
Serial.begin(115200);
AudioToolsLogger.begin(Serial, AudioToolsLogLevel::Info);
// setup multi output
out.add(outMeta);
out.add(out2dec);
// setup file
SD.begin(SdSpiConfig(PIN_CS, DEDICATED_SPI, SD_SCK_MHZ(2)));
//audioFile = SD.open("/Music/Conquistadores.mp3");
audioFile = SD.open("/test/002.mp3");
// setup metadata
outMeta.setCallback(printMetaData);
outMeta.begin();
// setup i2s
auto config = i2s.defaultConfig(TX_MODE);
i2s.begin(config);
// setup I2S based on sampling rate provided by decoder
out2dec.begin();
}
void loop(){
copier.copy();
}

View File

@@ -0,0 +1,39 @@
# Generating Audio with Tensorflow Liete
The starting point is the good overview provided by [the "Hallo World" example of Tensorflow Lite](https://www.tensorflow.org/lite/microcontrollers/get_started_low_level#train_a_model) which describes how to create, train and use a model which based on the __sine function__.
We just send a generated sine wave to the I2S interface. Further information can be found in the [Wiki](https://github.com/pschatzmann/arduino-audio-tools/wiki/Tensorflow-Lite----Audio-Output)
Please note the log level should be set so that there is no disturbing output!
### External DAC:
For my tests I am using the 24-bit PCM5102 PCM5102A Stereo DAC Digital-to-analog Converter PLL Voice Module pHAT
![DAC](https://pschatzmann.github.io/Resources/img/dac.jpeg)
I am just using the default pins defined by the framework. However I could change them with the help of the config object. The mute pin can be defined in the constructor of the I2SStream - by not defining anything we use the default which is GPIO23
DAC | ESP32
-----|----------------
VCC | 5V
GND | GND
BCK | BCK (GPIO14)
DIN | OUT (GPIO22)
LCK | BCK (GPIO15)
FMT | GND
XMT | 3V (or another GPIO PIN which is set to high)
- DMP - De-emphasis control for 44.1kHz sampling rate(1): Off (Low) / On (High)
- FLT - Filter select : Normal latency (Low) / Low latency (High)
- SCL - System clock input (probably SCL on your board).
- FMT - Audio format selection : I2S (Low) / Left justified (High)
- XMT - Soft mute control(1): Soft mute (Low) / soft un-mute (High)
## Dependencies
You need to install the following libraries:
- https://github.com/pschatzmann/arduino-audio-tools
- https://github.com/pschatzmann/tflite-micro-arduino-examples

View File

@@ -0,0 +1,206 @@
#pragma once
const unsigned char g_model[] = {
0x20, 0x00, 0x00, 0x00, 0x54, 0x46, 0x4c, 0x33, 0x00, 0x00, 0x00, 0x00,
0x14, 0x00, 0x20, 0x00, 0x04, 0x00, 0x08, 0x00, 0x0c, 0x00, 0x10, 0x00,
0x14, 0x00, 0x00, 0x00, 0x18, 0x00, 0x1c, 0x00, 0x14, 0x00, 0x00, 0x00,
0x03, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x1c, 0x00, 0x00, 0x00,
0x28, 0x01, 0x00, 0x00, 0x1c, 0x00, 0x00, 0x00, 0xd0, 0x00, 0x00, 0x00,
0x48, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x98, 0x03, 0x00, 0x00,
0x01, 0x00, 0x00, 0x00, 0x30, 0x01, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00,
0x10, 0x09, 0x00, 0x00, 0x0c, 0x09, 0x00, 0x00, 0xdc, 0x07, 0x00, 0x00,
0x30, 0x07, 0x00, 0x00, 0xbc, 0x05, 0x00, 0x00, 0x18, 0x05, 0x00, 0x00,
0x94, 0x04, 0x00, 0x00, 0x2c, 0x04, 0x00, 0x00, 0xf0, 0x08, 0x00, 0x00,
0xec, 0x08, 0x00, 0x00, 0xe8, 0x08, 0x00, 0x00, 0xbc, 0x00, 0x00, 0x00,
0x01, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x00,
0x10, 0x00, 0x0c, 0x00, 0x08, 0x00, 0x04, 0x00, 0x0a, 0x00, 0x00, 0x00,
0x0c, 0x00, 0x00, 0x00, 0x1c, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00,
0x0f, 0x00, 0x00, 0x00, 0x73, 0x65, 0x72, 0x76, 0x69, 0x6e, 0x67, 0x5f,
0x64, 0x65, 0x66, 0x61, 0x75, 0x6c, 0x74, 0x00, 0x01, 0x00, 0x00, 0x00,
0x14, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x24, 0x00, 0x00, 0x00,
0x08, 0x00, 0x0c, 0x00, 0x08, 0x00, 0x04, 0x00, 0x08, 0x00, 0x00, 0x00,
0x09, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00,
0x64, 0x65, 0x6e, 0x73, 0x65, 0x5f, 0x34, 0x00, 0xba, 0xf8, 0xff, 0xff,
0x04, 0x00, 0x00, 0x00, 0x0d, 0x00, 0x00, 0x00, 0x64, 0x65, 0x6e, 0x73,
0x65, 0x5f, 0x32, 0x5f, 0x69, 0x6e, 0x70, 0x75, 0x74, 0x00, 0x00, 0x00,
0x01, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x08, 0x00, 0x0c, 0x00,
0x04, 0x00, 0x08, 0x00, 0x08, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00,
0x0b, 0x00, 0x00, 0x00, 0x13, 0x00, 0x00, 0x00, 0x6d, 0x69, 0x6e, 0x5f,
0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x5f, 0x76, 0x65, 0x72, 0x73,
0x69, 0x6f, 0x6e, 0x00, 0x0a, 0xf9, 0xff, 0xff, 0x04, 0x00, 0x00, 0x00,
0x10, 0x00, 0x00, 0x00, 0x31, 0x2e, 0x31, 0x34, 0x2e, 0x30, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00,
0x4d, 0x4c, 0x49, 0x52, 0x20, 0x43, 0x6f, 0x6e, 0x76, 0x65, 0x72, 0x74,
0x65, 0x64, 0x2e, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x18, 0x00, 0x04, 0x00,
0x08, 0x00, 0x0c, 0x00, 0x10, 0x00, 0x14, 0x00, 0x0e, 0x00, 0x00, 0x00,
0x14, 0x00, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00,
0x44, 0x00, 0x00, 0x00, 0x50, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00,
0x44, 0x07, 0x00, 0x00, 0xc8, 0x06, 0x00, 0x00, 0x3c, 0x06, 0x00, 0x00,
0x88, 0x05, 0x00, 0x00, 0x24, 0x04, 0x00, 0x00, 0x70, 0x03, 0x00, 0x00,
0xfc, 0x02, 0x00, 0x00, 0x38, 0x02, 0x00, 0x00, 0x1c, 0x01, 0x00, 0x00,
0x60, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x01, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00,
0xc0, 0x01, 0x00, 0x00, 0xc8, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00,
0x04, 0x00, 0x00, 0x00, 0x6d, 0x61, 0x69, 0x6e, 0x00, 0x00, 0x00, 0x00,
0x5a, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x08, 0x18, 0x00, 0x00, 0x00,
0x0c, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0xa0, 0xf8, 0xff, 0xff,
0x01, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00,
0x08, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00,
0x54, 0xf9, 0xff, 0xff, 0x00, 0x00, 0x00, 0x09, 0x14, 0x00, 0x00, 0x00,
0x0a, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00,
0x30, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
0x01, 0x00, 0x00, 0x00, 0x19, 0x00, 0x00, 0x00, 0x53, 0x74, 0x61, 0x74,
0x65, 0x66, 0x75, 0x6c, 0x50, 0x61, 0x72, 0x74, 0x69, 0x74, 0x69, 0x6f,
0x6e, 0x65, 0x64, 0x43, 0x61, 0x6c, 0x6c, 0x3a, 0x30, 0x00, 0x00, 0x00,
0x02, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x01, 0x00, 0x00, 0x00,
0x3c, 0xf9, 0xff, 0xff, 0x08, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00,
0x01, 0x00, 0x00, 0x00, 0x2c, 0xce, 0x0a, 0x3c, 0x01, 0x00, 0x00, 0x00,
0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, 0x00,
0x14, 0x00, 0x00, 0x00, 0x08, 0x00, 0x0c, 0x00, 0x07, 0x00, 0x10, 0x00,
0x0e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x1c, 0x00, 0x00, 0x00,
0x10, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x0a, 0xff, 0xff, 0xff,
0x00, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00,
0x03, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00,
0x04, 0x00, 0x00, 0x00, 0x0c, 0xfa, 0xff, 0xff, 0x00, 0x00, 0x00, 0x09,
0x14, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00,
0x78, 0x00, 0x00, 0x00, 0x68, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,
0x01, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x52, 0x00, 0x00, 0x00,
0x73, 0x65, 0x71, 0x75, 0x65, 0x6e, 0x74, 0x69, 0x61, 0x6c, 0x5f, 0x31,
0x2f, 0x64, 0x65, 0x6e, 0x73, 0x65, 0x5f, 0x33, 0x2f, 0x4d, 0x61, 0x74,
0x4d, 0x75, 0x6c, 0x3b, 0x73, 0x65, 0x71, 0x75, 0x65, 0x6e, 0x74, 0x69,
0x61, 0x6c, 0x5f, 0x31, 0x2f, 0x64, 0x65, 0x6e, 0x73, 0x65, 0x5f, 0x33,
0x2f, 0x52, 0x65, 0x6c, 0x75, 0x3b, 0x73, 0x65, 0x71, 0x75, 0x65, 0x6e,
0x74, 0x69, 0x61, 0x6c, 0x5f, 0x31, 0x2f, 0x64, 0x65, 0x6e, 0x73, 0x65,
0x5f, 0x33, 0x2f, 0x42, 0x69, 0x61, 0x73, 0x41, 0x64, 0x64, 0x00, 0x00,
0x02, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x10, 0x00, 0x00, 0x00,
0x2c, 0xfa, 0xff, 0xff, 0x08, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00,
0x01, 0x00, 0x00, 0x00, 0xe4, 0xd1, 0xc0, 0x3b, 0x01, 0x00, 0x00, 0x00,
0x80, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x0e, 0x00, 0x16, 0x00, 0x00, 0x00, 0x08, 0x00, 0x0c, 0x00,
0x07, 0x00, 0x10, 0x00, 0x0e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08,
0x24, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00,
0x00, 0x00, 0x06, 0x00, 0x08, 0x00, 0x07, 0x00, 0x06, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00,
0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
0x02, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x10, 0x00, 0x0b, 0x00, 0x00, 0x00,
0x0c, 0x00, 0x04, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x09, 0x04, 0x00, 0x00, 0x00, 0x24, 0xfb, 0xff, 0xff,
0x00, 0x00, 0x00, 0x09, 0x14, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00,
0x18, 0x00, 0x00, 0x00, 0x78, 0x00, 0x00, 0x00, 0x68, 0x00, 0x00, 0x00,
0x02, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00,
0x52, 0x00, 0x00, 0x00, 0x73, 0x65, 0x71, 0x75, 0x65, 0x6e, 0x74, 0x69,
0x61, 0x6c, 0x5f, 0x31, 0x2f, 0x64, 0x65, 0x6e, 0x73, 0x65, 0x5f, 0x32,
0x2f, 0x4d, 0x61, 0x74, 0x4d, 0x75, 0x6c, 0x3b, 0x73, 0x65, 0x71, 0x75,
0x65, 0x6e, 0x74, 0x69, 0x61, 0x6c, 0x5f, 0x31, 0x2f, 0x64, 0x65, 0x6e,
0x73, 0x65, 0x5f, 0x32, 0x2f, 0x52, 0x65, 0x6c, 0x75, 0x3b, 0x73, 0x65,
0x71, 0x75, 0x65, 0x6e, 0x74, 0x69, 0x61, 0x6c, 0x5f, 0x31, 0x2f, 0x64,
0x65, 0x6e, 0x73, 0x65, 0x5f, 0x32, 0x2f, 0x42, 0x69, 0x61, 0x73, 0x41,
0x64, 0x64, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff,
0x10, 0x00, 0x00, 0x00, 0x44, 0xfb, 0xff, 0xff, 0x08, 0x00, 0x00, 0x00,
0x0c, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x56, 0xdf, 0x47, 0x3c,
0x01, 0x00, 0x00, 0x00, 0x80, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0x00, 0x00, 0x00, 0x00, 0x6a, 0xfc, 0xff, 0xff, 0x04, 0x00, 0x00, 0x00,
0x04, 0x00, 0x00, 0x00, 0x8c, 0xef, 0xff, 0xff, 0x56, 0xfc, 0xff, 0xff,
0x00, 0x00, 0x00, 0x02, 0x10, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00,
0x10, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
0x01, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x64, 0x65, 0x6e, 0x73,
0x65, 0x5f, 0x34, 0x2f, 0x62, 0x69, 0x61, 0x73, 0x00, 0x00, 0x00, 0x00,
0xac, 0xfb, 0xff, 0xff, 0x08, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00,
0x01, 0x00, 0x00, 0x00, 0x22, 0xd9, 0x51, 0x38, 0x01, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xce, 0xfc, 0xff, 0xff,
0x04, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x21, 0xa5, 0x8b, 0xca,
0x5e, 0x1d, 0xce, 0x42, 0x9d, 0xce, 0x1f, 0xb0, 0xdf, 0x54, 0x2f, 0x81,
0xc6, 0xfc, 0xff, 0xff, 0x00, 0x00, 0x00, 0x09, 0x10, 0x00, 0x00, 0x00,
0x06, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00,
0x02, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00,
0x1b, 0x00, 0x00, 0x00, 0x73, 0x65, 0x71, 0x75, 0x65, 0x6e, 0x74, 0x69,
0x61, 0x6c, 0x5f, 0x31, 0x2f, 0x64, 0x65, 0x6e, 0x73, 0x65, 0x5f, 0x34,
0x2f, 0x4d, 0x61, 0x74, 0x4d, 0x75, 0x6c, 0x00, 0x2c, 0xfc, 0xff, 0xff,
0x08, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
0xce, 0x4d, 0x0b, 0x3c, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x4e, 0xfd, 0xff, 0xff, 0x04, 0x00, 0x00, 0x00,
0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xb5, 0x04, 0x00, 0x00,
0x78, 0x0a, 0x00, 0x00, 0x2d, 0x06, 0x00, 0x00, 0x71, 0xf8, 0xff, 0xff,
0x00, 0x00, 0x00, 0x00, 0x99, 0x0a, 0x00, 0x00, 0xfe, 0xf7, 0xff, 0xff,
0x0f, 0x05, 0x00, 0x00, 0xd4, 0x09, 0x00, 0x00, 0x47, 0xfe, 0xff, 0xff,
0xb6, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xac, 0xf7, 0xff, 0xff,
0x4b, 0xf9, 0xff, 0xff, 0x4a, 0x05, 0x00, 0x00, 0x76, 0xfd, 0xff, 0xff,
0x00, 0x00, 0x00, 0x02, 0x10, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00,
0x10, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
0x10, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x64, 0x65, 0x6e, 0x73,
0x65, 0x5f, 0x33, 0x2f, 0x62, 0x69, 0x61, 0x73, 0x00, 0x00, 0x00, 0x00,
0xcc, 0xfc, 0xff, 0xff, 0x08, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00,
0x01, 0x00, 0x00, 0x00, 0xb2, 0x9e, 0x21, 0x39, 0x01, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xee, 0xfd, 0xff, 0xff,
0x04, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0xee, 0xfc, 0x00, 0xec,
0x05, 0x17, 0xef, 0xec, 0xe6, 0xf8, 0x03, 0x01, 0x00, 0xfa, 0xf8, 0xf5,
0xdc, 0xeb, 0x27, 0x14, 0xf1, 0xde, 0xe2, 0xdb, 0xf0, 0xde, 0x31, 0x06,
0x02, 0xe6, 0xee, 0xf9, 0x00, 0x16, 0x07, 0xe0, 0xfe, 0xff, 0xe9, 0x06,
0xe7, 0xef, 0x81, 0x1b, 0x18, 0xea, 0xc9, 0x01, 0x0f, 0x00, 0xda, 0xf7,
0x0e, 0xec, 0x13, 0x1f, 0x04, 0x13, 0xb4, 0xe6, 0xfd, 0x06, 0xb9, 0xe0,
0x0d, 0xec, 0xf0, 0xde, 0xeb, 0xf7, 0x05, 0x26, 0x1a, 0xe4, 0x6f, 0x1a,
0xea, 0x1e, 0x35, 0xdf, 0x1a, 0xf3, 0xf1, 0x19, 0x0f, 0x03, 0x1b, 0xe1,
0xde, 0x13, 0xf6, 0x19, 0xff, 0xf6, 0x1b, 0x18, 0xf0, 0x1c, 0xda, 0x1b,
0x1b, 0x20, 0xe5, 0x1a, 0xf5, 0xff, 0x96, 0x0b, 0x00, 0x01, 0xcd, 0xde,
0x0d, 0xf6, 0x16, 0xe3, 0xed, 0xfc, 0x0e, 0xe9, 0xfa, 0xeb, 0x5c, 0xfc,
0x1d, 0x02, 0x5b, 0xe2, 0xe1, 0xf5, 0x15, 0xec, 0xf4, 0x00, 0x13, 0x05,
0xec, 0x0c, 0x1d, 0x14, 0x0e, 0xe7, 0x0b, 0xf4, 0x19, 0x00, 0xd7, 0x05,
0x27, 0x02, 0x15, 0xea, 0xea, 0x02, 0x9b, 0x00, 0x0c, 0xfa, 0xe8, 0xea,
0xfd, 0x00, 0x14, 0xfd, 0x0b, 0x02, 0xef, 0xee, 0x06, 0xee, 0x01, 0x0d,
0x06, 0xe6, 0xf7, 0x11, 0xf7, 0x09, 0xf8, 0xf1, 0x21, 0xff, 0x0e, 0xf3,
0xec, 0x12, 0x26, 0x1d, 0xf2, 0xe9, 0x28, 0x18, 0xe0, 0xfb, 0xf3, 0xf4,
0x05, 0x1d, 0x1d, 0xfb, 0xfd, 0x1e, 0xfc, 0x11, 0xe8, 0x07, 0x09, 0x03,
0x12, 0xf2, 0x36, 0xfb, 0xdc, 0x1c, 0xf9, 0xef, 0xf3, 0xe7, 0x6f, 0x0c,
0x1d, 0x00, 0x45, 0xfd, 0x0e, 0xf0, 0x0b, 0x19, 0x1a, 0xfa, 0xe0, 0x19,
0x1f, 0x13, 0x36, 0x1c, 0x12, 0xeb, 0x3b, 0x0c, 0xb4, 0xcb, 0xe6, 0x13,
0xfa, 0xeb, 0xf1, 0x06, 0x1c, 0xfa, 0x18, 0xe5, 0xeb, 0xcb, 0x0c, 0xf4,
0xd6, 0xfe, 0xff, 0xff, 0x00, 0x00, 0x00, 0x09, 0x10, 0x00, 0x00, 0x00,
0x04, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00,
0x02, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00,
0x1b, 0x00, 0x00, 0x00, 0x73, 0x65, 0x71, 0x75, 0x65, 0x6e, 0x74, 0x69,
0x61, 0x6c, 0x5f, 0x31, 0x2f, 0x64, 0x65, 0x6e, 0x73, 0x65, 0x5f, 0x33,
0x2f, 0x4d, 0x61, 0x74, 0x4d, 0x75, 0x6c, 0x00, 0x3c, 0xfe, 0xff, 0xff,
0x08, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
0x6b, 0x01, 0x4f, 0x3c, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x5e, 0xff, 0xff, 0xff, 0x04, 0x00, 0x00, 0x00,
0x40, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x77, 0x0b, 0x00, 0x00,
0x53, 0xf6, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x77, 0x0c, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xd3, 0x06, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x72, 0x21, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x2f, 0x07, 0x00, 0x00, 0x67, 0xf5, 0xff, 0xff,
0x34, 0xf0, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x86, 0xff, 0xff, 0xff,
0x00, 0x00, 0x00, 0x02, 0x10, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00,
0x10, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
0x10, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x64, 0x65, 0x6e, 0x73,
0x65, 0x5f, 0x32, 0x2f, 0x62, 0x69, 0x61, 0x73, 0x00, 0x00, 0x00, 0x00,
0xdc, 0xfe, 0xff, 0xff, 0x08, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00,
0x01, 0x00, 0x00, 0x00, 0x28, 0xb3, 0xd9, 0x38, 0x01, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x00,
0x08, 0x00, 0x04, 0x00, 0x06, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00,
0x10, 0x00, 0x00, 0x00, 0x75, 0x1c, 0x11, 0xe1, 0x0c, 0x81, 0xa5, 0x42,
0xfe, 0xd5, 0xd4, 0xb2, 0x61, 0x78, 0x19, 0xdf, 0x00, 0x00, 0x0e, 0x00,
0x18, 0x00, 0x08, 0x00, 0x07, 0x00, 0x0c, 0x00, 0x10, 0x00, 0x14, 0x00,
0x0e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x09, 0x10, 0x00, 0x00, 0x00,
0x02, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00,
0x02, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
0x1b, 0x00, 0x00, 0x00, 0x73, 0x65, 0x71, 0x75, 0x65, 0x6e, 0x74, 0x69,
0x61, 0x6c, 0x5f, 0x31, 0x2f, 0x64, 0x65, 0x6e, 0x73, 0x65, 0x5f, 0x32,
0x2f, 0x4d, 0x61, 0x74, 0x4d, 0x75, 0x6c, 0x00, 0x74, 0xff, 0xff, 0xff,
0x08, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
0xd5, 0x6b, 0x8a, 0x3b, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x14, 0x00, 0x1c, 0x00, 0x08, 0x00, 0x07, 0x00,
0x0c, 0x00, 0x10, 0x00, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00,
0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x09, 0x14, 0x00, 0x00, 0x00,
0x01, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x50, 0x00, 0x00, 0x00,
0x34, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
0x01, 0x00, 0x00, 0x00, 0x1f, 0x00, 0x00, 0x00, 0x73, 0x65, 0x72, 0x76,
0x69, 0x6e, 0x67, 0x5f, 0x64, 0x65, 0x66, 0x61, 0x75, 0x6c, 0x74, 0x5f,
0x64, 0x65, 0x6e, 0x73, 0x65, 0x5f, 0x32, 0x5f, 0x69, 0x6e, 0x70, 0x75,
0x74, 0x3a, 0x30, 0x00, 0x02, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff,
0x01, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00,
0x04, 0x00, 0x08, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00,
0x0c, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x5d, 0x4f, 0xc9, 0x3c,
0x01, 0x00, 0x00, 0x00, 0x80, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0x04, 0x00, 0x04, 0x00, 0x04, 0x00, 0x00, 0x00
};
unsigned int g_model_len = 2408;

View File

@@ -0,0 +1,44 @@
/**
* @file streams-tf-i2s.ino
* @author Phil Schatzmann
* @brief We use Tenorflow lite to generate some audio data and output it via I2S
* @version 0.1
* @date 2022-04-07
*
* @copyright Copyright (c) 2022
*
*/
#include "AudioTools.h"
#include "AudioTools/AudioLibs/TfLiteAudioStream.h"
#include "model.h"
TfLiteSineReader tf_reader(20000,0.3); // Audio generation logic
TfLiteAudioStream tf_stream; // Audio source -> no classification so N is 0
I2SStream i2s; // Audio destination
StreamCopy copier(i2s, tf_stream); // copy tf_stream to i2s
int channels = 1;
int samples_per_second = 16000;
void setup() {
Serial.begin(115200);
AudioToolsLogger.begin(Serial, AudioToolsLogLevel::Warning);
// Setup tensorflow input
auto tcfg = tf_stream.defaultConfig();
tcfg.channels = channels;
tcfg.sample_rate = samples_per_second;
tcfg.kTensorArenaSize = 2 * 1024;
tcfg.model = g_model;
tcfg.reader = &tf_reader;
tf_stream.begin(tcfg);
// setup Audioi2s output
auto cfg = i2s.defaultConfig(TX_MODE);
cfg.channels = channels;
cfg.sample_rate = samples_per_second;
i2s.begin(cfg);
}
void loop() { copier.copy(); }