arduino-audio-tools
All Classes Namespaces Files Functions Variables Typedefs Enumerations Friends Macros Modules Pages
Public Member Functions | Public Attributes | Protected Member Functions | Protected Attributes | List of all members
DSFDecoder Class Reference

DSF (DSD Stream File) format decoder. More...

#include <CodecDSF.h>

Inheritance diagram for DSFDecoder:
AudioDecoder AudioWriter AudioInfoSource AudioInfoSupport

Public Member Functions

 DSFDecoder (DSFMetadata metaData)
 
virtual void addNotifyAudioChange (AudioInfoSupport &bi)
 Adds target to be notified about audio changes.
 
AudioInfo audioInfo () override
 provides the actual input AudioInfo
 
virtual AudioInfo audioInfoOut ()
 
bool begin ()
 Initialize the decoder.
 
virtual bool begin (AudioInfo info) override
 
virtual void clearNotifyAudioChange ()
 Deletes all change notify subscriptions.
 
void end () override
 
const DSFMetadata getMetadata ()
 Get DSF file metadata.
 
PrintgetOutput ()
 
bool isHeaderAvailable ()
 Check if decoder is ready.
 
bool isNotifyActive ()
 Checks if the automatic AudioInfo update is active.
 
virtual bool isResultPCM ()
 Returns true to indicate that the decoding result is PCM data.
 
 operator bool ()
 
virtual bool removeNotifyAudioChange (AudioInfoSupport &bi)
 Removes a target in order not to be notified about audio changes.
 
void setAudioInfo (AudioInfo from) override
 
virtual bool setCodecConfig (const uint8_t *data, size_t len)
 Some decoders need e.g. a magic cookie to provide the relevant info for decoding.
 
void setMetaData (DSFMetadata metaData)
 
void setNotifyActive (bool flag)
 Deactivate/Reactivate automatic AudioInfo updates: (default is active)
 
virtual void setOutput (AudioOutput &out_stream)
 Defines where the decoded result is written to.
 
virtual void setOutput (AudioStream &out_stream)
 Defines where the decoded result is written to.
 
virtual void setOutput (Print &out_stream) override
 Defines where the decoded result is written to.
 
size_t write (const uint8_t *data, size_t len)
 Main entry point for processing incoming DSF data.
 

Public Attributes

int id
 custom id to be used by application
 

Protected Member Functions

size_t bufferDSDData (const uint8_t *data, size_t len, size_t startPos)
 Buffer incoming DSD data into ring buffer.
 
float clip (float value)
 Clips audio values to valid range.
 
void convertDSDToPCM ()
 Convert buffered DSD data to PCM samples and output them.
 
int findTag (const char *tag, const uint8_t *data, size_t len)
 Find a specific tag within binary data.
 
int getOutputBufferSize ()
 The buffer size is defined in the metadata: it must be at least 1 frame.
 
bool hasEnoughData ()
 Check if sufficient DSD data is available for conversion.
 
void notifyAudioChange (AudioInfo info)
 
bool parseData (const uint8_t *data, size_t len)
 Parse DSF data chunk to extract audio data information.
 
bool parseFMT (const uint8_t *data, size_t len)
 Parse DSF format chunk to extract audio parameters.
 
size_t processDSDData (const uint8_t *data, size_t len, size_t startPos)
 Process DSD audio data: buffer it and convert to PCM when possible.
 
size_t processHeader (const uint8_t *data, size_t len, size_t startPos)
 Process header data until header is complete or data is exhausted.
 
void setupDecimationStep ()
 Calculate optimal decimation step for DSD to PCM conversion.
 
void setupTargetPCMRate ()
 Set up low-pass filters for all channels.
 
void writeBlocking (Print *out, uint8_t *data, size_t len)
 
void writePCMSample (float filteredValue)
 Convert filtered DSD value to PCM sample in the buffer.
 

Protected Attributes

Vector< float > channelAccum
 
Vector< LowPassFilter< float > > channelFilters
 Anti-aliasing filters for each channel.
 
Vector< float > channelIntegrator
 
uint64_t dataSize
 Size of audio data section in bytes.
 
uint32_t decimationStep
 Decimation factor for DSD to PCM conversion.
 
RingBuffer< uint8_t > dsdBuffer {0}
 Ring buffer for DSD data.
 
size_t filePos
 Current position in DSF file.
 
bool headerParsed = false
 Flag indicating if header parsing is complete.
 
size_t headerSize
 Current size of accumulated header data.
 
AudioInfo info
 
bool is_notify_active = true
 
bool isActive = false
 Flag indicating if decoder is active and ready.
 
float max_value = 0.0f
 
DSFMetadata meta
 Extracted DSF file metadata.
 
Vector< AudioInfoSupport * > notify_vector
 
Printp_print = nullptr
 
SingleBuffer< uint8_t > pcmBuffer {0}
 

Detailed Description

DSF (DSD Stream File) format decoder.

Author
pschatzmann

Decodes DSF files containing Direct Stream Digital (DSD) audio data and converts it to PCM format. DSF is a file format that stores DSD audio streams, commonly used for high-resolution audio. This decoder:

The decoder uses BiQuad low-pass filters for high-quality anti-aliasing during the DSD to PCM conversion process, replacing traditional FIR filter implementations for better performance and modularity.

Note
Supports mono and stereo DSD files with sample rates >= 2.8224 MHz (DSD64)

Member Function Documentation

◆ addNotifyAudioChange()

virtual void addNotifyAudioChange ( AudioInfoSupport bi)
inlinevirtualinherited

◆ audioInfo()

AudioInfo audioInfo ( )
inlineoverridevirtual

provides the actual input AudioInfo

Reimplemented from AudioDecoder.

◆ audioInfoOut()

virtual AudioInfo audioInfoOut ( )
inlinevirtualinherited

◆ begin() [1/2]

bool begin ( )
inlinevirtual

Initialize the decoder.

Returns
true if initialization successful

Sets up the decoder state, initializes buffers, and configures the low-pass filters with default parameters. The filters are initialized with a cutoff frequency of 40% of the Nyquist frequency to provide effective anti-aliasing.

Reimplemented from AudioDecoder.

◆ begin() [2/2]

virtual bool begin ( AudioInfo  info)
inlineoverridevirtualinherited

Reimplemented from AudioWriter.

◆ bufferDSDData()

size_t bufferDSDData ( const uint8_t *  data,
size_t  len,
size_t  startPos 
)
inlineprotected

Buffer incoming DSD data into ring buffer.

Parameters
dataInput data buffer
lenLength of input data
startPosStarting position in input buffer
Returns
Number of bytes successfully buffered

Copies DSD data bytes into the internal ring buffer until either all data is consumed or the buffer becomes full.

◆ clip()

float clip ( float  value)
inlineprotected

Clips audio values to valid range.

Parameters
valueInput audio value
Returns
Clipped value in range [-1.0, 1.0]

Ensures that filtered audio values stay within the valid range to prevent clipping artifacts in the final PCM output.

◆ convertDSDToPCM()

void convertDSDToPCM ( )
inlineprotected

Convert buffered DSD data to PCM samples and output them.

Performs the core DSD to PCM conversion process using integrator-based approach:

  1. Integrates DSD bits over the decimation period for each channel
  2. Converts DSD bits to analog values (-1 or +1) with proper delta-sigma handling
  3. Applies low-pass filtering to remove high-frequency noise
  4. Converts filtered values to PCM samples
  5. Outputs PCM samples for all channels

The conversion uses BiQuad low-pass filters for anti-aliasing, providing better audio quality than simple decimation.

DSF format uses byte interleaving: each byte contains 8 DSD samples for one channel, and channels are interleaved at the byte level (not bit level).

◆ end()

void end ( )
inlineoverridevirtual

Reimplemented from AudioDecoder.

◆ findTag()

int findTag ( const char *  tag,
const uint8_t *  data,
size_t  len 
)
inlineprotected

Find a specific tag within binary data.

Parameters
tagThe tag string to search for (e.g., "fmt ", "data")
dataThe binary data buffer to search in
lenThe length of the data buffer
Returns
The position of the tag if found, -1 if not found

Searches for DSF chunk identifiers within the file data. Used to locate format and data sections within the DSF file structure.

◆ getMetadata()

const DSFMetadata getMetadata ( )
inline

Get DSF file metadata.

Returns
Reference to DSFMetadata structure containing format information

Returns metadata extracted from the DSF file header, including DSD sample rate, data size, estimated PCM frames, and calculated duration.

◆ hasEnoughData()

bool hasEnoughData ( )
inlineprotected

Check if sufficient DSD data is available for conversion.

Returns
true if enough data is buffered for one decimation step

Determines if the DSD buffer contains enough data to perform one decimation step of DSD to PCM conversion. For DSF format with byte interleaving, we need enough bytes for all channels over the decimation period.

◆ isHeaderAvailable()

bool isHeaderAvailable ( )
inline

Check if decoder is ready.

Returns
true if DSF header has been successfully parsed

Indicates whether the decoder has successfully parsed the DSF file header and is ready to process audio data.

◆ isResultPCM()

virtual bool isResultPCM ( )
inlinevirtualinherited

Returns true to indicate that the decoding result is PCM data.

Reimplemented in CopyDecoder, DecoderNetworkFormat, GGWaveDecoder, and ContainerM4A.

◆ operator bool()

operator bool ( )
inlinevirtual

Implements AudioWriter.

◆ parseData()

bool parseData ( const uint8_t *  data,
size_t  len 
)
inlineprotected

Parse DSF data chunk to extract audio data information.

Parameters
dataPointer to the data chunk
lenLength of available data
Returns
true if parsing was successful, false otherwise

Extracts audio data size information and calculates estimated playback duration and total PCM frames that will be produced after DSD to PCM conversion is complete.

◆ parseFMT()

bool parseFMT ( const uint8_t *  data,
size_t  len 
)
inlineprotected

Parse DSF format chunk to extract audio parameters.

Parameters
dataPointer to the fmt chunk data
lenLength of available data
Returns
true if parsing was successful, false otherwise

Extracts essential audio format information from the DSF format chunk, including channel count, DSD sample rate, and validates the parameters are within acceptable ranges for processing.

◆ processDSDData()

size_t processDSDData ( const uint8_t *  data,
size_t  len,
size_t  startPos 
)
inlineprotected

Process DSD audio data: buffer it and convert to PCM when possible.

Parameters
dataInput data buffer containing DSD audio data
lenLength of input data
startPosStarting position in input buffer
Returns
Number of bytes processed for audio data

Buffers incoming DSD data and triggers PCM conversion when sufficient data is available for processing.

◆ processHeader()

size_t processHeader ( const uint8_t *  data,
size_t  len,
size_t  startPos 
)
inlineprotected

Process header data until header is complete or data is exhausted.

Parameters
dataInput data buffer
lenLength of input data
startPosStarting position in input buffer
Returns
Number of bytes processed for header parsing

Accumulates header bytes and attempts to parse the DSF file header. When a complete and valid header is found, sets headerParsed flag and updates decimation parameters.

◆ setAudioInfo()

void setAudioInfo ( AudioInfo  from)
inlineoverridevirtual

Can be used to set up alternative sample rate (default is 44100 Hz) and bits

Reimplemented from AudioDecoder.

◆ setCodecConfig()

virtual bool setCodecConfig ( const uint8_t *  data,
size_t  len 
)
inlinevirtualinherited

Some decoders need e.g. a magic cookie to provide the relevant info for decoding.

Reimplemented in DecoderALAC, and MultiDecoder.

◆ setOutput() [1/3]

virtual void setOutput ( AudioOutput out_stream)
inlinevirtualinherited

Defines where the decoded result is written to.

Reimplemented in ADTSDecoder, CodecChain, MTSDecoder, MTSDecoderTSDemux, and MetaDataFilterDecoder.

◆ setOutput() [2/3]

virtual void setOutput ( AudioStream out_stream)
inlinevirtualinherited

Defines where the decoded result is written to.

Reimplemented in ADTSDecoder, CodecChain, MTSDecoder, MTSDecoderTSDemux, and MetaDataFilterDecoder.

◆ setOutput() [3/3]

virtual void setOutput ( Print out_stream)
inlineoverridevirtualinherited

◆ setupDecimationStep()

void setupDecimationStep ( )
inlineprotected

Calculate optimal decimation step for DSD to PCM conversion.

Calculates the decimation factor as the ratio of DSD sample rate to target PCM sample rate. Clamps the value between 64 and 512 to ensure reasonable processing efficiency and audio quality while maintaining good anti-aliasing performance.

◆ setupTargetPCMRate()

void setupTargetPCMRate ( )
inlineprotected

Set up low-pass filters for all channels.

Initializes anti-aliasing filters for each audio channel with appropriate cutoff frequency (40% of Nyquist frequency) for the current sample rate. This ensures proper anti-aliasing performance during DSD to PCM conversion.

◆ write()

size_t write ( const uint8_t *  data,
size_t  len 
)
inlinevirtual

Main entry point for processing incoming DSF data.

Parameters
dataIncoming DSF file data bytes
lenNumber of bytes in data buffer
Returns
Number of bytes consumed (always returns len for streaming compatibility)

Processes incoming DSF file data in two phases:

  1. Header parsing: Extracts format information from DSF file header
  2. Audio processing: Buffers DSD data and converts to PCM output

The method is designed for streaming operation and always reports full consumption of input data for compatibility with streaming frameworks.

Implements AudioWriter.

◆ writePCMSample()

void writePCMSample ( float  filteredValue)
inlineprotected

Convert filtered DSD value to PCM sample in the buffer.

Parameters
filteredValueThe filtered DSD value (range -1.0 to 1.0)
channelChannel index (0 for left/mono, 1 for right)

Member Data Documentation

◆ channelAccum

Vector<float> channelAccum
protected

Accumulator for each channel during DSD to PCM conversion

◆ channelIntegrator

Vector<float> channelIntegrator
protected

Integrator state for each channel (for better DSD conversion)

◆ pcmBuffer

SingleBuffer<uint8_t> pcmBuffer {0}
protected

Buffer for PCM output samples - supports multi-channel up to 32-bit


The documentation for this class was generated from the following file: