Ver código fonte

minor bug fix at the computation of the target frequency

providing the actual anti-aliasing attenuation and resampling filter length
dds
awalch6679 4 anos atrás
pai
commit
832bef49b7
4 arquivos alterados com 33 adições e 10 exclusões
  1. +10
    -1
      Resampler.cpp
  2. +5
    -1
      Resampler.h
  3. +13
    -5
      async_input_spdif3.cpp
  4. +5
    -3
      async_input_spdif3.h

+ 10
- 1
Resampler.cpp Ver arquivo

@@ -129,6 +129,12 @@ void Resampler::setFilter(int32_t halfFiltLength,int32_t overSampling, float cut
double Resampler::getStep() const {
return _stepAdapted;
}
double Resampler::getAttenuation() const {
return _attenuation;
}
int32_t Resampler::getHalfFilterLength() const{
return _halfFilterLength;
}
void Resampler::reset(){
_initialized=false;
}
@@ -136,6 +142,7 @@ void Resampler::configure(float fs, float newFs, float attenuation, int32_t minH
// Serial.print("configure, fs: ");
// Serial.println(fs);
if (fs<=0. || newFs <=0.){
_attenuation=0;
_initialized=false;
return;
}
@@ -152,9 +159,10 @@ void Resampler::configure(float fs, float newFs, float attenuation, int32_t minH
float cutOffFrequ, kaiserBeta;
_overSamplingFactor=1024;
if (fs <= newFs){
_attenuation=0;
cutOffFrequ=1.;
kaiserBeta=10;
_halfFilterLength=minHalfFilterLength;
_halfFilterLength=min(minHalfFilterLength,MAX_HALF_FILTER_LENGTH);
}
else{
cutOffFrequ=newFs/fs;
@@ -204,6 +212,7 @@ void Resampler::configure(float fs, float newFs, float attenuation, int32_t minH
int32_t f = (noSamples-1)/(MAX_FILTER_SAMPLES-1)+1;
_overSamplingFactor/=f;
}
_attenuation=attenuation;
}

#ifdef DEBUG_RESAMPLER

+ 5
- 1
Resampler.h Ver arquivo

@@ -69,6 +69,8 @@ class Resampler {
void addToPos(double val);
void fixStep();
bool initialized() const;
double getAttenuation() const;
int32_t getHalfFilterLength() const;
//resampling NOCHANNELS channels. Performance is increased a lot if the number of channels is known at compile time -> the number of channels is a template argument
template <uint8_t NOCHANNELS>
@@ -206,7 +208,7 @@ class Resampler {
float* _endOfBuffer[MAX_NO_CHANNELS];

int32_t _overSamplingFactor;
int32_t _halfFilterLength;
int32_t _halfFilterLength=0;
int32_t _filterLength;
bool _initialized=false;
@@ -218,6 +220,8 @@ class Resampler {
double _cPos;
double _sum;
double _oldDiffs[2];
double _attenuation=0;
};

#endif

+ 13
- 5
async_input_spdif3.cpp Ver arquivo

@@ -36,6 +36,7 @@ namespace {
#define SPDIF_RX_BUFFER_LENGTH AUDIO_BLOCK_SAMPLES
const int32_t bufferLength=8*AUDIO_BLOCK_SAMPLES;
const uint16_t noSamplerPerIsr=SPDIF_RX_BUFFER_LENGTH/4;
const float toFloatAudio= 1.f/pow(2., 23.);
}
volatile bool AsyncAudioInputSPDIF3::resetResampler=true;

@@ -199,14 +200,13 @@ void AsyncAudioInputSPDIF3::isr(void)
#endif
float *destR = &(bufferR[buffer_offset]);
float *destL = &(bufferL[buffer_offset]);
const float factor= pow(2., 23.)+1;
do {
int32_t n=(*src) & 0x800000 ? (*src)|0xFF800000 : (*src) & 0xFFFFFF;
*destL++ = (float)(n)/factor;
*destL++ = (float)(n)*toFloatAudio;
++src;

n=(*src) & 0x800000 ? (*src)|0xFF800000 : (*src) & 0xFFFFFF;
*destR++ = (float)(n)/factor;
*destR++ = (float)(n)*toFloatAudio;
++src;
} while (src < end);
buffer_offset=(buffer_offset+SPDIF_RX_BUFFER_LENGTH/4)%bufferLength;
@@ -280,8 +280,9 @@ void AsyncAudioInputSPDIF3::configure(){
if (abs(frequDiff) > 0.01 || !_resampler.initialized()){
//the new sample frequency differs from the last one -> configure the _resampler again
_inputFrequency=inputF;
const int32_t targetLatency=round(_targetLatencyS*inputF);
_targetLatencyS=max(0.001,(noSamplerPerIsr*3./2./_inputFrequency));
_maxLatency=max(2.*_blockDuration, 2*noSamplerPerIsr/_inputFrequency);
const int32_t targetLatency=round(_targetLatencyS*inputF);
__disable_irq();
resample_offset = targetLatency <= buffer_offset ? buffer_offset - targetLatency : bufferLength -(targetLatency-buffer_offset);
__enable_irq();
@@ -402,8 +403,9 @@ void AsyncAudioInputSPDIF3::update(void)
double AsyncAudioInputSPDIF3::getInputFrequency() const{
__disable_irq();
double f=_lastValidInputFrequ;
bool l=locked;
__enable_irq();
return f;
return l ? f : 0.;
}
double AsyncAudioInputSPDIF3::getTargetLantency() const {
__disable_irq();
@@ -411,6 +413,12 @@ double AsyncAudioInputSPDIF3::getTargetLantency() const {
__enable_irq();
return l ;
}
double AsyncAudioInputSPDIF3::getAttenuation() const{
return _resampler.getAttenuation();
}
int32_t AsyncAudioInputSPDIF3::getHalfFilterLength() const{
return _resampler.getHalfFilterLength();
}
void AsyncAudioInputSPDIF3::config_spdifIn(){
//CCM Clock Gating Register 5, imxrt1060_rev1.pdf page 1145
CCM_CCGR5 |=CCM_CCGR5_SPDIF(CCM_CCGR_ON); //turn spdif clock on - necessary for receiver!

+ 5
- 3
async_input_spdif3.h Ver arquivo

@@ -51,6 +51,8 @@ public:
double getInputFrequency() const;
bool isLocked() const;
double getTargetLantency() const;
double getAttenuation() const;
int32_t getHalfFilterLength() const;
protected:
static DMAChannel dma;
static void isr(void);
@@ -84,10 +86,10 @@ private:
volatile double _bufferedTime;
volatile double _lastValidInputFrequ;
double _inputFrequency;
double _inputFrequency=0.;
double _targetLatencyS; //target latency [seconds]
const double _blockDuration=AUDIO_BLOCK_SAMPLES/AUDIO_SAMPLE_RATE; //[seconds]
const double _maxLatency=2.*_blockDuration;
const double _blockDuration=AUDIO_BLOCK_SAMPLES/AUDIO_SAMPLE_RATE_EXACT; //[seconds]
double _maxLatency=2.*_blockDuration;

#ifdef DEBUG_SPDIF_IN
static volatile bool bufferOverflow;

Carregando…
Cancelar
Salvar