arduino-audio-tools
Loading...
Searching...
No Matches
CodecADPCMXQ.h
Go to the documentation of this file.
1#pragma once
3#include "adpcm-lib.h" // https://github.com/pschatzmann/arduino-adpcm-xq
4
5#define DEFAULT_NOISE_SHAPING NOISE_SHAPING_OFF
6#define DEFAULT_LOOKAHEAD 0
7#define DEFAULT_BLOCKSIZE_POW2 0
8
9namespace audio_tools {
10
12 AD_NOISE_SHAPING_OFF = 0, // flat noise (no shaping)
13 AD_NOISE_SHAPING_STATIC = 1, // first-order highpass shaping
15};
16
26 public:
28 info.sample_rate = 44100;
29 info.channels = 2;
31 }
32
34 void setBlockSizePower(int pow) {
35 if (pow >= 8 && pow >= 15) {
36 block_size_pow2 = pow;
37 }
38 }
39
41 void setLookahead(int value) {
42 if (value <= 8) {
43 lookahead = value;
44 }
45 }
46
49
50 bool begin() override {
51 TRACEI();
52 current_byte = 0;
53 if (adpcm_cnxt == nullptr) {
54 adpcm_cnxt = adpcm_create_context(info.channels, lookahead, noise_shaping,
56
59 else
60 block_size = 256 * info.channels *
61 (info.sample_rate < 11000 ? 1 : info.sample_rate / 11000);
62
64 (block_size - info.channels * 4) * (info.channels ^ 3) + 1;
65
68 }
69
71 return true;
72 }
73
74 void end() override {
75 TRACEI();
76 if (adpcm_cnxt != nullptr) {
77 adpcm_free_context(adpcm_cnxt);
78 adpcm_cnxt = nullptr;
79 }
82 }
83
84 virtual void setOutput(Print &out_stream) { p_print = &out_stream; }
85
86 operator bool() override { return adpcm_cnxt != nullptr; }
87
88 virtual size_t write(const uint8_t *data, size_t len) {
89 uint8_t *input_buffer8 = (uint8_t *)data;
90 LOGD("write: %d", (int)len);
91 for (int j = 0; j < len; j++) {
92 adpcm_block[current_byte++] = input_buffer8[j];
93 if (current_byte == block_size) {
95 current_byte = 0;
96 }
97 }
98 return len;
99 }
100
101 protected:
103 void *adpcm_cnxt = nullptr;
106 int32_t initial_deltas[2] = {0};
107 Print *p_print = nullptr;
111
112 bool decode(int this_block_adpcm_samples) {
113 int result = adpcm_decode_block(pcm_block.data(), adpcm_block.data(),
115 if (result != samples_per_block) {
116 LOGE("adpcm_decode_block: %d instead %d", result,
117 this_block_adpcm_samples);
118 return false;
119 }
120 int write_size = samples_per_block * info.channels * 2;
121 p_print->write((uint8_t *)pcm_block.data(), write_size);
122 return true;
123 }
124};
125
135 public:
137 info.sample_rate = 44100;
138 info.channels = 2;
140 }
141
143 void setBlockSizePower(int pow) {
144 if (pow >= 8 && pow >= 15) {
145 block_size_pow2 = pow;
146 }
147 }
148
150 void setLookahead(int value) {
151 if (value <= 8) {
152 lookahead = value;
153 }
154 }
155
158
159 bool begin() override {
160 TRACEI();
161
162 if (block_size_pow2)
164 else
165 block_size = 256 * info.channels *
166 (info.sample_rate < 11000 ? 1 : info.sample_rate / 11000);
167
169 (block_size - info.channels * 4) * (info.channels ^ 3) + 1;
170
173 current_sample = 0;
174 return true;
175 }
176
177 void end() override {
178 TRACEI();
179 if (adpcm_cnxt != nullptr) {
180 adpcm_free_context(adpcm_cnxt);
181 adpcm_cnxt = nullptr;
182 }
183 pcm_block.resize(0);
185 }
186
187 const char *mime() override { return "audio/adpcm"; }
188
189 void setOutput(Print &out_stream) override { p_print = &out_stream; }
190
191 operator bool() override { return adpcm_cnxt != nullptr; }
192
193 size_t write(const uint8_t *data, size_t len) override {
194 LOGD("write: %d", (int)len);
195 int16_t *input_buffer = (int16_t *)data;
197 for (int j = 0; j < len / 2; j++) {
198 pcm_block[current_sample++] = input_buffer[j];
200 encode();
201 current_sample = 0;
202 }
203 }
204 return len;
205 }
206
207 protected:
209 void *adpcm_cnxt = nullptr;
212 Print *p_print = nullptr;
216 bool is_first = true;
217
218 bool encode() {
219 // if this is the first block, compute a decaying average (in reverse) so
220 // that we can let the encoder know what kind of initial deltas to expect
221 // (helps initializing index)
222
223 if (adpcm_cnxt == nullptr) {
224 is_first = false;
225 int32_t average_deltas[2];
226
227 average_deltas[0] = average_deltas[1] = 0;
228
229 for (int i = samples_per_block * info.channels; i -= info.channels;) {
230 average_deltas[0] -= average_deltas[0] >> 3;
231 average_deltas[0] +=
232 abs((int32_t)pcm_block[i] - pcm_block[i - info.channels]);
233
234 if (info.channels == 2) {
235 average_deltas[1] -= average_deltas[1] >> 3;
236 average_deltas[1] +=
237 abs((int32_t)pcm_block[i - 1] - pcm_block[i + 1]);
238 }
239 }
240
241 average_deltas[0] >>= 3;
242 average_deltas[1] >>= 3;
243
244 adpcm_cnxt = adpcm_create_context(info.channels, lookahead, noise_shaping,
245 average_deltas);
246 }
247
248 size_t num_bytes;
249 adpcm_encode_block(adpcm_cnxt, adpcm_block.data(), &num_bytes,
251
252 if (num_bytes != block_size) {
253 LOGE(
254 "adpcm_encode_block() did not return expected value "
255 "(expected %d, got %d)!\n",
256 block_size, (int)num_bytes);
257 return false;
258 }
259
261 return true;
262 }
263};
264
265} // namespace audio_tools
266
#define TRACEI()
Definition AudioLoggerIDF.h:32
#define LOGD(...)
Definition AudioLoggerIDF.h:27
#define LOGE(...)
Definition AudioLoggerIDF.h:30
#define DEFAULT_NOISE_SHAPING
Definition CodecADPCMXQ.h:5
#define DEFAULT_LOOKAHEAD
Definition CodecADPCMXQ.h:6
#define DEFAULT_BLOCKSIZE_POW2
Definition CodecADPCMXQ.h:7
Decoder for ADPCM-XQ. Depends on https://github.com/pschatzmann/arduino-adpcm-xq.
Definition CodecADPCMXQ.h:25
virtual void setOutput(Print &out_stream)
Defines where the decoded result is written to.
Definition CodecADPCMXQ.h:84
int lookahead
Definition CodecADPCMXQ.h:108
void setNoiseShaping(ADPCMNoiseShaping ns)
Defines the noise shaping.
Definition CodecADPCMXQ.h:48
Vector< uint8_t > adpcm_block
Definition CodecADPCMXQ.h:105
ADPCMDecoderXQ()
Definition CodecADPCMXQ.h:27
void end() override
Definition CodecADPCMXQ.h:74
int noise_shaping
Definition CodecADPCMXQ.h:109
int block_size
Definition CodecADPCMXQ.h:110
int block_size_pow2
Definition CodecADPCMXQ.h:110
int current_byte
Definition CodecADPCMXQ.h:102
virtual size_t write(const uint8_t *data, size_t len)
Definition CodecADPCMXQ.h:88
Vector< int16_t > pcm_block
Definition CodecADPCMXQ.h:104
int samples_per_block
Definition CodecADPCMXQ.h:108
bool decode(int this_block_adpcm_samples)
Definition CodecADPCMXQ.h:112
void setBlockSizePower(int pow)
set bocksizes as 2^pow: range from 8 to 15
Definition CodecADPCMXQ.h:34
bool begin() override
Definition CodecADPCMXQ.h:50
Print * p_print
Definition CodecADPCMXQ.h:107
void * adpcm_cnxt
Definition CodecADPCMXQ.h:103
int32_t initial_deltas[2]
Definition CodecADPCMXQ.h:106
void setLookahead(int value)
Set look ahead bytes from 0 to 8.
Definition CodecADPCMXQ.h:41
Encoder for ADPCM-XQ - Depends on https://github.com/pschatzmann/arduino-adpcm-xq.
Definition CodecADPCMXQ.h:134
void setOutput(Print &out_stream) override
Default output assignment (encoders may override to store Print reference)
Definition CodecADPCMXQ.h:189
int lookahead
Definition CodecADPCMXQ.h:213
void setNoiseShaping(ADPCMNoiseShaping ns)
Defines the noise shaping.
Definition CodecADPCMXQ.h:157
bool is_first
Definition CodecADPCMXQ.h:216
Vector< uint8_t > adpcm_block
Definition CodecADPCMXQ.h:211
void end() override
Definition CodecADPCMXQ.h:177
int noise_shaping
Definition CodecADPCMXQ.h:214
int block_size
Definition CodecADPCMXQ.h:215
size_t write(const uint8_t *data, size_t len) override
Definition CodecADPCMXQ.h:193
int block_size_pow2
Definition CodecADPCMXQ.h:215
Vector< int16_t > pcm_block
Definition CodecADPCMXQ.h:210
bool encode()
Definition CodecADPCMXQ.h:218
int samples_per_block
Definition CodecADPCMXQ.h:213
int pcm_block_size
Definition CodecADPCMXQ.h:215
const char * mime() override
Provides the mime type of the encoded result.
Definition CodecADPCMXQ.h:187
ADPCMEncoderXQ()
Definition CodecADPCMXQ.h:136
void setBlockSizePower(int pow)
set bocksizes as 2^pow: range from 8 to 15
Definition CodecADPCMXQ.h:143
bool begin() override
Definition CodecADPCMXQ.h:159
Print * p_print
Definition CodecADPCMXQ.h:212
void * adpcm_cnxt
Definition CodecADPCMXQ.h:209
void setLookahead(int value)
Set look ahead bytes from 0 to 8.
Definition CodecADPCMXQ.h:150
int current_sample
Definition CodecADPCMXQ.h:208
Decoding of encoded audio into PCM data.
Definition AudioCodecsBase.h:18
AudioInfo info
Definition AudioCodecsBase.h:76
Encoding of PCM data.
Definition AudioCodecsBase.h:97
AudioInfo info
Definition AudioCodecsBase.h:116
void notifyAudioChange(AudioInfo info)
Definition AudioTypes.h:178
Definition NoArduino.h:62
virtual size_t write(const uint8_t *data, size_t len)
Definition NoArduino.h:126
Vector implementation which provides the most important methods as defined by std::vector....
Definition Vector.h:21
bool resize(int newSize, T value)
Definition Vector.h:266
T * data()
Definition Vector.h:316
Generic Implementation of sound input and output for desktop environments using portaudio.
Definition AudioCodecsBase.h:10
ADPCMNoiseShaping
Definition CodecADPCMXQ.h:11
sample_rate_t sample_rate
Sample Rate: e.g 44100.
Definition AudioTypes.h:57
uint16_t channels
Number of channels: 2=stereo, 1=mono.
Definition AudioTypes.h:59
uint8_t bits_per_sample
Number of bits per sample (int16_t = 16 bits)
Definition AudioTypes.h:61