|
|
|
|
|
|
|
|
#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! |