arduino-audio-tools
Loading...
Searching...
No Matches
I2SCodecStream.h
Go to the documentation of this file.
1#pragma once
2#include "AudioBoard.h" // install audio-driver library
3#include "AudioToolsConfig.h"
5
6
7//#pragma GCC diagnostic ignored "-Wclass-memaccess"
8
9// Added to be compatible with the AudioKitStream.h
10#ifndef PIN_AUDIO_KIT_SD_CARD_CS
11#define PIN_AUDIO_KIT_SD_CARD_CS 13
12#define PIN_AUDIO_KIT_SD_CARD_MISO 2
13#define PIN_AUDIO_KIT_SD_CARD_MOSI 15
14#define PIN_AUDIO_KIT_SD_CARD_CLK 14
15#endif
16
17namespace audio_tools {
18// we heavily depend on the audio driver functionality
19using namespace audio_driver;
20
21// The legacy class name was DriverPins
22#if !defined(AUDIO_DRIVER_USE_NEW_API)
24#endif
25
26
33struct I2SCodecConfig : public I2SConfig {
36 // to be compatible with the AudioKitStream -> do not activate SD spi if false
37 bool sd_active = true;
38 bool sdmmc_active = false;
39 // define pin source in driver configuration
40 PinFunction i2s_function = PinFunction::UNDEFINED; //CODEC;
42 return input_device == alt.input_device &&
43 output_device == alt.output_device && *((AudioInfo *)this) == alt;
44 }
45
46 bool operator!=(I2SCodecConfig alt) { return !(*this == alt); }
47};
48
56 public:
58 I2SCodecStream() = default;
69
81
82 bool begin() {
83 TRACED();
84 return begin(cfg);
85 }
86
88 virtual bool begin(I2SCodecConfig cfg) {
89 TRACED();
90 this->cfg = cfg;
91 this->info = cfg;
92 return begin1();
93 }
94
96 void end() {
97 TRACED();
98 if (p_board) p_board->end();
99 i2s.end();
100 is_active = false;
101 }
102
105 TRACEI();
108
112
113 // update codec_cfg
115 codec_cfg.i2s.rate = toRate(cfg.sample_rate);
116
117 // return if we we are not ready
118 if (!is_active || p_board == nullptr) {
119 return;
120 }
121
122 // return if there is nothing to do
126 return;
127 }
128
129 // update cfg
130 p_board->setConfig(codec_cfg);
131 }
132
134 virtual size_t write(const uint8_t *data, size_t len) {
135 LOGD("I2SStream::write: %d", len);
136 return i2s.write(data, len);
137 }
138
140 virtual size_t readBytes(uint8_t *data, size_t len) override {
141 return i2s.readBytes(data, len);
142 }
143
145 virtual int available() override { return i2s.available(); }
146
148 virtual int availableForWrite() override { return i2s.availableForWrite(); }
149
151 bool setVolume(float vol) override {
153 if (!is_active || p_board == nullptr) return false;
154 return p_board->setVolume(vol * 100.0);
155 }
156
158 float volume() override {
159 if (p_board == nullptr) return 0.0f;
160 return static_cast<float>(p_board->getVolume()) / 100.0f;
161 }
163 float getVolume() { return volume(); }
164
166 bool setMute(bool mute) {
167 if (p_board == nullptr) return false;
168 return p_board->setMute(mute);
169 }
171 bool setMute(bool mute, int line) {
172 if (p_board == nullptr) return false;
173 return p_board->setMute(mute, line);
174 }
175
177 bool setPAPower(bool active) {
178 if (p_board == nullptr) return false;
179 return p_board->setPAPower(active);
180 }
181
183 bool setInputVolume(float vol){
184 if (!is_active || p_board == nullptr) return false;
185 return p_board->setInputVolume(100.0 * vol);
186 }
187
189 AudioBoard &board() { return *p_board; }
195 bool hasBoard() { return p_board != nullptr; }
196
199 if (p_board == nullptr) return GPIO_NONE;
200 return p_board->getPins().getPinID(function);
201 }
202
205 if (p_board == nullptr) return GPIO_NONE;
206 return p_board->getPins().getPinID(function, pos);
207 }
209 digital_pin_t getKey(int pos) { return getPinID(PinFunction::KEY, pos); }
210
212 DriverDeviceInfo &getPins() { return p_board->getPins(); }
213
216
218 void digitalWrite(digital_pin_t pin, bool value) {
219 p_board->getPins().getGPIO().digitalWrite(pin, value);
220 }
221
224 return p_board->getPins().getGPIO().digitalRead(pin);
225 }
226
227 protected:
231 AudioBoard *p_board = nullptr;
232 bool is_active = false;
233
234 bool begin1() {
235 TRACED();
237 setupI2SPins();
238
239 if (!i2s.begin(cfg)){
240 TRACEE();
241 is_active = false;
242 return false;
243 }
244
245 delay(200); // wait for codec to be ready
246
247 if (!beginCodec(cfg)) {
248 TRACEE();
249 is_active = false;
250 return false;
251 }
252
253 // if setvolume was called before begin
255 if (tobeVol >= 0.0f) {
257 }
258 return true;
259 }
260
263 if (cfg.i2s_function == PinFunction::UNDEFINED){
264 if (cfg.rx_tx_mode == RX_MODE){
265 auto i2s = p_board->getPins().getI2SPins(PinFunction::CODEC_ADC);
266 if (i2s){
267 cfg.i2s_function = PinFunction::CODEC_ADC;
268 LOGI("using i2s_function: CODEC_ADC");
269 } else {
270 cfg.i2s_function = PinFunction::CODEC;
271 }
272 } else {
273 cfg.i2s_function = PinFunction::CODEC;
274 }
275 }
276 }
277
280 TRACED();
281 // determine relevant I2S pins from driver configuration
282 auto i2s = getI2SPins();
283 if (i2s) {
284 // determine i2s pins from board definition
285 PinsI2S i2s_pins = i2s.value();
286#if defined(__zephyr__)
287 // use device from audio-driver library
288 if (i2s_pins.dev != nullptr){
289 cfg.dev = i2s_pins.dev;
290 }
291#else
292 cfg.pin_bck = i2s_pins.bck;
293 cfg.pin_mck = i2s_pins.mclk;
294 cfg.pin_ws = i2s_pins.ws;
295 switch (cfg.rx_tx_mode) {
296 case RX_MODE:
297 cfg.pin_data = i2s_pins.data_in;
298 break;
299 case TX_MODE:
300 cfg.pin_data = i2s_pins.data_out;
301 break;
302 default:
303 cfg.pin_data = i2s_pins.data_out;
304 cfg.pin_data_rx = i2s_pins.data_in;
305 break;
306 }
307#endif
308 }
309 }
310
311 audio_driver_local::Optional<PinsI2S> getI2SPins(){
312 TRACED();
313 audio_driver_local::Optional<PinsI2S> i2s;
314 // Deterine I2S pins
315 return p_board->getPins().getI2SPins(cfg.i2s_function);
316 }
317
319 TRACED();
320 switch (cfg.rx_tx_mode) {
321 case RX_MODE:
322 codec_cfg.input_device = info.input_device;
323 codec_cfg.output_device = DAC_OUTPUT_NONE;
324 break;
325 case TX_MODE:
326 codec_cfg.output_device = info.output_device;
327 codec_cfg.input_device = ADC_INPUT_NONE;
328 break;
329 default:
330 codec_cfg.input_device = info.input_device;
331 codec_cfg.output_device = info.output_device;
332 break;
333 }
334 codec_cfg.sd_active = info.sd_active;
335 codec_cfg.sdmmc_active = info.sdmmc_active;
336 LOGD("input: %d", info.input_device);
337 LOGD("output: %d", info.output_device);
339 codec_cfg.i2s.rate = toRate(info.sample_rate);
340 codec_cfg.i2s.fmt = toFormat(info.i2s_format);
341#ifndef __zephyr__
342 codec_cfg.i2s.signal_type = (signal_t) info.signal_type;
343#endif
344 // use reverse logic for codec setting
345 codec_cfg.i2s.mode = info.is_master ? MODE_SLAVE : MODE_MASTER;
346 if (p_board == nullptr) return false;
347
348 // setup driver only on changes
349 return p_board->begin(codec_cfg);
350 }
351
353 switch (bits) {
354 case 16:
355 LOGD("BIT_LENGTH_16BITS");
356 return BIT_LENGTH_16BITS;
357 case 24:
358 LOGD("BIT_LENGTH_24BITS");
359 return BIT_LENGTH_24BITS;
360 case 32:
361 LOGD("BIT_LENGTH_32BITS");
362 return BIT_LENGTH_32BITS;
363 }
364 LOGE("Unsupported bits: %d", bits);
365 return BIT_LENGTH_16BITS;
366 }
368 if (rate <= 8000) {
369 LOGD("RATE_8K");
370 return RATE_8K;
371 }
372 if (rate <= 11000) {
373 LOGD("RATE_11K");
374 return RATE_11K;
375 }
376 if (rate <= 16000) {
377 LOGD("RATE_16K");
378 return RATE_16K;
379 }
380 if (rate <= 22050) {
381 LOGD("RATE_22K");
382 return RATE_22K;
383 }
384 if (rate <= 32000) {
385 LOGD("RATE_32K");
386 return RATE_32K;
387 }
388 if (rate <= 44100) {
389 LOGD("RATE_44K");
390 return RATE_44K;
391 }
392 if (rate <= 48000 || rate > 48000) {
393 LOGD("RATE_48K");
394 return RATE_44K;
395 }
396 LOGE("Invalid rate: %d using 44K", rate);
397 return RATE_44K;
398 }
399
401 switch (fmt) {
403 case I2S_STD_FORMAT:
404 LOGD("I2S_NORMAL");
405 return I2S_NORMAL;
407 case I2S_MSB_FORMAT:
408 LOGD("I2S_LEFT");
409 return I2S_LEFT;
411 case I2S_LSB_FORMAT:
412 LOGD("I2S_RIGHT");
413 return I2S_RIGHT;
414 case I2S_PCM:
415 LOGD("I2S_DSP");
416 return I2S_DSP;
417 default:
418 LOGE("unsupported mode");
419 return I2S_NORMAL;
420 }
421 }
422};
423
424} // namespace audio_tools
#define TRACEI()
Definition AudioLoggerIDF.h:32
#define TRACED()
Definition AudioLoggerIDF.h:31
#define LOGI(...)
Definition AudioLoggerIDF.h:28
#define TRACEE()
Definition AudioLoggerIDF.h:34
#define LOGD(...)
Definition AudioLoggerIDF.h:27
#define LOGE(...)
Definition AudioLoggerIDF.h:30
Base class for all Audio Streams. It support the boolean operator to test if the object is ready with...
Definition BaseStream.h:120
AudioInfo info
Definition BaseStream.h:171
virtual void setAudioInfo(AudioInfo newInfo) override
Defines the input AudioInfo.
Definition BaseStream.h:128
I2S Stream which also sets up a codec chip and i2s.
Definition I2SCodecStream.h:55
digital_pin_t getKey(int pos)
Provides the gpio for the indicated key pos.
Definition I2SCodecStream.h:209
bool hasBoard()
checks if a board has been defined
Definition I2SCodecStream.h:195
bool beginCodec(I2SCodecConfig info)
Definition I2SCodecStream.h:318
audio_driver_local::Optional< PinsI2S > getI2SPins()
Definition I2SCodecStream.h:311
void digitalWrite(digital_pin_t pin, bool value)
set value of digital pin
Definition I2SCodecStream.h:218
sample_bits_t toCodecBits(int bits)
Definition I2SCodecStream.h:352
bool is_active
Definition I2SCodecStream.h:232
CodecConfig codec_cfg
Definition I2SCodecStream.h:230
I2SCodecConfig cfg
Definition I2SCodecStream.h:229
I2SStream i2s
Definition I2SCodecStream.h:228
I2SCodecStream(AudioBoard &board)
Default constructor: for available AudioBoard values check audioboard variables in https://pschatzman...
Definition I2SCodecStream.h:66
bool digitalRead(digital_pin_t pin)
get value of digital pin
Definition I2SCodecStream.h:223
digital_pin_t getPinID(PinFunction function)
Provides the gpio for the indicated function.
Definition I2SCodecStream.h:198
bool setMute(bool mute, int line)
Mute / unmute of an individual line (codec)
Definition I2SCodecStream.h:171
bool begin()
Definition I2SCodecStream.h:82
bool begin1()
Definition I2SCodecStream.h:234
virtual size_t readBytes(uint8_t *data, size_t len) override
Reads the audio data.
Definition I2SCodecStream.h:140
void setBoard(AudioBoard &board)
(re)defines the board
Definition I2SCodecStream.h:191
I2SCodecStream(AudioBoard *board)
Provide board via pointer.
Definition I2SCodecStream.h:68
virtual int availableForWrite() override
Provides the available audio data.
Definition I2SCodecStream.h:148
bool setInputVolume(float vol)
Sets the volume of the microphone (if available)
Definition I2SCodecStream.h:183
I2SCodecConfig defaultConfig(RxTxMode mode=TX_MODE)
Provides the default configuration.
Definition I2SCodecStream.h:71
float volume() override
Provides the actual volume (0.0f - 1.0f)
Definition I2SCodecStream.h:158
DriverDeviceInfo & getPins()
Provides access to the pin information.
Definition I2SCodecStream.h:212
virtual void setAudioInfo(AudioInfo info)
updates the sample rate dynamically
Definition I2SCodecStream.h:104
virtual size_t write(const uint8_t *data, size_t len)
Writes the audio data to I2S.
Definition I2SCodecStream.h:134
AudioBoard & board()
Provides the board.
Definition I2SCodecStream.h:189
samplerate_t toRate(int rate)
Definition I2SCodecStream.h:367
I2SCodecStream()=default
Default Constructor (w/o codec)
bool setMute(bool mute)
Mute / unmote.
Definition I2SCodecStream.h:166
virtual bool begin(I2SCodecConfig cfg)
Starts the I2S interface.
Definition I2SCodecStream.h:88
void setupI2SFunction()
if the cfg.i2s_function was not defined we determine the "correct" default value
Definition I2SCodecStream.h:262
void end()
Stops the I2S interface.
Definition I2SCodecStream.h:96
void setupI2SPins()
We use the board pins if they are available.
Definition I2SCodecStream.h:279
float getVolume()
legacy: same as volume()
Definition I2SCodecStream.h:163
void setBoard(AudioBoard *board)
(re)defines the board
Definition I2SCodecStream.h:193
bool setPAPower(bool active)
Sets the output of the PA Power Pin.
Definition I2SCodecStream.h:177
digital_pin_t getPinID(PinFunction function, int pos)
Provides the gpio for the indicated function.
Definition I2SCodecStream.h:204
bool setVolume(float vol) override
sets the volume (range 0.0f - 1.0f)
Definition I2SCodecStream.h:151
i2s_format_t toFormat(I2SFormat fmt)
Definition I2SCodecStream.h:400
AudioBoard * p_board
Definition I2SCodecStream.h:231
I2SDriverBase * driver()
Provides the i2s driver.
Definition I2SCodecStream.h:215
virtual int available() override
Provides the available audio data.
Definition I2SCodecStream.h:145
Configuration for ESP32 legacy i2s.
Definition I2SConfigESP32.h:24
int pin_mck
Definition I2SConfigESP32.h:69
RxTxMode rx_tx_mode
public settings
Definition I2SConfigESP32.h:60
int pin_ws
Definition I2SConfigESP32.h:65
int pin_data
Definition I2SConfigESP32.h:67
int pin_data_rx
Definition I2SConfigESP32.h:68
int pin_bck
Definition I2SConfigESP32.h:66
Definition I2SDriverBase.h:7
We support the Stream interface for the I2S access. In addition we allow a separate mute pin which mi...
Definition I2SStream.h:40
bool begin()
Definition I2SStream.h:60
virtual size_t readBytes(uint8_t *data, size_t len) override
Reads the audio data.
Definition I2SStream.h:131
virtual int availableForWrite() override
Provides the available audio data.
Definition I2SStream.h:139
I2SConfig defaultConfig(RxTxMode mode=TX_MODE)
Provides the default configuration.
Definition I2SStream.h:56
virtual void setAudioInfo(AudioInfo info)
updates the sample rate dynamically
Definition I2SStream.h:101
virtual size_t write(const uint8_t *data, size_t len)
Writes the audio data to I2S.
Definition I2SStream.h:124
void end()
Stops the I2S interface.
Definition I2SStream.h:91
I2SDriverBase * driver()
Provides access to the driver.
Definition I2SStream.h:144
virtual int available() override
Provides the available audio data.
Definition I2SStream.h:136
Supports the setting and getting of the volume.
Definition AudioTypes.h:187
virtual float volume()
provides the actual volume in the range of 0.0f to 1.0f
Definition AudioTypes.h:190
virtual bool setVolume(float volume)
define the actual volume in the range of 0.0f to 1.0f
Definition AudioTypes.h:192
RxTxMode
The Microcontroller is the Audio Source (TX_MODE) or Audio Sink (RX_MODE). RXTX_MODE is Source and Si...
Definition AudioTypes.h:26
@ TX_MODE
Definition AudioTypes.h:26
@ RX_MODE
Definition AudioTypes.h:26
Generic Implementation of sound input and output for desktop environments using portaudio.
Definition AudioCodecsBase.h:10
gpio_dt_spec digital_pin_t
Zephyr GPIO spec as digital_pin_t.
Definition Arduino.h:266
static gpio_dt_spec GPIO_NONE
GPIO_NONE is no pin defined.
Definition Arduino.h:269
DriverPins DriverDeviceInfo
Definition I2SCodecStream.h:23
I2SFormat
I2S Formats.
Definition AudioTypes.h:416
@ I2S_STD_FORMAT
Definition AudioTypes.h:417
@ I2S_PHILIPS_FORMAT
Definition AudioTypes.h:420
@ I2S_LSB_FORMAT
Definition AudioTypes.h:418
@ I2S_LEFT_JUSTIFIED_FORMAT
Definition AudioTypes.h:422
@ I2S_RIGHT_JUSTIFIED_FORMAT
Definition AudioTypes.h:421
@ I2S_MSB_FORMAT
Definition AudioTypes.h:419
@ I2S_PCM
Definition AudioTypes.h:423
void delay(uint32_t ms)
Definition Arduino.h:255
size_t writeData(Print *p_out, T *data, int samples, int maxSamples=512)
Definition AudioTypes.h:508
Basic Audio information which drives e.g. I2S.
Definition AudioTypes.h:51
void copyFrom(AudioInfo info)
Same as set.
Definition AudioTypes.h:101
sample_rate_t sample_rate
Sample Rate: e.g 44100.
Definition AudioTypes.h:53
uint16_t channels
Number of channels: 2=stereo, 1=mono.
Definition AudioTypes.h:55
uint8_t bits_per_sample
Number of bits per sample (int16_t = 16 bits)
Definition AudioTypes.h:57
Configuration for I2SCodecStream.
Definition I2SCodecStream.h:33
bool operator!=(I2SCodecConfig alt)
Definition I2SCodecStream.h:46
bool sdmmc_active
Definition I2SCodecStream.h:38
PinFunction i2s_function
Definition I2SCodecStream.h:40
output_device_t output_device
Definition I2SCodecStream.h:35
bool operator==(I2SCodecConfig alt)
Definition I2SCodecStream.h:41
bool sd_active
Definition I2SCodecStream.h:37
input_device_t input_device
Definition I2SCodecStream.h:34