The audio i/o core now uses "underflow" sample as it's request word (i.e. different for PCM/DSD). This gets passed all the way through mixer and on to decouple such that it can be used in the underflow state. This allows the removal of the communication of the underflow state to the audio i/o core from decouple and thus "stand-alone" mixer now works again.

This commit is contained in:
Ross Owen
2015-03-20 17:23:24 +00:00
parent 8938dc7afc
commit 7cd5631e4b
3 changed files with 74 additions and 114 deletions

View File

@@ -218,109 +218,85 @@ static inline void TransferAdatTxSamples(chanend c_adat_out, const unsigned samp
static inline unsigned DoSampleTransfer(chanend c_out, int readBuffNo, unsigned underflowWord)
{
unsigned command;
unsigned underflow;
outuint(c_out, 0);
outuint(c_out, underflowWord);
/* Check for sample freq change (or other command) or new samples from mixer*/
if(testct(c_out))
{
unsigned command = inct(c_out);
/* Check for sample freq change (or other command) or new samples from mixer*/
if(testct(c_out))
{
unsigned command = inct(c_out);
#ifndef CODEC_MASTER
// Set clocks low
p_lrclk <: 0;
p_bclk <: 0;
// Set clocks low
p_lrclk <: 0;
p_bclk <: 0;
#if(DSD_CHANS_DAC != 0)
/* DSD Clock might not be shared with lrclk or bclk... */
p_dsd_clk <: 0;
p_dsd_clk <: 0;
#endif
#endif
#if (DSD_CHANS_DAC > 0)
if(dsdMode == DSD_MODE_DOP)
dsdMode = DSD_MODE_OFF;
if(dsdMode == DSD_MODE_DOP)
dsdMode = DSD_MODE_OFF;
#endif
#pragma xta endpoint "received_command"
return command;
}
else
{
underflow = inuint(c_out);
}
else
{
#ifndef MIXER // Interfaces straight to decouple()
#if NUM_USB_CHAN_IN > 0
#pragma loop unroll
for(int i = 0; i < I2S_CHANS_ADC; i++)
{
if(readBuffNo)
outuint(c_out, samplesIn_1[i]);
else
outuint(c_out, samplesIn_0[i]);
}
/* Send over the digi channels - no odd buffering required */
#pragma loop unroll
for(int i = I2S_CHANS_ADC; i < NUM_USB_CHAN_IN; i++)
{
for(int i = 0; i < I2S_CHANS_ADC; i++)
{
if(readBuffNo)
outuint(c_out, samplesIn_1[i]);
else
outuint(c_out, samplesIn_0[i]);
}
}
/* Send over the digi channels - no odd buffering required */
#pragma loop unroll
for(int i = I2S_CHANS_ADC; i < NUM_USB_CHAN_IN; i++)
{
outuint(c_out, samplesIn_0[i]);
}
#endif
#if NUM_USB_CHAN_OUT > 0
if(underflow)
{
#pragma loop unroll
for(int i = 0; i < NUM_USB_CHAN_OUT; i++)
{
samplesOut[i] = underflowWord;
}
}
else
{
#pragma loop unroll
for(int i = 0; i < NUM_USB_CHAN_OUT; i++)
{
samplesOut[i] = inuint(c_out);
}
}
for(int i = 0; i < NUM_USB_CHAN_OUT; i++)
{
samplesOut[i] = inuint(c_out);
}
#endif
#else /* ifndef MIXER */
#if NUM_USB_CHAN_OUT > 0
if(underflow)
{
for(int i = 0; i < NUM_USB_CHAN_OUT; i++)
{
samplesOut[i] = underflowWord;
}
}
else
{
#pragma loop unroll
for(int i = 0; i < NUM_USB_CHAN_OUT; i++)
{
int tmp = inuint(c_out);
samplesOut[i] = tmp;
}
}
for(int i = 0; i < NUM_USB_CHAN_OUT; i++)
{
int tmp = inuint(c_out);
samplesOut[i] = tmp;
}
#endif
#if NUM_USB_CHAN_IN > 0
#pragma loop unroll
for(int i = 0; i < I2S_CHANS_ADC; i++)
{
if(readBuffNo)
outuint(c_out, samplesIn_1[i]);
else
outuint(c_out, samplesIn_0[i]);
}
/* Send over the digi channels - no odd buffering required */
#pragma loop unroll
for(int i = I2S_CHANS_ADC; i < NUM_USB_CHAN_IN; i++)
{
for(int i = 0; i < I2S_CHANS_ADC; i++)
{
if(readBuffNo)
outuint(c_out, samplesIn_1[i]);
else
outuint(c_out, samplesIn_0[i]);
}
#endif
#endif
}
/* Send over the digi channels - no odd buffering required */
#pragma loop unroll
for(int i = I2S_CHANS_ADC; i < NUM_USB_CHAN_IN; i++)
{
outuint(c_out, samplesIn_0[i]);
}
#endif
#endif
}
return 0;
return 0;
}
@@ -453,9 +429,6 @@ unsigned static deliver(chanend c_out, chanend ?c_spd_out,
#if (I2S_CHANS_ADC != 0) || defined(SPDIF)
unsigned sample;
#endif
unsigned underflow = 0;
#if NUM_USB_CHAN_OUT > 0
#endif
//#if NUM_USB_CHAN_IN > 0
/* Since DAC and ADC buffered ports off by one sample we buffer previous ADC frame */

View File

@@ -201,9 +201,8 @@ static inline void GiveSamplesToHost(chanend c, xc_ptr ptr, xc_ptr multIn)
}
#pragma unsafe arrays
static inline void GetSamplesFromHost(chanend c, unsigned underflow)
static inline void GetSamplesFromHost(chanend c)
{
if(!underflow)
{
#pragma loop unroll
for (int i=0; i<NUM_USB_CHAN_OUT; i++)
@@ -245,11 +244,8 @@ static inline void GetSamplesFromHost(chanend c, unsigned underflow)
}
#pragma unsafe arrays
static inline void GiveSamplesToDevice(chanend c, xc_ptr ptr, xc_ptr multOut, unsigned underflow)
static inline void GiveSamplesToDevice(chanend c, xc_ptr ptr, xc_ptr multOut)
{
outuint(c, underflow);
if(!underflow)
{
#pragma loop unroll
for (int i=0; i<NUM_USB_CHAN_OUT; i++)
@@ -354,17 +350,16 @@ static void mixer1(chanend c_host, chanend c_mix_ctl, chanend c_mixer2)
int mixed;
#endif
unsigned cmd;
unsigned underflow = 1;
unsigned request = 0;
while (1)
{
#pragma xta endpoint "mixer1_req"
/* Request from audio() */
inuint(c_mixer2);
/* Request from audio()/mixer2() */
request = inuint(c_mixer2);
/* Request data from decouple thread */
outuint(c_host, 0);
/* Forward on Request for data to decouple thread */
outuint(c_host, request);
/* Between request to decouple and respose ~ 400nS latency for interrupt to fire */
select
@@ -536,14 +531,14 @@ static void mixer1(chanend c_host, chanend c_mix_ctl, chanend c_mixer2)
}
else
{
underflow = inuint(c_host);
inuint(c_host);
#if MAX_MIX_COUNT > 0
outuint(c_mixer2, underflow);
outuint(c_mixer2, 0);
GiveSamplesToHost(c_host, samples_to_host_map, multIn);
outuint(c_mixer2, 0);
inuint(c_mixer2);
GetSamplesFromHost(c_host, underflow);
GetSamplesFromHost(c_host);
outuint(c_mixer2, 0);
inuint(c_mixer2);
#ifdef FAST_MIXER
@@ -603,10 +598,10 @@ static void mixer1(chanend c_host, chanend c_mix_ctl, chanend c_mixer2)
}
#else /* IF MAX_MIX_COUNT > 0 */
/* No mixes, this thread runs on its own doing just volume */
GiveSamplesToDevice(c_mixer2, samples_to_device_map, multOut, underflow);
GiveSamplesToDevice(c_mixer2, samples_to_device_map, multOut);
GetSamplesFromDevice(c_mixer2);
GiveSamplesToHost(c_host, samples_to_host_map, multIn);
GetSamplesFromHost(c_host, underflow);
GetSamplesFromHost(c_host);
#endif
}
}
@@ -619,13 +614,16 @@ static int mixer2_mix2_flag = (DEFAULT_FREQ > 96000);
static void mixer2(chanend c_mixer1, chanend c_audio)
{
int mixed;
unsigned underflow = 0;
unsigned request;
while (1)
{
outuint(c_mixer1, 0);
#pragma xta endpoint "mixer2_req"
inuint(c_audio);
request = inuint(c_audio);
/* Forward the request on */
outuint(c_mixer1, request);
if(testct(c_mixer1))
{
int sampFreq;
@@ -670,8 +668,8 @@ static void mixer2(chanend c_mixer1, chanend c_audio)
}
else
{
underflow = inuint(c_mixer1);
GiveSamplesToDevice(c_audio, samples_to_device_map, multOut, underflow);
(void) inuint(c_mixer1);
GiveSamplesToDevice(c_audio, samples_to_device_map, multOut);
inuint(c_mixer1);
outuint(c_mixer1, 0);
GetSamplesFromDevice(c_audio);

View File

@@ -129,10 +129,9 @@ void handle_audio_request(chanend c_mix_out)
int space_left;
/* Input word that triggered interrupt and handshake back */
(void) inuint(c_mix_out);
/* Reply with underflow */
outuint(c_mix_out, outUnderflow);
unsigned underflowSample = inuint(c_mix_out);
outuint(c_mix_out, 0);
/* If in overflow condition then receive samples and throw away */
if(inOverflow || sampsToWrite == 0)
@@ -290,21 +289,11 @@ __builtin_unreachable();
if(outUnderflow)
{
#pragma xta endpoint "out_underflow"
#if 0
/* We're still pre-buffering, send out 0 samps */
for(int i = 0; i < NUM_USB_CHAN_OUT; i++)
{
unsigned sample;
unsigned mode;
GET_SHARED_GLOBAL(sample, g_muteSample);
GET_SHARED_GLOBAL(mode, dsdMode);
if(mode == DSD_MODE_DOP)
outuint(c_mix_out, 0xFA969600);
else
outuint(c_mix_out, sample);
outuint(c_mix_out, underflowSample);
}
#endif
/* Calc how many samples left in buffer */
outSamps = g_aud_from_host_wrptr - g_aud_from_host_rdptr;