@@ -24,28 +24,21 @@ class AnalogDriverArduino : public AnalogDriverBase {
24
24
25
25
bool begin (AnalogConfig cfg) {
26
26
TRACED ();
27
- if (cfg.rx_tx_mode == RXTX_MODE) {
27
+ config = cfg;
28
+ if (config.rx_tx_mode == RXTX_MODE) {
28
29
LOGE (" RXTX not supported" );
29
30
return false ;
30
31
}
31
- config = cfg;
32
- if (buffer == nullptr ) {
33
- // allocate buffer_count
34
- buffer = new NBuffer<int16_t >(cfg.buffer_size , cfg.buffer_count );
35
- if (buffer == nullptr ) {
36
- LOGE (" Not enough memory for buffer" );
37
- return false ;
38
- }
39
- // setup pins
40
- setupPins ();
41
- } else {
42
- timer.end ();
43
- }
32
+
33
+ frame_size = config.channels *(config.bits_per_sample /8 );
34
+ result_factor = 1 ;
35
+
36
+ if (!setupTx ()) return false ;
37
+
38
+ if (!setupBuffer ()) return false ;
44
39
45
40
// (re)start timer
46
- LOGI (" sample_rate: %d" , cfg.sample_rate );
47
- timer.setCallbackParameter (this );
48
- return timer.begin (callback, cfg.sample_rate , TimeUnit::HZ);
41
+ return setupTimer ();
49
42
}
50
43
51
44
void end () override { timer.end (); }
@@ -59,35 +52,107 @@ class AnalogDriverArduino : public AnalogDriverBase {
59
52
size_t readBytes (uint8_t *values, size_t len) {
60
53
if (config.rx_tx_mode == TX_MODE) return 0 ;
61
54
if (buffer == nullptr ) return 0 ;
62
- int samples = len / 2 ;
63
- return buffer->readArray (( int16_t *) values, samples) * 2 ;
55
+ int bytes = len / frame_size * frame_size ;
56
+ return buffer->readArray (values, bytes) ;
64
57
}
65
58
66
59
int availableForWrite () {
67
60
if (config.rx_tx_mode == RX_MODE) return 0 ;
68
- return buffer == nullptr ? 0 : buffer->availableForWrite () * 2 ;
61
+ if (buffer == nullptr ) return 0 ;
62
+ return config.is_blocking_write ? config.buffer_size : buffer->availableForWrite ();
69
63
}
70
64
71
65
size_t write (const uint8_t *data, size_t len) {
66
+ LOGD (" write: %d" , (int )len);
72
67
if (config.rx_tx_mode == RX_MODE) return 0 ;
68
+ // only process full frames
69
+ len = len / frame_size * frame_size;
70
+
71
+ if (isCombinedChannel ()){
72
+ ChannelReducer cr (1 , 2 , config.bits_per_sample );
73
+ len = cr.convert ((uint8_t *)data, len);
74
+ LOGD (" ChannelReducer len: %d" , (int ) len);
75
+ }
76
+
77
+ if (isDecimateActive ()){
78
+ Decimate dec (decim, 1 , config.bits_per_sample );
79
+ len = dec.convert ((uint8_t *)data, len);
80
+ LOGD (" Decimate len: %d for factor %d" , (int ) len, decim);
81
+ }
73
82
74
83
// blocking write ?
75
84
if (config.is_blocking_write ) {
76
85
LOGD (" Waiting for buffer to be available" );
77
- while (buffer->availableForWrite () == 0 ) {
86
+ while (buffer->availableForWrite () < len ) {
78
87
delay (10 );
79
88
}
80
89
}
90
+
81
91
// write data
82
- int16_t *data_16 = (int16_t *)data;
83
- return buffer->writeArray (data_16, len / 2 ) * 2 ;
92
+ size_t result = buffer->writeArray (data, len) * result_factor;
93
+ LOGD (" write: -> %d / factor: %d" , (int )result, result_factor);
94
+ return result;
84
95
}
85
96
86
97
protected:
87
98
AnalogConfig config;
88
99
TimerAlarmRepeating timer;
89
- BaseBuffer<int16_t > *buffer = nullptr ;
100
+ BaseBuffer<uint8_t > *buffer = nullptr ;
90
101
int avg_value, min, max, count;
102
+ bool is_combined_channels = false ;
103
+ uint16_t frame_size = 0 ;
104
+ int result_factor = 1 ;
105
+ int decim = 1 ;
106
+
107
+ bool setupTx (){
108
+ if (config.rx_tx_mode == TX_MODE) {
109
+ // check channels
110
+ if (config.channels >ANALOG_MAX_OUT_CHANNELS){
111
+ if (config.channels == 2 ){
112
+ is_combined_channels = true ;
113
+ config.channels = 1 ;
114
+ } else {
115
+ LOGE (" Unsupported channels" );
116
+ return false ;
117
+ }
118
+ }
119
+ if (isDecimateActive ()){
120
+ LOGI (" Using reduced sample rate: %d" , effectiveOutputSampleRate ());
121
+ decim = decimation ();
122
+ result_factor = result_factor * decim;
123
+ }
124
+ if (isCombinedChannel ()){
125
+ LOGI (" Combining channels" );
126
+ result_factor = result_factor * 2 ;
127
+ }
128
+ }
129
+ return true ;
130
+ }
131
+
132
+ bool setupBuffer (){
133
+ if (buffer == nullptr ) {
134
+ // allocate buffer_count
135
+ buffer = new RingBuffer<uint8_t >(config.buffer_size * config.buffer_count );
136
+ if (buffer == nullptr ) {
137
+ LOGE (" Not enough memory for buffer" );
138
+ return false ;
139
+ }
140
+ // setup pins
141
+ setupPins ();
142
+ } else {
143
+ LOGE (" Not enough memory" );
144
+ timer.end ();
145
+ return false ;
146
+ }
147
+ return true ;
148
+ }
149
+
150
+ bool setupTimer (){
151
+ int sample_rate = config.rx_tx_mode == TX_MODE ? effectiveOutputSampleRate () : config.sample_rate ;
152
+ LOGI (" sample_rate: %d" , sample_rate);
153
+ timer.setCallbackParameter (this );
154
+ return timer.begin (callback, sample_rate, TimeUnit::HZ);
155
+ }
91
156
92
157
// / Sample data and write to buffer
93
158
static void callback (void *arg) {
@@ -163,6 +228,34 @@ class AnalogDriverArduino : public AnalogDriverBase {
163
228
max = INT_MIN;
164
229
count = 0 ;
165
230
}
231
+
232
+ // / The requested sampling rate is too hight: we only process half of the samples so we can half the sampling rate
233
+ bool isDecimateActive (){
234
+ return config.sample_rate >= ANALOG_MAX_SAMPLE_RATE;
235
+ }
236
+
237
+ // combined stereo channel to mono
238
+ bool isCombinedChannel (){
239
+ return is_combined_channels;
240
+ }
241
+
242
+ // / Returns the effective output sample rate
243
+ int effectiveOutputSampleRate (){
244
+ return config.sample_rate / decimation ();
245
+ }
246
+
247
+ int decimation () {
248
+ if (config.sample_rate <= ANALOG_MAX_SAMPLE_RATE) return 1 ;
249
+ for (int j=2 ;j<6 ;j+=2 ){
250
+ if (config.sample_rate /j <= ANALOG_MAX_SAMPLE_RATE) {
251
+ return j;
252
+ }
253
+ }
254
+ return 6 ;
255
+ }
256
+
257
+
258
+
166
259
};
167
260
168
261
using AnalogDriver = AnalogDriverArduino;
0 commit comments