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) static inline unsigned DoSampleTransfer(chanend c_out, int readBuffNo, unsigned underflowWord)
{ {
unsigned command; 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*/ /* Check for sample freq change (or other command) or new samples from mixer*/
if(testct(c_out)) if(testct(c_out))
{ {
unsigned command = inct(c_out); unsigned command = inct(c_out);
#ifndef CODEC_MASTER #ifndef CODEC_MASTER
// Set clocks low // Set clocks low
p_lrclk <: 0; p_lrclk <: 0;
p_bclk <: 0; p_bclk <: 0;
#if(DSD_CHANS_DAC != 0) #if(DSD_CHANS_DAC != 0)
/* DSD Clock might not be shared with lrclk or bclk... */ /* DSD Clock might not be shared with lrclk or bclk... */
p_dsd_clk <: 0; p_dsd_clk <: 0;
#endif #endif
#endif #endif
#if (DSD_CHANS_DAC > 0) #if (DSD_CHANS_DAC > 0)
if(dsdMode == DSD_MODE_DOP) if(dsdMode == DSD_MODE_DOP)
dsdMode = DSD_MODE_OFF; dsdMode = DSD_MODE_OFF;
#endif #endif
#pragma xta endpoint "received_command" #pragma xta endpoint "received_command"
return command; return command;
}
} else
else {
{
underflow = inuint(c_out);
#ifndef MIXER // Interfaces straight to decouple() #ifndef MIXER // Interfaces straight to decouple()
#if NUM_USB_CHAN_IN > 0 #if NUM_USB_CHAN_IN > 0
#pragma loop unroll #pragma loop unroll
for(int i = 0; i < I2S_CHANS_ADC; i++) for(int i = 0; i < I2S_CHANS_ADC; i++)
{ {
if(readBuffNo) if(readBuffNo)
outuint(c_out, samplesIn_1[i]); outuint(c_out, samplesIn_1[i]);
else 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]); 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 #endif
#if NUM_USB_CHAN_OUT > 0 #if NUM_USB_CHAN_OUT > 0
if(underflow)
{
#pragma loop unroll #pragma loop unroll
for(int i = 0; i < NUM_USB_CHAN_OUT; i++) for(int i = 0; i < NUM_USB_CHAN_OUT; i++)
{ {
samplesOut[i] = underflowWord; samplesOut[i] = inuint(c_out);
} }
}
else
{
#pragma loop unroll
for(int i = 0; i < NUM_USB_CHAN_OUT; i++)
{
samplesOut[i] = inuint(c_out);
}
}
#endif #endif
#else /* ifndef MIXER */ #else /* ifndef MIXER */
#if NUM_USB_CHAN_OUT > 0 #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 #pragma loop unroll
for(int i = 0; i < NUM_USB_CHAN_OUT; i++) for(int i = 0; i < NUM_USB_CHAN_OUT; i++)
{ {
int tmp = inuint(c_out); int tmp = inuint(c_out);
samplesOut[i] = tmp; samplesOut[i] = tmp;
} }
}
#endif #endif
#if NUM_USB_CHAN_IN > 0 #if NUM_USB_CHAN_IN > 0
#pragma loop unroll #pragma loop unroll
for(int i = 0; i < I2S_CHANS_ADC; i++) for(int i = 0; i < I2S_CHANS_ADC; i++)
{ {
if(readBuffNo) if(readBuffNo)
outuint(c_out, samplesIn_1[i]); outuint(c_out, samplesIn_1[i]);
else 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]); 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) #if (I2S_CHANS_ADC != 0) || defined(SPDIF)
unsigned sample; unsigned sample;
#endif
unsigned underflow = 0;
#if NUM_USB_CHAN_OUT > 0
#endif #endif
//#if NUM_USB_CHAN_IN > 0 //#if NUM_USB_CHAN_IN > 0
/* Since DAC and ADC buffered ports off by one sample we buffer previous ADC frame */ /* 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 #pragma unsafe arrays
static inline void GetSamplesFromHost(chanend c, unsigned underflow) static inline void GetSamplesFromHost(chanend c)
{ {
if(!underflow)
{ {
#pragma loop unroll #pragma loop unroll
for (int i=0; i<NUM_USB_CHAN_OUT; i++) 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 #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 #pragma loop unroll
for (int i=0; i<NUM_USB_CHAN_OUT; i++) 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; int mixed;
#endif #endif
unsigned cmd; unsigned cmd;
unsigned request = 0;
unsigned underflow = 1;
while (1) while (1)
{ {
#pragma xta endpoint "mixer1_req" #pragma xta endpoint "mixer1_req"
/* Request from audio() */ /* Request from audio()/mixer2() */
inuint(c_mixer2); request = inuint(c_mixer2);
/* Request data from decouple thread */ /* Forward on Request for data to decouple thread */
outuint(c_host, 0); outuint(c_host, request);
/* Between request to decouple and respose ~ 400nS latency for interrupt to fire */ /* Between request to decouple and respose ~ 400nS latency for interrupt to fire */
select select
@@ -536,14 +531,14 @@ static void mixer1(chanend c_host, chanend c_mix_ctl, chanend c_mixer2)
} }
else else
{ {
underflow = inuint(c_host); inuint(c_host);
#if MAX_MIX_COUNT > 0 #if MAX_MIX_COUNT > 0
outuint(c_mixer2, underflow); outuint(c_mixer2, 0);
GiveSamplesToHost(c_host, samples_to_host_map, multIn); GiveSamplesToHost(c_host, samples_to_host_map, multIn);
outuint(c_mixer2, 0); outuint(c_mixer2, 0);
inuint(c_mixer2); inuint(c_mixer2);
GetSamplesFromHost(c_host, underflow); GetSamplesFromHost(c_host);
outuint(c_mixer2, 0); outuint(c_mixer2, 0);
inuint(c_mixer2); inuint(c_mixer2);
#ifdef FAST_MIXER #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 */ #else /* IF MAX_MIX_COUNT > 0 */
/* No mixes, this thread runs on its own doing just volume */ /* 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); GetSamplesFromDevice(c_mixer2);
GiveSamplesToHost(c_host, samples_to_host_map, multIn); GiveSamplesToHost(c_host, samples_to_host_map, multIn);
GetSamplesFromHost(c_host, underflow); GetSamplesFromHost(c_host);
#endif #endif
} }
} }
@@ -619,13 +614,16 @@ static int mixer2_mix2_flag = (DEFAULT_FREQ > 96000);
static void mixer2(chanend c_mixer1, chanend c_audio) static void mixer2(chanend c_mixer1, chanend c_audio)
{ {
int mixed; int mixed;
unsigned underflow = 0; unsigned request;
while (1) while (1)
{ {
outuint(c_mixer1, 0);
#pragma xta endpoint "mixer2_req" #pragma xta endpoint "mixer2_req"
inuint(c_audio); request = inuint(c_audio);
/* Forward the request on */
outuint(c_mixer1, request);
if(testct(c_mixer1)) if(testct(c_mixer1))
{ {
int sampFreq; int sampFreq;
@@ -670,8 +668,8 @@ static void mixer2(chanend c_mixer1, chanend c_audio)
} }
else else
{ {
underflow = inuint(c_mixer1); (void) inuint(c_mixer1);
GiveSamplesToDevice(c_audio, samples_to_device_map, multOut, underflow); GiveSamplesToDevice(c_audio, samples_to_device_map, multOut);
inuint(c_mixer1); inuint(c_mixer1);
outuint(c_mixer1, 0); outuint(c_mixer1, 0);
GetSamplesFromDevice(c_audio); GetSamplesFromDevice(c_audio);

View File

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