Add DS3 to I2S input
- I2S downsampling is disabled by default. - I2S rate is always scaled up: The host may not issue a SET_SAMPLE_FREQ command so always scale up, and back down where the value may be a another command.
This commit is contained in:
@@ -31,11 +31,31 @@
|
||||
#include "commands.h"
|
||||
#include "xc_ptr.h"
|
||||
|
||||
#ifndef I2S_DOWNSAMPLE_FACTOR
|
||||
#define I2S_DOWNSAMPLE_FACTOR (1)
|
||||
#endif
|
||||
#define I2S_RATE_SCALING (I2S_DOWNSAMPLE_FACTOR)
|
||||
|
||||
#if I2S_RATE_SCALING != I2S_DOWNSAMPLE_FACTOR
|
||||
#error "Unsupported I2S rate scaling and downsampling configuration"
|
||||
#endif
|
||||
|
||||
// I2S channels for stereo AEC reference input
|
||||
#define I2S_CHANS_DIGI_IN (2)
|
||||
// The PDM mic channels start after the I2S AEC reference channels
|
||||
#define PDM_RX_INDEX (I2S_CHANS_DIGI_IN)
|
||||
|
||||
#if (NUM_USB_CHAN_IN < (I2S_CHANS_DIGI_IN + NUM_PDM_MICS))
|
||||
#error "Not enough USB input channels to support number of I2S and PDM inputs"
|
||||
#endif
|
||||
|
||||
/* TODO 32 is max expected channels */
|
||||
static unsigned samplesOut[32];
|
||||
|
||||
/* Two buffers for ADC data to allow for DAC and ADC ports being offset */
|
||||
static unsigned samplesIn[2][32];
|
||||
static unsigned samplesIn[2][I2S_DOWNSAMPLE_FACTOR][32];
|
||||
|
||||
static int downsamplingCounter = 0;
|
||||
|
||||
#if (DSD_CHANS_DAC != 0)
|
||||
extern buffered out port:32 p_dsd_dac[DSD_CHANS_DAC];
|
||||
@@ -266,16 +286,24 @@ static inline unsigned DoSampleTransfer(chanend c_out, const int readBuffNo, con
|
||||
#else
|
||||
inuint(c_out);
|
||||
#endif
|
||||
UserBufferManagement(samplesOut, samplesIn[readBuffNo], i_audMan);
|
||||
}
|
||||
unsigned downsampledI2S[2];
|
||||
// TODO: run ds3 here
|
||||
// Pass samplesIn[readBuffNo][0,I2S_DOWNSAMPLE_FACTOR][i]) to ds3()
|
||||
UserBufferManagement(samplesOut, samplesIn[readBuffNo][downsamplingCounter], i_audMan);
|
||||
|
||||
#if NUM_USB_CHAN_IN > 0
|
||||
#pragma loop unroll
|
||||
for(int i = 0; i < NUM_USB_CHAN_IN; i++)
|
||||
{
|
||||
outuint(c_out, samplesIn[readBuffNo][i]);
|
||||
}
|
||||
#endif
|
||||
for(int i = 0; i < I2S_CHANS_DIGI_IN; i++)
|
||||
{
|
||||
outuint(c_out, downsampledI2S[i]);
|
||||
}
|
||||
#pragma loop unroll
|
||||
for (int i = PDM_RX_INDEX; i < (NUM_PDM_MICS + PDM_RX_INDEX); i++)
|
||||
{
|
||||
outuint(c_out, samplesIn[readBuffNo][downsamplingCounter][i]);
|
||||
}
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -479,6 +507,8 @@ unsigned static deliver(chanend c_out, chanend ?c_spd_out,
|
||||
return command;
|
||||
}
|
||||
|
||||
downsamplingCounter = 0;
|
||||
|
||||
InitPorts(divide);
|
||||
|
||||
/* TODO In master mode, the i/o loop assumes L/RCLK = 32bit clocks. We should check this every interation
|
||||
@@ -684,20 +714,22 @@ unsigned static deliver(chanend c_out, chanend ?c_spd_out,
|
||||
#endif
|
||||
|
||||
#if (NUM_PDM_MICS > 0)
|
||||
/* Get samples from PDM->PCM comverter */
|
||||
c_pdm_pcm <: 1;
|
||||
master
|
||||
if ((I2S_DOWNSAMPLE_FACTOR - 1) == downsamplingCounter)
|
||||
{
|
||||
/* Get samples from PDM->PCM comverter */
|
||||
c_pdm_pcm <: 1;
|
||||
master
|
||||
{
|
||||
#pragma loop unroll
|
||||
for(int i = 0; i < NUM_PDM_MICS; i++)
|
||||
{
|
||||
c_pdm_pcm :> samplesIn[readBuffNo][i];
|
||||
}
|
||||
for(int i = PDM_RX_INDEX; i < (NUM_PDM_MICS + PDM_RX_INDEX); i++)
|
||||
{
|
||||
c_pdm_pcm :> samplesIn[readBuffNo][downsamplingCounter][i];
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
#if (I2S_CHANS_ADC != 0)
|
||||
index = 0;
|
||||
/* Channels 0, 2, 4.. on each line */
|
||||
@@ -794,22 +826,30 @@ unsigned static deliver(chanend c_out, chanend ?c_spd_out,
|
||||
if(frameCount == I2S_CHANS_PER_FRAME)
|
||||
#endif
|
||||
{
|
||||
/* Do samples transfer */
|
||||
/* The below looks a bit odd but forces the compiler to inline twice */
|
||||
unsigned command;
|
||||
if(readBuffNo)
|
||||
command = DoSampleTransfer(c_out, 1, underflowWord, i_audMan);
|
||||
else
|
||||
command = DoSampleTransfer(c_out, 0, underflowWord, i_audMan);
|
||||
|
||||
if(command)
|
||||
if ((I2S_DOWNSAMPLE_FACTOR - 1) == downsamplingCounter)
|
||||
{
|
||||
return command;
|
||||
}
|
||||
/* Do samples transfer */
|
||||
/* The below looks a bit odd but forces the compiler to inline twice */
|
||||
unsigned command;
|
||||
if(readBuffNo)
|
||||
command = DoSampleTransfer(c_out, 1, underflowWord, i_audMan);
|
||||
else
|
||||
command = DoSampleTransfer(c_out, 0, underflowWord, i_audMan);
|
||||
|
||||
/* Reset frame counter and flip the ADC buffer */
|
||||
frameCount = 0;
|
||||
readBuffNo = !readBuffNo;
|
||||
if(command)
|
||||
{
|
||||
return command;
|
||||
}
|
||||
|
||||
/* Reset frame counter and flip the ADC buffer */
|
||||
downsamplingCounter = 0;
|
||||
frameCount = 0;
|
||||
readBuffNo = !readBuffNo;
|
||||
}
|
||||
else
|
||||
{
|
||||
++downsamplingCounter;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -924,7 +964,7 @@ chanend ?c_config, chanend ?c
|
||||
unsigned adatMultiple = 0;
|
||||
#endif
|
||||
|
||||
unsigned curSamFreq = DEFAULT_FREQ;
|
||||
unsigned curSamFreq = DEFAULT_FREQ * I2S_RATE_SCALING;
|
||||
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;
|
||||
@@ -1079,7 +1119,7 @@ chanend ?c_config, chanend ?c
|
||||
{
|
||||
/* TODO wait for good mclk instead of delay */
|
||||
/* No delay for DFU modes */
|
||||
if ((curSamFreq != AUDIO_REBOOT_FROM_DFU) && (curSamFreq != AUDIO_STOP_FOR_DFU) && command)
|
||||
if (((curSamFreq / I2S_RATE_SCALING) != AUDIO_REBOOT_FROM_DFU) && ((curSamFreq / I2S_RATE_SCALING) != AUDIO_STOP_FOR_DFU) && command)
|
||||
{
|
||||
#if 0
|
||||
/* User should ensure MCLK is stable in AudioHwConfig */
|
||||
@@ -1122,7 +1162,7 @@ chanend ?c_config, chanend ?c
|
||||
|
||||
#if NUM_PDM_MICS > 0
|
||||
/* Send decimation factor to PDM task(s) */
|
||||
c_pdm_in <: curSamFreq;
|
||||
c_pdm_in <: curSamFreq / I2S_DOWNSAMPLE_FACTOR;
|
||||
#endif
|
||||
|
||||
#ifdef ADAT_TX
|
||||
@@ -1163,7 +1203,7 @@ chanend ?c_config, chanend ?c
|
||||
|
||||
if(command == SET_SAMPLE_FREQ)
|
||||
{
|
||||
curSamFreq = inuint(c_mix_out);
|
||||
curSamFreq = inuint(c_mix_out) * I2S_RATE_SCALING;
|
||||
}
|
||||
else if(command == SET_STREAM_FORMAT_OUT)
|
||||
{
|
||||
@@ -1176,7 +1216,7 @@ chanend ?c_config, chanend ?c
|
||||
}
|
||||
|
||||
/* Currently no more audio will happen after this point */
|
||||
if (curSamFreq == AUDIO_STOP_FOR_DFU)
|
||||
if ((curSamFreq / I2S_RATE_SCALING) == AUDIO_STOP_FOR_DFU)
|
||||
{
|
||||
outct(c_mix_out, XS1_CT_END);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user