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;
98 const char*
mime()
override {
return "audio/dsf"; }
148 size_t write(
const uint8_t* data,
size_t len) {
149 LOGD(
"write: %u", (
unsigned)len);
177 int buffer_size = frame_size;
185 LOGI(
"processHeader: %u", (
unsigned)len);
187 if (memcmp(data,
"DSD ", 4) != 0) {
188 LOGE(
"Invalid DSF header magic");
192 int dataPos =
findTag(
"data", data, len);
193 int fmtPos =
findTag(
"fmt ", data, len);
194 if (dataPos < 0 || fmtPos < 0) {
195 LOGE(
"DSF header not found in data (fmt: %d, data: %d)", fmtPos, dataPos);
199 parseFMT(data + fmtPos, len - fmtPos);
200 parseData(data + dataPos, len - dataPos);
204 infoCallback(*
reinterpret_cast<const DSFFormat*
>(data + fmtPos));
211 return dataPos +
sizeof(DSFDataHeader);
215 LOGD(
"processDSDData: %u (%u)", (
unsigned)len, (
unsigned)startPos);
218 size_t rawLen = len - startPos;
223 size_t totalProcessed = 0;
224 size_t pos = startPos;
228 if (buffered == 0)
break;
230 totalProcessed += buffered;
234 return totalProcessed;
241 for (
size_t i = startPos; i < len; i++) {
263 for (
int b = 0; b < bytesPerDecimation; b++) {
271 for (
int s = 0; s < stages; s++) {
306 v = (v & 0x55) + ((v >> 1) & 0x55);
307 v = (v & 0x33) + ((v >> 2) & 0x33);
308 return (v & 0x0F) + ((v >> 4) & 0x0F);
312 if (value > 1.0f)
return 1.0f;
313 if (value < -1.0f)
return -1.0f;
319 if (stages < 0) stages = 0;
320 if (stages > 3) stages = 3;
333 static const float butterworthQ[][3] = {
335 {0.5412f, 1.3066f, 0},
336 {0.5176f, 0.7071f, 1.9319f},
340 for (
int s = 0; s < stages; s++) {
341 float q = butterworthQ[stages - 1][s];
350 LOGE(
"Invalid sample rates: DSD=%u, PCM=%u",
357 LOGW(
"Decimation step %u too low, setting to 64",
362 LOGW(
"Decimation step %u too high, setting to 512",
370 LOGI(
"Decimation step set to %u for DSD rate %u and target PCM rate %u",
378 int8_t buffer8 =
static_cast<int8_t
>(filteredValue * 127.0f);
383 int16_t buffer16 =
static_cast<int16_t
>(filteredValue * 32767.0f);
388 int24_t buffer24 =
static_cast<int24_t>(filteredValue * 8388607.0f);
393 int32_t buffer32 =
static_cast<int32_t
>(filteredValue * 2147483647.0f);
403 int findTag(
const char* tag,
const uint8_t* data,
size_t len) {
404 int taglen = strlen(tag);
405 for (
size_t j = 0; j + taglen <= len; j++) {
406 if (memcmp(tag, data + j, taglen) == 0) {
415 if (len <
sizeof(DSFFormat)) {
416 LOGE(
"FMT section too short to parse DSF format header");
419 DSFFormat* fmt = (DSFFormat*)data;
431 LOGI(
"channels: %u, DSD sample rate: %u, block size: %u",
439 if (len <
sizeof(DSFDataHeader)) {
440 LOGE(
"Data section too short to parse DSF data header");
443 DSFDataHeader* header = (DSFDataHeader*)data;
448 uint64_t totalPCMFrames =
470 const char*
mime()
override {
return "audio/dsf"; }
515 size_t write(
const uint8_t* data,
size_t len)
override {
526 if (frameSize == 0)
return 0;
529 while (pos + frameSize <= len) {
531 float sample =
readPCMSample(data + pos + ch * bytesPerSample);
544 operator bool()
override {
return isOpen; }
567 return *
reinterpret_cast<const int8_t*
>(ptr) / 127.0f;
570 memcpy(&v, ptr,
sizeof(int16_t));
575 memcpy(&v, ptr,
sizeof(
int24_t));
576 return static_cast<float>(
static_cast<int32_t
>(v)) / 8388607.0f;
580 memcpy(&v, ptr,
sizeof(int32_t));
581 return v / 2147483647.0f;
589 float prevSample =
chState[ch].prevSample;
594 float input = prevSample + t * (currentSample - prevSample);
598 float shaped = input + 2.0f *
chState[ch].dsError1 -
chState[ch].dsError2;
599 int bit = (shaped >= 0.0f) ? 1 : 0;
600 float feedback = bit ? 1.0f : -1.0f;
601 float quantError = shaped - feedback;
603 if (quantError > 4.0f) quantError = 4.0f;
604 if (quantError < -4.0f) quantError = -4.0f;
607 chState[ch].dsError1 = quantError;
622 chState[ch].prevSample = currentSample;
642 bool hasData =
false;
649 if (!hasData)
return;
670 bool streaming = (dsdDataBytes == 0);
671 uint64_t headerTotal =
672 sizeof(DSDPrefix) +
sizeof(DSFFormat) +
sizeof(DSFDataHeader);
675 memcpy(prefix.id,
"DSD ", 4);
676 prefix.chunkSize =
sizeof(DSDPrefix);
677 prefix.fileSize = streaming ? 0 : (headerTotal + dsdDataBytes);
678 prefix.metadataOffset = 0;
681 memcpy(fmt.id,
"fmt ", 4);
682 fmt.chunkSize =
sizeof(DSFFormat);
683 fmt.formatVersion = 1;
688 fmt.bitsPerSample = 1;
689 fmt.sampleCount = streaming ? 0 : (dsdDataBytes * 8 /
meta.
channels);
693 DSFDataHeader dataHdr;
694 memcpy(dataHdr.id,
"data", 4);
695 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__