23#pragma GCC optimize("O3")
25#include "AudioTools/AudioCodecs/AudioCodecsBase.h"
26#include "AudioTools/CoreAudio/AudioFilter/Filter.h"
27#include "AudioTools/CoreAudio/Buffers.h"
36#define DSD_BUFFER_SIZE 1024 * 2
60 float filter_q = 0.5f;
62 int output_buffer_size = 1024;
74struct __attribute__((packed)) DSDPrefix {
78 uint64_t metadataOffset;
82struct __attribute__((packed)) DSFFormat {
85 uint32_t formatVersion;
89 uint32_t samplingFrequency;
90 uint32_t bitsPerSample;
92 uint32_t blockSizePerChannel;
97struct __attribute__((packed)) DSFDataHeader {
176 void end()
override {
isActive =
false; }
201 operator bool() {
return isActive; }
217 size_t write(
const uint8_t* data,
size_t len) {
218 LOGD(
"write: %u", (
unsigned)len);
217 size_t write(
const uint8_t* data,
size_t len) {
…}
254 float max_value = 0.0f;
260 int buffer_size = frame_size;
261 if (
meta.output_buffer_size > buffer_size)
262 buffer_size =
meta.output_buffer_size;
279 LOGI(
"processHeader: %u (%u)", (
unsigned)len, (
unsigned)startPos);
282 if (memcmp(data,
"DSD ", 4) != 0) {
283 LOGE(
"Invalid DSF header magic");
287 int dataPos =
findTag(
"data", data, len);
288 int fmtPos =
findTag(
"fmt ", data, len);
289 if (dataPos < 0 || fmtPos < 0) {
290 LOGE(
"DSF header not found in data (fmt: %d, data: %d)", fmtPos, dataPos);
294 parseFMT(data + fmtPos, len - fmtPos);
295 parseData(data + dataPos, len - dataPos);
301 return dataPos +
sizeof(DSFDataHeader);
315 LOGD(
"processDSDData: %u (%u)", (
unsigned)len, (
unsigned)startPos);
316 size_t bytesProcessed = 0;
324 return bytesProcessed;
338 int write_len = len - startPos;
380 int samplesProcessed = 0;
382 for (
int i = 0; i < bytesPerDecimationStep && !
dsdBuffer.isEmpty(); i++) {
388 for (
int bit = 0; bit < 8; bit++) {
389 int channelBit = (dsdByte >> (7 - bit)) & 1;
400 samplesProcessed += 8;
405 float samplesPerChannel = samplesProcessed /
meta.
channels;
407 if (samplesPerChannel > 0) {
412 meta.filter_q > 0.0f) {
431 if (written != frameSize) {
433 "Failed to write PCM samples: expected %zu bytes, wrote %zu "
451 if (value > 1.0f)
return 1.0f;
452 if (value < -1.0f)
return -1.0f;
489 LOGE(
"Invalid sample rates: DSD=%u, PCM=%u",
496 LOGW(
"Decimation step %u too low, setting to 64",
501 LOGW(
"Decimation step %u too high, setting to 512",
510 LOGI(
"Decimation step set to %u for DSD rate %u and target PCM rate %u",
543 int8_t buffer8 =
static_cast<int8_t
>(filteredValue * 127.0f);
548 int16_t buffer16 =
static_cast<int16_t
>(filteredValue * 32767.0f);
554 static_cast<int24_t>(filteredValue * 8388607.0f);
560 static_cast<int32_t
>(filteredValue * 2147483647.0f);
580 int findTag(
const char* tag,
const uint8_t* data,
size_t len) {
581 int taglen = strlen(tag);
583 for (
int j = 0; j < len - taglen; j++) {
584 if (memcmp(tag, data + j, taglen) == 0) {
580 int findTag(
const char* tag,
const uint8_t* data,
size_t len) {
…}
603 if (len <
sizeof(DSFFormat)) {
604 LOGE(
"FMT section too short to parse DSF format header");
607 DSFFormat* fmt = (DSFFormat*)data;
615 LOGE(
"Invalid channel count: %u (must be 1-8)", (
unsigned)
meta.
channels);
619 LOGI(
"channels: %u, DSD sample rate: %u", (
unsigned)
meta.
channels,
636 if (len <
sizeof(DSFDataHeader)) {
637 LOGE(
"Data section too short to parse DSF data header");
640 DSFDataHeader* header = (DSFDataHeader*)data;
646 uint64_t totalPCMFrames =
#define DSD_BUFFER_SIZE
Buffer size for DSD data processing - must accommodate decimation step.
Definition CodecDSF.h:36