forked from PAWPAW-Mirror/lib_xua
Output FIFO - sounds great!
This commit is contained in:
72
examples/xua_lite_example/src/fifo_impl.h
Normal file
72
examples/xua_lite_example/src/fifo_impl.h
Normal file
@@ -0,0 +1,72 @@
|
|||||||
|
#ifndef __FIFO__
|
||||||
|
#define __FIFO__
|
||||||
|
#include <string.h> //memcpy
|
||||||
|
#include "fifo_types.h"
|
||||||
|
|
||||||
|
//Asynch FIFO implementaion
|
||||||
|
//Note these are in the include file to allow the compiler to inline for performance
|
||||||
|
|
||||||
|
///////////////////////////////////////
|
||||||
|
//Shared memory FIFO (sample by sample)
|
||||||
|
//Can be any size
|
||||||
|
///////////////////////////////////////
|
||||||
|
|
||||||
|
|
||||||
|
static inline unsigned fifo_get_fill(volatile mem_fifo_t * unsafe fifo) {
|
||||||
|
unsafe{
|
||||||
|
unsigned fifo_fill = 0;
|
||||||
|
if (fifo->write_idx >= fifo->read_idx){
|
||||||
|
fifo_fill = fifo->write_idx - fifo->read_idx;
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
fifo_fill = (fifo->size + fifo->write_idx) - fifo->read_idx;
|
||||||
|
}
|
||||||
|
return fifo_fill;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#pragma unsafe arrays
|
||||||
|
static inline fifo_ret_t fifo_block_push(volatile mem_fifo_t * unsafe fifo, int data[], unsigned n) {
|
||||||
|
unsafe{
|
||||||
|
//check there is a block of space large enough
|
||||||
|
unsigned space_remaining = fifo->size - fifo_get_fill(fifo) - 1;
|
||||||
|
if (n > space_remaining) {
|
||||||
|
return FIFO_FULL;
|
||||||
|
}
|
||||||
|
for (int i = 0; i < n; i++){
|
||||||
|
unsigned next_idx = fifo->write_idx + 1;
|
||||||
|
if (next_idx == fifo->size) next_idx = 0; //Check for wrap
|
||||||
|
fifo->data_base_ptr[fifo->write_idx] = data[i];
|
||||||
|
fifo->write_idx = next_idx;
|
||||||
|
}
|
||||||
|
return FIFO_SUCCESS;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#pragma unsafe arrays
|
||||||
|
static inline fifo_ret_t fifo_block_pop(volatile mem_fifo_t * unsafe fifo, int data[], unsigned n) {
|
||||||
|
unsafe{
|
||||||
|
//Check we have a block big enough to send
|
||||||
|
if (n > fifo_get_fill(fifo)){
|
||||||
|
return FIFO_EMPTY;
|
||||||
|
}
|
||||||
|
for (int i = 0; i < n; i++){
|
||||||
|
data[i] = fifo->data_base_ptr[fifo->read_idx];
|
||||||
|
fifo->read_idx++;
|
||||||
|
if (fifo->read_idx == fifo->size) fifo->read_idx = 0; //Check for wrap
|
||||||
|
}
|
||||||
|
return FIFO_SUCCESS;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//Version of above that returns fill level relative to half full
|
||||||
|
static inline int fifo_get_fill_relative_half(volatile mem_fifo_t * unsafe fifo){
|
||||||
|
unsafe{
|
||||||
|
int fifo_fill = (int)fifo_get_fill(fifo);
|
||||||
|
fifo_fill -= (fifo->size / 2);
|
||||||
|
return fifo_fill;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
30
examples/xua_lite_example/src/fifo_types.h
Normal file
30
examples/xua_lite_example/src/fifo_types.h
Normal file
@@ -0,0 +1,30 @@
|
|||||||
|
#ifndef __ASRC_FIFO_TYPES__
|
||||||
|
#define __ASRC_FIFO_TYPES__
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
//Shared FIFO return types
|
||||||
|
typedef enum fifo_ret_t {
|
||||||
|
FIFO_SUCCESS = 0,
|
||||||
|
FIFO_FULL,
|
||||||
|
FIFO_EMPTY
|
||||||
|
} fifo_ret_t;
|
||||||
|
|
||||||
|
/////////////////////////////////////////////////////////////////////////
|
||||||
|
//Shared memory FIFO (sample by sample or block)
|
||||||
|
//Can be any size
|
||||||
|
//
|
||||||
|
//Note that the actual storage for the FIFO is declared externally
|
||||||
|
//and a reference to the base address of the storage is passed in along
|
||||||
|
//with the size of the storage. This way, multiple instances may be
|
||||||
|
//different sizes.
|
||||||
|
//
|
||||||
|
/////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
typedef struct mem_fifo_t {
|
||||||
|
const unsigned size; //Size in INTs
|
||||||
|
int * const unsafe data_base_ptr; //Base of the data array - declared externally so we can have differnt sized FIFOs
|
||||||
|
unsigned write_idx;
|
||||||
|
unsigned read_idx;
|
||||||
|
} mem_fifo_t;
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -9,7 +9,7 @@
|
|||||||
#define DEBUG_PRINT_ENABLE_XUA_LITE_BUFFER 1
|
#define DEBUG_PRINT_ENABLE_XUA_LITE_BUFFER 1
|
||||||
#include "debug_print.h"
|
#include "debug_print.h"
|
||||||
#include "xua.h"
|
#include "xua.h"
|
||||||
//#include "fifo_impl.h" //xua_conf.h must be included before hand so that we have FIFO sizes
|
#include "fifo_impl.h"
|
||||||
|
|
||||||
//Currently only single frequency supported
|
//Currently only single frequency supported
|
||||||
#define NOMINAL_SR_DEVICE DEFAULT_FREQ
|
#define NOMINAL_SR_DEVICE DEFAULT_FREQ
|
||||||
@@ -93,7 +93,7 @@ static inline void pack_samples_to_buff(int input[], const unsigned n_samples, c
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void XUA_Buffer_lite(chanend c_aud_out, chanend c_feedback, chanend c_aud_in, chanend c_sof, chanend c_aud_ctl, in port p_for_mclk_count, chanend c_audio_hub){
|
void XUA_Buffer_lite(chanend c_aud_out, chanend c_feedback, chanend c_aud_in, chanend c_sof, chanend c_aud_ctl, in port p_for_mclk_count, chanend c_audio_hub) {
|
||||||
|
|
||||||
debug_printf("%d\n", MAX_OUT_SAMPLES_PER_SOF_PERIOD);
|
debug_printf("%d\n", MAX_OUT_SAMPLES_PER_SOF_PERIOD);
|
||||||
|
|
||||||
@@ -134,167 +134,177 @@ void XUA_Buffer_lite(chanend c_aud_out, chanend c_feedback, chanend c_aud_in, ch
|
|||||||
XUD_SetReady_InPtr(ep_aud_in, (unsigned)buffer_aud_in, num_samples_to_send_to_host);
|
XUD_SetReady_InPtr(ep_aud_in, (unsigned)buffer_aud_in, num_samples_to_send_to_host);
|
||||||
XUD_SetReady_InPtr(ep_feedback, (unsigned)buffer_feedback, FEEDBACK_BUFF_SIZE);
|
XUD_SetReady_InPtr(ep_feedback, (unsigned)buffer_feedback, FEEDBACK_BUFF_SIZE);
|
||||||
|
|
||||||
// printintln(OUT_AUDIO_BUFFER_SIZE_BYTES);
|
|
||||||
// printintln(MAX_OUT_SAMPLES_PER_SOF_PERIOD);
|
|
||||||
|
|
||||||
int loopback_samples[MAX_OUT_SAMPLES_PER_SOF_PERIOD] = {0};
|
int loopback_samples[MAX_OUT_SAMPLES_PER_SOF_PERIOD] = {0};
|
||||||
int32_t samples_out[NUM_USB_CHAN_OUT] = {0};
|
int32_t samples_out[NUM_USB_CHAN_OUT] = {0};
|
||||||
int32_t samples_in[NUM_USB_CHAN_IN] = {0};
|
int32_t samples_in[NUM_USB_CHAN_IN] = {0};
|
||||||
|
|
||||||
while(1){
|
unsafe{
|
||||||
|
|
||||||
|
int host_to_device_fifo_storage[MAX_OUT_SAMPLES_PER_SOF_PERIOD * 2];
|
||||||
|
mem_fifo_t host_to_device_fifo = {sizeof(host_to_device_fifo_storage)/sizeof(host_to_device_fifo_storage[0])
|
||||||
|
, host_to_device_fifo_storage, 0, 0};
|
||||||
|
volatile mem_fifo_t * unsafe host_to_device_fifo_ptr = &host_to_device_fifo;
|
||||||
|
|
||||||
XUD_Result_t result;
|
XUD_Result_t result;
|
||||||
unsigned length = 0;
|
unsigned length = 0;
|
||||||
|
|
||||||
|
while(1){
|
||||||
|
select{
|
||||||
|
//Handle control path from EP0
|
||||||
|
case testct_byref(c_aud_ctl, tmp):
|
||||||
|
//ignore tmp as is used for reboot signalling only
|
||||||
|
unsigned cmd = inuint(c_aud_ctl);
|
||||||
|
|
||||||
|
debug_printf("c_aud_ctl cmd: %d\n", cmd);
|
||||||
|
if(cmd == SET_SAMPLE_FREQ){
|
||||||
|
unsigned receivedSampleFreq = inuint(c_aud_ctl);
|
||||||
|
debug_printf("SET_SAMPLE_FREQ: %d\n", receivedSampleFreq);
|
||||||
|
sampleFreq = receivedSampleFreq;
|
||||||
|
}
|
||||||
|
|
||||||
select{
|
else if(cmd == SET_STREAM_FORMAT_IN){
|
||||||
//Handle control path from EP0
|
|
||||||
case testct_byref(c_aud_ctl, tmp):
|
|
||||||
//ignore tmp as is used for reboot signalling only
|
|
||||||
unsigned cmd = inuint(c_aud_ctl);
|
|
||||||
|
|
||||||
debug_printf("c_aud_ctl cmd: %d\n", cmd);
|
|
||||||
if(cmd == SET_SAMPLE_FREQ){
|
|
||||||
unsigned receivedSampleFreq = inuint(c_aud_ctl);
|
|
||||||
debug_printf("SET_SAMPLE_FREQ: %d\n", receivedSampleFreq);
|
|
||||||
sampleFreq = receivedSampleFreq;
|
|
||||||
}
|
|
||||||
|
|
||||||
else if(cmd == SET_STREAM_FORMAT_IN){
|
|
||||||
unsigned formatChange_DataFormat = inuint(c_aud_ctl);
|
|
||||||
unsigned formatChange_NumChans = inuint(c_aud_ctl);
|
|
||||||
unsigned formatChange_SubSlot = inuint(c_aud_ctl);
|
|
||||||
unsigned formatChange_SampRes = inuint(c_aud_ctl);
|
|
||||||
debug_printf("SET_STREAM_FORMAT_IN: %d %d %d %d\n", formatChange_DataFormat, formatChange_NumChans, formatChange_SubSlot, formatChange_SampRes);
|
|
||||||
in_subslot_size = formatChange_SubSlot;
|
|
||||||
in_num_chan = formatChange_NumChans;
|
|
||||||
}
|
|
||||||
|
|
||||||
else if (cmd == SET_STREAM_FORMAT_OUT)
|
|
||||||
{
|
|
||||||
XUD_BusSpeed_t busSpeed;
|
|
||||||
unsigned formatChange_DataFormat = inuint(c_aud_ctl);
|
unsigned formatChange_DataFormat = inuint(c_aud_ctl);
|
||||||
unsigned formatChange_NumChans = inuint(c_aud_ctl);
|
unsigned formatChange_NumChans = inuint(c_aud_ctl);
|
||||||
unsigned formatChange_SubSlot = inuint(c_aud_ctl);
|
unsigned formatChange_SubSlot = inuint(c_aud_ctl);
|
||||||
unsigned formatChange_SampRes = inuint(c_aud_ctl);
|
unsigned formatChange_SampRes = inuint(c_aud_ctl);
|
||||||
debug_printf("SET_STREAM_FORMAT_OUT: %d %d %d %d\n", formatChange_DataFormat, formatChange_NumChans, formatChange_SubSlot, formatChange_SampRes);
|
debug_printf("SET_STREAM_FORMAT_IN: %d %d %d %d\n", formatChange_DataFormat, formatChange_NumChans, formatChange_SubSlot, formatChange_SampRes);
|
||||||
out_subslot_size = formatChange_SubSlot;
|
in_subslot_size = formatChange_SubSlot;
|
||||||
out_num_chan = formatChange_NumChans;
|
in_num_chan = formatChange_NumChans;
|
||||||
}
|
}
|
||||||
|
|
||||||
else{
|
else if (cmd == SET_STREAM_FORMAT_OUT)
|
||||||
debug_printf("Unhandled command\n");
|
{
|
||||||
}
|
XUD_BusSpeed_t busSpeed;
|
||||||
outct(c_aud_ctl, XS1_CT_END);
|
unsigned formatChange_DataFormat = inuint(c_aud_ctl);
|
||||||
break;
|
unsigned formatChange_NumChans = inuint(c_aud_ctl);
|
||||||
|
unsigned formatChange_SubSlot = inuint(c_aud_ctl);
|
||||||
|
unsigned formatChange_SampRes = inuint(c_aud_ctl);
|
||||||
|
debug_printf("SET_STREAM_FORMAT_OUT: %d %d %d %d\n", formatChange_DataFormat, formatChange_NumChans, formatChange_SubSlot, formatChange_SampRes);
|
||||||
|
out_subslot_size = formatChange_SubSlot;
|
||||||
|
out_num_chan = formatChange_NumChans;
|
||||||
|
}
|
||||||
|
|
||||||
//SOF
|
else{
|
||||||
case inuint_byref(c_sof, tmp):
|
debug_printf("Unhandled command\n");
|
||||||
unsigned mclk_port_count = 0;
|
}
|
||||||
asm volatile(" getts %0, res[%1]" : "=r" (mclk_port_count) : "r" (p_for_mclk_count));
|
outct(c_aud_ctl, XS1_CT_END);
|
||||||
|
break;
|
||||||
|
|
||||||
/* Assuming 48kHz from a 24.576 master clock (0.0407uS period)
|
//SOF
|
||||||
* MCLK ticks per SOF = 125uS / 0.0407 = 3072 MCLK ticks per SOF.
|
case inuint_byref(c_sof, tmp):
|
||||||
* expected Feedback is 48000/8000 = 6 samples. so 0x60000 in 16:16 format.
|
unsigned mclk_port_count = 0;
|
||||||
* Average over 128 SOFs - 128 x 3072 = 0x60000.
|
asm volatile(" getts %0, res[%1]" : "=r" (mclk_port_count) : "r" (p_for_mclk_count));
|
||||||
*/
|
|
||||||
|
|
||||||
unsigned long long feedbackMul = 64ULL;
|
/* Assuming 48kHz from a 24.576 master clock (0.0407uS period)
|
||||||
if(AUDIO_CLASS == 1)
|
* MCLK ticks per SOF = 125uS / 0.0407 = 3072 MCLK ticks per SOF.
|
||||||
feedbackMul = 8ULL; /* TODO Use 4 instead of 8 to avoid windows LSB issues? */
|
* expected Feedback is 48000/8000 = 6 samples. so 0x60000 in 16:16 format.
|
||||||
|
* Average over 128 SOFs - 128 x 3072 = 0x60000.
|
||||||
|
*/
|
||||||
|
|
||||||
/* Number of MCLK ticks in this SOF period (E.g = 125 * 24.576 = 3072) */
|
unsigned long long feedbackMul = 64ULL;
|
||||||
int count = (int) ((short)(mclk_port_count - lastClock));
|
if(AUDIO_CLASS == 1)
|
||||||
|
feedbackMul = 8ULL; /* TODO Use 4 instead of 8 to avoid windows LSB issues? */
|
||||||
|
|
||||||
unsigned long long full_result = count * feedbackMul * DEFAULT_FREQ;
|
/* Number of MCLK ticks in this SOF period (E.g = 125 * 24.576 = 3072) */
|
||||||
|
int count = (int) ((short)(mclk_port_count - lastClock));
|
||||||
|
|
||||||
clockcounter += full_result;
|
unsigned long long full_result = count * feedbackMul * DEFAULT_FREQ;
|
||||||
|
|
||||||
/* Store MCLK for next time around... */
|
clockcounter += full_result;
|
||||||
lastClock = mclk_port_count;
|
|
||||||
|
|
||||||
/* Reset counts based on SOF counting. Expect 16ms (128 HS SOFs/16 FS SOFS) per feedback poll
|
/* Store MCLK for next time around... */
|
||||||
* We always count 128 SOFs, so 16ms @ HS, 128ms @ FS */
|
lastClock = mclk_port_count;
|
||||||
if(sof_count == 128)
|
|
||||||
{
|
|
||||||
debug_printf("fb\n");
|
|
||||||
sof_count = 0;
|
|
||||||
|
|
||||||
clockcounter += mod_from_last_time;
|
/* Reset counts based on SOF counting. Expect 16ms (128 HS SOFs/16 FS SOFS) per feedback poll
|
||||||
clocks = clockcounter / MCLK_48;
|
* We always count 128 SOFs, so 16ms @ HS, 128ms @ FS */
|
||||||
mod_from_last_time = clockcounter % MCLK_48;
|
if(sof_count == 128)
|
||||||
|
{
|
||||||
|
//debug_printf("fb\n");
|
||||||
|
sof_count = 0;
|
||||||
|
|
||||||
//Scale for working out number of samps to take from device for input
|
clockcounter += mod_from_last_time;
|
||||||
if(AUDIO_CLASS == 2)
|
clocks = clockcounter / MCLK_48;
|
||||||
{
|
mod_from_last_time = clockcounter % MCLK_48;
|
||||||
clocks <<= 3;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
clocks <<= 6;
|
|
||||||
}
|
|
||||||
asm volatile("stw %0, dp[g_speed]"::"r"(clocks)); // g_speed = clocks
|
|
||||||
|
|
||||||
//Write to feedback EP buffer
|
//Scale for working out number of samps to take from device for input
|
||||||
if (AUDIO_CLASS == 2)
|
if(AUDIO_CLASS == 2)
|
||||||
{
|
{
|
||||||
fb_clocks[0] = clocks;
|
clocks <<= 3;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
fb_clocks[0] = clocks >> 2;
|
clocks <<= 6;
|
||||||
}
|
}
|
||||||
clockcounter = 0;
|
asm volatile("stw %0, dp[g_speed]"::"r"(clocks)); // g_speed = clocks
|
||||||
}
|
|
||||||
sof_count++;
|
|
||||||
break;
|
|
||||||
|
|
||||||
//Receive samples from host
|
//Write to feedback EP buffer
|
||||||
case XUD_GetData_Select(c_aud_out, ep_aud_out, length, result):
|
if (AUDIO_CLASS == 2)
|
||||||
num_samples_received_from_host = length / out_subslot_size;
|
{
|
||||||
//debug_printf("out samps: %d\n", num_samples_received_from_host);
|
fb_clocks[0] = clocks;
|
||||||
outstanding_samples_to_host += num_samples_received_from_host;
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
fb_clocks[0] = clocks >> 2;
|
||||||
|
}
|
||||||
|
clockcounter = 0;
|
||||||
|
}
|
||||||
|
sof_count++;
|
||||||
|
break;
|
||||||
|
|
||||||
unpack_buff_to_samples(buffer_aud_out, num_samples_received_from_host, out_subslot_size, loopback_samples);
|
//Receive samples from host
|
||||||
|
case XUD_GetData_Select(c_aud_out, ep_aud_out, length, result):
|
||||||
|
num_samples_received_from_host = length / out_subslot_size;
|
||||||
|
//debug_printf("out samps: %d\n", num_samples_received_from_host);
|
||||||
|
outstanding_samples_to_host += num_samples_received_from_host;
|
||||||
|
|
||||||
num_samples_to_send_to_host = num_samples_received_from_host;
|
unpack_buff_to_samples(buffer_aud_out, num_samples_received_from_host, out_subslot_size, loopback_samples);
|
||||||
|
|
||||||
//Mark EP as ready for next frame from host
|
|
||||||
XUD_SetReady_OutPtr(ep_aud_out, (unsigned)buffer_aud_out);
|
|
||||||
break;
|
|
||||||
|
|
||||||
//Send feedback
|
fifo_ret_t ret = fifo_block_push(host_to_device_fifo_ptr, loopback_samples, num_samples_received_from_host);
|
||||||
case XUD_SetData_Select(c_feedback, ep_feedback, result):
|
if (ret != FIFO_SUCCESS) debug_printf("full\n");
|
||||||
//debug_printf("ep_feedback\n");
|
|
||||||
//XUD_SetReady_InPtr(ep_feedback, (unsigned)buffer_feedback, FEEDBACK_BUFF_SIZE);
|
|
||||||
if (AUDIO_CLASS == 2)
|
|
||||||
{
|
|
||||||
XUD_SetReady_In(ep_feedback, (fb_clocks, unsigned char[]), 4);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
XUD_SetReady_In(ep_feedback, (fb_clocks, unsigned char[]), 3);
|
|
||||||
}
|
|
||||||
|
|
||||||
break;
|
num_samples_to_send_to_host = num_samples_received_from_host;
|
||||||
|
|
||||||
|
//Mark EP as ready for next frame from host
|
||||||
|
XUD_SetReady_OutPtr(ep_aud_out, (unsigned)buffer_aud_out);
|
||||||
|
break;
|
||||||
|
|
||||||
//Send samples to host
|
//Send feedback
|
||||||
case XUD_SetData_Select(c_aud_in, ep_aud_in, result):
|
case XUD_SetData_Select(c_feedback, ep_feedback, result):
|
||||||
//debug_printf("sent data\n");
|
//debug_printf("ep_feedback\n");
|
||||||
|
//XUD_SetReady_InPtr(ep_feedback, (unsigned)buffer_feedback, FEEDBACK_BUFF_SIZE);
|
||||||
|
if (AUDIO_CLASS == 2)
|
||||||
|
{
|
||||||
|
XUD_SetReady_In(ep_feedback, (fb_clocks, unsigned char[]), 4);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
XUD_SetReady_In(ep_feedback, (fb_clocks, unsigned char[]), 3);
|
||||||
|
}
|
||||||
|
|
||||||
//Populate the input buffer ready for the next read
|
break;
|
||||||
pack_samples_to_buff(loopback_samples, num_samples_to_send_to_host, in_subslot_size, buffer_aud_in);
|
|
||||||
//Use the number of samples we received last time so we are always balanced (assumes same in/out count)
|
|
||||||
|
|
||||||
unsigned input_buffer_size = num_samples_to_send_to_host * in_subslot_size;
|
|
||||||
XUD_SetReady_InPtr(ep_aud_in, (unsigned)buffer_aud_in, input_buffer_size); //loopback
|
|
||||||
num_samples_to_send_to_host = 0;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case c_audio_hub :> samples_in[0]:
|
//Send samples to host
|
||||||
for (int i = 1; i < NUM_USB_CHAN_IN; i++) c_audio_hub :> samples_in[i];
|
case XUD_SetData_Select(c_aud_in, ep_aud_in, result):
|
||||||
// for (int i = 0; i < NUM_USB_CHAN_OUT; i++) c_audio_hub <: samples_out[1];
|
//debug_printf("sent data\n");
|
||||||
for (int i = 0; i < NUM_USB_CHAN_OUT; i++) c_audio_hub <: loopback_samples[i];
|
|
||||||
break;
|
//Populate the input buffer ready for the next read
|
||||||
|
pack_samples_to_buff(loopback_samples, num_samples_to_send_to_host, in_subslot_size, buffer_aud_in);
|
||||||
|
//Use the number of samples we received last time so we are always balanced (assumes same in/out count)
|
||||||
|
|
||||||
|
unsigned input_buffer_size = num_samples_to_send_to_host * in_subslot_size;
|
||||||
|
XUD_SetReady_InPtr(ep_aud_in, (unsigned)buffer_aud_in, input_buffer_size); //loopback
|
||||||
|
num_samples_to_send_to_host = 0;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case c_audio_hub :> samples_in[0]:
|
||||||
|
for (int i = 1; i < NUM_USB_CHAN_IN; i++) c_audio_hub :> samples_in[i];
|
||||||
|
// for (int i = 0; i < NUM_USB_CHAN_OUT; i++) c_audio_hub <: samples_out[1];
|
||||||
|
int out_samps[NUM_USB_CHAN_OUT];
|
||||||
|
fifo_ret_t ret = fifo_block_pop(host_to_device_fifo_ptr, out_samps, NUM_USB_CHAN_OUT);
|
||||||
|
if (ret != FIFO_SUCCESS) debug_printf("empty\n");
|
||||||
|
for (int i = 0; i < NUM_USB_CHAN_OUT; i++) c_audio_hub <: out_samps[i];
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Reference in New Issue
Block a user