diff --git a/src/class/audio/audio_device.c b/src/class/audio/audio_device.c index 67c94837..7e7fef19 100644 --- a/src/class/audio/audio_device.c +++ b/src/class/audio/audio_device.c @@ -73,18 +73,22 @@ typedef struct uint8_t altSetting[CFG_TUD_AUDIO_N_AS_INT]; #endif /*------------- From this point, data is not cleared by bus reset -------------*/ + + // Buffer for control requests + CFG_TUSB_MEM_ALIGN uint8_t ctrl_buf[CFG_TUD_AUDIO_CTRL_BUF_SIZE]; + // FIFO -#if CFG_TUD_AUDIO_EPSIZE_IN && CFG_TUD_AUDIO_USE_TX_FIFO +#if CFG_TUD_AUDIO_EPSIZE_IN && CFG_TUD_AUDIO_TX_FIFO_SIZE tu_fifo_t tx_ff[CFG_TUD_AUDIO_N_CHANNELS_TX]; - CFG_TUSB_MEM_ALIGN uint8_t tx_ff_buf[CFG_TUD_AUDIO_N_CHANNELS_TX][CFG_TUD_AUDIO_TX_BUFSIZE]; + CFG_TUSB_MEM_ALIGN uint8_t tx_ff_buf[CFG_TUD_AUDIO_N_CHANNELS_TX][CFG_TUD_AUDIO_TX_FIFO_SIZE]; #if CFG_FIFO_MUTEX osal_mutex_def_t tx_ff_mutex[CFG_TUD_AUDIO_N_CHANNELS_TX]; #endif #endif -#if CFG_TUD_AUDIO_EPSIZE_OUT && CFG_TUD_AUDIO_USE_RX_FIFO +#if CFG_TUD_AUDIO_EPSIZE_OUT && CFG_TUD_AUDIO_RX_FIFO_SIZE tu_fifo_t rx_ff[CFG_TUD_AUDIO_N_CHANNELS_RX]; - CFG_TUSB_MEM_ALIGN uint8_t rx_ff_buf[CFG_TUD_AUDIO_N_CHANNELS_RX][CFG_TUD_AUDIO_RX_BUFSIZE]; + CFG_TUSB_MEM_ALIGN uint8_t rx_ff_buf[CFG_TUD_AUDIO_N_CHANNELS_RX][CFG_TUD_AUDIO_RX_FIFO_SIZE]; #if CFG_FIFO_MUTEX osal_mutex_def_t rx_ff_mutex[CFG_TUD_AUDIO_N_CHANNELS_RX]; #endif @@ -119,19 +123,21 @@ typedef struct } audiod_interface_t; -#if CFG_TUD_AUDIO_EPSIZE_IN && CFG_TUD_AUDIO_USE_TX_FIFO -#define ITF_MEM_RESET_SIZE offsetof(audiod_interface_t, tx_ff) -#elif CFG_TUD_AUDIO_EPSIZE_OUT && CFG_TUD_AUDIO_USE_RX_FIFO -#define ITF_MEM_RESET_SIZE offsetof(audiod_interface_t, rx_ff) -#elif CFG_TUD_AUDIO_INT_CTR_EPSIZE_IN -#define ITF_MEM_RESET_SIZE offsetof(audiod_interface_t, int_ctr_ff) -#elif CFG_TUD_AUDIO_EPSIZE_OUT -#define ITF_MEM_RESET_SIZE offsetof(audiod_interface_t, epout_buf) -#elif CFG_TUD_AUDIO_EPSIZE_IN -#define ITF_MEM_RESET_SIZE offsetof(audiod_interface_t, epin_buf) -#elif CFG_TUD_AUDIO_INT_CTR_EPSIZE_IN -#define ITF_MEM_RESET_SIZE offsetof(audiod_interface_t, ep_int_ctr_buf) -#endif +#define ITF_MEM_RESET_SIZE offsetof(audiod_interface_t, ctrl_buf) + +//#if CFG_TUD_AUDIO_EPSIZE_IN && CFG_TUD_AUDIO_TX_FIFO_SIZE +//#define ITF_MEM_RESET_SIZE offsetof(audiod_interface_t, tx_ff) +//#elif CFG_TUD_AUDIO_EPSIZE_OUT && CFG_TUD_AUDIO_RX_FIFO_SIZE +//#define ITF_MEM_RESET_SIZE offsetof(audiod_interface_t, rx_ff) +//#elif CFG_TUD_AUDIO_INT_CTR_EPSIZE_IN +//#define ITF_MEM_RESET_SIZE offsetof(audiod_interface_t, int_ctr_ff) +//#elif CFG_TUD_AUDIO_EPSIZE_OUT +//#define ITF_MEM_RESET_SIZE offsetof(audiod_interface_t, epout_buf) +//#elif CFG_TUD_AUDIO_EPSIZE_IN +//#define ITF_MEM_RESET_SIZE offsetof(audiod_interface_t, epin_buf) +//#elif CFG_TUD_AUDIO_INT_CTR_EPSIZE_IN +//#define ITF_MEM_RESET_SIZE offsetof(audiod_interface_t, ep_int_ctr_buf) +//#endif //--------------------------------------------------------------------+ // INTERNAL OBJECT & FUNCTION DECLARATION @@ -195,7 +201,7 @@ bool tud_audio_n_mounted(uint8_t itf) // READ API //--------------------------------------------------------------------+ -#if CFG_TUD_AUDIO_EPSIZE_OUT && CFG_TUD_AUDIO_USE_RX_FIFO +#if CFG_TUD_AUDIO_EPSIZE_OUT && CFG_TUD_AUDIO_RX_FIFO_SIZE uint16_t tud_audio_n_available(uint8_t itf, uint8_t channelId) { @@ -237,7 +243,7 @@ void tud_audio_int_ctr_n_read_flush (uint8_t itf) #endif // This function is called once something is received by USB and is responsible for decoding received stream into audio channels. -// If you prefer your own (more efficient) implementation suiting your purpose set CFG_TUD_AUDIO_USE_RX_FIFO = 0. +// If you prefer your own (more efficient) implementation suiting your purpose set CFG_TUD_AUDIO_RX_FIFO_SIZE = 0. #if CFG_TUD_AUDIO_EPSIZE_OUT @@ -256,7 +262,7 @@ static bool audio_rx_done_cb(uint8_t rhport, audiod_interface_t* audio, uint8_t* { case AUDIO_DATA_FORMAT_TYPE_I_PCM: -#if CFG_TUD_AUDIO_USE_RX_FIFO +#if CFG_TUD_AUDIO_RX_FIFO_SIZE TU_VERIFY(audio_rx_done_type_I_pcm_ff_cb(rhport, audio, buffer, bufsize)); #else #error YOUR DECODING AND BUFFERING IS REQUIRED HERE! @@ -283,8 +289,8 @@ static bool audio_rx_done_cb(uint8_t rhport, audiod_interface_t* audio, uint8_t* #endif //CFG_TUD_AUDIO_EPSIZE_OUT -// The following functions are used in case CFG_TUD_AUDIO_USE_RX_FIFO == 1 -#if CFG_TUD_AUDIO_USE_RX_FIFO +// The following functions are used in case CFG_TUD_AUDIO_RX_FIFO_SIZE != 0 +#if CFG_TUD_AUDIO_RX_FIFO_SIZE static bool audio_rx_done_type_I_pcm_ff_cb(uint8_t rhport, audiod_interface_t* audio, uint8_t * buffer, uint16_t bufsize) { (void) rhport; @@ -320,7 +326,7 @@ static bool audio_rx_done_type_I_pcm_ff_cb(uint8_t rhport, audiod_interface_t* a } } } } -#endif //CFG_TUD_AUDIO_USE_RX_FIFO +#endif //CFG_TUD_AUDIO_RX_FIFO_SIZE #if CFG_TUD_AUDIO_EPSIZE_OUT @@ -342,7 +348,7 @@ TU_ATTR_WEAK bool tud_audio_rx_done_cb(uint8_t rhport, uint8_t * buffer, uint16_ // WRITE API //--------------------------------------------------------------------+ -#if CFG_TUD_AUDIO_EPSIZE_IN > 0 && CFG_TUD_AUDIO_USE_TX_FIFO +#if CFG_TUD_AUDIO_EPSIZE_IN && CFG_TUD_AUDIO_TX_FIFO_SIZE uint16_t tud_audio_n_write(uint8_t itf, uint8_t channelId, uint8_t const* buffer, uint16_t bufsize) { audiod_interface_t* audio = &_audiod_itf[itf]; @@ -370,7 +376,7 @@ uint32_t tud_audio_int_ctr_n_write(uint8_t itf, uint8_t const* buffer, uint32_t // This function is called once a transmit of an audio packet was successfully completed. Here, we encode samples and place it in IN EP's buffer for next transmission. -// If you prefer your own (more efficient) implementation suiting your purpose set CFG_TUD_AUDIO_USE_TX_FIFO = 0. +// If you prefer your own (more efficient) implementation suiting your purpose set CFG_TUD_AUDIO_TX_FIFO_SIZE = 0. #if CFG_TUD_AUDIO_EPSIZE_IN static bool audio_tx_done_cb(uint8_t rhport, audiod_interface_t* audio, uint16_t * n_bytes_copied) { @@ -387,7 +393,7 @@ static bool audio_tx_done_cb(uint8_t rhport, audiod_interface_t* audio, uint16_t { case AUDIO_DATA_FORMAT_TYPE_I_PCM: -#if CFG_TUD_AUDIO_USE_TX_FIFO +#if CFG_TUD_AUDIO_TX_FIFO_SIZE TU_VERIFY(audio_tx_done_type_I_pcm_ff_cb(rhport, audio, n_bytes_copied)); #else #error YOUR ENCODING AND BUFFERING IS REQUIRED HERE! @@ -414,7 +420,7 @@ static bool audio_tx_done_cb(uint8_t rhport, audiod_interface_t* audio, uint16_t #endif //CFG_TUD_AUDIO_EPSIZE_IN -#if CFG_TUD_AUDIO_USE_TX_FIFO +#if CFG_TUD_AUDIO_TX_FIFO_SIZE static bool audio_tx_done_type_I_pcm_ff_cb(uint8_t rhport, audiod_interface_t* audio, uint16_t * n_bytes_copied) { // We encode directly into IN EP's buffer - abort if previous transfer not complete @@ -478,7 +484,7 @@ static bool audio_tx_done_type_I_pcm_ff_cb(uint8_t rhport, audiod_interface_t* a return true; } -#endif //CFG_TUD_AUDIO_USE_TX_FIFO +#endif //CFG_TUD_AUDIO_TX_FIFO_SIZE // This function is called once a transmit of an feedback packet was successfully completed. Here, we get the next feedback value to be sent @@ -580,20 +586,20 @@ void audiod_init(void) audiod_interface_t* audio = &_audiod_itf[i]; // Initialize TX FIFOs if required -#if CFG_TUD_AUDIO_EPSIZE_IN > 0 && CFG_TUD_AUDIO_USE_TX_FIFO +#if CFG_TUD_AUDIO_EPSIZE_IN && CFG_TUD_AUDIO_TX_FIFO_SIZE for (cnt = 0; cnt < CFG_TUD_AUDIO_N_CHANNELS_TX; cnt++) { - tu_fifo_config(&audio->tx_ff[cnt], &audio->tx_ff_buf[cnt], CFG_TUD_AUDIO_TX_BUFSIZE, CFG_TUD_AUDIO_TX_ITEMSIZE, true); + tu_fifo_config(&audio->tx_ff[cnt], &audio->tx_ff_buf[cnt], CFG_TUD_AUDIO_TX_FIFO_SIZE, CFG_TUD_AUDIO_TX_ITEMSIZE, true); #if CFG_FIFO_MUTEX tu_fifo_config_mutex(&audio->tx_ff[cnt], osal_mutex_create(&audio->tx_ff_mutex[cnt])); #endif } #endif -#if CFG_TUD_AUDIO_EPSIZE_OUT > 0 && CFG_TUD_AUDIO_USE_RX_FIFO +#if CFG_TUD_AUDIO_EPSIZE_OUT && CFG_TUD_AUDIO_RX_FIFO_SIZE for (cnt = 0; cnt < CFG_TUD_AUDIO_N_CHANNELS_RX; cnt++) { - tu_fifo_config(&audio->rx_ff[cnt], &audio->rx_ff_buf[cnt], CFG_TUD_AUDIO_RX_BUFSIZE, CFG_TUD_AUDIO_RX_ITEMSIZE, true); + tu_fifo_config(&audio->rx_ff[cnt], &audio->rx_ff_buf[cnt], CFG_TUD_AUDIO_RX_FIFO_SIZE, CFG_TUD_AUDIO_RX_ITEMSIZE, true); #if CFG_FIFO_MUTEX tu_fifo_config_mutex(&audio->rx_ff[cnt], osal_mutex_create(&audio->rx_ff_mutex[cnt])); #endif @@ -619,14 +625,14 @@ void audiod_reset(uint8_t rhport) tu_memclr(audio, ITF_MEM_RESET_SIZE); uint8_t cnt; -#if CFG_TUD_AUDIO_EPSIZE_IN > 0 && CFG_TUD_AUDIO_USE_TX_FIFO +#if CFG_TUD_AUDIO_EPSIZE_IN && CFG_TUD_AUDIO_TX_FIFO_SIZE for (cnt = 0; cnt < CFG_TUD_AUDIO_N_CHANNELS_TX; cnt++) { tu_fifo_clear(&audio->tx_ff[cnt]); } #endif -#if CFG_TUD_AUDIO_EPSIZE_OUT > 0 && CFG_TUD_AUDIO_USE_RX_FIFO +#if CFG_TUD_AUDIO_EPSIZE_OUT && CFG_TUD_AUDIO_RX_FIFO_SIZE for (cnt = 0; cnt < CFG_TUD_AUDIO_N_CHANNELS_RX; cnt++) { tu_fifo_clear(&audio->rx_ff[cnt]); @@ -1376,7 +1382,7 @@ static bool audiod_verify_ep_exists(uint8_t ep) // //#if CFG_TUD_AUDIO_FORMAT_TYPE_I_TX == AUDIO_DATA_FORMAT_TYPE_I_PCM // -//#if CFG_TUD_AUDIO_USE_TX_FIFO +//#if CFG_TUD_AUDIO_TX_FIFO_SIZE // TU_VERIFY(audio_tx_done_type_I_pcm_cb(rhport, audio, n_bytes_copied)); //#else //#error YOUR ENCODING AND SENDING IS REQUIRED HERE! @@ -1407,7 +1413,7 @@ static bool audiod_verify_ep_exists(uint8_t ep) // //#if CFG_TUD_AUDIO_FORMAT_TYPE_I_RX == AUDIO_DATA_FORMAT_TYPE_I_PCM // -//#if CFG_TUD_AUDIO_USE_RX_FIFO +//#if CFG_TUD_AUDIO_RX_FIFO_SIZE // TU_VERIFY(audio_rx_done_type_I_pcm_ff_cb(rhport, audio, buffer, bufsize)); //#else //#error YOUR DECODING AND BUFFERING IS REQUIRED HERE! diff --git a/src/class/audio/audio_device.h b/src/class/audio/audio_device.h index 95b361ac..cc757d45 100644 --- a/src/class/audio/audio_device.h +++ b/src/class/audio/audio_device.h @@ -43,16 +43,23 @@ #define CFG_TUD_AUDIO_N_AS_INT 0 #endif -// Use internal FIFOs - In this case, audio.c implements FIFOs for RX and TX (whatever required) and implements encoding and decoding (parameterized by the defines below). -// For RX: the input stream gets decoded into its corresponding channels, where for each channel a FIFO is setup to hold its data -> see: audio_rx_done_cb(). -// For TX: the output stream is composed from CFG_TUD_AUDIO_N_CHANNELS_TX channels, where for each channel a FIFO is defined. -// If you disable this you need to fill in desired code into audio_rx_done_cb() and Y on your own, however, this allows for optimizations in byte processing. -#ifndef CFG_TUD_AUDIO_USE_RX_FIFO -#define CFG_TUD_AUDIO_USE_RX_FIFO 0 +// Size of control buffer used to receive and send control messages via EP0 - has to be big enough to hold your biggest request structure e.g. range requests with multiple intervals defined or cluster descriptors +#ifndef CFG_TUD_AUDIO_CTRL_BUF_SIZE +#define CFG_TUD_AUDIO_CTRL_BUF_SIZE 64 #endif -#ifndef CFG_TUD_AUDIO_USE_TX_FIFO -#define CFG_TUD_AUDIO_USE_TX_FIFO 0 +// Use of TX/RX FIFOs - If sizes are not zero, audio.c implements FIFOs for RX and TX (whatever defined). +// For RX: the input stream gets decoded into its corresponding channels, where for each channel a FIFO is setup to hold its data -> see: audio_rx_done_cb(). +// For TX: the output stream is composed from CFG_TUD_AUDIO_N_CHANNELS_TX channels, where for each channel a FIFO is defined. +// Further, it implements encoding and decoding of the individual channels (parameterized by the defines below). +// If you don't use the FIFOs you need to handle encoding and decoding on your own in audio_rx_done_cb() and Y. This, however, allows for optimizations. + +#ifndef CFG_TUD_AUDIO_TX_FIFO_SIZE +#define CFG_TUD_AUDIO_TX_FIFO_SIZE 0 // Buffer size per channel +#endif + +#ifndef CFG_TUD_AUDIO_RX_FIFO_SIZE +#define CFG_TUD_AUDIO_RX_FIFO_SIZE 0 // Buffer size per channel #endif // End point sizes - Limits: Full Speed <= 1023, High Speed <= 1024 @@ -60,22 +67,10 @@ #define CFG_TUD_AUDIO_EPSIZE_IN 0 // TX #endif -#if CFG_TUD_AUDIO_EPSIZE_IN > 0 -#ifndef CFG_TUD_AUDIO_TX_BUFSIZE -#define CFG_TUD_AUDIO_TX_BUFSIZE CFG_TUD_AUDIO_EPSIZE_IN // Buffer size per channel -#endif -#endif - #ifndef CFG_TUD_AUDIO_EPSIZE_OUT #define CFG_TUD_AUDIO_EPSIZE_OUT 0 // RX #endif -#if CFG_TUD_AUDIO_EPSIZE_OUT > 0 -#ifndef CFG_TUD_AUDIO_RX_BUFSIZE -#define CFG_TUD_AUDIO_RX_BUFSIZE CFG_TUD_AUDIO_EPSIZE_OUT // Buffer size per channel -#endif -#endif - #ifndef CFG_TUD_AUDIO_ENABLE_FEEDBACK_EP #define CFG_TUD_AUDIO_ENABLE_FEEDBACK_EP 0 // Feedback #endif @@ -169,13 +164,13 @@ extern "C" { //--------------------------------------------------------------------+ bool tud_audio_n_mounted (uint8_t itf); -#if CFG_TUD_AUDIO_EPSIZE_OUT > 0 && CFG_TUD_AUDIO_USE_RX_FIFO +#if CFG_TUD_AUDIO_EPSIZE_OUT && CFG_TUD_AUDIO_RX_BUFSIZE uint16_t tud_audio_n_available (uint8_t itf, uint8_t channelId); uint16_t tud_audio_n_read (uint8_t itf, uint8_t channelId, void* buffer, uint16_t bufsize); void tud_audio_n_read_flush (uint8_t itf, uint8_t channelId); #endif -#if CFG_TUD_AUDIO_EPSIZE_IN > 0 && CFG_TUD_AUDIO_USE_TX_FIFO +#if CFG_TUD_AUDIO_EPSIZE_IN && CFG_TUD_AUDIO_TX_BUFSIZE uint16_t tud_audio_n_write (uint8_t itf, uint8_t channelId, uint8_t const* buffer, uint16_t bufsize); #endif @@ -192,13 +187,13 @@ uint16_t tud_audio_int_ctr_n_write (uint8_t itf, uint8_t const* buffer, uint16 inline bool tud_audio_mounted (void); -#if CFG_TUD_AUDIO_EPSIZE_OUT > 0 && CFG_TUD_AUDIO_USE_RX_FIFO +#if CFG_TUD_AUDIO_EPSIZE_OUT && CFG_TUD_AUDIO_RX_BUFSIZE inline uint16_t tud_audio_available (void); inline uint16_t tud_audio_read (void* buffer, uint16_t bufsize); inline void tud_audio_read_flush (void); #endif -#if CFG_TUD_AUDIO_EPSIZE_IN > 0 && CFG_TUD_AUDIO_USE_TX_FIFO +#if CFG_TUD_AUDIO_EPSIZE_IN && CFG_TUD_AUDIO_TX_BUFSIZE inline uint16_t tud_audio_write (uint8_t channelId, uint8_t const* buffer, uint16_t bufsize); #endif @@ -259,14 +254,14 @@ inline bool tud_audio_mounted(void) return tud_audio_n_mounted(0); } -#if CFG_TUD_AUDIO_EPSIZE_IN > 0 && CFG_TUD_AUDIO_USE_TX_FIFO +#if CFG_TUD_AUDIO_EPSIZE_IN && CFG_TUD_AUDIO_TX_BUFSIZE inline uint16_t tud_audio_write (uint8_t channelId, uint8_t const* buffer, uint16_t bufsize) // Short version if only one audio function is used { return tud_audio_n_write(0, channelId, buffer, bufsize); } -#endif // CFG_TUD_AUDIO_EPSIZE_IN > 0 && CFG_TUD_AUDIO_USE_TX_FIFO +#endif // CFG_TUD_AUDIO_EPSIZE_IN && CFG_TUD_AUDIO_TX_BUFSIZE -#if CFG_TUD_AUDIO_EPSIZE_OUT > 0 && CFG_TUD_AUDIO_USE_RX_FIFO +#if CFG_TUD_AUDIO_EPSIZE_OUT && CFG_TUD_AUDIO_RX_BUFSIZE inline uint16_t tud_audio_available(uint8_t channelId) { return tud_audio_n_available(0, channelId);