Skip to content

Commit d6240e9

Browse files
committed
DRAFT Arduino Giga Support
1 parent 7aafe4f commit d6240e9

File tree

3 files changed

+202
-0
lines changed

3 files changed

+202
-0
lines changed

src/AudioAnalog/AnalogAudio.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
#include "AudioAnalog/AnalogAudioBase.h"
55
#include "AudioAnalog/AnalogAudioESP32.h"
66
#include "AudioAnalog/AnalogAudioArduino.h"
7+
#include "AudioAnalog/AnalogAudioMBED.h"
78

89
namespace audio_tools {
910

src/AudioAnalog/AnalogAudioMBED.h

Lines changed: 173 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,173 @@
1+
2+
#pragma once
3+
4+
#include "AudioConfig.h"
5+
#if defined(IS_MBED) && defined(USE_I2S_ANALOG)
6+
7+
#if __has_include && !__has_include(<Arduino_AdvancedAnalog.h>)
8+
#error "Please install the Arduino_AdvancedAnalog library"
9+
#else
10+
11+
#include <Arduino_AdvancedAnalog.h>
12+
//#include <pins_arduino.h>
13+
14+
namespace audio_tools {
15+
16+
/**
17+
* @brief Please use AnalogAudioStream: A ADC and DAC API for the Arduino Giga.
18+
* @ingroup platform
19+
* @author Phil Schatzmann
20+
* @copyright GPLv3
21+
*/
22+
23+
class AnalogDriverMBED : public AnalogDriverBase {
24+
public:
25+
/// Default constructor
26+
AnalogDriverMBED() = default;
27+
28+
/// Destructor
29+
virtual ~AnalogDriverMBED() { end(); }
30+
31+
/// starts the DAC
32+
bool begin(AnalogConfig cfg) {
33+
TRACEI();
34+
if (cfg.bits_per_sample != 16) {
35+
LOGE("Only 16 bits_per_sample supported");
36+
return false;
37+
}
38+
if (cfg.channels > 2) {
39+
LOGE("max channels: 2");
40+
return false;
41+
}
42+
if (cfg.channels <= 0) {
43+
LOGE("no channels");
44+
return false;
45+
}
46+
info = cfg;
47+
int n_samples = cfg.buffer_size / (cfg.bits_per_sample / 8);
48+
ring_buffer.resize(n_samples);
49+
switch (info.channels) {
50+
case 1:
51+
dac1.begin(AN_RESOLUTION_12, info.sample_rate, n_samples,
52+
cfg.buffer_count);
53+
break;
54+
case 2:
55+
dac1.begin(AN_RESOLUTION_12, info.sample_rate, n_samples / 2,
56+
cfg.buffer_count);
57+
dac2.begin(AN_RESOLUTION_12, info.sample_rate, n_samples / 2,
58+
cfg.buffer_count);
59+
break;
60+
}
61+
return true;
62+
}
63+
64+
/// stops the I2S and unistalls the driver
65+
void end() override {
66+
active = false;
67+
dac1.stop();
68+
dac2.stop();
69+
adc1.stop();
70+
adc2.stop();
71+
}
72+
73+
int availableForWrite() {
74+
return dac1.available() ? info.buffer_size : 0;
75+
}
76+
77+
/// writes the data to the I2S interface
78+
size_t write(const uint8_t *src, size_t size_bytes) override {
79+
TRACED();
80+
if (!dac1.available())
81+
return 0;
82+
83+
// collect data in ringbuffer
84+
size_t result = 0;
85+
int sample_count = size_bytes / 2;
86+
Sample *data = (Sample *)src;
87+
for (int j = 0; j < sample_count; j++) {
88+
ring_buffer.write(data[j]);
89+
// process ringbuffer when it is full
90+
if (ring_buffer.isFull()) {
91+
result += writeBuffer();
92+
}
93+
}
94+
return result;
95+
}
96+
97+
void flush() {
98+
const int size = info.buffer_size;
99+
const uint8_t data[size] = {0};
100+
write(data, size);
101+
ring_buffer.reset();
102+
}
103+
104+
size_t readBytes(uint8_t *dest, size_t size_bytes) override {
105+
TRACED();
106+
size_t result = 0;
107+
int16_t *data = (int16_t *)dest;
108+
size_t samples = size_bytes / 2;
109+
switch (info.channels) {
110+
case 1:
111+
for (int j = 0; j < samples; j++) {
112+
data[j] = adc1.read();
113+
result += 2;
114+
}
115+
break;
116+
case 2:
117+
for (int j = 0; j < samples; j += 2) {
118+
data[j] = adc1.read();
119+
data[j + 1] = adc2.read();
120+
result += 4;
121+
}
122+
break;
123+
}
124+
return result;
125+
}
126+
127+
virtual int available() override { return info.buffer_size; }
128+
129+
protected:
130+
RingBuffer<Sample> ring_buffer{0};
131+
AnalogConfig info;
132+
AdvancedDAC dac1{PIN_DAC_1};
133+
AdvancedDAC dac2{PIN_DAC_2};
134+
AdvancedADC adc1{PIN_ADC_START};
135+
AdvancedADC adc2{PIN_ADC_START + 1};
136+
bool active = false;
137+
138+
/// The ringbuffer is used to make sure that we can write full SampleBuffers
139+
size_t writeBuffer() {
140+
size_t result = 0;
141+
switch (info.channels) {
142+
case 1: {
143+
SampleBuffer buf = dac1.dequeue();
144+
for (size_t i = 0; i < buf.size(); i++) {
145+
buf[i] = ring_buffer.read();
146+
result += 2;
147+
}
148+
dac1.write(buf);
149+
} break;
150+
case 2: {
151+
SampleBuffer buf1 = dac1.dequeue();
152+
SampleBuffer buf2 = dac2.dequeue();
153+
for (size_t i = 0; i < buf1.size(); i += 2) {
154+
buf1[i] = ring_buffer.read();
155+
buf2[i] = ring_buffer.read();
156+
result += 4;
157+
}
158+
dac1.write(buf1);
159+
dac2.write(buf2);
160+
} break;
161+
}
162+
assert(ring_buffer.isEmpty());
163+
return result;
164+
}
165+
};
166+
167+
/// @brief AnalogAudioStream
168+
using AnalogDriver = AnalogDriverMBED;
169+
170+
} // namespace audio_tools
171+
172+
#endif // __has_include
173+
#endif // USE_I2S_ANALOG

src/AudioConfig.h

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -528,6 +528,29 @@ using WiFiServerSecure = BearSSL::WiFiServerSecure;
528528
#define USE_URL_ARDUINO
529529
#define USE_AUDIO_SERVER
530530
#endif
531+
532+
//---- GIGA ------------
533+
// DRAFT Support - Not tested !
534+
#if defined(ARDUINO_GIGA) || defined(ARDUINO_ARCH_MBED_PORTENTA)
535+
#include <WiFi.h>
536+
#define IS_MBED
537+
#define USE_INT24_FROM_INT
538+
#define USE_TYPETRAITS
539+
#define USE_EFFECTS_SUITE
540+
#define USE_I2S_ANALOG
541+
#define USE_STREAM_WRITE_OVERRIDE
542+
#define ADC_BUFFER_SIZE 1024
543+
#define ADC_BUFFERS 10
544+
#define USE_URL_ARDUINO
545+
#define USE_AUDIO_SERVER
546+
547+
#define PIN_ADC_START A7
548+
#define PIN_DAC_1 A12
549+
#define PIN_DAC_2 A13
550+
551+
#endif
552+
553+
531554
//------ VS1053 ----------
532555

533556
// Default Pins for VS1053
@@ -543,8 +566,11 @@ using WiFiServerSecure = BearSSL::WiFiServerSecure;
543566
#define VS1053_DEFAULT_VOLUME 0.7
544567

545568

569+
546570
//----------------
547571

572+
573+
548574
#ifdef IS_DESKTOP
549575
# include <Client.h>
550576
# include <WiFiClient.h>
@@ -582,3 +608,5 @@ typedef WiFiClient WiFiClientSecure;
582608
#pragma GCC diagnostic ignored "-Wunused-variable"
583609
#pragma GCC diagnostic ignored "-Wunused-function"
584610
#pragma GCC diagnostic ignored "-Wvla"
611+
#pragma GCC diagnostic ignored "-Wsign-compare"
612+
#pragma GCC diagnostic ignored "-Wunused-but-set-variable"

0 commit comments

Comments
 (0)