20#pragma GCC optimize("O3")
60 uint64_t metadataOffset;
67 uint32_t formatVersion;
71 uint32_t samplingFrequency;
72 uint32_t bitsPerSample;
74 uint32_t blockSizePerChannel;
146 size_t write(
const uint8_t* data,
size_t len) {
147 LOGD(
"write: %u", (
unsigned)len);
175 int buffer_size = frame_size;
183 LOGI(
"processHeader: %u", (
unsigned)len);
185 if (memcmp(data,
"DSD ", 4) != 0) {
186 LOGE(
"Invalid DSF header magic");
190 int dataPos =
findTag(
"data", data, len);
191 int fmtPos =
findTag(
"fmt ", data, len);
192 if (dataPos < 0 || fmtPos < 0) {
193 LOGE(
"DSF header not found in data (fmt: %d, data: %d)", fmtPos, dataPos);
197 parseFMT(data + fmtPos, len - fmtPos);
198 parseData(data + dataPos, len - dataPos);
202 infoCallback(*
reinterpret_cast<const DSFFormat*
>(data + fmtPos));
209 return dataPos +
sizeof(DSFDataHeader);
213 LOGD(
"processDSDData: %u (%u)", (
unsigned)len, (
unsigned)startPos);
216 size_t rawLen = len - startPos;
221 size_t totalProcessed = 0;
222 size_t pos = startPos;
226 if (buffered == 0)
break;
228 totalProcessed += buffered;
232 return totalProcessed;
239 for (
size_t i = startPos; i < len; i++) {
261 for (
int b = 0; b < bytesPerDecimation; b++) {
269 for (
int s = 0; s < stages; s++) {
304 v = (v & 0x55) + ((v >> 1) & 0x55);
305 v = (v & 0x33) + ((v >> 2) & 0x33);
306 return (v & 0x0F) + ((v >> 4) & 0x0F);
310 if (value > 1.0f)
return 1.0f;
311 if (value < -1.0f)
return -1.0f;
317 if (stages < 0) stages = 0;
318 if (stages > 3) stages = 3;
331 static const float butterworthQ[][3] = {
333 {0.5412f, 1.3066f, 0},
334 {0.5176f, 0.7071f, 1.9319f},
338 for (
int s = 0; s < stages; s++) {
339 float q = butterworthQ[stages - 1][s];
348 LOGE(
"Invalid sample rates: DSD=%u, PCM=%u",
355 LOGW(
"Decimation step %u too low, setting to 64",
360 LOGW(
"Decimation step %u too high, setting to 512",
368 LOGI(
"Decimation step set to %u for DSD rate %u and target PCM rate %u",
376 int8_t buffer8 =
static_cast<int8_t
>(filteredValue * 127.0f);
381 int16_t buffer16 =
static_cast<int16_t
>(filteredValue * 32767.0f);
386 int24_t buffer24 =
static_cast<int24_t>(filteredValue * 8388607.0f);
391 int32_t buffer32 =
static_cast<int32_t
>(filteredValue * 2147483647.0f);
401 int findTag(
const char* tag,
const uint8_t* data,
size_t len) {
402 int taglen = strlen(tag);
403 for (
size_t j = 0; j + taglen <= len; j++) {
404 if (memcmp(tag, data + j, taglen) == 0) {
413 if (len <
sizeof(DSFFormat)) {
414 LOGE(
"FMT section too short to parse DSF format header");
417 DSFFormat* fmt = (DSFFormat*)data;
429 LOGI(
"channels: %u, DSD sample rate: %u, block size: %u",
437 if (len <
sizeof(DSFDataHeader)) {
438 LOGE(
"Data section too short to parse DSF data header");
441 DSFDataHeader* header = (DSFDataHeader*)data;
446 uint64_t totalPCMFrames =
468 const char*
mime()
override {
return "audio/dsf"; }
513 size_t write(
const uint8_t* data,
size_t len)
override {
524 if (frameSize == 0)
return 0;
527 while (pos + frameSize <= len) {
529 float sample =
readPCMSample(data + pos + ch * bytesPerSample);
542 operator bool()
override {
return isOpen; }
565 return *
reinterpret_cast<const int8_t*
>(ptr) / 127.0f;
568 memcpy(&v, ptr,
sizeof(int16_t));
573 memcpy(&v, ptr,
sizeof(
int24_t));
574 return static_cast<float>(
static_cast<int32_t
>(v)) / 8388607.0f;
578 memcpy(&v, ptr,
sizeof(int32_t));
579 return v / 2147483647.0f;
587 float prevSample =
chState[ch].prevSample;
592 float input = prevSample + t * (currentSample - prevSample);
596 float shaped = input + 2.0f *
chState[ch].dsError1 -
chState[ch].dsError2;
597 int bit = (shaped >= 0.0f) ? 1 : 0;
598 float feedback = bit ? 1.0f : -1.0f;
599 float quantError = shaped - feedback;
601 if (quantError > 4.0f) quantError = 4.0f;
602 if (quantError < -4.0f) quantError = -4.0f;
605 chState[ch].dsError1 = quantError;
620 chState[ch].prevSample = currentSample;
640 bool hasData =
false;
647 if (!hasData)
return;
668 bool streaming = (dsdDataBytes == 0);
669 uint64_t headerTotal =
670 sizeof(DSDPrefix) +
sizeof(DSFFormat) +
sizeof(DSFDataHeader);
673 memcpy(prefix.id,
"DSD ", 4);
674 prefix.chunkSize =
sizeof(DSDPrefix);
675 prefix.fileSize = streaming ? 0 : (headerTotal + dsdDataBytes);
676 prefix.metadataOffset = 0;
679 memcpy(fmt.id,
"fmt ", 4);
680 fmt.chunkSize =
sizeof(DSFFormat);
681 fmt.formatVersion = 1;
686 fmt.bitsPerSample = 1;
687 fmt.sampleCount = streaming ? 0 : (dsdDataBytes * 8 /
meta.
channels);
691 DSFDataHeader dataHdr;
692 memcpy(dataHdr.id,
"data", 4);
693 dataHdr.chunkSize = streaming ? 0 : (
sizeof(DSFDataHeader) + dsdDataBytes);
#define LOGW(...)
Definition AudioLoggerIDF.h:29
#define TRACEI()
Definition AudioLoggerIDF.h:32
#define TRACED()
Definition AudioLoggerIDF.h:31
#define LOGI(...)
Definition AudioLoggerIDF.h:28
#define LOGD(...)
Definition AudioLoggerIDF.h:27
#define LOGE(...)
Definition AudioLoggerIDF.h:30
virtual size_t write(const uint8_t *data, size_t len)
Definition Arduino.h:120
enum VBanDataTypeList __attribute__