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
|
||||
#include "debug_print.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
|
||||
#define NOMINAL_SR_DEVICE DEFAULT_FREQ
|
||||
@@ -134,18 +134,21 @@ 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_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};
|
||||
int32_t samples_out[NUM_USB_CHAN_OUT] = {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;
|
||||
unsigned length = 0;
|
||||
|
||||
|
||||
while(1){
|
||||
select{
|
||||
//Handle control path from EP0
|
||||
case testct_byref(c_aud_ctl, tmp):
|
||||
@@ -216,7 +219,7 @@ void XUA_Buffer_lite(chanend c_aud_out, chanend c_feedback, chanend c_aud_in, ch
|
||||
* We always count 128 SOFs, so 16ms @ HS, 128ms @ FS */
|
||||
if(sof_count == 128)
|
||||
{
|
||||
debug_printf("fb\n");
|
||||
//debug_printf("fb\n");
|
||||
sof_count = 0;
|
||||
|
||||
clockcounter += mod_from_last_time;
|
||||
@@ -256,6 +259,9 @@ void XUA_Buffer_lite(chanend c_aud_out, chanend c_feedback, chanend c_aud_in, ch
|
||||
|
||||
unpack_buff_to_samples(buffer_aud_out, num_samples_received_from_host, out_subslot_size, loopback_samples);
|
||||
|
||||
fifo_ret_t ret = fifo_block_push(host_to_device_fifo_ptr, loopback_samples, num_samples_received_from_host);
|
||||
if (ret != FIFO_SUCCESS) debug_printf("full\n");
|
||||
|
||||
num_samples_to_send_to_host = num_samples_received_from_host;
|
||||
|
||||
//Mark EP as ready for next frame from host
|
||||
@@ -293,8 +299,12 @@ void XUA_Buffer_lite(chanend c_aud_out, chanend c_feedback, chanend c_aud_in, ch
|
||||
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];
|
||||
for (int i = 0; i < NUM_USB_CHAN_OUT; i++) c_audio_hub <: loopback_samples[i];
|
||||
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