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
0 commit comments