Merge
This commit is contained in:
@@ -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)
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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):
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user