This commit is contained in:
Ross Owen
2015-09-17 17:11:07 +01:00
13 changed files with 336 additions and 264 deletions

View File

@@ -131,161 +131,9 @@ void handle_audio_request(chanend c_mix_out)
/* Input word that triggered interrupt and handshake back */
unsigned underflowSample = inuint(c_mix_out);
#if (NUM_USB_CHAN_OUT == 0)
outuint(c_mix_out, 0);
/* If in overflow condition then receive samples and throw away */
if(inOverflow || sampsToWrite == 0)
{
#pragma loop unroll
for(int i = 0; i < NUM_USB_CHAN_IN; i++)
{
(void) inuint(c_mix_out);
}
/* Calculate how much space left in buffer */
space_left = g_aud_to_host_rdptr - g_aud_to_host_wrptr;
if (space_left <= 0)
{
space_left += BUFF_SIZE_IN*4;
}
/* Check if we can come out of overflow */
if (space_left > (BUFF_SIZE_IN*4/2))
{
inOverflow = 0;
}
}
else
{
/* Not in overflow, store samples from mixer into sample buffer */
switch(g_curSubSlot_In)
{
case 2:
#if (STREAM_FORMAT_INPUT_SUBSLOT_2_USED == 0)
__builtin_unreachable();
#endif
for(int i = 0; i < g_numUsbChan_In; i++)
{
/* Receive sample */
int sample = inuint(c_mix_out);
#if (INPUT_VOLUME_CONTROL == 1)
#if !defined(IN_VOLUME_IN_MIXER)
/* Apply volume */
int mult;
int h;
unsigned l;
asm volatile("ldw %0, %1[%2]":"=r"(mult):"r"(p_multIn),"r"(i));
{h, l} = macs(mult, sample, 0, 0);
sample = h << 3;
/* Note, in 2 byte sub slot - ignore lower bits of macs */
#elif defined(IN_VOLUME_IN_MIXER) && defined(IN_VOLUME_AFTER_MIX)
sample = sample << 3;
#endif
#endif
write_short_via_xc_ptr(g_aud_to_host_dptr, sample>>16);
g_aud_to_host_dptr+=2;
}
break;
case 4:
{
#if (STREAM_FORMAT_INPUT_SUBSLOT_4_USED == 0)
__builtin_unreachable();
#endif
unsigned ptr = g_aud_to_host_dptr;
for(int i = 0; i < g_numUsbChan_In; i++)
{
/* Receive sample */
int sample = inuint(c_mix_out);
#if(INPUT_VOLUME_CONTROL == 1)
#if !defined(IN_VOLUME_IN_MIXER)
/* Apply volume */
int mult;
int h;
unsigned l;
asm volatile("ldw %0, %1[%2]":"=r"(mult):"r"(p_multIn),"r"(i));
{h, l} = macs(mult, sample, 0, 0);
sample = h << 3;
#if (STREAM_FORMAT_INPUT_RESOLUTION_32BIT_USED == 1)
sample |= (l >> 29) & 0x7; // Note, this step is not required if we assume sample depth is 24 (rather than 32)
#endif
#elif defined(IN_VOLUME_IN_MIXER) && defined(IN_VOLUME_AFTER_MIX)
sample = sample << 3;
#endif
#endif
/* Write into fifo */
write_via_xc_ptr(ptr, sample);
ptr+=4;
}
/* Update global pointer */
g_aud_to_host_dptr = ptr;
break;
}
case 3:
#if (STREAM_FORMAT_INPUT_SUBSLOT_3_USED == 0)
__builtin_unreachable();
#endif
for(int i = 0; i < g_numUsbChan_In; i++)
{
/* Receive sample */
int sample = inuint(c_mix_out);
#if (INPUT_VOLUME_CONTROL) && !defined(IN_VOLUME_IN_MIXER)
/* Apply volume */
int mult;
int h;
unsigned l;
asm volatile("ldw %0, %1[%2]":"=r"(mult):"r"(p_multIn),"r"(i));
{h, l} = macs(mult, sample, 0, 0);
sample = h << 3;
#endif
/* Pack 3 byte samples */
switch (packState&0x3)
{
case 0:
packData = sample;
break;
case 1:
packData = (packData >> 8) | ((sample & 0xff00)<<16);
write_via_xc_ptr(g_aud_to_host_dptr, packData);
g_aud_to_host_dptr+=4;
write_via_xc_ptr(g_aud_to_host_dptr, sample>>16);
packData = sample;
break;
case 2:
packData = (packData>>16) | ((sample & 0xffff00) << 8);
write_via_xc_ptr(g_aud_to_host_dptr, packData);
g_aud_to_host_dptr+=4;
packData = sample;
break;
case 3:
packData = (packData >> 24) | (sample & 0xffffff00);
write_via_xc_ptr(g_aud_to_host_dptr, packData);
g_aud_to_host_dptr+=4;
break;
}
packState++;
}
break;
default:
__builtin_unreachable();
break;
}
/* Input any remaining channels - past this thread we always operate on max channel count */
for(int i = 0; i < NUM_USB_CHAN_IN - g_numUsbChan_In; i++)
{
inuint(c_mix_out);
}
sampsToWrite--;
}
#else
if(outUnderflow)
{
#pragma xta endpoint "out_underflow"
@@ -443,6 +291,164 @@ __builtin_unreachable();
aud_data_remaining_to_device -= (g_numUsbChan_Out * g_curSubSlot_Out);
}
#endif
/* If in overflow condition then receive samples and throw away */
if(inOverflow || sampsToWrite == 0)
{
#pragma loop unroll
for(int i = 0; i < NUM_USB_CHAN_IN; i++)
{
(void) inuint(c_mix_out);
}
/* Calculate how much space left in buffer */
space_left = g_aud_to_host_rdptr - g_aud_to_host_wrptr;
if (space_left <= 0)
{
space_left += BUFF_SIZE_IN*4;
}
/* Check if we can come out of overflow */
if (space_left > (BUFF_SIZE_IN*4/2))
{
inOverflow = 0;
}
}
else
{
/* Not in overflow, store samples from mixer into sample buffer */
switch(g_curSubSlot_In)
{
case 2:
#if (STREAM_FORMAT_INPUT_SUBSLOT_2_USED == 0)
__builtin_unreachable();
#endif
for(int i = 0; i < g_numUsbChan_In; i++)
{
/* Receive sample */
int sample = inuint(c_mix_out);
#if (INPUT_VOLUME_CONTROL == 1)
#if !defined(IN_VOLUME_IN_MIXER)
/* Apply volume */
int mult;
int h;
unsigned l;
asm volatile("ldw %0, %1[%2]":"=r"(mult):"r"(p_multIn),"r"(i));
{h, l} = macs(mult, sample, 0, 0);
sample = h << 3;
/* Note, in 2 byte sub slot - ignore lower bits of macs */
#elif defined(IN_VOLUME_IN_MIXER) && defined(IN_VOLUME_AFTER_MIX)
sample = sample << 3;
#endif
#endif
write_short_via_xc_ptr(g_aud_to_host_dptr, sample>>16);
g_aud_to_host_dptr+=2;
}
break;
case 4:
{
#if (STREAM_FORMAT_INPUT_SUBSLOT_4_USED == 0)
__builtin_unreachable();
#endif
unsigned ptr = g_aud_to_host_dptr;
for(int i = 0; i < g_numUsbChan_In; i++)
{
/* Receive sample */
int sample = inuint(c_mix_out);
#if(INPUT_VOLUME_CONTROL == 1)
#if !defined(IN_VOLUME_IN_MIXER)
/* Apply volume */
int mult;
int h;
unsigned l;
asm volatile("ldw %0, %1[%2]":"=r"(mult):"r"(p_multIn),"r"(i));
{h, l} = macs(mult, sample, 0, 0);
sample = h << 3;
#if (STREAM_FORMAT_INPUT_RESOLUTION_32BIT_USED == 1)
sample |= (l >> 29) & 0x7; // Note, this step is not required if we assume sample depth is 24 (rather than 32)
#endif
#elif defined(IN_VOLUME_IN_MIXER) && defined(IN_VOLUME_AFTER_MIX)
sample = sample << 3;
#endif
#endif
/* Write into fifo */
write_via_xc_ptr(ptr, sample);
ptr+=4;
}
/* Update global pointer */
g_aud_to_host_dptr = ptr;
break;
}
case 3:
#if (STREAM_FORMAT_INPUT_SUBSLOT_3_USED == 0)
__builtin_unreachable();
#endif
for(int i = 0; i < g_numUsbChan_In; i++)
{
/* Receive sample */
int sample = inuint(c_mix_out);
#if (INPUT_VOLUME_CONTROL) && !defined(IN_VOLUME_IN_MIXER)
/* Apply volume */
int mult;
int h;
unsigned l;
asm volatile("ldw %0, %1[%2]":"=r"(mult):"r"(p_multIn),"r"(i));
{h, l} = macs(mult, sample, 0, 0);
sample = h << 3;
#endif
/* Pack 3 byte samples */
switch (packState&0x3)
{
case 0:
packData = sample;
break;
case 1:
packData = (packData >> 8) | ((sample & 0xff00)<<16);
write_via_xc_ptr(g_aud_to_host_dptr, packData);
g_aud_to_host_dptr+=4;
write_via_xc_ptr(g_aud_to_host_dptr, sample>>16);
packData = sample;
break;
case 2:
packData = (packData>>16) | ((sample & 0xffff00) << 8);
write_via_xc_ptr(g_aud_to_host_dptr, packData);
g_aud_to_host_dptr+=4;
packData = sample;
break;
case 3:
packData = (packData >> 24) | (sample & 0xffffff00);
write_via_xc_ptr(g_aud_to_host_dptr, packData);
g_aud_to_host_dptr+=4;
break;
}
packState++;
}
break;
default:
__builtin_unreachable();
break;
}
/* Input any remaining channels - past this thread we always operate on max channel count */
for(int i = 0; i < NUM_USB_CHAN_IN - g_numUsbChan_In; i++)
{
inuint(c_mix_out);
}
sampsToWrite--;
}
if (!inOverflow)
{
if (sampsToWrite == 0)

View File

@@ -21,7 +21,9 @@
void buffer(chanend c_aud_out,
chanend c_aud_in,
#if (NUM_USB_CHAN_IN == 0) || defined (UAC_FORCE_FEEDBACK_EP)
chanend c_aud_fb,
#endif
#ifdef MIDI
chanend c_midi_from_host,
chanend c_midi_to_host,

View File

@@ -94,7 +94,10 @@ unsigned char fb_clocks[16];
* @param c_aud_fb chanend for feeback to xud
* @return void
*/
void buffer(register chanend c_aud_out, register chanend c_aud_in, chanend c_aud_fb,
void buffer(register chanend c_aud_out, register chanend c_aud_in,
#if (NUM_USB_CHAN_IN == 0) || defined (UAC_FORCE_FEEDBACK_EP)
chanend c_aud_fb,
#endif
#ifdef MIDI
chanend c_midi_from_host,
chanend c_midi_to_host,
@@ -131,7 +134,9 @@ void buffer(register chanend c_aud_out, register chanend c_aud_in, chanend c_aud
{
XUD_ep ep_aud_out = XUD_InitEp(c_aud_out);
XUD_ep ep_aud_in = XUD_InitEp(c_aud_in);
#if (NUM_USB_CHAN_IN == 0) || defined (UAC_FORCE_FEEDBACK_EP)
XUD_ep ep_aud_fb = XUD_InitEp(c_aud_fb);
#endif
#ifdef MIDI
XUD_ep ep_midi_from_host = XUD_InitEp(c_midi_from_host);
XUD_ep ep_midi_to_host = XUD_InitEp(c_midi_to_host);
@@ -348,6 +353,7 @@ void buffer(register chanend c_aud_out, register chanend c_aud_in, chanend c_aud
SET_SHARED_GLOBAL(g_formatChange_DataFormat, formatChange_DataFormat);
SET_SHARED_GLOBAL(g_formatChange_SampRes, formatChange_SampRes);
#if (NUM_USB_CHAN_IN == 0) || defined(UAC_FORCE_FEEDBACK_EP)
/* Host is starting up the output stream. Setup (or potentially resize) feedback packet based on bus-speed
* This is only really important on inital start up (when bus-speed
was unknown) and when changing bus-speeds */
@@ -361,7 +367,7 @@ void buffer(register chanend c_aud_out, register chanend c_aud_in, chanend c_aud
{
XUD_SetReady_In(ep_aud_fb, fb_clocks, 3);
}
#endif
}
/* Pass on sample freq change to decouple() via global flag (saves a chanend) */
/* Note: freqChange flags now used to communicate other commands also */
@@ -464,6 +470,7 @@ void buffer(register chanend c_aud_out, register chanend c_aud_in, chanend c_aud
#endif
#if (NUM_USB_CHAN_OUT > 0)
#if (NUM_USB_CHAN_IN == 0) || defined(UAC_FORCE_FEEDBACK_EP)
/* Feedback Pipe */
case XUD_SetData_Select(c_aud_fb, ep_aud_fb, result):
{
@@ -481,7 +488,7 @@ void buffer(register chanend c_aud_out, register chanend c_aud_in, chanend c_aud
}
}
break;
#endif
/* Received Audio packet HOST -> DEVICE. Datalength written to length */
case XUD_GetData_Select(c_aud_out, ep_aud_out, length, result):
{