24#include "WrappedAudioOutputBase.h"
25#include "BackgroundAudioBuffers.h"
26#include "BackgroundAudioGain.h"
33template<
class DataBuffer>
74 _gain = (int32_t)(scale * (1 << 16));
91 _out->setBuffers(5, framelen);
92 _out->onTransmit(&_cb, (
void *)
this);
93 _out->setBitsPerSample(16);
94 _out->setStereo(
true);
95 _out->setFrequency(44100);
99 uint32_t zeros[32] = {};
100 while (_out->availableForWrite() > 32) {
101 _out->write((uint8_t *)zeros,
sizeof(zeros));
142 size_t write(
const void *data,
size_t len) {
143 return _ib.write((
const uint8_t *)data, len);
158 return _ib.availableForWrite();
167 return _ib.available() - _accumShift;
267 static void _cb(
void *ptr) {
271 void generateOneFrame() {
272 int16_t *out = (int16_t *)_outSample;
273 int16_t *
end = &_outSample[framelen * 2];
276 if (_accumShift > _ib.size() / 2) {
277 _ib.shiftUp(_accumShift);
282 const unsigned char *b = _ib.buffer() + _accumShift;
283 int avail = _ib.available() - _accumShift;
288 int toSkip = std::min(_dataSkipped, avail);
289 _accumShift += toSkip;
290 _dataSkipped -= toSkip;
293 if (_dataRemaining > 0) {
294 if ((_channels == 1) && (_bps == 8)) {
304 }
else if ((_channels == 2) && (_bps == 8)) {
317 }
else if ((_channels == 1) && (_bps == 16)) {
321 int16_t l = b[0] | (b[1] << 8);
329 int16_t l = b[0] | (b[1] << 8);
331 int16_t r = b[2] | (b[3] << 8);
336 if (!_dataRemaining) {
344 if (!memcmp(b,
"RIFF", 4)) {
348 if (!memcmp(b + 8,
"WAVE", 4)) {
356 }
else if (_seenRIFF && !_seenFMT && !memcmp(b,
"fmt ", 4)) {
360 if ((b[4] != 16) || b[5] || b[6] || b[7] || (b[8] != 1) || b[9]) {
367 _channels = b[10] | (b[11] << 8);
368 _sampleRate = b[12] | (b[13] << 8) | (b[14] << 16) | (b[15] << 24);
369 _bps = b[22] | (b[23] << 8);
370 if ((_channels == 0) || (_channels > 2) || !((_bps == 8) || (_bps == 16)) || (_sampleRate < 4000) || (_sampleRate > 48000)) {
380 }
else if (_seenRIFF && _seenFMT && !_seenDATA && !memcmp(b,
"data", 4)) {
384 _dataRemaining = b[4] | (b[5] << 8) | (b[6] << 16) | (b[7] << 24);
385 _dataRemaining /= _bps / 8;
386 _dataRemaining /= _channels;
396 _dataSkipped = b[4] | (b[5] << 8) | (b[6] << 16) | (b[7] << 24);
405 _ib.shiftUp(_accumShift);
417 ApplyGain(_outSample, framelen * 2, _gain);
423 while (_out->availableForWrite() >= (
int)framelen) {
425 bzero((uint8_t *)_outSample, framelen * 2 *
sizeof(int16_t));
429 _out->setFrequency(_sampleRate);
432 _out->write((uint8_t *)_outSample, framelen * 2 *
sizeof(int16_t));
437 AudioOutputBase *_out;
438 bool _playing =
false;
439 bool _paused =
false;
440 static const size_t framelen = 512;
442 int16_t _outSample[framelen * 2] __attribute__((aligned(4)));
443 int32_t _gain = 1 << 16;
444 uint32_t _accumShift = 0;
445 bool _seenRIFF =
false;
446 bool _seenFMT =
false;
447 bool _seenDATA =
false;
448 int _dataRemaining = 0;
449 int _dataSkipped = 0;
451 int _sampleRate = 44100;
456 uint32_t _frames = 0;
457 uint32_t _shifts = 0;
458 uint32_t _underflows = 0;
459 uint32_t _errors = 0;
Interrupt-driven WAV decoder. Generates a full frame of samples each cycle and uses the RawBuffer to ...
Definition BackgroundAudioWAV.h:34
BackgroundAudioWAVClass(AudioOutputBase &d)
Construct an AAC decoder with a given AudioOutputBase.
Definition BackgroundAudioWAV.h:47
uint32_t underflows()
Get the number of times the WAV decoder has underflowed waiting on raw data since begin
Definition BackgroundAudioWAV.h:202
size_t availableForWrite()
Gets number of bytes available to write to raw buffer.
Definition BackgroundAudioWAV.h:157
void flush()
Flushes any existing WAV data, resets the processor to start a new WAV.
Definition BackgroundAudioWAV.h:231
bool playing()
Determines if the WAV decoder has been started.
Definition BackgroundAudioWAV.h:120
bool done()
Determine if no more WAV file is present in the buffer.
Definition BackgroundAudioWAV.h:175
void pause()
Pause the decoder. Won't process raw input data and will transmit silence.
Definition BackgroundAudioWAV.h:246
uint32_t dumps()
Get the number of full buffer dumps (catastrophic data error) since begin
Definition BackgroundAudioWAV.h:220
void unpause()
Unpause previously paused WAV playback. Will start processing input data again.
Definition BackgroundAudioWAV.h:262
uint32_t errors()
Get the number of decoder errors since begin
Definition BackgroundAudioWAV.h:211
uint32_t shifts()
Get the number of input data shifts processed by decoder since begin
Definition BackgroundAudioWAV.h:193
size_t available()
Gets number of bytes already in the raw buffer.
Definition BackgroundAudioWAV.h:166
bool paused()
Determine if the WAV playback is paused.
Definition BackgroundAudioWAV.h:255
void end()
Stops the WAV decoder process and the calls the output device's end to shut it down,...
Definition BackgroundAudioWAV.h:111
void setGain(float scale)
Set the gain multiplier (volume) for the stream. Takes effect immediately.
Definition BackgroundAudioWAV.h:73
bool setDevice(AudioOutputBase *d)
Configure the output device before begin
Definition BackgroundAudioWAV.h:60
bool begin()
Starts the background WAV decoder/player. Will initialize the output device and start sending silence...
Definition BackgroundAudioWAV.h:82
uint32_t frames()
Get number of "frames" processed by decoder.
Definition BackgroundAudioWAV.h:184
size_t write(const void *data, size_t len)
Writes a block of raw data to the decoder's buffer.
Definition BackgroundAudioWAV.h:142