Skip to content

Commit ece3afb

Browse files
committed
DRAFT AnalogAudioArduino
1 parent e51f22e commit ece3afb

File tree

12 files changed

+178
-29
lines changed

12 files changed

+178
-29
lines changed

examples/examples-stream/streams-memory_mp3-pwm/README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,4 +26,4 @@ The pins depend on the Processor:
2626
| Right | GPI3 | GPIO3 | GPI3 |
2727
| GND | GND | GND | GND |
2828

29-
To verify check the PWM_START_PIN in AudioConfig.h or you can set the pins by calling setPins() method on the PWMConfig object.
29+
To verify check the PIN_PWM_START in AudioConfig.h or you can set the pins by calling setPins() method on the PWMConfig object.

examples/tests/test-timercb_rx/test-timercb_rx.ino

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,6 @@
22
#include "AudioTools.h"
33

44

5-
6-
75
TimerCallbackAudioStream timerStream;
86

97
uint16_t IRAM_ATTR callback(uint8_t *data, uint16_t len){

src/AudioAnalog/AnalogAudio.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
#pragma once
22

33
#include "AudioAnalog/AnalogAudioESP32.h"
4+
#include "AudioAnalog/AnalogAudioArduino.h"
45

56

67

src/AudioAnalog/AnalogAudioArduino.h

Lines changed: 120 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,120 @@
1+
#pragma once
2+
3+
#include "AudioConfig.h"
4+
#ifdef USE_ADC_ARDUINO
5+
#include "AudioTimer/AudioTimer.h"
6+
#include "AudioTools/AudioStreams.h"
7+
#include "AudioTools/AudioTypes.h"
8+
#include "AudioTools/Buffers.h"
9+
10+
namespace audio_tools {
11+
12+
13+
/**
14+
* @brief Configuration for Analog Reader
15+
* @author Phil Schatzmann
16+
* @copyright GPLv3
17+
*/
18+
class AnalogConfig : public AudioBaseInfo {
19+
public:
20+
AnalogConfig() {
21+
channels = 1;
22+
sample_rate = 10000;
23+
bits_per_sample = 16;
24+
}
25+
int start_pin = PIN_ADC_START;
26+
uint16_t buffer_size = ADC_BUFFER_SIZE;
27+
uint8_t buffers = ADC_BUFFERS;
28+
};
29+
30+
/**
31+
* @brief Reading Analog Data using a timer and the Arduino analogRead() method
32+
* @author Phil Schatzmann
33+
* @copyright GPLv3
34+
*
35+
*/
36+
class AnalogAudioStream : public AudioStreamX {
37+
public:
38+
AnalogAudioStream() = default;
39+
40+
AnalogConfig defaultConfig() {
41+
AnalogConfig cfg;
42+
return cfg;
43+
}
44+
45+
void setAudioInfo(AudioBaseInfo info) { LOGW("setAudioInfo() not supported") }
46+
47+
bool begin(AnalogConfig cfg) {
48+
LOGD("%s", __func__);
49+
config = cfg;
50+
if (buffer == nullptr) {
51+
// allocate buffers
52+
buffer = new NBuffer<int16_t>(cfg.buffer_size, cfg.buffers);
53+
if (buffer==nullptr){
54+
LOGE("Not enough memory for buffer");
55+
return false;
56+
} else {
57+
LOGI("buffer: %d", (int) buffer);
58+
LOGI("self: %d", (int) this);
59+
}
60+
// setup pins
61+
setupPins();
62+
} else {
63+
timer.end();
64+
}
65+
66+
// (re)start timer
67+
uint32_t time = AudioUtils::toTimeUs(config.sample_rate);
68+
LOGI("sample_rate: %d", cfg.sample_rate);
69+
LOGI("time us: %u", time);
70+
timer.setCallbackParameter(this);
71+
return timer.begin(callback, time, TimeUnit::US);
72+
}
73+
74+
virtual int available() { return buffer==nullptr ? 0 : buffer->available(); };
75+
76+
/// Provides the sampled audio data
77+
size_t readBytes(uint8_t *values, size_t len) {
78+
if (buffer==nullptr) return 0;
79+
int samples = len / 2;
80+
return buffer->readArray((int16_t *)values, samples);
81+
}
82+
83+
protected:
84+
AnalogConfig config;
85+
TimerAlarmRepeating timer;
86+
BaseBuffer<int16_t> *buffer = nullptr;
87+
88+
/// Sample data and write to buffer
89+
static void callback(void *arg) {
90+
int16_t value = 0;
91+
AnalogAudioStream *self = (AnalogAudioStream *)arg;
92+
if (self->buffer != nullptr) {
93+
int channels = self->config.channels;
94+
for (int j = 0; j < channels; j++) {
95+
//Serial.print("+");
96+
// provides value in range 0…4095
97+
value = analogRead(self->config.start_pin + j);
98+
//Serial.print("-");
99+
value = (value-2048)*15;
100+
self->buffer->write(value);
101+
}
102+
}
103+
}
104+
105+
/// pinmode input for defined analog pins
106+
void setupPins() {
107+
LOGD("%s", __func__);
108+
LOGI("start_pin: %d", config.start_pin);
109+
// setup pins for read
110+
for (int j = 0; j < config.channels; j++) {
111+
int pin = config.start_pin + j;
112+
pinMode(pin, INPUT);
113+
LOGD("pinMode(%d, INPUT)",pin);
114+
}
115+
}
116+
};
117+
118+
} // namespace audio_tools
119+
120+
#endif

src/AudioConfig.h

Lines changed: 28 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -148,7 +148,7 @@
148148
#define USE_URLSTREAM_TASK
149149

150150
#define PWM_FREQENCY 30000
151-
#define PWM_START_PIN 12
151+
#define PIN_PWM_START 12
152152
#define PIN_I2S_BCK 14
153153
#define PIN_I2S_WS 15
154154
#define PIN_I2S_DATA_IN 32
@@ -196,7 +196,7 @@ typedef uint32_t eps32_i2s_sample_rate_type;
196196
#define USE_AUDIO_SERVER
197197
//#define USE_ESP8266_AUDIO
198198

199-
#define PWM_START_PIN 12
199+
#define PIN_PWM_START 12
200200
#define PIN_I2S_BCK -1
201201
#define PIN_I2S_WS -1
202202
#define PIN_I2S_DATA_IN -1
@@ -212,7 +212,7 @@ typedef uint32_t eps32_i2s_sample_rate_type;
212212
#define USE_I2S
213213
#define USE_PWM
214214

215-
#define PWM_START_PIN 6
215+
#define PIN_PWM_START 6
216216
#define PIN_I2S_BCK 2
217217
#define PIN_I2S_WS 1
218218
#define PIN_I2S_DATA_IN 3
@@ -226,8 +226,10 @@ typedef uint32_t eps32_i2s_sample_rate_type;
226226
#if defined(ARDUINO_ARCH_MBED_RP2040)
227227
//#define USE_I2S 1
228228
#define USE_PWM
229+
#define USE_ADC_ARDUINO
229230

230-
#define PWM_START_PIN 6
231+
#define PIN_ADC_START 26
232+
#define PIN_PWM_START 6
231233
#define PIN_I2S_BCK 26
232234
#define PIN_I2S_WS PIN_I2S_BCK+1
233235
#define PIN_I2S_DATA_IN 28
@@ -239,14 +241,24 @@ typedef uint32_t eps32_i2s_sample_rate_type;
239241
// fix missing __sync_synchronize symbol
240242
#define FIX_SYNC_SYNCHRONIZE
241243
#define IRAM_ATTR
244+
#ifndef ADC_BUFFER_SIZE
245+
#define ADC_BUFFER_SIZE 1024
246+
#endif
247+
248+
#ifndef ADC_BUFFERS
249+
#define ADC_BUFFERS 50
250+
#endif
251+
242252
//#define USE_ESP8266_AUDIO
243253

244254
//----------------
245255
#elif defined(ARDUINO_ARCH_RP2040)
246256
#define USE_I2S 1
247257
#define USE_PWM
258+
#define USE_ADC_ARDUINO
248259

249-
#define PWM_START_PIN 6
260+
#define PIN_ADC_START 26
261+
#define PIN_PWM_START 6
250262
#define PIN_I2S_BCK 26
251263
#define PIN_I2S_WS PIN_I2S_BCK+1
252264
#define PIN_I2S_DATA_IN 28
@@ -258,6 +270,15 @@ typedef uint32_t eps32_i2s_sample_rate_type;
258270
// fix missing __sync_synchronize symbol
259271
#define FIX_SYNC_SYNCHRONIZE
260272
#define IRAM_ATTR
273+
274+
#ifndef ADC_BUFFER_SIZE
275+
#define ADC_BUFFER_SIZE 256
276+
#endif
277+
278+
#ifndef ADC_BUFFERS
279+
#define ADC_BUFFERS 100
280+
#endif
281+
261282
//#define USE_ESP8266_AUDIO
262283

263284
#endif
@@ -266,7 +287,7 @@ typedef uint32_t eps32_i2s_sample_rate_type;
266287
#ifdef __AVR__
267288
#define USE_PWM
268289

269-
#define PWM_START_PIN 6
290+
#define PIN_PWM_START 6
270291
#define PIN_CS CS
271292
#endif
272293

@@ -279,7 +300,7 @@ typedef uint32_t eps32_i2s_sample_rate_type;
279300
#define USE_I2S
280301
#define USE_PWM
281302

282-
#define PWM_START_PIN 6
303+
#define PIN_PWM_START 6
283304
#define PIN_I2S_BCK 1
284305
#define PIN_I2S_WS PIN_I2S_BCK+1
285306
#define PIN_I2S_DATA_IN 3

src/AudioExperiments/AudioDAC.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ class DACInfo : public AudioBaseInfo {
3030
int oversample_factor = 1;
3131

3232
/// Defines the pins: channel 0 is start_pin, channel 1 is start_pin+1 etc.
33-
int start_pin = PWM_START_PIN;
33+
int start_pin = PIN_PWM_START;
3434

3535
/// Max number of bits used to output signal
3636
int output_bits = 64;

src/AudioPWM/PWMAudioBase.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@ struct PWMConfig : public AudioBaseInfo {
4646
uint8_t timer_id = 0; // Only used by ESP32 must be between 0 and 3
4747

4848
#ifndef __AVR__
49-
uint16_t start_pin = PWM_START_PIN;
49+
uint16_t start_pin = PIN_PWM_START;
5050

5151
// define all pins by passing an array and updates the channels by the number of pins
5252
template<size_t N>
@@ -59,7 +59,7 @@ struct PWMConfig : public AudioBaseInfo {
5959
}
6060
pins = array;
6161
start_pin = -1; // mark start pin as invalid
62-
LOGI("start_pin: %d", PWM_START_PIN);
62+
LOGI("start_pin: %d", PIN_PWM_START);
6363
}
6464

6565
#endif

src/AudioPWM/PWMAudioMBED.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ class PWMAudioStreamMBED : public PWMAudioStreamBase {
2929

3030
// Ends the output
3131
virtual void end(){
32-
LOGD(LOG_METHOD);
32+
LOGD(LOG_METHOD);
3333
ticker.detach(); // it does not hurt to call this even if it has not been started
3434
is_timer_started = false;
3535

src/AudioTimer/AudioTimerDef.h

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ enum TimerFunction {DirectTimerCallback, TimerCallbackInThread, SimpleThreadLoop
1313
*/
1414
class TimerAlarmRepeatingDef {
1515
public:
16+
TimerAlarmRepeatingDef() = default;
1617
virtual ~TimerAlarmRepeatingDef() = default;
1718
virtual bool begin(repeating_timer_callback_t callback_f, uint32_t time, TimeUnit unit = MS) = 0;
1819
virtual bool end() = 0;
@@ -26,7 +27,7 @@ class TimerAlarmRepeatingDef {
2627
}
2728

2829
protected:
29-
void* object;
30+
void* object=nullptr;
3031

3132
};
3233

@@ -39,6 +40,9 @@ class AudioUtils {
3940
/// converts sampling rate to delay in microseconds (μs)
4041
static uint32_t toTimeUs(uint32_t samplingRate, uint8_t limit=10){
4142
uint32_t result = 1000000l / samplingRate;
43+
if (1000000l % samplingRate!=0){
44+
result++;
45+
}
4246
if (result <= limit){
4347
LOGW("Time for samplingRate %u -> %lu is < %u μs - we rounded up", (unsigned int)samplingRate, result, limit);
4448
result = limit;
@@ -48,6 +52,9 @@ class AudioUtils {
4852

4953
static uint32_t toTimeMs(uint32_t samplingRate, uint8_t limit=1){
5054
uint32_t result = 1000l / samplingRate;
55+
if (1000000l % samplingRate!=0){
56+
result++;
57+
}
5158
if (result <= limit){
5259
LOGW("Time for samplingRate %u -> %lu is < %u μs - we rounded up", (unsigned int)samplingRate, result, limit);
5360
result = limit;

src/AudioTimer/AudioTimerMBED.h

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -19,16 +19,15 @@ TimerAlarmRepeatingMBED *timerAlarmRepeating = nullptr;
1919
*/
2020
class TimerAlarmRepeatingMBED : public TimerAlarmRepeatingDef {
2121
public:
22-
23-
TimerAlarmRepeatingMBED(TimerFunction function=DirectTimerCallback, int id=0){
22+
23+
TimerAlarmRepeatingMBED(TimerFunction function=DirectTimerCallback, int id=0) : TimerAlarmRepeatingDef(){
2424
timerAlarmRepeating = this;
2525
}
2626

2727
~TimerAlarmRepeatingMBED(){
2828
end();
2929
}
3030

31-
3231
/**
3332
* Starts the alarm timer
3433
*/
@@ -38,10 +37,10 @@ class TimerAlarmRepeatingMBED : public TimerAlarmRepeatingDef {
3837
// we determine the time in microseconds
3938
switch(unit){
4039
case MS:
41-
ticker.attach(tickerCallback, time * 1000);
40+
ticker.attach_us(tickerCallback, (us_timestamp_t) time * 1000);
4241
break;
4342
case US:
44-
ticker.attach(tickerCallback, time);
43+
ticker.attach_us(tickerCallback,(us_timestamp_t) time);
4544
break;
4645
}
4746
return true;
@@ -57,8 +56,8 @@ class TimerAlarmRepeatingMBED : public TimerAlarmRepeatingDef {
5756
mbed::Ticker ticker;
5857
repeating_timer_callback_t callback;
5958

60-
static void tickerCallback(){
61-
timerAlarmRepeating->callback(timerAlarmRepeating);
59+
inline static void tickerCallback(){
60+
timerAlarmRepeating->callback(timerAlarmRepeating->object);
6261
}
6362

6463
};

0 commit comments

Comments
 (0)