Skip to content

Commit 9e9f0c8

Browse files
committed
Stream support
1 parent b3891a8 commit 9e9f0c8

File tree

76 files changed

+112724
-866
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

76 files changed

+112724
-866
lines changed

.DS_Store

0 Bytes
Binary file not shown.

README.md

Lines changed: 102 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -1,43 +1,119 @@
11
# Arduino Audio Tools
22

3-
Some basic C++ classes that can be used for Audio Processing privided as Arduino Library
3+
Some basic __header-only C++ classes__ that can be used for __Audio Processing__ provided as __Arduino Library__:
44

5-
- Additional Stream implementations: MemoryStream - ESP32 only: UrlStream, I2SStream
6-
- a simple I2S class (to read and write to the internal I2S) [ESP32 only]
7-
- a simple ADC class (to read analog data with the help of I2S) [ESP32 only]
5+
- a simple I2S class (to read and write to the internal I2S)
6+
- a simple ADC class (to read analog data with the help of I2S)
7+
- Additional Stream implementations: MemoryStream, UrlStream, I2SStream, A2DPStream, PrintStream
88
- Converters
9-
- Musical Notes (with Frequencies of notes)
9+
- Musical Notes (with frequencies of notes)
1010
- SineWaveGenerator (to generate some sine tone)
1111
- NBuffer (Multi buffer for writing and reading of (audio) data)
1212
- TimerAlarmRepeating (e.g. for sampling audio data using exact times) [ESP32 only]
1313
- A Wav Encoder and Decoder
14-
- AudioOutputWithCallback class to provide callback integration with ESP8266Audio
14+
- AudioOutputWithCallback class to provide callback integration e.g. 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. 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__. We all know the Arduino Streams. We use them to write out print messages and sometimes we use them to read the output from Serial devices. The same thing applies to my “Audio Streams”: You can read audio data from “Audio Sources” and you write them to “Audio Sinks”.
1818

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.
19+
As “Audio Sources” we will have e.g.:
2020

21+
- Analog Microphones – AnalogStream
22+
- Digital Microphonse – I2SStream
23+
- Files on the Internet – UrlStream
24+
- Generated Sound – GeneratedSoundStream
25+
- Mobile Phone A2DP Bluetooth – A2DPStream
26+
- Binary Data in Flash Memory – MemoryStream
27+
- SD Files
2128

22-
## Optional Libraries
29+
As “Audio Sinks” we will have e.g:
2330

24-
Dependent on the example you might need to install some of the following libraries:
31+
- external DAC – I2SStream
32+
- an Amplifier – AnalogStream
33+
- Bluetooth Speakers – A2DPStream
34+
- Serial to display the data as CSV – CsvStream.
35+
- SD Files
36+
37+
Here is an simple example which streams a file from the Flash Memory and writes it to I2S:
38+
39+
```
40+
#include "AudioTools.h"
41+
#include "StarWars30.h"
42+
43+
using namespace audio_tools;
44+
45+
uint8_t channels = 2;
46+
uint16_t sample_rate = 22050;
47+
48+
MemoryStream music(StarWars30_raw, StarWars30_raw_len);
49+
I2SStream i2s; // Output to I2S
50+
StreamCopyT<int16_t> copier(i2s, music); // copies sound into i2s
51+
52+
void setup(){
53+
Serial.begin(115200);
54+
55+
I2SConfig config = i2s.defaultConfig(TX_MODE);
56+
config.sample_rate = sample_rate;
57+
config.channels = channels;
58+
config.bits_per_sample = 16;
59+
i2s.begin(config);
60+
}
61+
62+
void loop(){
63+
if (!copier.copy2()){
64+
i2s.end();
65+
stop();
66+
}
67+
}
68+
69+
```
70+
A complete list of the supported Audio Stream classes and scenarios can be found in the [Scenarios Document](Scenarios.md)
71+
72+
73+
## Examples
2574

26-
- [ESP32-A2DP Library](https://github.com/pschatzmann/ESP32-A2DP)
27-
- [ESP8266Audio](https://github.com/earlephilhower/ESP8266Audio)
28-
- [SD Library](https://www.arduino.cc/en/reference/SD)
29-
- [arduino-fdk-aac](https://github.com/pschatzmann/arduino-fdk-aac)
75+
The examples follow the following naming convention: "scenario type"-"source"-"destination". For the scenario types we might have __base__ (using basic api functionality), __stream__ for examples using Streams and __test__ for the test cases.
3076

77+
For the __source__ we currently have __adc__ for analog input devices like analog microphones, __i2s__ for digital input devices (e.g. digital microphones), __file__ for SD files and __a2dp__ for input from Bluetooth A2DP (e.g. from a Mobile Phone).
3178

32-
# Examples
79+
For the __destination__ we use __dac__ for analog output (e.g. to an amplifier), __i2s__ for digital output devices (e.g. an external DAC), __file__ for SD files and __a2dp__ for output to Bluetooth A2DP (e.g. a Bluetooth Speaker).
80+
81+
82+
Here is the list of examples:
83+
84+
#### Stream API
85+
86+
- [streams-url_raw-serial](/examples/streams-url_raw-serial) Displaying a music file from the internet on the Serial Plotter
87+
- [streams-generator-serial](/examples/streams-generator-serial) Displaying generated sound on the Serial Plotter
88+
- [streams-adc-serial](/examples/streams-adc-serial) Displaying input from analog microphone on the Serial Plotter
89+
- [streams-i2s-a2dp](examples/streams-i2s-a2dp) - Sample analog sound and write it to a A2DP Bluetooth source
90+
- [streams-file_raw-a2dp](examples/streams-file_raw-a2dp) - Read Raw File from SD card write it A2DP Bluetooth
91+
- [streams-adc-a2dp](examples/streams-adc-a2dp) - Sample analog sound from analog microphone and send it to Bluetooth Speaker
92+
- [streams-memory_raw-i2s_external_dac](examples/streams-memory_raw-i2s_external_dac) - Play music form Flash Memory via I2S to External DAC
93+
94+
... these are just a few examples, but you can combine any Input Stream with any Output Stream as you like...
95+
96+
#### Basic API
97+
98+
- [base-adc-serial](examples/base-adc-serial) - Sample analog sound and write it to Serial
99+
- [base-adc-a2dp](examples/base-adc-a2dp) - Sample analog sound and write it to a A2DP Bluetooth source
100+
- [base-file_raw-serial](examples/base-file_raw-serial) - Read Raw File from SD card to and write it to Serial
101+
- [base-file_raw-a2dp](examples/base-file_raw-a2dp) - Read Raw File from SD card write it A2DP Bluetooth
102+
- [base-file_mp3-a2dp](examples/base-file_mp3-a2dp) - Stream MP3 File from SD card to A2DP Bluetooth using the ESP8266Audio library
103+
- [base-i2s-serial](examples/base-i2s-serial) - Sample digital sound and write it to Serial
104+
- [base-i2s-a2dp](examples/base-i2s-a2dp) - Sample analog sound and write it to a A2DP Bluetooth source
105+
106+
107+
108+
## Optional Libraries
109+
110+
Dependent on the example you might need to install some of the following libraries:
111+
112+
- [ESP32-A2DP Library](https://github.com/pschatzmann/ESP32-A2DP) to support A2DP Bluetooth Audio
113+
- [ESP8266Audio]( ) to play different audio Formats
114+
- [SD Library](https://www.arduino.cc/en/reference/SD) to read and write files.
115+
- [arduino-fdk-aac](https://github.com/pschatzmann/arduino-fdk-aac) to encode or decode AAC
33116

34-
- [adc-a2dp](examples/adc-a2dp) - Stream Analog input to A2DP Bluetooth
35-
- [adc-serial](examples/adc-serial) - Stream Analog input to Serial
36-
- [file_raw-a2dp](examples/file_raw-a2dp) - Stream Row File from SD card to A2DP Bluetooth
37-
- [file_raw-serial](examples/file_raw-serial) - Stream Raw File from SD card to Serial
38-
- [file_mp3-a2dp](examples/file_mp3-a2dp) - Stream MP3 File from SD card to A2DP Bluetooth using the ESP8266Audio library
39-
- [i2s-a2dp](examples/i2s-a2dp) - Stream I2S Input to A2DP Bluetooth
40-
- [i2s-serial](examples/i2s-serial) - Stream I2S Input to Serial
41117

42118

43119
## Installation
@@ -52,7 +128,9 @@ git clone pschatzmann/arduino-audio-tools.git
52128

53129
## Documentation
54130

55-
Here is the generated [Class documentation](https://pschatzmann.github.io/arduino-audio-tools/html/annotated.html). You might find further information in [one of my blogs](https://www.pschatzmann.ch/home/category/machine-sound/)
131+
Here is the generated [Class documentation](https://pschatzmann.github.io/arduino-audio-tools/html/annotated.html).
132+
133+
You also might find further information in [one of my blogs](https://www.pschatzmann.ch/home/category/machine-sound/)
56134

57135
## Project Status
58136

@@ -63,7 +141,7 @@ This is currently work in progress:
63141
| Analog input - ADC | tested |
64142
| I2S | tested |
65143
| Files (RAW, MP3...) | tested |
66-
| Streams | open |
144+
| Streams | tested |
67145
| WAV encoding/deconding | open |
68146
| AAC encoding/deconding | open |
69147
| int24_t | tested |

Scenarios.md

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
# Schenarios
2+
3+
### Supported Architectures
4+
5+
Unfortunatly Arduino does not provide an I2S functionality which is standrdized acress the different processors. There is only an official documentation for SAMD21 processors. The full functionality of the library is currently only available on the ESP32:
6+
7+
8+
| Processor | I2SStream | ADCStream | A2DP | UrlStream | Other |
9+
|----------------|-----------|-----------|--------|-----------|--------|
10+
| ESP32 | + | + | + | + | + |
11+
| ESP8266 | * | * | | | + |
12+
| SAMD21 | * | | | | + |
13+
| Raspberry Pico | | | | | + |
14+
15+
16+
+ supported
17+
* not tested
18+
19+
20+
### Supported Schenarios
21+
22+
Here are the related Stream classes with their supported operations that can be used:
23+
24+
| Class | Read | Write | Comments |
25+
|-------------------------|------|-------|--------------------|
26+
| I2SStream | + | + | i2s |
27+
| AnalogAudioStream | + | + | adc, dac |
28+
| MemoryStream | + | + | memory |
29+
| UrlStream | + | | url |
30+
| A2DPStream | + | + | a2dp |
31+
| GeneratedSoundStream | + | | gen |
32+
| AudioOutputWithCallback | + | + | |
33+
| CsvStream | | + | csv |
34+
| File | + | + | From SD library |
35+
| Serial, ... | + | + | Std Arduino |
36+
37+
38+
39+
In theory we should be able to support the following scenarios:
40+
41+
| Input | dac | i2s | file | a2dp | Serial | csv |
42+
|--------|------|-----|------|------|--------|------|
43+
| adc | + | + | + | + | + | + |
44+
| i2s | + | + | + | + | + | + |
45+
| file | + | + | + | + | + | + |
46+
| a2dp | + | + | + | - | + | + |
47+
| Serial | + | + | + | + | + | + |
48+
| memory | + | + | + | + | + | + |
49+
| url | + | + | + | - | + | + |
50+
| gen | + | + | + | + | + | + |
51+
52+
53+

docs/.DS_Store

0 Bytes
Binary file not shown.
File renamed without changes.

examples/adc-a2dp/adc-a2dp.ino renamed to examples/base-adc-a2dp/base-adc-a2dp.ino

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -17,17 +17,17 @@ using namespace audio_tools;
1717
* @brief We use a mcp6022 analog microphone as input and send the data to A2DP
1818
*/
1919

20-
ADC adc;
20+
AnalogAudio adc;
2121
BluetoothA2DPSource a2dp_source;
2222
// The data has a center of around 26427, so we we need to shift it down to bring the center to 0
23-
FilterScaler<int16_t> scaler(1.0, -26427, 32700 );
23+
ConverterScaler<int16_t> scaler(1.0, -26427, 32700 );
2424

2525
// callback used by A2DP to provide the sound data
2626
int32_t get_sound_data(Channels* data, int32_t len) {
2727
arrayOf2int16_t *data_arrays = (arrayOf2int16_t *) data;
2828
// the ADC provides data in 16 bits
2929
size_t result_len = adc.read(data_arrays, len);
30-
scaler.process(data_arrays, result_len);
30+
scaler.convert(data_arrays, result_len);
3131
return result_len;
3232
}
3333

@@ -37,7 +37,7 @@ void setup(void) {
3737

3838
// start i2s input with default configuration
3939
Serial.println("starting I2S-ADC...");
40-
adc.begin(adc.defaultConfig());
40+
adc.begin(adc.defaultConfig(RX_MODE));
4141

4242
// start the bluetooth
4343
Serial.println("starting A2DP...");
File renamed without changes.

examples/adc-serial/adc-serial.ino renamed to examples/base-adc-serial/base-adc-serial.ino

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -17,27 +17,27 @@ using namespace audio_tools;
1717
* @brief We use a mcp6022 analog microphone on GPIO34 and write it to Serial
1818
*/
1919

20-
ADC adc;
20+
AnalogAudio adc;
2121
const int32_t max_buffer_len = 512;
2222
int16_t buffer[max_buffer_len][2];
2323
// The data has a center of around 26427, so we we need to shift it down to bring the center to 0
24-
FilterScaler<int16_t> scaler(1.0, -26427, 32700 );
24+
ConverterScaler<int16_t> scaler(1.0, -26427, 32700 );
2525

2626
// Arduino Setup
2727
void setup(void) {
2828
Serial.begin(115200);
2929

3030
// start i2s input with default configuration
3131
Serial.println("starting I2S-ADC...");
32-
adc.begin(adc.defaultConfig());
32+
adc.begin(adc.defaultConfig(RX_MODE));
3333

3434
}
3535

3636
// Arduino loop - repeated processing
3737
void loop() {
3838
size_t len = adc.read(buffer, max_buffer_len);
3939
// move center to 0 and scale the values
40-
scaler.process(buffer, len);
40+
scaler.convert(buffer, len);
4141

4242
for (int j=0;j<len;j++){
4343
Serial.print(buffer[j][0]);
File renamed without changes.

examples/file_mp3-a2dp/file_mp3-a2dp.ino renamed to examples/base-file_mp3-a2dp/base-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 "ESP8266AudioSupport.h"
14+
#include "AudioESP8266.h"
1515
#include "BluetoothA2DPSource.h"
1616
#include "AudioTools.h"
1717

0 commit comments

Comments
 (0)