forked from PAWPAW-Mirror/lib_xua
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 "commands.h"
|
||||||
#include "xc_ptr.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 */
|
/* TODO 32 is max expected channels */
|
||||||
static unsigned samplesOut[32];
|
static unsigned samplesOut[32];
|
||||||
|
|
||||||
/* Two buffers for ADC data to allow for DAC and ADC ports being offset */
|
/* 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)
|
#if (DSD_CHANS_DAC != 0)
|
||||||
extern buffered out port:32 p_dsd_dac[DSD_CHANS_DAC];
|
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
|
#else
|
||||||
inuint(c_out);
|
inuint(c_out);
|
||||||
#endif
|
#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
|
#if NUM_USB_CHAN_IN > 0
|
||||||
#pragma loop unroll
|
#pragma loop unroll
|
||||||
for(int i = 0; i < NUM_USB_CHAN_IN; i++)
|
for(int i = 0; i < I2S_CHANS_DIGI_IN; i++)
|
||||||
{
|
{
|
||||||
outuint(c_out, samplesIn[readBuffNo][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
|
#endif
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@@ -479,6 +507,8 @@ unsigned static deliver(chanend c_out, chanend ?c_spd_out,
|
|||||||
return command;
|
return command;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
downsamplingCounter = 0;
|
||||||
|
|
||||||
InitPorts(divide);
|
InitPorts(divide);
|
||||||
|
|
||||||
/* TODO In master mode, the i/o loop assumes L/RCLK = 32bit clocks. We should check this every interation
|
/* 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
|
#endif
|
||||||
|
|
||||||
#if (NUM_PDM_MICS > 0)
|
#if (NUM_PDM_MICS > 0)
|
||||||
|
if ((I2S_DOWNSAMPLE_FACTOR - 1) == downsamplingCounter)
|
||||||
|
{
|
||||||
/* Get samples from PDM->PCM comverter */
|
/* Get samples from PDM->PCM comverter */
|
||||||
c_pdm_pcm <: 1;
|
c_pdm_pcm <: 1;
|
||||||
master
|
master
|
||||||
{
|
{
|
||||||
#pragma loop unroll
|
#pragma loop unroll
|
||||||
for(int i = 0; i < NUM_PDM_MICS; i++)
|
for(int i = PDM_RX_INDEX; i < (NUM_PDM_MICS + PDM_RX_INDEX); i++)
|
||||||
{
|
{
|
||||||
c_pdm_pcm :> samplesIn[readBuffNo][i];
|
c_pdm_pcm :> samplesIn[readBuffNo][downsamplingCounter][i];
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
#if (I2S_CHANS_ADC != 0)
|
#if (I2S_CHANS_ADC != 0)
|
||||||
index = 0;
|
index = 0;
|
||||||
/* Channels 0, 2, 4.. on each line */
|
/* Channels 0, 2, 4.. on each line */
|
||||||
@@ -793,6 +825,8 @@ unsigned static deliver(chanend c_out, chanend ?c_spd_out,
|
|||||||
frameCount+=2;
|
frameCount+=2;
|
||||||
if(frameCount == I2S_CHANS_PER_FRAME)
|
if(frameCount == I2S_CHANS_PER_FRAME)
|
||||||
#endif
|
#endif
|
||||||
|
{
|
||||||
|
if ((I2S_DOWNSAMPLE_FACTOR - 1) == downsamplingCounter)
|
||||||
{
|
{
|
||||||
/* Do samples transfer */
|
/* Do samples transfer */
|
||||||
/* The below looks a bit odd but forces the compiler to inline twice */
|
/* The below looks a bit odd but forces the compiler to inline twice */
|
||||||
@@ -808,9 +842,15 @@ unsigned static deliver(chanend c_out, chanend ?c_spd_out,
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Reset frame counter and flip the ADC buffer */
|
/* Reset frame counter and flip the ADC buffer */
|
||||||
|
downsamplingCounter = 0;
|
||||||
frameCount = 0;
|
frameCount = 0;
|
||||||
readBuffNo = !readBuffNo;
|
readBuffNo = !readBuffNo;
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
++downsamplingCounter;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#pragma xta endpoint "deliver_return"
|
#pragma xta endpoint "deliver_return"
|
||||||
@@ -924,7 +964,7 @@ chanend ?c_config, chanend ?c
|
|||||||
unsigned adatMultiple = 0;
|
unsigned adatMultiple = 0;
|
||||||
#endif
|
#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_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 curSamRes_ADC = STREAM_FORMAT_INPUT_1_RESOLUTION_BITS; /* Default to something reasonable - note, currently this never changes*/
|
||||||
unsigned command;
|
unsigned command;
|
||||||
@@ -1079,7 +1119,7 @@ chanend ?c_config, chanend ?c
|
|||||||
{
|
{
|
||||||
/* TODO wait for good mclk instead of delay */
|
/* TODO wait for good mclk instead of delay */
|
||||||
/* No delay for DFU modes */
|
/* 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
|
#if 0
|
||||||
/* User should ensure MCLK is stable in AudioHwConfig */
|
/* User should ensure MCLK is stable in AudioHwConfig */
|
||||||
@@ -1122,7 +1162,7 @@ chanend ?c_config, chanend ?c
|
|||||||
|
|
||||||
#if NUM_PDM_MICS > 0
|
#if NUM_PDM_MICS > 0
|
||||||
/* Send decimation factor to PDM task(s) */
|
/* Send decimation factor to PDM task(s) */
|
||||||
c_pdm_in <: curSamFreq;
|
c_pdm_in <: curSamFreq / I2S_DOWNSAMPLE_FACTOR;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef ADAT_TX
|
#ifdef ADAT_TX
|
||||||
@@ -1163,7 +1203,7 @@ chanend ?c_config, chanend ?c
|
|||||||
|
|
||||||
if(command == SET_SAMPLE_FREQ)
|
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)
|
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 */
|
/* 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);
|
outct(c_mix_out, XS1_CT_END);
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user