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
33 const char *mime() override { return "audio/adpcm"; }
34
36 void setBlockSizePower(int pow) {
37 if (pow >= 8 && pow >= 15) {
38 block_size_pow2 = pow;
39 }
40 }
41
43 void setLookahead(int value) {
44 if (value <= 8) {
45 lookahead = value;
46 }
47 }
48
51
52 bool begin() override {
53 TRACEI();
54 current_byte = 0;
55 if (adpcm_cnxt == nullptr) {
56 adpcm_cnxt = adpcm_create_context(info.channels, lookahead, noise_shaping,
58
61 else
62 block_size = 256 * info.channels *
63 (info.sample_rate < 11000 ? 1 : info.sample_rate / 11000);
64
66 (block_size - info.channels * 4) * (info.channels ^ 3) + 1;
67
70 }
71
73 return true;
74 }
75
76 void end() override {
77 TRACEI();
78 if (adpcm_cnxt != nullptr) {
79 adpcm_free_context(adpcm_cnxt);
80 adpcm_cnxt = nullptr;
81 }
84 }
85
86 virtual void setOutput(Print &out_stream) { p_print = &out_stream; }
87
88 operator bool() override { return adpcm_cnxt != nullptr; }
89
90 virtual size_t write(const uint8_t *data, size_t len) {
91 uint8_t *input_buffer8 = (uint8_t *)data;
92 LOGD("write: %d", (int)len);
93 for (int j = 0; j < len; j++) {
94 adpcm_block[current_byte++] = input_buffer8[j];
95 if (current_byte == block_size) {
97 current_byte = 0;
98 }
99 }
100 return len;
101 }
102
103 protected:
105 void *adpcm_cnxt = nullptr;
108 int32_t initial_deltas[2] = {0};
109 Print *p_print = nullptr;
113
114 bool decode(int this_block_adpcm_samples) {
115 int result = adpcm_decode_block(pcm_block.data(), adpcm_block.data(),
117 if (result != samples_per_block) {
118 LOGE("adpcm_decode_block: %d instead %d", result,
119 this_block_adpcm_samples);
120 return false;
121 }
122 int write_size = samples_per_block * info.channels * 2;
123 p_print->write((uint8_t *)pcm_block.data(), write_size);
124 return true;
125 }
126};
127
137 public:
139 info.sample_rate = 44100;
140 info.channels = 2;
142 }
143
145 void setBlockSizePower(int pow) {
146 if (pow >= 8 && pow >= 15) {
147 block_size_pow2 = pow;
148 }
149 }
150
152 void setLookahead(int value) {
153 if (value <= 8) {
154 lookahead = value;
155 }
156 }
157
160
161 bool begin() override {
162 TRACEI();
163
164 if (block_size_pow2)
166 else
167 block_size = 256 * info.channels *
168 (info.sample_rate < 11000 ? 1 : info.sample_rate / 11000);
169
171 (block_size - info.channels * 4) * (info.channels ^ 3) + 1;
172
175 current_sample = 0;
176 return true;
177 }
178
179 void end() override {
180 TRACEI();
181 if (adpcm_cnxt != nullptr) {
182 adpcm_free_context(adpcm_cnxt);
183 adpcm_cnxt = nullptr;
184 }
185 pcm_block.resize(0);
187 }
188
189 const char *mime() override { return "audio/adpcm"; }
190
191 void setOutput(Print &out_stream) override { p_print = &out_stream; }
192
193 operator bool() override { return adpcm_cnxt != nullptr; }
194
195 size_t write(const uint8_t *data, size_t len) override {
196 LOGD("write: %d", (int)len);
197 int16_t *input_buffer = (int16_t *)data;
199 for (int j = 0; j < len / 2; j++) {
200 pcm_block[current_sample++] = input_buffer[j];
202 encode();
203 current_sample = 0;
204 }
205 }
206 return len;
207 }
208
209 protected:
211 void *adpcm_cnxt = nullptr;
214 Print *p_print = nullptr;
218 bool is_first = true;
219
220 bool encode() {
221 // if this is the first block, compute a decaying average (in reverse) so
222 // that we can let the encoder know what kind of initial deltas to expect
223 // (helps initializing index)
224
225 if (adpcm_cnxt == nullptr) {
226 is_first = false;
227 int32_t average_deltas[2];
228
229 average_deltas[0] = average_deltas[1] = 0;
230
231 for (int i = samples_per_block * info.channels; i -= info.channels;) {
232 average_deltas[0] -= average_deltas[0] >> 3;
233 average_deltas[0] +=
234 abs((int32_t)pcm_block[i] - pcm_block[i - info.channels]);
235
236 if (info.channels == 2) {
237 average_deltas[1] -= average_deltas[1] >> 3;
238 average_deltas[1] +=
239 abs((int32_t)pcm_block[i - 1] - pcm_block[i + 1]);
240 }
241 }
242
243 average_deltas[0] >>= 3;
244 average_deltas[1] >>= 3;
245
246 adpcm_cnxt = adpcm_create_context(info.channels, lookahead, noise_shaping,
247 average_deltas);
248 }
249
250 size_t num_bytes;
251 adpcm_encode_block(adpcm_cnxt, adpcm_block.data(), &num_bytes,
253
254 if (num_bytes != block_size) {
255 LOGE(
256 "adpcm_encode_block() did not return expected value "
257 "(expected %d, got %d)!\n",
258 block_size, (int)num_bytes);
259 return false;
260 }
261
263 return true;
264 }
265};
266
267} // namespace audio_tools
268
#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
Definition Arduino.h:56
virtual size_t write(const uint8_t *data, size_t len)
Definition Arduino.h:120
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:86
int lookahead
Definition CodecADPCMXQ.h:110
void setNoiseShaping(ADPCMNoiseShaping ns)
Defines the noise shaping.
Definition CodecADPCMXQ.h:50
Vector< uint8_t > adpcm_block
Definition CodecADPCMXQ.h:107
ADPCMDecoderXQ()
Definition CodecADPCMXQ.h:27
void end() override
Definition CodecADPCMXQ.h:76
int noise_shaping
Definition CodecADPCMXQ.h:111
int block_size
Definition CodecADPCMXQ.h:112
int block_size_pow2
Definition CodecADPCMXQ.h:112
int current_byte
Definition CodecADPCMXQ.h:104
virtual size_t write(const uint8_t *data, size_t len)
Definition CodecADPCMXQ.h:90
Vector< int16_t > pcm_block
Definition CodecADPCMXQ.h:106
int samples_per_block
Definition CodecADPCMXQ.h:110
bool decode(int this_block_adpcm_samples)
Definition CodecADPCMXQ.h:114
const char * mime() override
Provides the mime type of the data that is expected by this decoder.
Definition CodecADPCMXQ.h:33
void setBlockSizePower(int pow)
set bocksizes as 2^pow: range from 8 to 15
Definition CodecADPCMXQ.h:36
bool begin() override
Definition CodecADPCMXQ.h:52
Print * p_print
Definition CodecADPCMXQ.h:109
void * adpcm_cnxt
Definition CodecADPCMXQ.h:105
int32_t initial_deltas[2]
Definition CodecADPCMXQ.h:108
void setLookahead(int value)
Set look ahead bytes from 0 to 8.
Definition CodecADPCMXQ.h:43
Encoder for ADPCM-XQ - Depends on https://github.com/pschatzmann/arduino-adpcm-xq.
Definition CodecADPCMXQ.h:136
void setOutput(Print &out_stream) override
Default output assignment (encoders may override to store Print reference)
Definition CodecADPCMXQ.h:191
int lookahead
Definition CodecADPCMXQ.h:215
void setNoiseShaping(ADPCMNoiseShaping ns)
Defines the noise shaping.
Definition CodecADPCMXQ.h:159
bool is_first
Definition CodecADPCMXQ.h:218
Vector< uint8_t > adpcm_block
Definition CodecADPCMXQ.h:213
void end() override
Definition CodecADPCMXQ.h:179
int noise_shaping
Definition CodecADPCMXQ.h:216
int block_size
Definition CodecADPCMXQ.h:217
size_t write(const uint8_t *data, size_t len) override
Definition CodecADPCMXQ.h:195
int block_size_pow2
Definition CodecADPCMXQ.h:217
Vector< int16_t > pcm_block
Definition CodecADPCMXQ.h:212
bool encode()
Definition CodecADPCMXQ.h:220
int samples_per_block
Definition CodecADPCMXQ.h:215
int pcm_block_size
Definition CodecADPCMXQ.h:217
const char * mime() override
Provides the mime type of the encoded result.
Definition CodecADPCMXQ.h:189
ADPCMEncoderXQ()
Definition CodecADPCMXQ.h:138
void setBlockSizePower(int pow)
set bocksizes as 2^pow: range from 8 to 15
Definition CodecADPCMXQ.h:145
bool begin() override
Definition CodecADPCMXQ.h:161
Print * p_print
Definition CodecADPCMXQ.h:214
void * adpcm_cnxt
Definition CodecADPCMXQ.h:211
void setLookahead(int value)
Set look ahead bytes from 0 to 8.
Definition CodecADPCMXQ.h:152
int current_sample
Definition CodecADPCMXQ.h:210
Decoding of encoded audio into PCM data.
Definition AudioCodecsBase.h:19
AudioInfo info
Definition AudioCodecsBase.h:80
Encoding of PCM data.
Definition AudioCodecsBase.h:101
AudioInfo info
Definition AudioCodecsBase.h:120
void notifyAudioChange(AudioInfo info)
Definition AudioTypes.h:175
Vector implementation which provides the most important methods as defined by std::vector....
Definition Vector.h:21
bool resize(size_t 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 LMSEchoCancellationStream.h:6
ADPCMNoiseShaping
Definition CodecADPCMXQ.h:11
sample_rate_t sample_rate
Sample Rate: e.g 44100.
Definition AudioTypes.h:53
uint16_t channels
Number of channels: 2=stereo, 1=mono.
Definition AudioTypes.h:55
uint8_t bits_per_sample
Number of bits per sample (int16_t = 16 bits)
Definition AudioTypes.h:57