Skip to content

Commit b3891a8

Browse files
committed
Some I2S scenarios
1 parent bcef45b commit b3891a8

File tree

11 files changed

+233
-18
lines changed

11 files changed

+233
-18
lines changed

README.md

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,10 @@ Some basic C++ classes that can be used for Audio Processing privided as Arduino
1414
- AudioOutputWithCallback class to provide callback integration with ESP8266Audio
1515

1616
This functionality provides the glue which makes different audio processing components and libraries work together.
17-
We also provide plenty of examples that demonstrate how to implement the different scenarios.
17+
We also provide plenty of examples that demonstrate how to implement the different scenarios.
18+
19+
The design philosophy is based on the Arduino conventions: we use the ```begin()``` and ```end()``` methods to start and stop the processing and we propagate the use of Streams.
20+
1821

1922
## Optional Libraries
2023

examples/file_mp3-a2dp/file_mp3-a2dp.ino

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
#include <SD.h>
1212
#include "AudioFileSourceSD.h"
1313
#include "AudioGeneratorMP3.h"
14-
#include "AudioOutputWithCallback.h"
14+
#include "ESP8266AudioSupport.h"
1515
#include "BluetoothA2DPSource.h"
1616
#include "AudioTools.h"
1717

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
# Stream SD File to I2S external DAC
2+
3+
We are reading a raw audio file from the SD card and write the data to the I2S interface. The audio file must be available using 16 bit integers with 2 channels.
4+
5+
[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 my example I was using the file [audio.raw](https://pschatzmann.github.io/arduino-audio-tools/resources/audio.raw).
6+
7+
### SD Pins:
8+
9+
The SD module is connected with the help of the SPI bus
10+
11+
![sd](https://pschatzmann.github.io/arduino-audio-tools/resources/sd-module.jpeg)
12+
13+
We connect the SD to the ESP32:
14+
15+
| SD | ESP32
16+
|---------|---------------
17+
| VCC | 5V
18+
| GND | GND
19+
| CS | CS GP5
20+
| SCK | SCK GP18
21+
| MOSI | MOSI GP23
22+
| MISO | MISO GP19
23+
24+
25+
### External DAC:
26+
27+
| DAC | ESP32
28+
| --------| ---------------
29+
| VDD | 5V
30+
| GND | GND
31+
| SD | OUT (GPIO22)
32+
| L/R | GND
33+
| WS | WS (GPIO15)
34+
| SCK | BCK (GPIO14)
35+
36+
37+
38+
39+
40+
Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
/**
2+
* @file file_raw-external_dac.ino
3+
* @author Phil Schatzmann
4+
* @brief see https://github.com/pschatzmann/arduino-audio-tools/blob/main/examples/file_raw-external_dac/README.md
5+
*
6+
* @author Phil Schatzmann
7+
* @copyright GPLv3
8+
*/
9+
10+
#include "AudioTools.h"
11+
#include <SPI.h>
12+
#include <SD.h>
13+
14+
using namespace audio_tools;
15+
16+
File sound_file;
17+
I2S<int16_t> i2s;
18+
I2SStream i2s_stream(i2s);
19+
StreamCopy streamCopy(i2s_stream, sound_file, 1024);
20+
const char* file_name = "/audio.raw";
21+
const int sd_ss_pin = 5;
22+
23+
24+
// Arduino Setup
25+
void setup(void) {
26+
Serial.begin(115200);
27+
28+
// Setup SD and open file
29+
SD.begin(sd_ss_pin);
30+
sound_file = SD.open(file_name, FILE_READ);
31+
32+
// start I2S with external DAC
33+
Serial.println("starting I2S...");
34+
i2s.begin(i2s.defaultConfig(TX_MODE));
35+
}
36+
37+
// Arduino loop - repeated processing
38+
void loop() {
39+
if (streamCopy.copy()){
40+
Serial.print(".");
41+
} else {
42+
Serial.println();
43+
Serial.println("Copy ended");
44+
delay(10000);
45+
}
46+
}
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
# Stream SD File to I2S internal DAC
2+
3+
We are reading a raw audio file from the SD card and write the data to the analog pins of the ESP32 using the I2S interface. The audio file must be available using 16 bit integers with 2 channels.
4+
5+
[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 my example I was using the file [audio.raw](https://pschatzmann.github.io/arduino-audio-tools/resources/audio.raw).
6+
7+
### SD Pins:
8+
9+
The SD module is connected with the help of the SPI bus
10+
11+
![sd](https://pschatzmann.github.io/arduino-audio-tools/resources/sd-module.jpeg)
12+
13+
We connect the SD to the ESP32:
14+
15+
| SD | ESP32
16+
|---------|---------------
17+
| VCC | 5V
18+
| GND | GND
19+
| CS | CS GP5
20+
| SCK | SCK GP18
21+
| MOSI | MOSI GP23
22+
| MISO | MISO GP19
23+
24+
25+
### Amplifier Pins:
26+
27+
To hear the sound we connect the ESP32 to an amplifier module: The analog output is available on GPIO25 & GPIO26. You could also use some earphones.
28+
29+
30+
| Amp | ESP32
31+
|---------|---------------
32+
| + | 5V
33+
| - | GND
34+
| L | GPIO25
35+
| R | GPIO26
36+
| T | GND
37+
38+
39+
40+
41+
Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
/**
2+
* @file file_raw-internal_dac.ino
3+
* @author Phil Schatzmann
4+
* @brief see https://github.com/pschatzmann/arduino-audio-tools/blob/main/examples/file_raw-internal_dac/README.md
5+
*
6+
* @author Phil Schatzmann
7+
* @copyright GPLv3
8+
*/
9+
10+
#include "AudioTools.h"
11+
#include <SPI.h>
12+
#include <SD.h>
13+
14+
using namespace audio_tools;
15+
16+
File sound_file;
17+
I2S<int16_t> i2s;
18+
I2SStream i2s_stream(i2s);
19+
StreamCopy streamCopy(i2s_stream, sound_file, 1024);
20+
const char* file_name = "/audio.raw";
21+
const int sd_ss_pin = 5;
22+
23+
24+
// Arduino Setup
25+
void setup(void) {
26+
Serial.begin(115200);
27+
28+
// Setup SD and open file
29+
SD.begin(sd_ss_pin);
30+
sound_file = SD.open(file_name, FILE_READ);
31+
32+
// start I2S with internal DAC -> GPIO25 & GPIO26
33+
Serial.println("starting I2S...");
34+
I2SConfig<int16_t> config = i2s.defaultConfig(TX_MODE);
35+
config.i2s.mode = static_cast<i2s_mode_t>( I2S_MODE_MASTER | I2S_MODE_TX | I2S_MODE_DAC_BUILT_IN);
36+
i2s.begin(config);
37+
}
38+
39+
// Arduino loop - repeated processing
40+
void loop() {
41+
if (streamCopy.copy()){
42+
Serial.print(".");
43+
} else {
44+
Serial.println();
45+
Serial.println("Copy ended");
46+
delay(10000);
47+
}
48+
}

sandbox/flash_midi-a2dp/flash_midi-a2dp.ino

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99

1010
#include <AudioFileSourcePROGMEM.h>
1111
#include "AudioGeneratorMIDI.h"
12-
#include "AudioOutputWithCallback.h"
12+
#include "ESP8266AudioSupport.h"
1313
#include "BluetoothA2DPSource.h"
1414
#include "AudioTools.h"
1515
#include "Undertale_Megalovania.h" // midi

src/AudioTools/AudioLogger.h

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,12 @@ class AudioLogger {
3636
void begin(Stream& out, LogLevel level=SOUND_LOG_LEVEL) {
3737
this->log_stream_ptr = &out;
3838
this->log_level = level;
39+
this->active = true;
40+
}
41+
42+
/// stops the logger
43+
void end(){
44+
this->active = false;
3945
}
4046

4147
/// checks if the logging is active
@@ -66,7 +72,7 @@ class AudioLogger {
6672
/// printf support
6773
int printf(LogLevel current_level, const char* fmt, ...) const {
6874
int len = 0;
69-
if (log_stream_ptr!=nullptr && current_level >= log_level){
75+
if (this->active && log_stream_ptr!=nullptr && current_level >= log_level){
7076
char serial_printf_buffer[PRINTF_BUFFER_SIZE] = {0};
7177
va_list args;
7278
va_start(args,fmt);
@@ -80,7 +86,7 @@ class AudioLogger {
8086

8187
/// write an message to the log
8288
void log(LogLevel current_level, const char *str, const char* str1=nullptr, const char* str2=nullptr) const {
83-
if (log_stream_ptr!=nullptr){
89+
if (this->active && log_stream_ptr!=nullptr){
8490
if (current_level >= log_level){
8591
log_stream_ptr->print((char*)str);
8692
if (str1!=nullptr){
@@ -109,7 +115,8 @@ class AudioLogger {
109115

110116
protected:
111117
Stream *log_stream_ptr;
112-
LogLevel log_level;
118+
LogLevel log_level;
119+
bool active;
113120

114121
AudioLogger(){
115122

src/AudioTools/Streams.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -93,7 +93,7 @@ class MemoryStream : public Stream {
9393
*/
9494
class StreamCopy {
9595
public:
96-
StreamCopy(Stream &from, Stream &to, int buffer_size){
96+
StreamCopy(Stream &to, Stream &from, int buffer_size){
9797
this->from = &from;
9898
this->to = &to;
9999
this->buffer_size = buffer_size;
@@ -129,6 +129,8 @@ class StreamCopy {
129129

130130
};
131131

132+
133+
132134
#ifdef ESP32
133135
/**
134136
* @brief Represents the content of a URL as Stream. We use the ESP32 ESP HTTP Client API

src/AudioWAV.h

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -149,14 +149,6 @@ class WAVHeader {
149149
size_t data_pos = 0;
150150
size_t sound_pos = 0;
151151

152-
void logInfo(){
153-
WAVLogger.printf(AudioLogger::Info,"WAVHeader sound_pos: ", sound_pos);
154-
WAVLogger.printf(AudioLogger::Info,"WAVHeader channels: ", headerInfo.channels);
155-
WAVLogger.printf(AudioLogger::Info,"WAVHeader bits_per_sample: ", headerInfo.bits_per_sample);
156-
WAVLogger.printf(AudioLogger::Info,"WAVHeader sample_rate: ", headerInfo.sample_rate);
157-
WAVLogger.printf(AudioLogger::Info,"WAVHeader format: ", headerInfo.format);
158-
}
159-
160152
uint32_t read_tag() {
161153
uint32_t tag = 0;
162154
tag = (tag << 8) | getChar();
@@ -210,6 +202,15 @@ class WAVHeader {
210202
bool eof() {
211203
return data_pos>=len-1;
212204
}
205+
206+
void logInfo(){
207+
WAVLogger.printf(AudioLogger::Info,"WAVHeader sound_pos: ", sound_pos);
208+
WAVLogger.printf(AudioLogger::Info,"WAVHeader channels: ", headerInfo.channels);
209+
WAVLogger.printf(AudioLogger::Info,"WAVHeader bits_per_sample: ", headerInfo.bits_per_sample);
210+
WAVLogger.printf(AudioLogger::Info,"WAVHeader sample_rate: ", headerInfo.sample_rate);
211+
WAVLogger.printf(AudioLogger::Info,"WAVHeader format: ", headerInfo.format);
212+
}
213+
213214
};
214215

215216
AudioBaseInfoDependent AudioBaseInfoDependentNone;

0 commit comments

Comments
 (0)