Browse Source

minor bug fix at the computation of the target frequency

providing the actual anti-aliasing attenuation and resampling filter length
dds
awalch6679 4 years ago
parent
commit
832bef49b7
4 changed files with 33 additions and 10 deletions
  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 View File

double Resampler::getStep() const { double Resampler::getStep() const {
return _stepAdapted; return _stepAdapted;
} }
double Resampler::getAttenuation() const {
return _attenuation;
}
int32_t Resampler::getHalfFilterLength() const{
return _halfFilterLength;
}
void Resampler::reset(){ void Resampler::reset(){
_initialized=false; _initialized=false;
} }
// Serial.print("configure, fs: "); // Serial.print("configure, fs: ");
// Serial.println(fs); // Serial.println(fs);
if (fs<=0. || newFs <=0.){ if (fs<=0. || newFs <=0.){
_attenuation=0;
_initialized=false; _initialized=false;
return; return;
} }
float cutOffFrequ, kaiserBeta; float cutOffFrequ, kaiserBeta;
_overSamplingFactor=1024; _overSamplingFactor=1024;
if (fs <= newFs){ if (fs <= newFs){
_attenuation=0;
cutOffFrequ=1.; cutOffFrequ=1.;
kaiserBeta=10; kaiserBeta=10;
_halfFilterLength=minHalfFilterLength;
_halfFilterLength=min(minHalfFilterLength,MAX_HALF_FILTER_LENGTH);
} }
else{ else{
cutOffFrequ=newFs/fs; cutOffFrequ=newFs/fs;
int32_t f = (noSamples-1)/(MAX_FILTER_SAMPLES-1)+1; int32_t f = (noSamples-1)/(MAX_FILTER_SAMPLES-1)+1;
_overSamplingFactor/=f; _overSamplingFactor/=f;
} }
_attenuation=attenuation;
} }


#ifdef DEBUG_RESAMPLER #ifdef DEBUG_RESAMPLER

+ 5
- 1
Resampler.h View File

void addToPos(double val); void addToPos(double val);
void fixStep(); void fixStep();
bool initialized() const; 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 //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> template <uint8_t NOCHANNELS>
float* _endOfBuffer[MAX_NO_CHANNELS]; float* _endOfBuffer[MAX_NO_CHANNELS];


int32_t _overSamplingFactor; int32_t _overSamplingFactor;
int32_t _halfFilterLength;
int32_t _halfFilterLength=0;
int32_t _filterLength; int32_t _filterLength;
bool _initialized=false; bool _initialized=false;
double _cPos; double _cPos;
double _sum; double _sum;
double _oldDiffs[2]; double _oldDiffs[2];
double _attenuation=0;
}; };


#endif #endif

+ 13
- 5
async_input_spdif3.cpp View File

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


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


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

+ 5
- 3
async_input_spdif3.h View File

double getInputFrequency() const; double getInputFrequency() const;
bool isLocked() const; bool isLocked() const;
double getTargetLantency() const; double getTargetLantency() const;
double getAttenuation() const;
int32_t getHalfFilterLength() const;
protected: protected:
static DMAChannel dma; static DMAChannel dma;
static void isr(void); static void isr(void);
volatile double _bufferedTime; volatile double _bufferedTime;
volatile double _lastValidInputFrequ; volatile double _lastValidInputFrequ;
double _inputFrequency;
double _inputFrequency=0.;
double _targetLatencyS; //target latency [seconds] 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 #ifdef DEBUG_SPDIF_IN
static volatile bool bufferOverflow; static volatile bool bufferOverflow;

Loading…
Cancel
Save