arduino-audio-tools
All Classes Namespaces Files Functions Variables Typedefs Enumerations Friends Modules Pages
AnalogDriverMBED.h
1
2#pragma once
3
4#include "AudioToolsConfig.h"
5#if defined(IS_MBED) && defined(USE_ANALOG) || defined(DOXYGEN)
6
7namespace audio_tools {
8
17public:
19 AnalogDriverMBED() = default;
20
22 virtual ~AnalogDriverMBED() { end(); }
23
25 bool begin(AnalogConfig cfg) {
26 TRACEI();
27 if (cfg.bits_per_sample != 16) {
28 LOGE("Only 16 bits_per_sample supported");
29 return false;
30 }
31 if (cfg.channels > 2) {
32 LOGE("max channels: 2");
33 return false;
34 }
35 if (cfg.channels <= 0) {
36 LOGE("no channels");
37 return false;
38 }
39 info = cfg;
40 auto_center.begin(config.channels, config.bits_per.sample);
41 int n_samples = cfg.buffer_size / (cfg.bits_per_sample / 8);
42 ring_buffer.resize(n_samples);
43 switch (info.channels) {
44 case 1:
45 dac1.begin(AN_RESOLUTION_12, info.sample_rate, n_samples,
46 cfg.buffer_count);
47 break;
48 case 2:
49 dac1.begin(AN_RESOLUTION_12, info.sample_rate, n_samples / 2,
50 cfg.buffer_count);
51 dac2.begin(AN_RESOLUTION_12, info.sample_rate, n_samples / 2,
52 cfg.buffer_count);
53 break;
54 }
55 return true;
56 }
57
59 void end() override {
60 active = false;
61 dac1.stop();
62 dac2.stop();
63 adc1.stop();
64 adc2.stop();
65 }
66
67 int availableForWrite() {
68 return dac1.available() ? info.buffer_size : 0;
69 }
70
72 size_t write(const uint8_t *src, size_t size_bytes) override {
73 TRACED();
74 if (!dac1.available())
75 return 0;
76
77 // collect data in ringbuffer
78 size_t result = 0;
79 int sample_count = size_bytes / 2;
80 Sample *data = (Sample *)src;
81 for (int j = 0; j < sample_count; j++) {
82 ring_buffer.write(data[j]);
83 // process ringbuffer when it is full
84 if (ring_buffer.isFull()) {
85 result += writeBuffer();
86 }
87 }
88 return result;
89 }
90
91 void flush() {
92 const int size = info.buffer_size;
93 const uint8_t data[size] = {0};
94 write(data, size);
95 ring_buffer.reset();
96 }
97
98 size_t readBytes(uint8_t *dest, size_t size_bytes) override {
99 TRACED();
100 size_t result = 0;
101 int16_t *data = (int16_t *)dest;
102 size_t samples = size_bytes / 2;
103 switch (info.channels) {
104 case 1:
105 for (int j = 0; j < samples; j++) {
106 data[j] = adc1.read();
107 result += 2;
108 }
109 break;
110 case 2:
111 for (int j = 0; j < samples; j += 2) {
112 data[j] = adc1.read();
113 data[j + 1] = adc2.read();
114 result += 4;
115 }
116 break;
117 }
118
119 // make sure that the center is at 0
120 if (adc_config.is_auto_center_read){
121 auto_center.convert(dest, result);
122 }
123
124 return result;
125 }
126
127 virtual int available() override { return info.buffer_size; }
128
129protected:
130 audio_tools::RingBuffer<Sample> ring_buffer{0};
131 AnalogConfig info;
132 ConverterAutoCenter auto_center;
133 AdvancedDAC dac1{PIN_DAC_1};
134 AdvancedDAC dac2{PIN_DAC_2};
135 AdvancedADC adc1{PIN_ANALOG_START};
136 AdvancedADC adc2{PIN_ANALOG_START + 1};
137 bool active = false;
138
140 size_t writeBuffer() {
141 size_t result = 0;
142 switch (info.channels) {
143 case 1: {
144 SampleBuffer buf = dac1.dequeue();
145 for (size_t i = 0; i < buf.size(); i++) {
146 buf[i] = ring_buffer.read();
147 result += 2;
148 }
149 dac1.write(buf);
150 } break;
151 case 2: {
152 SampleBuffer buf1 = dac1.dequeue();
153 SampleBuffer buf2 = dac2.dequeue();
154 for (size_t i = 0; i < buf1.size(); i += 2) {
155 buf1[i] = ring_buffer.read();
156 buf2[i] = ring_buffer.read();
157 result += 4;
158 }
159 dac1.write(buf1);
160 dac2.write(buf2);
161 } break;
162 }
163 assert(ring_buffer.isEmpty());
164 return result;
165 }
166};
167
169using AnalogDriver = AnalogDriverMBED;
170
171} // namespace audio_tools
172
173#endif // USE_ANALOG
ESP32 specific configuration for i2s input via adc. The default input pin is GPIO34....
Definition AnalogConfigESP32.h:22
Definition AnalogDriverBase.h:13
Please use AnalogAudioStream: A ADC and DAC API for the Arduino Giga.
Definition AnalogDriverMBED.h:16
size_t write(const uint8_t *src, size_t size_bytes) override
writes the data to the I2S interface
Definition AnalogDriverMBED.h:72
bool begin(AnalogConfig cfg)
starts the DAC
Definition AnalogDriverMBED.h:25
void end() override
stops the I2S and unistalls the driver
Definition AnalogDriverMBED.h:59
virtual ~AnalogDriverMBED()
Destructor.
Definition AnalogDriverMBED.h:22
size_t writeBuffer()
The ringbuffer is used to make sure that we can write full SampleBuffers.
Definition AnalogDriverMBED.h:140
AnalogDriverMBED()=default
Default constructor.
Implements a typed Ringbuffer.
Definition Buffers.h:308
bool read(T &result) override
reads a single value
Definition Buffers.h:315
virtual bool write(T data)
write add an entry to the buffer
Definition Buffers.h:358
virtual void reset()
clears the buffer
Definition Buffers.h:370
virtual bool isFull()
checks if the buffer is full
Definition Buffers.h:353
Generic Implementation of sound input and output for desktop environments using portaudio.
Definition AudioCodecsBase.h:10
AnalogDriverArduino AnalogDriver
AnalogAudioStream.
Definition AnalogDriverArduino.h:48
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