diff options
| author | Reinhard Panhuber <[email protected]> | 2021-03-10 19:32:13 +0100 |
|---|---|---|
| committer | Reinhard Panhuber <[email protected]> | 2021-03-10 19:32:13 +0100 |
| commit | d5a5a1cab63e8e43b22f13db95df35afdfa6befb (patch) | |
| tree | dcc98d73c01d9bf3ab1f045fc1284a4e0a63871e /src/class | |
| parent | de1f36f2b02b00d8012748be304186e1eb78c728 (diff) | |
Implement audio PCM type I enc./decoding acc. to 2.3.1.5 Audio Streams
Extending capabilities of support FIFOs
Removing copy from to FIFO
Adjusting audio examples
Remove peek/read into other FIFO
Diffstat (limited to 'src/class')
| -rw-r--r-- | src/class/audio/audio_device.c | 185 | ||||
| -rw-r--r-- | src/class/audio/audio_device.h | 70 |
2 files changed, 145 insertions, 110 deletions
diff --git a/src/class/audio/audio_device.c b/src/class/audio/audio_device.c index c0d3e123c..00d95ede5 100644 --- a/src/class/audio/audio_device.c +++ b/src/class/audio/audio_device.c @@ -161,18 +161,18 @@ typedef struct // Support FIFOs #if CFG_TUD_AUDIO_EPSIZE_IN && CFG_TUD_AUDIO_TX_SUPPORT_SW_FIFO_SIZE - tu_fifo_t tx_supp_ff[CFG_TUD_AUDIO_N_CHANNELS_TX]; - CFG_TUSB_MEM_ALIGN uint8_t tx_supp_ff_buf[CFG_TUD_AUDIO_N_CHANNELS_TX][CFG_TUD_AUDIO_TX_SUPPORT_SW_FIFO_SIZE]; + tu_fifo_t tx_supp_ff[CFG_TUD_AUDIO_N_TX_SUPPORT_SW_FIFO]; + CFG_TUSB_MEM_ALIGN uint8_t tx_supp_ff_buf[CFG_TUD_AUDIO_N_TX_SUPPORT_SW_FIFO][CFG_TUD_AUDIO_TX_SUPPORT_SW_FIFO_SIZE * CFG_TUD_AUDIO_N_BYTES_PER_SAMPLE_TX]; #if CFG_FIFO_MUTEX - osal_mutex_def_t tx_supp_ff_mutex_wr[CFG_TUD_AUDIO_N_CHANNELS_TX]; // No need for read mutex as only USB driver reads from FIFO + osal_mutex_def_t tx_supp_ff_mutex_wr[CFG_TUD_AUDIO_N_TX_SUPPORT_SW_FIFO]; // No need for read mutex as only USB driver reads from FIFO #endif #endif #if CFG_TUD_AUDIO_EPSIZE_OUT && CFG_TUD_AUDIO_RX_SUPPORT_SW_FIFO_SIZE - tu_fifo_t rx_supp_ff[CFG_TUD_AUDIO_N_CHANNELS_RX]; - CFG_TUSB_MEM_ALIGN uint8_t rx_supp_ff_buf[CFG_TUD_AUDIO_N_CHANNELS_RX][CFG_TUD_AUDIO_RX_SUPPORT_SW_FIFO_SIZE]; + tu_fifo_t rx_supp_ff[CFG_TUD_AUDIO_N_RX_SUPPORT_SW_FIFO]; + CFG_TUSB_MEM_ALIGN uint8_t rx_supp_ff_buf[CFG_TUD_AUDIO_N_RX_SUPPORT_SW_FIFO][CFG_TUD_AUDIO_RX_SUPPORT_SW_FIFO_SIZE * CFG_TUD_AUDIO_N_BYTES_PER_SAMPLE_RX]; #if CFG_FIFO_MUTEX - osal_mutex_def_t rx_supp_ff_mutex_rd[CFG_TUD_AUDIO_N_CHANNELS_RX]; // No need for write mutex as only USB driver writes into FIFO + osal_mutex_def_t rx_supp_ff_mutex_rd[CFG_TUD_AUDIO_N_RX_SUPPORT_SW_FIFO]; // No need for write mutex as only USB driver writes into FIFO #endif #endif @@ -284,19 +284,19 @@ bool tud_audio_n_clear_ep_out_ff(uint8_t itf) // Delete all content in the support RX FIFOs bool tud_audio_n_clear_rx_support_ff(uint8_t itf, uint8_t channelId) { - TU_VERIFY(itf < CFG_TUD_AUDIO && _audiod_itf[itf].p_desc != NULL, channelId < CFG_TUD_AUDIO_N_CHANNELS_RX); + TU_VERIFY(itf < CFG_TUD_AUDIO && _audiod_itf[itf].p_desc != NULL, channelId < CFG_TUD_AUDIO_N_RX_SUPPORT_SW_FIFO); return tu_fifo_clear(&_audiod_itf[itf].rx_supp_ff[channelId]); } uint16_t tud_audio_n_available_support_ff(uint8_t itf, uint8_t channelId) { - TU_VERIFY(itf < CFG_TUD_AUDIO && _audiod_itf[itf].p_desc != NULL, channelId < CFG_TUD_AUDIO_N_CHANNELS_RX); + TU_VERIFY(itf < CFG_TUD_AUDIO && _audiod_itf[itf].p_desc != NULL, channelId < CFG_TUD_AUDIO_N_RX_SUPPORT_SW_FIFO); return tu_fifo_count(&_audiod_itf[itf].rx_supp_ff[channelId]); } uint16_t tud_audio_n_read_support_ff(uint8_t itf, uint8_t channelId, void* buffer, uint16_t bufsize) { - TU_VERIFY(itf < CFG_TUD_AUDIO && _audiod_itf[itf].p_desc != NULL, channelId < CFG_TUD_AUDIO_N_CHANNELS_RX); + TU_VERIFY(itf < CFG_TUD_AUDIO && _audiod_itf[itf].p_desc != NULL, channelId < CFG_TUD_AUDIO_N_RX_SUPPORT_SW_FIFO); return tu_fifo_read_n(&_audiod_itf[itf].rx_supp_ff[channelId], buffer, bufsize); } #endif @@ -382,35 +382,55 @@ static bool audiod_rx_done_cb(uint8_t rhport, audiod_interface_t* audio, uint16_ // The following functions are used in case CFG_TUD_AUDIO_RX_SUPPORT_SW_FIFO_SIZE != 0 #if CFG_TUD_AUDIO_RX_SUPPORT_SW_FIFO_SIZE && CFG_TUD_AUDIO_EPSIZE_OUT + +// Decoding according to 2.3.1.5 Audio Streams static bool audiod_decode_type_I_pcm(uint8_t rhport, audiod_interface_t* audio, uint16_t n_bytes_received) { (void) rhport; - // We assume there is always the correct number of samples available for decoding - extra checks make no sense here + // Determine amount of samples + uint16_t const nChannelsPerFF = CFG_TUD_AUDIO_N_CHANNELS_RX / CFG_TUD_AUDIO_N_RX_SUPPORT_SW_FIFO; + uint16_t const nBytesToCopy = nChannelsPerFF*CFG_TUD_AUDIO_N_BYTES_PER_SAMPLE_RX; + uint16_t const nSamplesPerFFToRead = n_bytes_received / CFG_TUD_AUDIO_N_BYTES_PER_SAMPLE_RX / CFG_TUD_AUDIO_N_RX_SUPPORT_SW_FIFO; + uint8_t cnt_ff; - uint16_t cnt = CFG_TUD_AUDIO_N_BYTES_PER_SAMPLE_RX * CFG_TUD_AUDIO_N_CHANNELS_RX; - uint16_t idxSample = 0; + // Decode + void * dst; + uint8_t * src; + uint8_t * dst_end; + uint16_t len; - while (cnt <= n_bytes_received) + for (cnt_ff = 0; cnt_ff < CFG_TUD_AUDIO_N_RX_SUPPORT_SW_FIFO; cnt_ff++) { - for (uint8_t cntChannel = 0; cntChannel < CFG_TUD_AUDIO_N_CHANNELS_RX; cntChannel++) - { - // If 8, 16, or 32 bit values are to be copied -#if CFG_TUD_AUDIO_N_BYTES_PER_SAMPLE_RX == CFG_TUD_AUDIO_RX_ITEMSIZE - // If this aborts then the target buffer is full - TU_VERIFY(tu_fifo_write_n(&audio->rx_supp_ff[cntChannel], &audio->lin_buf_out[idxSample], CFG_TUD_AUDIO_N_BYTES_PER_SAMPLE_RX)); -#else - uint32_t sample = audio->lin_buf_out[idxSample]; -#if CFG_TUD_AUDIO_JUSTIFICATION_RX == CFG_TUD_AUDIO_LEFT_JUSTIFIED - sample = sample << 8; -#endif + src = &audio->lin_buf_out[cnt_ff*nChannelsPerFF*CFG_TUD_AUDIO_N_BYTES_PER_SAMPLE_RX]; - TU_VERIFY(tu_fifo_write_n(&audio->rx_supp_ff[cntChannel], &sample, CFG_TUD_AUDIO_N_BYTES_PER_SAMPLE_RX)); -#endif - idxSample += CFG_TUD_AUDIO_N_BYTES_PER_SAMPLE_RX; + len = tu_fifo_get_linear_write_info(&audio->rx_supp_ff[cnt_ff], 0, &dst, nSamplesPerFFToRead); + tu_fifo_advance_write_pointer(&audio->rx_supp_ff[cnt_ff], len); + + dst_end = dst + len * CFG_TUD_AUDIO_N_BYTES_PER_SAMPLE_RX; + + while((uint8_t *)dst < dst_end) + { + memcpy(dst, src, nBytesToCopy); + dst = (uint8_t *)dst + nBytesToCopy; + src += nBytesToCopy * CFG_TUD_AUDIO_N_RX_SUPPORT_SW_FIFO; } - cnt += CFG_TUD_AUDIO_N_BYTES_PER_SAMPLE_RX * CFG_TUD_AUDIO_N_CHANNELS_RX; + // Handle wrapped part of FIFO + if (len < nSamplesPerFFToRead) + { + len = tu_fifo_get_linear_write_info(&audio->rx_supp_ff[cnt_ff], 0, &dst, nSamplesPerFFToRead - len); + tu_fifo_advance_write_pointer(&audio->rx_supp_ff[cnt_ff], len); + + dst_end = dst + len * CFG_TUD_AUDIO_N_BYTES_PER_SAMPLE_RX; + + while((uint8_t *)dst < dst_end) + { + memcpy(dst, src, nBytesToCopy); + dst = (uint8_t *)dst + nBytesToCopy; + src += nBytesToCopy * CFG_TUD_AUDIO_N_RX_SUPPORT_SW_FIFO; + } + } } // Number of bytes should be a multiple of CFG_TUD_AUDIO_N_BYTES_PER_SAMPLE_RX * CFG_TUD_AUDIO_N_CHANNELS_RX but checking makes no sense - no way to correct it @@ -469,13 +489,13 @@ uint16_t tud_audio_n_flush_tx_support_ff(uint8_t itf) // Force a bool tud_audio_n_clear_tx_support_ff(uint8_t itf, uint8_t channelId) { - TU_VERIFY(itf < CFG_TUD_AUDIO && _audiod_itf[itf].p_desc != NULL, channelId < CFG_TUD_AUDIO_N_CHANNELS_TX); + TU_VERIFY(itf < CFG_TUD_AUDIO && _audiod_itf[itf].p_desc != NULL, channelId < CFG_TUD_AUDIO_N_TX_SUPPORT_SW_FIFO); return tu_fifo_clear(&_audiod_itf[itf].tx_supp_ff[channelId]); } uint16_t tud_audio_n_write_support_ff(uint8_t itf, uint8_t channelId, const void * data, uint16_t len) { - TU_VERIFY(itf < CFG_TUD_AUDIO && _audiod_itf[itf].p_desc != NULL, channelId < CFG_TUD_AUDIO_N_CHANNELS_TX); + TU_VERIFY(itf < CFG_TUD_AUDIO && _audiod_itf[itf].p_desc != NULL, channelId < CFG_TUD_AUDIO_N_TX_SUPPORT_SW_FIFO); return tu_fifo_write_n(&_audiod_itf[itf].tx_supp_ff[channelId], data, len); } #endif @@ -590,60 +610,91 @@ static bool audiod_tx_done_cb(uint8_t rhport, audiod_interface_t * audio) #if CFG_TUD_AUDIO_TX_SUPPORT_SW_FIFO_SIZE && CFG_TUD_AUDIO_EPSIZE_IN // Take samples from the support buffer and encode them into the IN EP software FIFO // Returns number of bytes written into linear buffer + +/* 2.3.1.7.1 PCM Format +The PCM (Pulse Coded Modulation) format is the most commonly used audio format to represent audio +data streams. The audio data is not compressed and uses a signed two’s-complement fixed point format. It +is left-justified (the sign bit is the Msb) and data is padded with trailing zeros to fill the remaining unused +bits of the subslot. The binary point is located to the right of the sign bit so that all values lie within the +range [-1, +1) +*/ + +/* + * This function encodes channels saved within the support FIFOs into one stream by interleaving the PCM samples + * in the support FIFOs according to 2.3.1.5 Audio Streams. It does not control justification (left or right) and + * does not change the number of bytes per sample. + * */ + static uint16_t audiod_encode_type_I_pcm(uint8_t rhport, audiod_interface_t* audio) { - // We encode directly into IN EP's FIFO - abort if previous transfer not complete + // We encode directly into IN EP's linear buffer - abort if previous transfer not complete TU_VERIFY(!usbd_edpt_busy(rhport, audio->ep_in)); // Determine amount of samples - uint16_t const nEndpointSampleCapacity = CFG_TUD_AUDIO_EP_IN_SW_BUFFER_SIZE / CFG_TUD_AUDIO_N_CHANNELS_TX / CFG_TUD_AUDIO_N_BYTES_PER_SAMPLE_TX; - uint16_t nSamplesPerChannelToSend = tu_fifo_count(&audio->tx_supp_ff[0]); // We first look for the minimum number of bytes and afterwards convert it to sample size - uint8_t cntChannel; + uint16_t const nChannelsPerFF = CFG_TUD_AUDIO_N_CHANNELS_TX / CFG_TUD_AUDIO_N_TX_SUPPORT_SW_FIFO; + uint16_t const nBytesToCopy = nChannelsPerFF*CFG_TUD_AUDIO_N_BYTES_PER_SAMPLE_TX; + uint16_t const capSamplesPerFF = CFG_TUD_AUDIO_EP_IN_SW_BUFFER_SIZE / CFG_TUD_AUDIO_N_BYTES_PER_SAMPLE_TX / CFG_TUD_AUDIO_N_TX_SUPPORT_SW_FIFO; + uint16_t nSamplesPerFFToSend = tu_fifo_count(&audio->tx_supp_ff[0]); + uint8_t cnt_ff; - for (cntChannel = 1; cntChannel < CFG_TUD_AUDIO_N_CHANNELS_TX; cntChannel++) + for (cnt_ff = 1; cnt_ff < CFG_TUD_AUDIO_N_TX_SUPPORT_SW_FIFO; cnt_ff++) { - uint16_t const count = tu_fifo_count(&audio->tx_supp_ff[cntChannel]); - if (count < nSamplesPerChannelToSend) + uint16_t const count = tu_fifo_count(&audio->tx_supp_ff[cnt_ff]); + if (count < nSamplesPerFFToSend) { - nSamplesPerChannelToSend = count; + nSamplesPerFFToSend = count; } } - // Convert to sample size - nSamplesPerChannelToSend = nSamplesPerChannelToSend / CFG_TUD_AUDIO_N_BYTES_PER_SAMPLE_TX; - // Check if there is enough - if (nSamplesPerChannelToSend == 0) return 0; + if (nSamplesPerFFToSend == 0) return 0; // Limit to maximum sample number - THIS IS A POSSIBLE ERROR SOURCE IF TOO MANY SAMPLE WOULD NEED TO BE SENT BUT CAN NOT! - nSamplesPerChannelToSend = tu_min16(nSamplesPerChannelToSend, nEndpointSampleCapacity); + nSamplesPerFFToSend = tu_min16(nSamplesPerFFToSend, capSamplesPerFF); + + // Round to full number of samples (flooring) + nSamplesPerFFToSend = (nSamplesPerFFToSend / nChannelsPerFF) * nChannelsPerFF; // Encode - uint16_t cntSample; - uint16_t idxSample = 0; + void * src; + uint8_t * dst; + uint8_t * src_end; + uint16_t len; - for (cntSample = 0; cntSample < nSamplesPerChannelToSend; cntSample++) + for (cnt_ff = 0; cnt_ff < CFG_TUD_AUDIO_N_TX_SUPPORT_SW_FIFO; cnt_ff++) { - for (cntChannel = 0; cntChannel < CFG_TUD_AUDIO_N_CHANNELS_TX; cntChannel++) + dst = &audio->lin_buf_in[cnt_ff*nChannelsPerFF*CFG_TUD_AUDIO_N_BYTES_PER_SAMPLE_TX]; + + len = tu_fifo_get_linear_read_info(&audio->tx_supp_ff[cnt_ff], 0, &src, nSamplesPerFFToSend); + tu_fifo_advance_read_pointer(&audio->tx_supp_ff[cnt_ff], len); + + src_end = src + len * CFG_TUD_AUDIO_N_BYTES_PER_SAMPLE_TX; + + while((uint8_t *)src < src_end) { - // If 8, 16, or 32 bit values are to be copied -#if CFG_TUD_AUDIO_N_BYTES_PER_SAMPLE_TX == CFG_TUD_AUDIO_TX_ITEMSIZE - tu_fifo_read_n(&audio->tx_supp_ff[cntChannel], &audio->lin_buf_in[idxSample], CFG_TUD_AUDIO_TX_ITEMSIZE); -#else - uint32_t sample = 0; + memcpy(dst, src, nBytesToCopy); + src = (uint8_t *)src + nBytesToCopy; + dst += nBytesToCopy * CFG_TUD_AUDIO_N_TX_SUPPORT_SW_FIFO; + } - // Get sample from buffer - tu_fifo_read_n(&audio->tx_supp_ff[cntChannel], &sample, CFG_TUD_AUDIO_N_BYTES_PER_SAMPLE_TX); + // Handle wrapped part of FIFO + if (len < nSamplesPerFFToSend) + { + len = tu_fifo_get_linear_read_info(&audio->tx_supp_ff[cnt_ff], 0, &src, nSamplesPerFFToSend - len); + tu_fifo_advance_read_pointer(&audio->tx_supp_ff[cnt_ff], len); -#if CFG_TUD_AUDIO_JUSTIFICATION_TX == CFG_TUD_AUDIO_LEFT_JUSTIFIED - sample = sample << 8; -#endif - audio->lin_buf_in[idxSample] = sample; -#endif - idxSample += CFG_TUD_AUDIO_TX_ITEMSIZE; + src_end = src + len * CFG_TUD_AUDIO_N_BYTES_PER_SAMPLE_TX; + + while((uint8_t *)src < src_end) + { + memcpy(dst, src, nBytesToCopy); + src = (uint8_t *)src + nBytesToCopy; + dst += nBytesToCopy * CFG_TUD_AUDIO_N_TX_SUPPORT_SW_FIFO; + } } } - return nSamplesPerChannelToSend * CFG_TUD_AUDIO_N_CHANNELS_TX * CFG_TUD_AUDIO_TX_ITEMSIZE; + + return nSamplesPerFFToSend * CFG_TUD_AUDIO_N_TX_SUPPORT_SW_FIFO; } #endif //CFG_TUD_AUDIO_TX_SUPPORT_SW_FIFO_SIZE @@ -685,9 +736,9 @@ void audiod_init(void) // Initialize TX support FIFOs if required #if CFG_TUD_AUDIO_EPSIZE_IN && CFG_TUD_AUDIO_TX_SUPPORT_SW_FIFO_SIZE - for (uint8_t cnt = 0; cnt < CFG_TUD_AUDIO_N_CHANNELS_TX; cnt++) + for (uint8_t cnt = 0; cnt < CFG_TUD_AUDIO_N_TX_SUPPORT_SW_FIFO; cnt++) { - tu_fifo_config(&audio->tx_supp_ff[cnt], &audio->tx_supp_ff_buf[cnt], CFG_TUD_AUDIO_TX_SUPPORT_SW_FIFO_SIZE, 1, true); + tu_fifo_config(&audio->tx_supp_ff[cnt], &audio->tx_supp_ff_buf[cnt], CFG_TUD_AUDIO_TX_SUPPORT_SW_FIFO_SIZE, CFG_TUD_AUDIO_N_BYTES_PER_SAMPLE_TX, true); #if CFG_FIFO_MUTEX tu_fifo_config_mutex(&audio->tx_supp_ff[cnt], osal_mutex_create(&audio->tx_supp_ff_mutex_wr[cnt]), NULL); #endif @@ -696,9 +747,9 @@ void audiod_init(void) // Initialize RX support FIFOs if required #if CFG_TUD_AUDIO_EPSIZE_OUT && CFG_TUD_AUDIO_RX_SUPPORT_SW_FIFO_SIZE - for (uint8_t cnt = 0; cnt < CFG_TUD_AUDIO_N_CHANNELS_RX; cnt++) + for (uint8_t cnt = 0; cnt < CFG_TUD_AUDIO_N_RX_SUPPORT_SW_FIFO; cnt++) { - tu_fifo_config(&audio->rx_supp_ff[cnt], &audio->rx_supp_ff_buf[cnt], CFG_TUD_AUDIO_RX_SUPPORT_SW_FIFO_SIZE, 1, true); + tu_fifo_config(&audio->rx_supp_ff[cnt], &audio->rx_supp_ff_buf[cnt], CFG_TUD_AUDIO_RX_SUPPORT_SW_FIFO_SIZE, CFG_TUD_AUDIO_N_BYTES_PER_SAMPLE_RX, true); #if CFG_FIFO_MUTEX tu_fifo_config_mutex(&audio->rx_supp_ff[cnt], NULL, osal_mutex_create(&audio->rx_supp_ff_mutex_rd[cnt])); #endif @@ -725,14 +776,14 @@ void audiod_reset(uint8_t rhport) #endif #if CFG_TUD_AUDIO_EP_IN_SW_BUFFER_SIZE && CFG_TUD_AUDIO_TX_SUPPORT_SW_FIFO_SIZE - for (uint8_t cnt = 0; cnt < CFG_TUD_AUDIO_N_CHANNELS_TX; cnt++) + for (uint8_t cnt = 0; cnt < CFG_TUD_AUDIO_N_TX_SUPPORT_SW_FIFO; cnt++) { tu_fifo_clear(&audio->tx_supp_ff[cnt]); } #endif #if CFG_TUD_AUDIO_EP_OUT_SW_BUFFER_SIZE && CFG_TUD_AUDIO_RX_SUPPORT_SW_FIFO_SIZE - for (uint8_t cnt = 0; cnt < CFG_TUD_AUDIO_N_CHANNELS_RX; cnt++) + for (uint8_t cnt = 0; cnt < CFG_TUD_AUDIO_N_RX_SUPPORT_SW_FIFO; cnt++) { tu_fifo_clear(&audio->rx_supp_ff[cnt]); } diff --git a/src/class/audio/audio_device.h b/src/class/audio/audio_device.h index ca74d68f4..730d42c38 100644 --- a/src/class/audio/audio_device.h +++ b/src/class/audio/audio_device.h @@ -50,7 +50,7 @@ #error You must define an audio class control request buffer size! #endif -// End point sizes - Limits: Full Speed <= 1023, High Speed <= 1024 +// End point sizes IN BYTES - Limits: Full Speed <= 1023, High Speed <= 1024 #ifndef CFG_TUD_AUDIO_EPSIZE_IN #define CFG_TUD_AUDIO_EPSIZE_IN 0 // TX #endif @@ -76,13 +76,13 @@ #define CFG_TUD_AUDIO_EP_OUT_SW_BUFFER_SIZE 0 #endif -// General information of number of TX and/or RX channels - is used in case support FIFOs (see below) are used and can be used for descriptor definitions +// General information of number of TX and/or RX channels - is used in combination with support FIFOs (see below) and can be used for descriptor definitions #ifndef CFG_TUD_AUDIO_N_CHANNELS_TX -#define CFG_TUD_AUDIO_N_CHANNELS_TX 0 +#define CFG_TUD_AUDIO_N_CHANNELS_TX 1 #endif #ifndef CFG_TUD_AUDIO_N_CHANNELS_RX -#define CFG_TUD_AUDIO_N_CHANNELS_RX 0 +#define CFG_TUD_AUDIO_N_CHANNELS_RX 1 #endif // Use of TX/RX support FIFOs @@ -104,7 +104,7 @@ // The encoding/decoding starts when the private callback functions // - audio_tx_done_cb() // - audio_rx_done_cb() -// are invoked. If support FIFOs are used the corresponding encoding/decoding functions are called from there. +// are invoked. If support FIFOs are used, the corresponding encoding/decoding functions are called from there. // Once encoding/decoding is done the result is put directly into the EP_X_SW_BUFFER_FIFOs. You can use the public callback functions // - tud_audio_tx_done_pre_load_cb() or tud_audio_tx_done_post_load_cb() // - tud_audio_rx_done_pre_read_cb() or tud_audio_rx_done_post_read_cb() @@ -120,13 +120,31 @@ // - audio_rx_done_cb() // functions. -// Size of support FIFOs - if size > 0 there are as many FIFOs set up as TX/RX channels defined +// The number of support FIFOs and number of channels is decoupled. The PCM encoding/decoding works depending on the ratio CFG_TUD_AUDIO_N_CHANNELS_XX / CFG_TUD_AUDIO_N_XX_SUPPORT_SW_FIFO, where currently 1:1 and 2:1 is implemented. The version 2:1 is useful in case of I2S for which usually 2 are channels already interleaved available. + +// Size of support FIFOs IN SAMPLES - if size > 0 there are as many FIFOs set up as CFG_TUD_AUDIO_N_TX_SUPPORT_SW_FIFO and CFG_TUD_AUDIO_N_RX_SUPPORT_SW_FIFO #ifndef CFG_TUD_AUDIO_TX_SUPPORT_SW_FIFO_SIZE -#define CFG_TUD_AUDIO_TX_SUPPORT_SW_FIFO_SIZE 0 // Buffer size per channel - minimum size: ceil(f_s/1000)*CFG_TUD_AUDIO_N_BYTES_PER_SAMPLE_TX +#define CFG_TUD_AUDIO_TX_SUPPORT_SW_FIFO_SIZE 0 // FIFO size - minimum size: // ceil(f_s/1000) * CFG_TUD_AUDIO_N_CHANNELS_TX / CFG_TUD_AUDIO_N_TX_SUPPORT_SW_FIFO #endif #ifndef CFG_TUD_AUDIO_RX_SUPPORT_SW_FIFO_SIZE -#define CFG_TUD_AUDIO_RX_SUPPORT_SW_FIFO_SIZE 0 // Buffer size per channel - minimum size: ceil(f_s/1000)*CFG_TUD_AUDIO_N_BYTES_PER_SAMPLE_RX +#define CFG_TUD_AUDIO_RX_SUPPORT_SW_FIFO_SIZE 0 // FIFO size - minimum size: ceil(f_s/1000) * CFG_TUD_AUDIO_N_BYTES_PER_SAMPLE_RX * CFG_TUD_AUDIO_N_CHANNELS_RX / CFG_TUD_AUDIO_N_RX_SUPPORT_SW_FIFO +#endif + +#ifndef CFG_TUD_AUDIO_N_TX_SUPPORT_SW_FIFO +#if CFG_TUD_AUDIO_TX_SUPPORT_SW_FIFO_SIZE +#define CFG_TUD_AUDIO_N_TX_SUPPORT_SW_FIFO CFG_TUD_AUDIO_N_CHANNELS_TX // default size is equal to number of channels +#else +#define CFG_TUD_AUDIO_N_TX_SUPPORT_SW_FIFO 0 +#endif +#endif + +#ifndef CFG_TUD_AUDIO_N_RX_SUPPORT_SW_FIFO +#if CFG_TUD_AUDIO_RX_SUPPORT_SW_FIFO_SIZE +#define CFG_TUD_AUDIO_N_RX_SUPPORT_SW_FIFO CFG_TUD_AUDIO_N_CHANNELS_RX // default size is equal to number of channels +#else +#define CFG_TUD_AUDIO_N_RX_SUPPORT_SW_FIFO 0 +#endif #endif // Enable/disable feedback EP (required for asynchronous RX applications) @@ -167,20 +185,6 @@ #define CFG_TUD_AUDIO_N_BYTES_PER_SAMPLE_TX 1 #endif -#ifndef CFG_TUD_AUDIO_TX_ITEMSIZE -#if CFG_TUD_AUDIO_N_BYTES_PER_SAMPLE_TX == 1 -#define CFG_TUD_AUDIO_TX_ITEMSIZE 1 -#elif CFG_TUD_AUDIO_N_BYTES_PER_SAMPLE_TX == 2 -#define CFG_TUD_AUDIO_TX_ITEMSIZE 2 -#else -#define CFG_TUD_AUDIO_TX_ITEMSIZE 4 -#endif -#endif - -#if CFG_TUD_AUDIO_TX_ITEMSIZE < CFG_TUD_AUDIO_N_BYTES_PER_SAMPLE_TX -#error FIFO element size (ITEMSIZE) must not be smaller then sample size -#endif - #endif #if CFG_TUD_AUDIO_FORMAT_TYPE_RX == AUDIO_FORMAT_TYPE_I @@ -193,26 +197,6 @@ #define CFG_TUD_AUDIO_N_BYTES_PER_SAMPLE_RX 1 #endif -#if CFG_TUD_AUDIO_N_BYTES_PER_SAMPLE_RX == 1 -#define CFG_TUD_AUDIO_RX_ITEMSIZE 1 -#elif CFG_TUD_AUDIO_N_BYTES_PER_SAMPLE_RX == 2 -#define CFG_TUD_AUDIO_RX_ITEMSIZE 2 -#else -#define CFG_TUD_AUDIO_RX_ITEMSIZE 4 -#endif - -#endif - -// In case PCM encoding/decoding of 24 into 32 bits, the adjustment needs to be defined -#define CFG_TUD_AUDIO_LEFT_JUSTIFIED -#define CFG_TUD_AUDIO_RIGHT_JUSTIFIED - -#ifndef CFG_TUD_AUDIO_JUSTIFICATION_RX -#define CFG_TUD_AUDIO_JUSTIFICATION_RX CFG_TUD_AUDIO_LEFT_JUSTIFIED -#endif - -#ifndef CFG_TUD_AUDIO_JUSTIFICATION_TX -#define CFG_TUD_AUDIO_JUSTIFICATION_TX CFG_TUD_AUDIO_LEFT_JUSTIFIED #endif //static_assert(sizeof(tud_audio_desc_lengths) != CFG_TUD_AUDIO, "Supply audio function descriptor pack length!"); @@ -256,7 +240,7 @@ bool tud_audio_n_clear_ep_in_ff (uint8_t itf); #if CFG_TUD_AUDIO_TX_SUPPORT_SW_FIFO_SIZE && CFG_TUD_AUDIO_EPSIZE_IN uint16_t tud_audio_n_flush_tx_support_ff (uint8_t itf); // Force all content in the support TX FIFOs to be written into EP SW FIFO -bool tud_audio_n_clear_tx_support_ff (uint8_t itf, uint8_t channelId); +bool tud_audio_n_clear_tx_support_ff (uint8_t itf, uint8_t channelId); uint16_t tud_audio_n_write_support_ff (uint8_t itf, uint8_t channelId, const void * data, uint16_t len); #endif |
