arduino-audio-tools
Loading...
Searching...
No Matches
Classes | Public Member Functions | Protected Member Functions | Protected Attributes | Static Protected Attributes | List of all members
EqualizerNBands< SampleT, AccT, NUM_TAPS, NUM_BANDS > Class Template Reference

N-Band Equalizer using FIR filters with logarithmically spaced bands. More...

#include <EqualizerNBands.h>

Inheritance diagram for EqualizerNBands< SampleT, AccT, NUM_TAPS, NUM_BANDS >:
ModifyingStream AudioStream BaseStream AudioInfoSupport AudioInfoSource Stream Print

Classes

class  EQFIRFilter
 

Public Member Functions

 EqualizerNBands ()
 
 EqualizerNBands (AudioOutput &out)
 
 EqualizerNBands (AudioStream &stream)
 
 EqualizerNBands (Print &out)
 
 EqualizerNBands (Stream &in)
 
 ~EqualizerNBands ()
 
virtual void addNotifyAudioChange (AudioInfoSupport &bi)
 Adds target to be notified about audio changes.
 
virtual AudioInfo audioInfo () override
 provides the actual input AudioInfo
 
virtual AudioInfo audioInfoOut ()
 
virtual int available () override
 
virtual int availableForWrite () override
 
bool begin () override
 Initializes the equalizer with the current audio info.
 
bool begin (AudioInfo info)
 
virtual void clearNotifyAudioChange ()
 Deletes all change notify subscriptions.
 
void end ()
 
virtual void flush () override
 
int getBandCount () const
 Get number of bands.
 
float getBandDB (int band) const
 
float getBandFrequency (int band) const
 
float getBandGain (int band)
 Get current gain for a specific band as normalized volume (-1.0 to 1.0)
 
bool isNotifyActive ()
 Checks if the automatic AudioInfo update is active.
 
virtual operator bool ()
 
size_t readBytes (uint8_t *data, size_t len) override
 
virtual size_t readSilence (uint8_t *buffer, size_t length)
 Source to generate silence: just sets the buffer to 0.
 
virtual bool removeNotifyAudioChange (AudioInfoSupport &bi)
 Removes a target in order not to be notified about audio changes.
 
virtual void setAudioInfo (AudioInfo newInfo) override
 Defines the input AudioInfo.
 
void setAutoUpdate (bool enabled)
 
bool setBandDB (int band, float gainDb)
 
bool setBandGain (int band, float volume)
 
bool setBandGains (float volume)
 Set same gain for all frequency bands.
 
void setNotifyActive (bool flag)
 Deactivate/Reactivate automatic AudioInfo updates: (default is active)
 
void setOutput (Print &out) override
 
void setStream (Stream &io) override
 
void setWriteBufferSize (int size)
 
bool update ()
 
size_t write (const uint8_t *data, size_t len) override
 
virtual size_t write (uint8_t ch) override
 
virtual void writeSilence (size_t len)
 Writes len bytes of silence (=0).
 

Protected Member Functions

void enterCritical ()
 
void exitCritical ()
 
void initializeKernel (volatile int16_t *kernel)
 
template<typename T >
float map (T x, T in_min, T in_max, T out_min, T out_max)
 
void maybeUpdateKernel ()
 
virtual int not_supported (int out, const char *msg="")
 
void notifyAudioChange (AudioInfo info)
 
void preCalculateWindow ()
 
void refillReadBuffer ()
 Refill small read buffer (e.g. 8 bytes) to avoid single byte reads when calling read()
 
void setupFrequencies (int sampleRate)
 
float sinc (float x)
 
bool updateFIRKernel ()
 

Protected Attributes

int _timeout = 10
 
volatile int16_tactiveKernel
 
bool autoUpdate = false
 
float centerFreqs [NUM_BANDS]
 
int currentSampleRate = 0
 
FilteredStream< SampleT, SampleTfiltered
 
Vector< EQFIRFilterfir_vector
 Vector of FIR filters for each channel.
 
float gains [NUM_BANDS] = {0}
 
volatile bool gainsDirty = false
 
AudioInfo info
 
bool is_notify_active = true
 
volatile bool isUpdating = false
 
int16_t kernelA [NUM_TAPS]
 
int16_t kernelB [NUM_TAPS]
 
Vector< AudioInfoSupport * > notify_vector
 
Printp_print = nullptr
 Output stream for write operations.
 
Streamp_stream = nullptr
 Input stream for read operations.
 
float pendingGains [NUM_BANDS] = {0}
 
float tempFloat [NUM_TAPS] = {0}
 
RingBuffer< uint8_ttmp_in {0}
 
RingBuffer< uint8_ttmp_out {0}
 
volatile int16_tupdateKernel
 
float windowCoeffs [NUM_TAPS]
 
int write_buffer_size = MAX_SINGLE_CHARS
 

Static Protected Attributes

static constexpr float Q15_SCALE = 32767.0f
 

Detailed Description

template<typename SampleT = int16_t, typename AccT = int64_t, int NUM_TAPS = 128, int NUM_BANDS = 12>
class audio_tools::EqualizerNBands< SampleT, AccT, NUM_TAPS, NUM_BANDS >

N-Band Equalizer using FIR filters with logarithmically spaced bands.

This class implements a graphic equalizer with configurable number of bands using FIR (Finite Impulse Response) filtering. Frequency bands are logarithmically spaced between 20Hz and Nyquist frequency.

Features:

Thread Safety: Uses double-buffering with two kernel buffers. Audio processing reads from the active kernel while updates are written to the inactive kernel. An atomic pointer swap ensures glitch-free transitions without blocking audio processing.

Template Parameters
NUM_TAPSNumber of FIR filter taps (higher = sharper transitions, more CPU usage). Typical values: 64, 128, 256
NUM_BANDSNumber of frequency bands. Typical values: 3, 5, 10, 31
Note
NUM_TAPS should be odd for symmetric filter response
Higher NUM_TAPS values require more memory and processing time

Constructor & Destructor Documentation

◆ EqualizerNBands() [1/5]

template<typename SampleT = int16_t, typename AccT = int64_t, int NUM_TAPS = 128, int NUM_BANDS = 12>
EqualizerNBands ( )
inline

◆ EqualizerNBands() [2/5]

template<typename SampleT = int16_t, typename AccT = int64_t, int NUM_TAPS = 128, int NUM_BANDS = 12>
EqualizerNBands ( Print out)
inline

Constructor with Print output

Parameters
outPrint stream for output

◆ EqualizerNBands() [3/5]

template<typename SampleT = int16_t, typename AccT = int64_t, int NUM_TAPS = 128, int NUM_BANDS = 12>
EqualizerNBands ( Stream in)
inline

Constructor with Stream input

Parameters
inStream for input

◆ EqualizerNBands() [4/5]

template<typename SampleT = int16_t, typename AccT = int64_t, int NUM_TAPS = 128, int NUM_BANDS = 12>
EqualizerNBands ( AudioOutput out)
inline

Constructor with AudioOutput

Parameters
outAudioOutput for output with automatic audio change notifications

◆ EqualizerNBands() [5/5]

template<typename SampleT = int16_t, typename AccT = int64_t, int NUM_TAPS = 128, int NUM_BANDS = 12>
EqualizerNBands ( AudioStream stream)
inline

Constructor with AudioStream

Parameters
streamAudioStream for input/output with automatic audio change notifications

◆ ~EqualizerNBands()

template<typename SampleT = int16_t, typename AccT = int64_t, int NUM_TAPS = 128, int NUM_BANDS = 12>
~EqualizerNBands ( )
inline

Member Function Documentation

◆ addNotifyAudioChange()

virtual void addNotifyAudioChange ( AudioInfoSupport bi)
inlinevirtualinherited

◆ audioInfo()

virtual AudioInfo audioInfo ( )
inlineoverridevirtualinherited

◆ audioInfoOut()

virtual AudioInfo audioInfoOut ( )
inlinevirtualinherited

◆ available()

virtual int available ( )
inlineoverridevirtualinherited

◆ availableForWrite()

virtual int availableForWrite ( )
inlineoverridevirtualinherited

◆ begin() [1/2]

template<typename SampleT = int16_t, typename AccT = int64_t, int NUM_TAPS = 128, int NUM_BANDS = 12>
bool begin ( )
inlineoverridevirtual

Initializes the equalizer with the current audio info.

Reimplemented from BaseStream.

◆ begin() [2/2]

template<typename SampleT = int16_t, typename AccT = int64_t, int NUM_TAPS = 128, int NUM_BANDS = 12>
bool begin ( AudioInfo  info)
inline

◆ clearNotifyAudioChange()

virtual void clearNotifyAudioChange ( )
inlinevirtualinherited

Deletes all change notify subscriptions.

Reimplemented in RTSPClient< TcpClient, UdpSocket >.

◆ end()

template<typename SampleT = int16_t, typename AccT = int64_t, int NUM_TAPS = 128, int NUM_BANDS = 12>
void end ( )
inlinevirtual

Reimplemented from BaseStream.

◆ enterCritical()

template<typename SampleT = int16_t, typename AccT = int64_t, int NUM_TAPS = 128, int NUM_BANDS = 12>
void enterCritical ( )
inlineprotected

◆ exitCritical()

template<typename SampleT = int16_t, typename AccT = int64_t, int NUM_TAPS = 128, int NUM_BANDS = 12>
void exitCritical ( )
inlineprotected

◆ flush()

virtual void flush ( )
inlineoverridevirtualinherited

◆ getBandCount()

template<typename SampleT = int16_t, typename AccT = int64_t, int NUM_TAPS = 128, int NUM_BANDS = 12>
int getBandCount ( ) const
inline

Get number of bands.

◆ getBandDB()

template<typename SampleT = int16_t, typename AccT = int64_t, int NUM_TAPS = 128, int NUM_BANDS = 12>
float getBandDB ( int  band) const
inline

Get current gain for a specific band in dB

Parameters
bandBand index (0 to NUM_BANDS-1)
Returns
Gain in dB (-90 to +12), or 0 if band index invalid

◆ getBandFrequency()

template<typename SampleT = int16_t, typename AccT = int64_t, int NUM_TAPS = 128, int NUM_BANDS = 12>
float getBandFrequency ( int  band) const
inline

Get center frequency for a specific band

Parameters
bandBand index (0 to NUM_BANDS-1)
Returns
Center frequency in Hz, or 0 if band index invalid

◆ getBandGain()

template<typename SampleT = int16_t, typename AccT = int64_t, int NUM_TAPS = 128, int NUM_BANDS = 12>
float getBandGain ( int  band)
inline

Get current gain for a specific band as normalized volume (-1.0 to 1.0)

◆ initializeKernel()

template<typename SampleT = int16_t, typename AccT = int64_t, int NUM_TAPS = 128, int NUM_BANDS = 12>
void initializeKernel ( volatile int16_t kernel)
inlineprotected

◆ isNotifyActive()

bool isNotifyActive ( )
inlineinherited

Checks if the automatic AudioInfo update is active.

◆ map()

template<typename SampleT = int16_t, typename AccT = int64_t, int NUM_TAPS = 128, int NUM_BANDS = 12>
template<typename T >
float map ( T  x,
T  in_min,
T  in_max,
T  out_min,
T  out_max 
)
inlineprotected

◆ maybeUpdateKernel()

template<typename SampleT = int16_t, typename AccT = int64_t, int NUM_TAPS = 128, int NUM_BANDS = 12>
void maybeUpdateKernel ( )
inlineprotected

◆ not_supported()

virtual int not_supported ( int  out,
const char msg = "" 
)
inlineprotectedvirtualinherited

◆ notifyAudioChange()

void notifyAudioChange ( AudioInfo  info)
inlineprotectedinherited

◆ operator bool()

virtual operator bool ( )
inlinevirtualinherited

◆ preCalculateWindow()

template<typename SampleT = int16_t, typename AccT = int64_t, int NUM_TAPS = 128, int NUM_BANDS = 12>
void preCalculateWindow ( )
inlineprotected

◆ readBytes()

template<typename SampleT = int16_t, typename AccT = int64_t, int NUM_TAPS = 128, int NUM_BANDS = 12>
size_t readBytes ( uint8_t data,
size_t  len 
)
inlineoverridevirtual

Reimplemented from AudioStream.

◆ readSilence()

virtual size_t readSilence ( uint8_t buffer,
size_t  length 
)
inlinevirtualinherited

Source to generate silence: just sets the buffer to 0.

◆ refillReadBuffer()

void refillReadBuffer ( )
inlineprotectedinherited

Refill small read buffer (e.g. 8 bytes) to avoid single byte reads when calling read()

◆ removeNotifyAudioChange()

virtual bool removeNotifyAudioChange ( AudioInfoSupport bi)
inlinevirtualinherited

Removes a target in order not to be notified about audio changes.

Reimplemented in RTSPClient< TcpClient, UdpSocket >.

◆ setAudioInfo()

virtual void setAudioInfo ( AudioInfo  info)
inlineoverridevirtualinherited

◆ setAutoUpdate()

template<typename SampleT = int16_t, typename AccT = int64_t, int NUM_TAPS = 128, int NUM_BANDS = 12>
void setAutoUpdate ( bool  enabled)
inline

Enable/disable automatic kernel updates during read/write

Parameters
enabledWhen true, pending gain changes are applied automatically

◆ setBandDB()

template<typename SampleT = int16_t, typename AccT = int64_t, int NUM_TAPS = 128, int NUM_BANDS = 12>
bool setBandDB ( int  band,
float  gainDb 
)
inline

Set gain for a specific band directly in dB

Parameters
bandBand index (0 to NUM_BANDS-1)
gainDbGain in dB (-90 to +12). The lower limit matches Q15 dynamic range; the upper limit prevents clipping.

◆ setBandGain()

template<typename SampleT = int16_t, typename AccT = int64_t, int NUM_TAPS = 128, int NUM_BANDS = 12>
bool setBandGain ( int  band,
float  volume 
)
inline

Set gain for a specific frequency band

Parameters
bandBand index (0 to NUM_BANDS-1)
volumeVolume level (-1.0 to 1.0) mapped to -12dB to +12dB. For deeper cuts use setBandDB() directly.

◆ setBandGains()

template<typename SampleT = int16_t, typename AccT = int64_t, int NUM_TAPS = 128, int NUM_BANDS = 12>
bool setBandGains ( float  volume)
inline

Set same gain for all frequency bands.

◆ setNotifyActive()

void setNotifyActive ( bool  flag)
inlineinherited

Deactivate/Reactivate automatic AudioInfo updates: (default is active)

◆ setOutput()

template<typename SampleT = int16_t, typename AccT = int64_t, int NUM_TAPS = 128, int NUM_BANDS = 12>
void setOutput ( Print out)
inlineoverridevirtual

Defines/Changes the output target

Parameters
outPrint stream where processed audio will be written

Implements ModifyingStream.

◆ setStream()

template<typename SampleT = int16_t, typename AccT = int64_t, int NUM_TAPS = 128, int NUM_BANDS = 12>
void setStream ( Stream io)
inlineoverridevirtual

Defines/Changes the input & output stream

Parameters
ioStream to use for both reading and writing audio data

Implements ModifyingStream.

◆ setupFrequencies()

template<typename SampleT = int16_t, typename AccT = int64_t, int NUM_TAPS = 128, int NUM_BANDS = 12>
void setupFrequencies ( int  sampleRate)
inlineprotected

◆ setWriteBufferSize()

void setWriteBufferSize ( int  size)
inlineinherited

◆ sinc()

template<typename SampleT = int16_t, typename AccT = int64_t, int NUM_TAPS = 128, int NUM_BANDS = 12>
float sinc ( float  x)
inlineprotected

◆ update()

template<typename SampleT = int16_t, typename AccT = int64_t, int NUM_TAPS = 128, int NUM_BANDS = 12>
bool update ( )
inline

◆ updateFIRKernel()

template<typename SampleT = int16_t, typename AccT = int64_t, int NUM_TAPS = 128, int NUM_BANDS = 12>
bool updateFIRKernel ( )
inlineprotected

◆ write() [1/2]

template<typename SampleT = int16_t, typename AccT = int64_t, int NUM_TAPS = 128, int NUM_BANDS = 12>
size_t write ( const uint8_t data,
size_t  len 
)
inlineoverridevirtual

Reimplemented from AudioStream.

◆ write() [2/2]

virtual size_t write ( uint8_t  ch)
inlineoverridevirtualinherited

◆ writeSilence()

virtual void writeSilence ( size_t  len)
inlinevirtualinherited

Writes len bytes of silence (=0).

Member Data Documentation

◆ _timeout

int _timeout = 10
protectedinherited

◆ activeKernel

template<typename SampleT = int16_t, typename AccT = int64_t, int NUM_TAPS = 128, int NUM_BANDS = 12>
volatile int16_t* activeKernel
protected

◆ autoUpdate

template<typename SampleT = int16_t, typename AccT = int64_t, int NUM_TAPS = 128, int NUM_BANDS = 12>
bool autoUpdate = false
protected

◆ centerFreqs

template<typename SampleT = int16_t, typename AccT = int64_t, int NUM_TAPS = 128, int NUM_BANDS = 12>
float centerFreqs[NUM_BANDS]
protected

◆ currentSampleRate

template<typename SampleT = int16_t, typename AccT = int64_t, int NUM_TAPS = 128, int NUM_BANDS = 12>
int currentSampleRate = 0
protected

◆ filtered

template<typename SampleT = int16_t, typename AccT = int64_t, int NUM_TAPS = 128, int NUM_BANDS = 12>
FilteredStream<SampleT, SampleT> filtered
protected

◆ fir_vector

template<typename SampleT = int16_t, typename AccT = int64_t, int NUM_TAPS = 128, int NUM_BANDS = 12>
Vector<EQFIRFilter> fir_vector
protected

Vector of FIR filters for each channel.

◆ gains

template<typename SampleT = int16_t, typename AccT = int64_t, int NUM_TAPS = 128, int NUM_BANDS = 12>
float gains[NUM_BANDS] = {0}
protected

◆ gainsDirty

template<typename SampleT = int16_t, typename AccT = int64_t, int NUM_TAPS = 128, int NUM_BANDS = 12>
volatile bool gainsDirty = false
protected

◆ info

AudioInfo info
protectedinherited

◆ is_notify_active

bool is_notify_active = true
protectedinherited

◆ isUpdating

template<typename SampleT = int16_t, typename AccT = int64_t, int NUM_TAPS = 128, int NUM_BANDS = 12>
volatile bool isUpdating = false
protected

◆ kernelA

template<typename SampleT = int16_t, typename AccT = int64_t, int NUM_TAPS = 128, int NUM_BANDS = 12>
int16_t kernelA[NUM_TAPS]
protected

◆ kernelB

template<typename SampleT = int16_t, typename AccT = int64_t, int NUM_TAPS = 128, int NUM_BANDS = 12>
int16_t kernelB[NUM_TAPS]
protected

◆ notify_vector

Vector<AudioInfoSupport*> notify_vector
protectedinherited

◆ p_print

template<typename SampleT = int16_t, typename AccT = int64_t, int NUM_TAPS = 128, int NUM_BANDS = 12>
Print* p_print = nullptr
protected

Output stream for write operations.

◆ p_stream

template<typename SampleT = int16_t, typename AccT = int64_t, int NUM_TAPS = 128, int NUM_BANDS = 12>
Stream* p_stream = nullptr
protected

Input stream for read operations.

◆ pendingGains

template<typename SampleT = int16_t, typename AccT = int64_t, int NUM_TAPS = 128, int NUM_BANDS = 12>
float pendingGains[NUM_BANDS] = {0}
protected

◆ Q15_SCALE

template<typename SampleT = int16_t, typename AccT = int64_t, int NUM_TAPS = 128, int NUM_BANDS = 12>
constexpr float Q15_SCALE = 32767.0f
staticconstexprprotected

◆ tempFloat

template<typename SampleT = int16_t, typename AccT = int64_t, int NUM_TAPS = 128, int NUM_BANDS = 12>
float tempFloat[NUM_TAPS] = {0}
protected

◆ tmp_in

RingBuffer<uint8_t> tmp_in {0}
protectedinherited

◆ tmp_out

RingBuffer<uint8_t> tmp_out {0}
protectedinherited

◆ updateKernel

template<typename SampleT = int16_t, typename AccT = int64_t, int NUM_TAPS = 128, int NUM_BANDS = 12>
volatile int16_t* updateKernel
protected

◆ windowCoeffs

template<typename SampleT = int16_t, typename AccT = int64_t, int NUM_TAPS = 128, int NUM_BANDS = 12>
float windowCoeffs[NUM_TAPS]
protected

◆ write_buffer_size

int write_buffer_size = MAX_SINGLE_CHARS
protectedinherited

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