arduino-audio-tools
All Classes Namespaces Files Functions Variables Typedefs Enumerations Friends Modules Pages
AudioBoardStream.h
1#pragma once
2
3#include "AudioToolsConfig.h"
4#include "AudioTools/AudioLibs/I2SCodecStream.h"
5#include "AudioTools/CoreAudio/AudioActions.h"
6
7namespace audio_tools {
8
20 struct AudioBoardAction : public AudioActions::Action {
21 AudioBoardAction(AudioBoard &board, AudioDriverKey key) {
22 this->key = key;
23 this->p_board = &board;
24 }
25 AudioDriverKey key;
26 AudioBoard *p_board;
27 int id() override { return key | 0x400; }
28 bool readValue() override { return p_board->isKeyPressed(key); }
29 };
30
31 public:
39 AudioBoardStream(audio_driver::AudioBoard &board) : I2SCodecStream(board) {
40 // pin mode already set up by driver library
41 actions.setPinMode(false);
42 }
43
44 bool begin() override { return I2SCodecStream::begin(); }
45
46 bool begin(I2SCodecConfig cfg) override { return I2SCodecStream::begin(cfg); }
47
53 // TRACED();
54 actions.processActions();
55 delay(1);
56 }
57
58
62 void addAction(AudioDriverKey key, void (*action)(bool, int, void *),
63 void *ref = nullptr) {
64 AudioBoardAction *abo = new AudioBoardAction(board(), key);
65 abo->actionOn = action;
66 abo->ref = (ref == nullptr) ? this : ref;
67 actions.add(*abo);
68 }
69
73 void addAction(AudioDriverKey key, void (*actionOn)(bool, int, void *),
74 void (*actionOff)(bool, int, void *),
75 void *ref = nullptr) {
76
77 AudioBoardAction *abo = new AudioBoardAction(board(), key);
78 abo->actionOn = actionOn;
79 abo->actionOn = actionOff;
80 abo->ref = (ref == nullptr) ? this : ref;
81 actions.add(*abo);
82 }
83
92 void addAction(int pin, void (*action)(bool, int, void *),
93 void *ref = nullptr) {
94 TRACEI();
95 // determine logic from config
96 AudioActions::ActiveLogic activeLogic = getActionLogic(pin);
97 actions.add(pin, action, activeLogic, ref == nullptr ? this : ref);
98 }
99
109 void addAction(int pin, void (*action)(bool, int, void *),
110 AudioActions::ActiveLogic activeLogic, void *ref = nullptr) {
111 TRACEI();
112 actions.add(pin, action, activeLogic, ref == nullptr ? this : ref);
113 }
114
116 AudioActions &audioActions() { return actions; }
117
118 AudioActions &getActions() { return actions; }
119
125 void incrementVolume(float inc) {
126 float current_volume = getVolume();
127 float new_volume = current_volume + inc;
128 LOGI("incrementVolume: %f -> %f", current_volume, new_volume);
129 setVolume(new_volume);
130 }
131
136 static void actionVolumeUp(bool, int, void *ref) {
137 TRACEI();
138 AudioBoardStream *self = (AudioBoardStream *)ref;
139 self->incrementVolume(+self->actionVolumeIncrementValue());
140 }
141
146 static void actionVolumeDown(bool, int, void *ref) {
147 TRACEI();
148 AudioBoardStream *self = (AudioBoardStream *)ref;
149 self->incrementVolume(-self->actionVolumeIncrementValue());
150 }
151
156 static void actionStartStop(bool, int, void *ref) {
157 TRACEI();
158 AudioBoardStream *self = (AudioBoardStream *)ref;
159 self->active = !self->active;
160 self->setActive(self->active);
161 }
162
167 static void actionStart(bool, int, void *ref) {
168 TRACEI();
169 AudioBoardStream *self = (AudioBoardStream *)ref;
170 self->active = true;
171 self->setActive(self->active);
172 }
173
177 static void actionStop(bool, int, void *ref) {
178 TRACEI();
179 AudioBoardStream *self = (AudioBoardStream *)ref;
180 self->active = false;
181 self->setActive(self->active);
182 }
183
189 static void actionHeadphoneDetection(bool, int, void *ref) {
190 AudioBoardStream *self = (AudioBoardStream *)ref;
191 if (self->pinHeadphoneDetect() >= 0) {
192 // detect changes
193 bool isConnected = self->headphoneStatus();
194 if (self->headphoneIsConnected != isConnected) {
195 self->headphoneIsConnected = isConnected;
196
197 // update if things have stabilized
198 bool powerActive = !isConnected;
199 LOGW("Headphone jack has been %s",
200 isConnected ? "inserted" : "removed");
201 self->setSpeakerActive(powerActive);
202 }
203 }
204 delay(1);
205 }
206
213 GpioPin pinAuxin() { return getPinID(PinFunction::AUXIN_DETECT); }
214
222 return getPinID(PinFunction::HEADPHONE_DETECT);
223 }
224
231 GpioPin pinPaEnable() { return getPinID(PinFunction::PA); }
232
233 // /**
234 // * @brief Get the gpio number for adc detection
235 // *
236 // * @return -1 non-existent
237 // * Others gpio number
238 // */
239 // GpioPin pinAdcDetect() { return getPin(AUXIN_DETECT); }
240
247 GpioPin pinInputRec() { return getPinID(PinFunction::KEY, 1); }
248
255 GpioPin pinInputMode() { return getPinID(PinFunction::KEY, 2); }
256
263 GpioPin pinInputSet() { return getPinID(PinFunction::KEY, 4); }
264
271 GpioPin pinInputPlay() { return getPinID(PinFunction::KEY, 3); }
272
279 GpioPin pinVolumeUp() { return getPinID(PinFunction::KEY, 6); }
280
287 GpioPin pinVolumeDown() { return getPinID(PinFunction::KEY, 5); }
288
295 GpioPin pinLed(int idx) { return getPinID(PinFunction::LED, idx); }
296
298 void setSpeakerActive(bool active) { setPAPower(active); }
299
307 int headphoneGpioPin = pinHeadphoneDetect();
308 return headphoneGpioPin > 0 ? !digitalRead(headphoneGpioPin) : false;
309 }
310
314 void setActive(bool active) { setMute(!active); }
315
318 // pin conflicts for pinInputMode() with the SD CS pin for AIThinker and
319 // buttons
320 int sd_cs = getSdCsPin();
321 int input_mode = pinInputMode();
322 if (input_mode != -1 && (input_mode != sd_cs || !cfg.sd_active)) {
323 LOGD("actionInputMode")
324 addAction(input_mode, actionStartStop);
325 }
326 }
327
330 // pin conflicts with SD Lyrat SD CS GpioPin and buttons / Conflict on
331 // Audiokit V. 2957
332 int sd_cs = getSdCsPin();
333 int vol_up = pinVolumeUp();
334 int vol_down = pinVolumeDown();
335 if ((vol_up != -1 && vol_down != -1) &&
336 (!cfg.sd_active || (vol_down != sd_cs && vol_up != sd_cs))) {
337 LOGD("actionVolumeDown")
338 addAction(vol_down, actionVolumeDown);
339 LOGD("actionVolumeUp")
340 addAction(vol_up, actionVolumeUp);
341 } else {
342 LOGW("Volume Buttons ignored because of conflict: %d ", pinVolumeDown());
343 }
344 }
345
348 // pin conflicts with AIThinker A101: key6 and headphone detection
349 int head_phone = pinHeadphoneDetect();
350 if (head_phone != -1 && (getPinID(PinFunction::KEY, 6) != head_phone)) {
351 actions.add(head_phone, actionHeadphoneDetection,
352 AudioActions::ActiveChange, this);
353 }
354 }
355
361 TRACEI();
365 }
366
369 action_increment_value = value;
370 }
371
372 float actionVolumeIncrementValue() { return action_increment_value; }
373
374 bool isKeyPressed(int key) {
375 if (!board()) return false;
376 return board().isKeyPressed(key);
377 }
378
379 protected:
380 AudioActions actions;
381 bool headphoneIsConnected = false;
382 bool active = true;
383 float action_increment_value = 0.02;
384
385 int getSdCsPin() {
386 static GpioPin sd_cs = -2;
387 // execute only once
388 if (sd_cs != -2) return sd_cs;
389
390 auto sd_opt = getPins().getSPIPins(PinFunction::SD);
391 if (sd_opt) {
392 sd_cs = sd_opt.value().cs;
393 } else {
394 // no spi -> no sd
395 LOGI("No sd defined -> sd_active=false")
396 cfg.sd_active = false;
397 sd_cs = -1;
398 }
399 return sd_cs;
400 }
401
403 AudioActions::ActiveLogic getActionLogic(int pin) {
404 auto opt = board().getPins().getPin(pin);
405 PinLogic logic = PinLogic::Input;
406 if (opt) logic = opt.value().pin_logic;
407 switch (logic) {
408 case PinLogic::Input:
409 case PinLogic::InputActiveLow:
410 return AudioActions::ActiveLow;
411 case PinLogic::InputActiveHigh:
412 return AudioActions::ActiveHigh;
413 case PinLogic::InputActiveTouch:
414 return AudioActions::ActiveTouch;
415 default:
416 return AudioActions::ActiveLow;
417 }
418 }
419};
420
421} // namespace audio_tools
int digitalRead(int pin)
e.g. for AudioActions
Definition NoArduino.h:200
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
void setPinMode(bool active)
setup pin mode when true
Definition AudioActions.h:228
New functionality which replaces the AudioKitStream that is based on the legacy AudioKit library....
Definition AudioBoardStream.h:19
void addAction(AudioDriverKey key, void(*actionOn)(bool, int, void *), void(*actionOff)(bool, int, void *), void *ref=nullptr)
Defines a new action that is executed when the Button is pressed and released.
Definition AudioBoardStream.h:73
GpioPin pinInputRec()
Get the record-button id for adc-button.
Definition AudioBoardStream.h:247
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 AudioBoardStream.h:92
GpioPin pinVolumeDown()
Get number for volume down function.
Definition AudioBoardStream.h:287
static void actionVolumeUp(bool, int, void *ref)
Increase the volume.
Definition AudioBoardStream.h:136
void setSpeakerActive(bool active)
the same as setPAPower()
Definition AudioBoardStream.h:298
static void actionHeadphoneDetection(bool, int, void *ref)
Switch off the PA if the headphone in plugged in and switch it on again if the headphone is unplugged...
Definition AudioBoardStream.h:189
static void actionVolumeDown(bool, int, void *ref)
Decrease the volume.
Definition AudioBoardStream.h:146
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 AudioBoardStream.h:109
void addAction(AudioDriverKey key, void(*action)(bool, int, void *), void *ref=nullptr)
Defines a new action that is executed when the Button is pressed.
Definition AudioBoardStream.h:62
GpioPin pinLed(int idx)
Get LED pin.
Definition AudioBoardStream.h:295
GpioPin pinAuxin()
Get the gpio number for auxin detection.
Definition AudioBoardStream.h:213
AudioActions::ActiveLogic getActionLogic(int pin)
Determines the action logic (ActiveLow or ActiveTouch) for the pin.
Definition AudioBoardStream.h:403
static void actionStartStop(bool, int, void *ref)
Toggle start stop.
Definition AudioBoardStream.h:156
GpioPin pinPaEnable()
Get the gpio number for PA enable.
Definition AudioBoardStream.h:231
GpioPin pinInputMode()
Get the number for mode-button.
Definition AudioBoardStream.h:255
AudioActions & audioActions()
Provides access to the AudioActions.
Definition AudioBoardStream.h:116
GpioPin pinInputPlay()
Get number for play function.
Definition AudioBoardStream.h:271
GpioPin pinHeadphoneDetect()
Get the gpio number for headphone detection.
Definition AudioBoardStream.h:221
GpioPin pinInputSet()
Get number for set function.
Definition AudioBoardStream.h:263
bool begin(I2SCodecConfig cfg) override
Starts the I2S interface.
Definition AudioBoardStream.h:46
void addHeadphoneDetectionAction()
Adds headphone determination.
Definition AudioBoardStream.h:347
void processActions()
Process input keys and pins.
Definition AudioBoardStream.h:52
void setActionVolumeIncrementValue(float value)
Defines the increment value used by actionVolumeDown/actionVolumeUp.
Definition AudioBoardStream.h:368
void addDefaultActions()
Setup the supported default actions (volume, start/stop, headphone detection)
Definition AudioBoardStream.h:360
void incrementVolume(float inc)
Relative volume control.
Definition AudioBoardStream.h:125
AudioBoardStream(audio_driver::AudioBoard &board)
Default constructor: for available AudioBoard values check the audioboard variables in https://pschat...
Definition AudioBoardStream.h:39
void setActive(bool active)
The oposite of setMute(): setActive(true) calls setMute(false)
Definition AudioBoardStream.h:314
void addVolumeActions()
add volume up and volume down action
Definition AudioBoardStream.h:329
void addStartStopAction()
add start/stop on inputMode
Definition AudioBoardStream.h:317
GpioPin pinVolumeUp()
number for volume up function
Definition AudioBoardStream.h:279
bool headphoneStatus()
Returns true if the headphone was detected.
Definition AudioBoardStream.h:306
static void actionStart(bool, int, void *ref)
Start.
Definition AudioBoardStream.h:167
static void actionStop(bool, int, void *ref)
Stop.
Definition AudioBoardStream.h:177
I2S Stream which also sets up a codec chip and i2s.
Definition I2SCodecStream.h:45
DriverPins & getPins()
Provides access to the pin information.
Definition I2SCodecStream.h:203
AudioBoard & board()
Provides the board.
Definition I2SCodecStream.h:179
bool setMute(bool mute)
Mute / unmote.
Definition I2SCodecStream.h:156
float getVolume()
legacy: same as volume()
Definition I2SCodecStream.h:153
bool setPAPower(bool active)
Sets the output of the PA Power Pin.
Definition I2SCodecStream.h:167
bool setVolume(float vol) override
sets the volume (range 0.0f - 1.0f)
Definition I2SCodecStream.h:141
GpioPin getPinID(PinFunction function)
Provides the gpio for the indicated function.
Definition I2SCodecStream.h:188
Generic Implementation of sound input and output for desktop environments using portaudio.
Definition AudioCodecsBase.h:10
Definition AudioActions.h:38
Configuration for I2SCodecStream.
Definition I2SCodecStream.h:24