diff --git a/CHANGELOG.rst b/CHANGELOG.rst index b53f39c5..c5158083 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -7,7 +7,7 @@ sc_usb_audio Change Log 7.0.0 ------ - - ADDED: I2S down-sampling (I2S_DOWNSAMPLE_FACTOR) + - ADDED: I2S down-sampling (I2S_DOWNSAMPLE_FACTOR_IN) - ADDED: I2S resynchronisation when in slave mode (CODEC_MASTER=1) - CHANGE: Various memory optimisations when MAX_FREQ = MIN_FREQ - CHANGE: Memory optimisations in audio buffering diff --git a/module_usb_audio/audio_io/audio_io.xc b/module_usb_audio/audio_io/audio_io.xc index 368c6ebf..57512d1b 100755 --- a/module_usb_audio/audio_io/audio_io.xc +++ b/module_usb_audio/audio_io/audio_io.xc @@ -57,17 +57,17 @@ static unsigned samplesIn[2][MAX(NUM_USB_CHAN_IN, IN_CHAN_COUNT)]; #undef SPDIF_RX #endif -static int downsamplingCounter = 0; -#if (I2S_DOWNSAMPLE_FACTOR > 1) +static int inDownsamplingCounter = 0; +#if (I2S_DOWNSAMPLE_FACTOR_IN > 1) #include "src.h" static union ds3Data { long long doubleWordAlignmentEnsured; /* [Number of I2S channels][Number of samples/phases][Taps per phase] */ - int32_t delayLine[I2S_DOWNSAMPLE_CHANS][I2S_DOWNSAMPLE_FACTOR][24]; + int32_t inputDelayLine[I2S_DOWNSAMPLE_CHANS_IN][I2S_DOWNSAMPLE_FACTOR_IN][24]; } ds3Data; -static int64_t ds3Sum[I2S_DOWNSAMPLE_CHANS]; -#endif +static int64_t inputDs3Sum[I2S_DOWNSAMPLE_CHANS_IN]; +#endif // (I2S_DOWNSAMPLE_FACTOR_IN > 1) #if (DSD_CHANS_DAC != 0) extern buffered out port:32 p_dsd_dac[DSD_CHANS_DAC]; @@ -501,8 +501,8 @@ unsigned static deliver(chanend c_out, chanend ?c_spd_out, } #endif -#if (I2S_DOWNSAMPLE_FACTOR > 1) - memset(&ds3Data.delayLine, 0, sizeof ds3Data); +#if (I2S_DOWNSAMPLE_FACTOR_IN > 1) + memset(&ds3Data.inputDelayLine, 0, sizeof ds3Data); #endif unsigned command = DoSampleTransfer(c_out, readBuffNo, underflowWord, i_audMan); @@ -519,7 +519,7 @@ unsigned static deliver(chanend c_out, chanend ?c_spd_out, return command; } - downsamplingCounter = 0; + inDownsamplingCounter = 0; InitPorts(divide); @@ -651,10 +651,10 @@ unsigned static deliver(chanend c_out, chanend ?c_spd_out, else #endif { -#if (I2S_DOWNSAMPLE_FACTOR > 1) - if (0 == downsamplingCounter) +#if (I2S_DOWNSAMPLE_FACTOR_IN > 1) + if (0 == inDownsamplingCounter) { - memset(&ds3Sum, 0, sizeof ds3Sum); + memset(&inputDs3Sum, 0, sizeof inputDs3Sum); } #endif #if (I2S_CHANS_ADC != 0) @@ -683,26 +683,26 @@ unsigned static deliver(chanend c_out, chanend ?c_spd_out, /* Note the use of readBuffNo changes based on frameCount */ samplesIn[buffIndex][((frameCount-2)&(I2S_CHANS_PER_FRAME-1))+i] = bitrev(sample); // channels 0, 2, 4.. on each line. -#if (I2S_DOWNSAMPLE_FACTOR > 1) - if ((I2S_DOWNSAMPLE_FACTOR - 1) == downsamplingCounter) +#if (I2S_DOWNSAMPLE_FACTOR_IN > 1) + if ((I2S_DOWNSAMPLE_FACTOR_IN - 1) == inDownsamplingCounter) { samplesIn[readBuffNo][((frameCount-2)&(I2S_CHANS_PER_FRAME-1))] = src_ds3_voice_add_final_sample( - ds3Sum[((frameCount-2)&(I2S_CHANS_PER_FRAME-1))+i], - ds3Data.delayLine[((frameCount-2)&(I2S_CHANS_PER_FRAME-1))+i][downsamplingCounter], - src_ff3v_ds3_voice_coefs[downsamplingCounter], + inputDs3Sum[((frameCount-2)&(I2S_CHANS_PER_FRAME-1))+i], + ds3Data.inputDelayLine[((frameCount-2)&(I2S_CHANS_PER_FRAME-1))+i][inDownsamplingCounter], + src_ff3v_ds3_voice_coefs[inDownsamplingCounter], samplesIn[readBuffNo][((frameCount-2)&(I2S_CHANS_PER_FRAME-1))]); } else { - ds3Sum[((frameCount-2)&(I2S_CHANS_PER_FRAME-1))+i] = + inputDs3Sum[((frameCount-2)&(I2S_CHANS_PER_FRAME-1))+i] = src_ds3_voice_add_sample( - ds3Sum[((frameCount-2)&(I2S_CHANS_PER_FRAME-1))+i], - ds3Data.delayLine[((frameCount-2)&(I2S_CHANS_PER_FRAME-1))+i][downsamplingCounter], - src_ff3v_ds3_voice_coefs[downsamplingCounter], + inputDs3Sum[((frameCount-2)&(I2S_CHANS_PER_FRAME-1))+i], + ds3Data.inputDelayLine[((frameCount-2)&(I2S_CHANS_PER_FRAME-1))+i][inDownsamplingCounter], + src_ff3v_ds3_voice_coefs[inDownsamplingCounter], samplesIn[readBuffNo][((frameCount-2)&(I2S_CHANS_PER_FRAME-1))]); } -#endif // (I2S_DOWNSAMPLE_FACTOR > 1) +#endif // (I2S_DOWNSAMPLE_FACTOR_IN > 1) } #endif @@ -776,7 +776,7 @@ unsigned static deliver(chanend c_out, chanend ?c_spd_out, #endif #if (NUM_PDM_MICS > 0) - if ((I2S_DOWNSAMPLE_FACTOR - 1) == downsamplingCounter) + if ((I2S_DOWNSAMPLE_FACTOR_IN - 1) == inDownsamplingCounter) { /* Get samples from PDM->PCM comverter */ c_pdm_pcm <: 1; @@ -819,26 +819,26 @@ unsigned static deliver(chanend c_out, chanend ?c_spd_out, #endif // CODEC_MASTER samplesIn[buffIndex][((frameCount-1)&(I2S_CHANS_PER_FRAME-1))+i] = bitrev(sample); // channels 1, 3, 5.. on each line. -#if ((I2S_DOWNSAMPLE_FACTOR > 1) && !I2S_DOWNSAMPLE_MONO) - if ((I2S_DOWNSAMPLE_FACTOR - 1) == downsamplingCounter) +#if ((I2S_DOWNSAMPLE_FACTOR_IN > 1) && !I2S_DOWNSAMPLE_MONO_IN) + if ((I2S_DOWNSAMPLE_FACTOR_IN - 1) == inDownsamplingCounter) { samplesIn[buffIndex][((frameCount-1)&(I2S_CHANS_PER_FRAME-1))+i] = src_ds3_voice_add_final_sample( - ds3Sum[((frameCount-1)&(I2S_CHANS_PER_FRAME-1))+i], - ds3Data.delayLine[((frameCount-1)&(I2S_CHANS_PER_FRAME-1))+i][downsamplingCounter], - src_ff3v_ds3_voice_coefs[downsamplingCounter], + inputDs3Sum[((frameCount-1)&(I2S_CHANS_PER_FRAME-1))+i], + ds3Data.inputDelayLine[((frameCount-1)&(I2S_CHANS_PER_FRAME-1))+i][inDownsamplingCounter], + src_ff3v_ds3_voice_coefs[inDownsamplingCounter], samplesIn[readBuffNo][((frameCount-1)&(I2S_CHANS_PER_FRAME-1))+i]); } else { - ds3Sum[((frameCount-2)&(I2S_CHANS_PER_FRAME-1))+i] = + inputDs3Sum[((frameCount-2)&(I2S_CHANS_PER_FRAME-1))+i] = src_ds3_voice_add_sample( - ds3Sum[((frameCount-1)&(I2S_CHANS_PER_FRAME-1))+i], - ds3Data.delayLine[((frameCount-1)&(I2S_CHANS_PER_FRAME-1))+i][downsamplingCounter], - src_ff3v_ds3_voice_coefs[downsamplingCounter], + inputDs3Sum[((frameCount-1)&(I2S_CHANS_PER_FRAME-1))+i], + ds3Data.inputDelayLine[((frameCount-1)&(I2S_CHANS_PER_FRAME-1))+i][inDownsamplingCounter], + src_ff3v_ds3_voice_coefs[inDownsamplingCounter], samplesIn[readBuffNo][((frameCount-1)&(I2S_CHANS_PER_FRAME-1))+i]); } -#endif // ((I2S_DOWNSAMPLE_FACTOR > 1) && !I2S_DOWNSAMPLE_MONO) +#endif // ((I2S_DOWNSAMPLE_FACTOR_IN > 1) && !I2S_DOWNSAMPLE_MONO_IN) } #endif @@ -924,7 +924,7 @@ unsigned static deliver(chanend c_out, chanend ?c_spd_out, if(frameCount == I2S_CHANS_PER_FRAME) #endif { - if ((I2S_DOWNSAMPLE_FACTOR - 1) == downsamplingCounter) + if ((I2S_DOWNSAMPLE_FACTOR_IN - 1) == inDownsamplingCounter) { /* Do samples transfer */ /* The below looks a bit odd but forces the compiler to inline twice */ @@ -940,13 +940,13 @@ unsigned static deliver(chanend c_out, chanend ?c_spd_out, } /* Reset frame counter and flip the ADC buffer */ - downsamplingCounter = 0; + inDownsamplingCounter = 0; frameCount = 0; readBuffNo = !readBuffNo; } else { - ++downsamplingCounter; + ++inDownsamplingCounter; } } } @@ -1063,7 +1063,7 @@ chanend ?c_config, chanend ?c unsigned adatMultiple = 0; #endif - unsigned curSamFreq = DEFAULT_FREQ * I2S_DOWNSAMPLE_FACTOR; + unsigned curSamFreq = DEFAULT_FREQ * I2S_DOWNSAMPLE_FACTOR_IN; unsigned curSamRes_DAC = STREAM_FORMAT_OUTPUT_1_RESOLUTION_BITS; /* Default to something reasonable */ unsigned curSamRes_ADC = STREAM_FORMAT_INPUT_1_RESOLUTION_BITS; /* Default to something reasonable - note, currently this never changes*/ unsigned command; @@ -1218,7 +1218,7 @@ chanend ?c_config, chanend ?c { /* TODO wait for good mclk instead of delay */ /* No delay for DFU modes */ - if (((curSamFreq / I2S_DOWNSAMPLE_FACTOR) != AUDIO_REBOOT_FROM_DFU) && ((curSamFreq / I2S_DOWNSAMPLE_FACTOR) != AUDIO_STOP_FOR_DFU) && command) + if (((curSamFreq / I2S_DOWNSAMPLE_FACTOR_IN) != AUDIO_REBOOT_FROM_DFU) && ((curSamFreq / I2S_DOWNSAMPLE_FACTOR_IN) != AUDIO_STOP_FOR_DFU) && command) { #if 0 /* User should ensure MCLK is stable in AudioHwConfig */ @@ -1261,7 +1261,7 @@ chanend ?c_config, chanend ?c #if NUM_PDM_MICS > 0 /* Send decimation factor to PDM task(s) */ - c_pdm_in <: curSamFreq / I2S_DOWNSAMPLE_FACTOR; + c_pdm_in <: curSamFreq / I2S_DOWNSAMPLE_FACTOR_IN; #endif #ifdef ADAT_TX @@ -1299,7 +1299,7 @@ chanend ?c_config, chanend ?c if(command == SET_SAMPLE_FREQ) { - curSamFreq = inuint(c_mix_out) * I2S_DOWNSAMPLE_FACTOR; + curSamFreq = inuint(c_mix_out) * I2S_DOWNSAMPLE_FACTOR_IN; } else if(command == SET_STREAM_FORMAT_OUT) { @@ -1312,7 +1312,7 @@ chanend ?c_config, chanend ?c } /* Currently no more audio will happen after this point */ - if ((curSamFreq / I2S_DOWNSAMPLE_FACTOR) == AUDIO_STOP_FOR_DFU) + if ((curSamFreq / I2S_DOWNSAMPLE_FACTOR_IN) == AUDIO_STOP_FOR_DFU) { outct(c_mix_out, XS1_CT_END); diff --git a/module_usb_audio/devicedefines.h b/module_usb_audio/devicedefines.h index 61bbbb51..b88d334b 100644 --- a/module_usb_audio/devicedefines.h +++ b/module_usb_audio/devicedefines.h @@ -126,21 +126,21 @@ * * Default: 1 i.e. downsampling is disabled. */ -#ifndef I2S_DOWNSAMPLE_FACTOR -#define I2S_DOWNSAMPLE_FACTOR (1) +#ifndef I2S_DOWNSAMPLE_FACTOR_IN +#define I2S_DOWNSAMPLE_FACTOR_IN (1) #else - #if (I2S_DOWNSAMPLE_FACTOR != 3) && (I2S_DOWNSAMPLE_FACTOR != 1) - #error Unsupported I2S downsampling configuration + #if (I2S_DOWNSAMPLE_FACTOR_IN != 3) && (I2S_DOWNSAMPLE_FACTOR_IN != 1) + #error Unsupported I2S input downsampling configuration #endif #endif /** - * @brief Only downsample one channel per I2S frame. + * @brief Only downsample one channel per input I2S frame. * - * Default: 0 i.e. mono mode is disabled, all channels will be downsampled. + * Default: 0 i.e. mono mode is disabled, all input channels will be downsampled. */ -#ifndef I2S_DOWNSAMPLE_MONO -#define I2S_DOWNSAMPLE_MONO (0) +#ifndef I2S_DOWNSAMPLE_MONO_IN +#define I2S_DOWNSAMPLE_MONO_IN (0) #endif /** @@ -148,13 +148,13 @@ * * Default: The number of I2S incoming channels, or half this if mono downsampling is enabled. */ -#if (I2S_DOWNSAMPLE_MONO == 1) - #define I2S_DOWNSAMPLE_CHANS (I2S_CHANS_ADC / 2) - #if ((I2S_DOWNSAMPLE_FACTOR > 1) && (I2S_MODE_TDM == 1)) - #error Mono I2S downsampling is not avaliable in TDM mode +#if (I2S_DOWNSAMPLE_MONO_IN == 1) + #define I2S_DOWNSAMPLE_CHANS_IN (I2S_CHANS_ADC / 2) + #if ((I2S_DOWNSAMPLE_FACTOR_IN > 1) && (I2S_MODE_TDM == 1)) + #error Mono I2S input downsampling is not avaliable in TDM mode #endif #else -#define I2S_DOWNSAMPLE_CHANS I2S_CHANS_ADC +#define I2S_DOWNSAMPLE_CHANS_IN I2S_CHANS_ADC #endif /**