arduino-audio-tools
All Classes Namespaces Files Functions Variables Typedefs Enumerations Friends Modules Pages
AudioKit.h
1#pragma once
2
3#include "AudioTools.h"
4#include "AudioKitHAL.h"
5#include "AudioTools/CoreAudio/AudioI2S/I2SConfig.h"
6#include "AudioTools/CoreAudio/AudioActions.h"
7
8#ifndef AUDIOKIT_V1
9#error Upgrade the AudioKit library
10#endif
11
12namespace audio_tools {
13
14class AudioKitStream;
15static AudioKitStream *pt_AudioKitStream = nullptr;
16
24
25friend class AudioKitStream;
26
27 public:
28 AudioKitStreamConfig(RxTxMode mode=RXTX_MODE) { setupI2SPins(mode); };
29 // set adc channel with audio_hal_adc_input_t
31 // set dac channel
33 bool sd_active = true;
34 bool default_actions_active = true;
35 audio_kit_pins pins;
37
40 TRACED();
41 audiokit_config.driver = driver;
42 audiokit_config.pins = pins;
43 audiokit_config.i2s_num = (i2s_port_t)port_no;
44 audiokit_config.adc_input = input_device;
45 audiokit_config.dac_output = output_device;
46 audiokit_config.codec_mode = toCodecMode();
47 audiokit_config.master_slave_mode = toMode();
48 audiokit_config.fmt = toFormat();
49 audiokit_config.sample_rate = toSampleRate();
50 audiokit_config.bits_per_sample = toBits();
51#if defined(ESP32)
52 audiokit_config.buffer_size = buffer_size;
53 audiokit_config.buffer_count = buffer_count;
54#endif
55 // we use the AudioKit library only to set up the codec
56 audiokit_config.i2s_active = false;
57#if AUDIOKIT_SETUP_SD
58 audiokit_config.sd_active = sd_active;
59#else
60// SD has been deactivated in the AudioKitConfig.h file
61 audiokit_config.sd_active = false;
62#endif
63 LOGW("sd_active = %s", sd_active ? "true" : "false" );
64
65 return audiokit_config;
66 }
67
68
69 protected:
70 AudioKitConfig audiokit_config;
71 board_driver board;
72
74 void setupI2SPins(RxTxMode rxtx_mode) {
75 TRACED();
76 this->rx_tx_mode = rxtx_mode;
78 board.setup(pins);
79 board.get_i2s_pins((i2s_port_t)port_no, &i2s_pins);
80 pin_mck = i2s_pins.mck_io_num;
81 pin_bck = i2s_pins.bck_io_num;
82 pin_ws = i2s_pins.ws_io_num;
83 if (rx_tx_mode == RX_MODE){
84 pin_data = i2s_pins.data_in_num;
85 pin_data_rx = I2S_PIN_NO_CHANGE;
86 } else {
87 pin_data = i2s_pins.data_out_num;
88 pin_data_rx = i2s_pins.data_in_num;
89 }
90 };
91
92 // convert to audio_hal_iface_samples_t
93 audio_hal_iface_bits_t toBits() {
94 TRACED();
95 static const int ia[] = {16, 24, 32};
96 static const audio_hal_iface_bits_t oa[] = {AUDIO_HAL_BIT_LENGTH_16BITS,
97 AUDIO_HAL_BIT_LENGTH_24BITS,
98 AUDIO_HAL_BIT_LENGTH_32BITS};
99 for (int j = 0; j < 3; j++) {
100 if (ia[j] == bits_per_sample) {
101 LOGD("-> %d",ia[j])
102 return oa[j];
103 }
104 }
105 LOGE("Bits per sample not supported: %d", bits_per_sample);
106 return AUDIO_HAL_BIT_LENGTH_16BITS;
107 }
108
111 TRACED();
112 static const int ia[] = {8000, 11025, 16000, 22050,
113 24000, 32000, 44100, 48000};
114 static const audio_hal_iface_samples_t oa[] = {
118 int diff = 99999;
119 int result = 0;
120 for (int j = 0; j < 8; j++) {
121 if (ia[j] == sample_rate) {
122 LOGD("-> %d",ia[j])
123 return oa[j];
124 } else {
125 int new_diff = abs((int)(oa[j] - sample_rate));
126 if (new_diff < diff) {
127 result = j;
128 diff = new_diff;
129 }
130 }
131 }
132 LOGE("Sample Rate not supported: %d - using %d", sample_rate, ia[result]);
133 return oa[result];
134 }
135
138 TRACED();
139 static const int ia[] = {I2S_STD_FORMAT,
140 I2S_LSB_FORMAT,
141 I2S_MSB_FORMAT,
142 I2S_PHILIPS_FORMAT,
143 I2S_RIGHT_JUSTIFIED_FORMAT,
144 I2S_LEFT_JUSTIFIED_FORMAT,
145 I2S_PCM};
146 static const audio_hal_iface_format_t oa[] = {
150 for (int j = 0; j < 8; j++) {
151 if (ia[j] == i2s_format) {
152 LOGD("-> %d",j)
153 return oa[j];
154 }
155 }
156 LOGE("Format not supported: %d", i2s_format);
158 }
159
165
168 switch (rx_tx_mode) {
169 case TX_MODE:
170 LOGD("-> %s","AUDIO_HAL_CODEC_MODE_DECODE");
172 case RX_MODE:
173 LOGD("-> %s","AUDIO_HAL_CODEC_MODE_ENCODE");
175 default:
176 LOGD("-> %s","AUDIO_HAL_CODEC_MODE_BOTH");
178 }
179 }
180};
181
190 public:
191 AudioKitStream() { pt_AudioKitStream = this; }
192
195 TRACED();
196 AudioKitStreamConfig result{mode};
197 result.rx_tx_mode = mode;
198 return result;
199 }
200
203 TRACED();
204 cfg = config;
205
207 cfg.logInfo("AudioKitStream");
208
209 // start codec
210 auto kit_cfg = cfg.toAudioKitConfig();
211 if (!kit.begin(kit_cfg)){
212 LOGE("begin faild: please verify your AUDIOKIT_BOARD setting: %d", AUDIOKIT_BOARD);
213 stop();
214 }
215
216 // start i2s
217 i2s_stream.begin(cfg);
218
219 // Volume control and headphone detection
220 if (cfg.default_actions_active){
221 setupActions();
222 }
223
224 // set initial volume
225 setVolume(volume_value);
226 is_started = true;
227 return true;
228 }
229
230 // restart after end with initial parameters
231 bool begin() override {
232 return begin(cfg);
233 }
234
236 void end() override {
237 TRACED();
238 kit.end();
239 i2s_stream.end();
240 is_started = false;
241 }
242
244 int available() {
245 return cfg.rx_tx_mode == TX_MODE ? 0 : DEFAULT_BUFFER_SIZE;
246 }
247
248 size_t write(const uint8_t *data, size_t len) override {
249 return i2s_stream.write(data, len);
250 }
251
253 size_t readBytes(uint8_t *data, size_t len) override {
254 return i2s_stream.readBytes(data, len);
255 }
256
259 void setAudioInfo(AudioInfo info) override {
260 TRACEI();
261
262 if (cfg.sample_rate != info.sample_rate
263 && cfg.bits_per_sample == info.bits_per_sample
264 && cfg.channels == info.channels
265 && is_started) {
266 // update sample rate only
267 LOGW("Update sample rate: %d", info.sample_rate);
268 cfg.sample_rate = info.sample_rate;
269 i2s_stream.setAudioInfo(cfg);
270 kit.setSampleRate(cfg.toSampleRate());
271 } else if (cfg.sample_rate != info.sample_rate
272 || cfg.bits_per_sample != info.bits_per_sample
273 || cfg.channels != info.channels
274 || !is_started) {
275 // more has changed and we need to start the processing
276 cfg.sample_rate = info.sample_rate;
278 cfg.channels = info.channels;
279 cfg.logInfo("AudioKit");
280
281 // Stop first
282 if(is_started){
283 end();
284 }
285 // start kit with new config
286 i2s_stream.begin(cfg);
287 kit.begin(cfg.toAudioKitConfig());
288 is_started = true;
289 }
290 }
291
292 AudioKitStreamConfig &config() { return cfg; }
293
295 bool setActive(bool active) { return kit.setActive(active); }
296
298 bool setMute(bool mute) { return kit.setMute(mute); }
299
301 bool setVolume(int vol) {
302 if (vol>100) LOGW("Volume is > 100: %d",vol);
303 // update variable, so if called before begin we set the default value
304 volume_value = vol;
305 return kit.setVolume(vol);
306 }
307
309 bool setVolume(float vol) {
310 if (vol>1.0) LOGW("Volume is > 1.0: %f",vol);
311 // update variable, so if called before begin we set the default value
312 volume_value = 100.0 * vol;
313 return kit.setVolume(volume_value);
314 }
315
317 bool setVolume(double vol) {
318 return setVolume((float)vol);
319 }
320
322 int volume() { return kit.volume(); }
323
326 void setSpeakerActive (bool active){
327 kit.setSpeakerActive(active);
328 }
329
333 return kit.headphoneStatus();
334 }
335
341// TRACED();
342 actions.processActions();
343 yield();
344 }
345
354 void addAction(int pin, void (*action)(bool,int,void*), void* ref=nullptr ) {
355 TRACEI();
356 // determine logic from config
357 AudioActions::ActiveLogic activeLogic = getActionLogic(pin);
358 actions.add(pin, action, activeLogic, ref);
359 }
360
370 void addAction(int pin, void (*action)(bool,int,void*), AudioActions::ActiveLogic activeLogic, void* ref=nullptr ) {
371 TRACEI();
372 actions.add(pin, action, activeLogic, ref);
373 }
374
377 return actions;
378 }
379
385 void incrementVolume(int vol) {
386 volume_value += vol;
387 LOGI("incrementVolume: %d -> %d",vol, volume_value);
388 kit.setVolume(volume_value);
389 }
390
395 static void actionVolumeUp(bool, int, void*) {
396 TRACEI();
397 pt_AudioKitStream->incrementVolume(+2);
398 }
399
404 static void actionVolumeDown(bool, int, void*) {
405 TRACEI();
406 pt_AudioKitStream->incrementVolume(-2);
407 }
408
413 static void actionStartStop(bool, int, void*) {
414 TRACEI();
415 pt_AudioKitStream->active = !pt_AudioKitStream->active;
416 pt_AudioKitStream->setActive(pt_AudioKitStream->active);
417 }
418
423 static void actionStart(bool, int, void*) {
424 TRACEI();
425 pt_AudioKitStream->active = true;
426 pt_AudioKitStream->setActive(pt_AudioKitStream->active);
427 }
428
433 static void actionStop(bool, int, void*) {
434 TRACEI();
435 pt_AudioKitStream->active = false;
436 pt_AudioKitStream->setActive(pt_AudioKitStream->active);
437 }
438
444 static void actionHeadphoneDetection(bool, int, void*) {
445 AudioKit::actionHeadphoneDetection();
446 }
447
448
455 int8_t pinAuxin() { return kit.pinAuxin(); }
456
463 int8_t pinHeadphoneDetect() { return kit.pinHeadphoneDetect(); }
464
471 int8_t pinPaEnable() { return kit.pinPaEnable(); }
472
479 int8_t pinAdcDetect() { return kit.pinAdcDetect(); }
480
487 int8_t pinEs7243Mclk() { return kit.pinEs7243Mclk(); }
488
495 int8_t pinInputRec() { return kit.pinInputRec(); }
496
503 int8_t pinInputMode() { return kit.pinInputMode(); }
504
511 int8_t pinInputSet() { return kit.pinInputSet(); };
512
519 int8_t pinInputPlay() { return kit.pinInputPlay(); }
520
527 int8_t pinVolumeUp() { return kit.pinVolumeUp(); }
528
535 int8_t pinVolumeDown() { return kit.pinVolumeDown(); }
536
543 int8_t pinResetCodec() { return kit.pinResetCodec(); }
544
551 int8_t pinResetBoard() { return kit.pinResetBoard(); }
552
559 int8_t pinGreenLed() { return kit.pinGreenLed(); }
560
567 int8_t pinBlueLed() { return kit.pinBlueLed(); }
568
569 protected:
570 AudioKit kit;
571 I2SStream i2s_stream;
572 AudioKitStreamConfig cfg = defaultConfig(RXTX_MODE);
573 AudioActions actions;
574 int volume_value = 40;
575 bool active = true;
576 bool is_started = false;
577
579 AudioActions::ActiveLogic getActionLogic(int pin){
580#if defined(USE_EXT_BUTTON_LOGIC)
582 int size = sizeof(input_key_info) / sizeof(input_key_info[0]);
583 for (int j=0; j<size; j++){
584 if (pin == input_key_info[j].act_id){
585 switch(input_key_info[j].type){
587 LOGD("getActionLogic for pin %d -> %d", pin, AudioActions::ActiveHigh);
588 return AudioActions::ActiveHigh;
589 case PERIPH_ID_BUTTON:
590 LOGD("getActionLogic for pin %d -> %d", pin, AudioActions::ActiveLow);
591 return AudioActions::ActiveLow;
592 case PERIPH_ID_TOUCH:
593 LOGD("getActionLogic for pin %d -> %d", pin, AudioActions::ActiveTouch);
594 return AudioActions::ActiveTouch;
595 }
596 }
597 }
598 LOGW("Undefined ActionLogic for pin: %d ",pin);
599#endif
600 return AudioActions::ActiveLow;
601 }
602
605 TRACEI();
606
607 // pin conflicts with the SD CS pin for AIThinker and buttons
608 if (! (cfg.sd_active && (AUDIOKIT_BOARD==5 || AUDIOKIT_BOARD==6))){
609 LOGD("actionStartStop")
610 addAction(kit.pinInputMode(), actionStartStop);
611 } else {
612 LOGW("Mode Button ignored because of conflict: %d ",kit.pinInputMode());
613 }
614
615 // pin conflicts with AIThinker A101 and headphone detection
616 if (! (cfg.sd_active && AUDIOKIT_BOARD==6)) {
617 LOGD("actionHeadphoneDetection pin:%d",kit.pinHeadphoneDetect())
618 actions.add(kit.pinHeadphoneDetect(), actionHeadphoneDetection, AudioActions::ActiveChange);
619 } else {
620 LOGW("Headphone detection ignored because of conflict: %d ",kit.pinHeadphoneDetect());
621 }
622
623 // pin conflicts with SD Lyrat SD CS GpioPinand buttons / Conflict on Audiokit V. 2957
624 if (! (cfg.sd_active && (AUDIOKIT_BOARD==1 || AUDIOKIT_BOARD==7))){
625 LOGD("actionVolumeDown")
626 addAction(kit.pinVolumeDown(), actionVolumeDown);
627 LOGD("actionVolumeUp")
628 addAction(kit.pinVolumeUp(), actionVolumeUp);
629 } else {
630 LOGW("Volume Buttons ignored because of conflict: %d ",kit.pinVolumeDown());
631 }
632 }
633};
634
635} // namespace audio_tools
A simple class to assign functions to gpio pins e.g. to implement a simple navigation control or volu...
Definition AudioActions.h:29
void processActions()
Execute all actions if the corresponding pin is low To minimize the runtime: With each call we proces...
Definition AudioActions.h:180
void add(Action &action)
Adds an Action.
Definition AudioActions.h:133
Configuration for AudioKitStream: we use as subclass of I2SConfig.
Definition AudioKit.h:23
AudioKitConfig toAudioKitConfig()
convert to config object needed by HAL
Definition AudioKit.h:39
void setupI2SPins(RxTxMode rxtx_mode)
Defines the pins based on the information provided by the AudioKit project.
Definition AudioKit.h:74
audio_hal_iface_mode_t toMode()
Definition AudioKit.h:162
audio_hal_codec_mode_t toCodecMode()
Convert to audio_hal_codec_mode_t.
Definition AudioKit.h:167
audio_hal_iface_samples_t toSampleRate()
Convert to audio_hal_iface_samples_t.
Definition AudioKit.h:110
audio_hal_iface_format_t toFormat()
Convert to audio_hal_iface_format_t.
Definition AudioKit.h:137
AudioKit Stream which uses the https://github.com/pschatzmann/arduino-audiokit library.
Definition AudioKit.h:189
void addAction(int pin, void(*action)(bool, int, void *), void *ref=nullptr)
Defines a new action that is executed when the indicated pin is active.
Definition AudioKit.h:354
static void actionVolumeDown(bool, int, void *)
Decrease the volume.
Definition AudioKit.h:404
static void actionStartStop(bool, int, void *)
Toggle start stop.
Definition AudioKit.h:413
int8_t pinGreenLed()
Get DSP reset gpio number.
Definition AudioKit.h:559
bool setVolume(double vol)
Defines the Volume: Range 0 to 1.0.
Definition AudioKit.h:317
void setSpeakerActive(bool active)
Definition AudioKit.h:326
int8_t pinEs7243Mclk()
Get the mclk gpio number of es7243.
Definition AudioKit.h:487
void addAction(int pin, void(*action)(bool, int, void *), AudioActions::ActiveLogic activeLogic, void *ref=nullptr)
Defines a new action that is executed when the indicated pin is active.
Definition AudioKit.h:370
int8_t pinResetCodec()
Get green led gpio number.
Definition AudioKit.h:543
int8_t pinInputPlay()
Get number for play function.
Definition AudioKit.h:519
AudioActions::ActiveLogic getActionLogic(int pin)
Determines the action logic (ActiveLow or ActiveTouch) for the pin.
Definition AudioKit.h:579
int available()
We get the data via I2S - we expect to fill one buffer size.
Definition AudioKit.h:244
int8_t pinBlueLed()
Get green led gpio number.
Definition AudioKit.h:567
size_t readBytes(uint8_t *data, size_t len) override
Reads the audio data.
Definition AudioKit.h:253
int volume()
Determines the volume.
Definition AudioKit.h:322
AudioActions & audioActions()
Provides access to the AudioActions.
Definition AudioKit.h:376
void incrementVolume(int vol)
Relative volume control.
Definition AudioKit.h:385
static void actionHeadphoneDetection(bool, int, void *)
Switch off the PA if the headphone in plugged in and switch it on again if the headphone is unplugged...
Definition AudioKit.h:444
void end() override
Stops the processing.
Definition AudioKit.h:236
bool setActive(bool active)
Sets the codec active / inactive.
Definition AudioKit.h:295
bool setVolume(int vol)
Defines the Volume: Range 0 to 100.
Definition AudioKit.h:301
int8_t pinVolumeDown()
Get number for volume down function.
Definition AudioKit.h:535
int8_t pinInputSet()
Get number for set function.
Definition AudioKit.h:511
void processActions()
Process input keys and pins.
Definition AudioKit.h:340
int8_t pinInputRec()
Get the record-button id for adc-button.
Definition AudioKit.h:495
static void actionVolumeUp(bool, int, void *)
Increase the volume.
Definition AudioKit.h:395
AudioKitStreamConfig defaultConfig(RxTxMode mode=RXTX_MODE)
Provides the default configuration.
Definition AudioKit.h:194
static void actionStart(bool, int, void *)
Start.
Definition AudioKit.h:423
int8_t pinResetBoard()
Get DSP reset gpio number.
Definition AudioKit.h:551
int8_t pinVolumeUp()
number for volume up function
Definition AudioKit.h:527
int8_t pinHeadphoneDetect()
Get the gpio number for headphone detection.
Definition AudioKit.h:463
bool setMute(bool mute)
Mutes the output.
Definition AudioKit.h:298
int8_t pinAdcDetect()
Get the gpio number for adc detection.
Definition AudioKit.h:479
void setupActions()
Setup the supported default actions.
Definition AudioKit.h:604
static void actionStop(bool, int, void *)
Stop.
Definition AudioKit.h:433
int8_t pinPaEnable()
Get the gpio number for PA enable.
Definition AudioKit.h:471
void setAudioInfo(AudioInfo info) override
Definition AudioKit.h:259
bool headphoneStatus()
Returns true if the headphone was detected.
Definition AudioKit.h:332
bool begin(AudioKitStreamConfig config)
Starts the processing.
Definition AudioKit.h:202
bool setVolume(float vol)
Defines the Volume: Range 0 to 1.0.
Definition AudioKit.h:309
int8_t pinInputMode()
Get the number for mode-button.
Definition AudioKit.h:503
int8_t pinAuxin()
Get the gpio number for auxin detection.
Definition AudioKit.h:455
Base class for all Audio Streams. It support the boolean operator to test if the object is ready with...
Definition BaseStream.h:115
virtual void setAudioInfo(AudioInfo newInfo) override
Defines the input AudioInfo.
Definition BaseStream.h:123
Configuration for ESP32 legacy i2s.
Definition I2SConfigESP32.h:23
RxTxMode rx_tx_mode
public settings
Definition I2SConfigESP32.h:59
We support the Stream interface for the I2S access. In addition we allow a separate mute pin which mi...
Definition I2SStream.h:33
virtual size_t readBytes(uint8_t *data, size_t len) override
Reads the audio data.
Definition I2SStream.h:122
virtual void setAudioInfo(AudioInfo info)
updates the sample rate dynamically
Definition I2SStream.h:92
virtual size_t write(const uint8_t *data, size_t len)
Writes the audio data to I2S.
Definition I2SStream.h:115
void end()
Stops the I2S interface.
Definition I2SStream.h:84
Vector implementation which provides the most important methods as defined by std::vector....
Definition Vector.h:21
void stop()
Public generic methods.
Definition AudioRuntime.h:28
RxTxMode
The Microcontroller is the Audio Source (TX_MODE) or Audio Sink (RX_MODE). RXTX_MODE is Source and Si...
Definition AudioTypes.h:28
Generic Implementation of sound input and output for desktop environments using portaudio.
Definition AudioConfig.h:885
Basic Audio information which drives e.g. I2S.
Definition AudioTypes.h:52
sample_rate_t sample_rate
Sample Rate: e.g 44100.
Definition AudioTypes.h:55
uint16_t channels
Number of channels: 2=stereo, 1=mono.
Definition AudioTypes.h:57
uint8_t bits_per_sample
Number of bits per sample (int16_t = 16 bits)
Definition AudioTypes.h:59