Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix UAC encoding, update example. #2259

Merged
merged 9 commits into from
Oct 11, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions examples/device/audio_4_channel_mic/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,11 @@ target_include_directories(${PROJECT} PUBLIC
${CMAKE_CURRENT_SOURCE_DIR}/src
)

# Add libm for GCC
if (CMAKE_C_COMPILER_ID STREQUAL "GNU")
target_link_libraries(${PROJECT} PUBLIC m)
endif()

# Configure compilation flags and libraries for the example without RTOS.
# See the corresponding function in hw/bsp/FAMILY/family.cmake for details.
family_configure_device_example(${PROJECT} noos)
5 changes: 4 additions & 1 deletion examples/device/audio_4_channel_mic/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,10 @@ INC += \
$(TOP)/hw \

# Example source
EXAMPLE_SOURCE += $(wildcard src/*.c)
EXAMPLE_SOURCE += \
src/main.c \
src/usb_descriptors.c \

SRC_C += $(addprefix $(CURRENT_PATH)/, $(EXAMPLE_SOURCE))

include ../../rules.mk
1 change: 1 addition & 0 deletions examples/device/audio_4_channel_mic/skip.txt
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
mcu:SAMD11
mcu:SAME5X
mcu:SAMG
family:broadcom_64bit
58 changes: 36 additions & 22 deletions examples/device/audio_4_channel_mic/src/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -34,17 +34,16 @@
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <math.h>

#include "bsp/board_api.h"
#include "tusb.h"
#include "tusb_config.h"

//--------------------------------------------------------------------+
// MACRO CONSTANT TYPEDEF PROTYPES
//--------------------------------------------------------------------+

#ifndef AUDIO_SAMPLE_RATE
#define AUDIO_SAMPLE_RATE 48000
#endif
#define AUDIO_SAMPLE_RATE CFG_TUD_AUDIO_FUNC_1_SAMPLE_RATE

/* Blink pattern
* - 250 ms : device not mounted
Expand All @@ -70,7 +69,7 @@ uint8_t clkValid;
audio_control_range_2_n_t(1) volumeRng[CFG_TUD_AUDIO_FUNC_1_N_CHANNELS_TX+1]; // Volume range state
audio_control_range_4_n_t(1) sampleFreqRng; // Sample frequency range state

// Audio test data
// Audio test data, each buffer contains 2 channels, buffer[0] for CH0-1, buffer[1] for CH1-2
uint16_t i2s_dummy_buffer[CFG_TUD_AUDIO_FUNC_1_N_TX_SUPP_SW_FIFO][CFG_TUD_AUDIO_FUNC_1_TX_SUPP_SW_FIFO_SZ/2]; // Ensure half word aligned

void led_blinking_task(void);
Expand All @@ -97,6 +96,27 @@ int main(void)
sampleFreqRng.subrange[0].bMax = AUDIO_SAMPLE_RATE;
sampleFreqRng.subrange[0].bRes = 0;

// Generate dummy data
uint16_t * p_buff = i2s_dummy_buffer[0];
uint16_t dataVal = 1;
for (uint16_t cnt = 0; cnt < AUDIO_SAMPLE_RATE/1000; cnt++)
{
// CH0 saw wave
*p_buff++ = dataVal;
// CH1 inverted saw wave
*p_buff++ = 60 + AUDIO_SAMPLE_RATE/1000 - dataVal;
dataVal++;
}
p_buff = i2s_dummy_buffer[1];
for (uint16_t cnt = 0; cnt < AUDIO_SAMPLE_RATE/1000; cnt++)
{
// CH3 square wave
*p_buff++ = cnt < (AUDIO_SAMPLE_RATE/1000/2) ? 120:170;
// CH4 sinus wave
float t = 2*3.1415f * cnt / (AUDIO_SAMPLE_RATE/1000);
*p_buff++ = (uint16_t)(sinf(t) * 25) + 200;
}

while (1)
{
tud_task(); // tinyusb device task
Expand Down Expand Up @@ -400,7 +420,17 @@ bool tud_audio_tx_done_pre_load_cb(uint8_t rhport, uint8_t itf, uint8_t ep_in, u
(void) ep_in;
(void) cur_alt_setting;

for (uint8_t cnt=0; cnt < CFG_TUD_AUDIO_FUNC_1_N_TX_SUPP_SW_FIFO; cnt++)

// In read world application data flow is driven by I2S clock,
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In real world ;)

// both tud_audio_tx_done_pre_load_cb() & tud_audio_tx_done_post_load_cb() are hardly used.
// For example in your I2S receive callback:
// void I2S_Rx_Callback(int channel, const void* data, uint16_t samples)
// {
// tud_audio_write_support_ff(channel, data, samples * N_BYTES_PER_SAMPLE * N_CHANNEL_PER_FIFO);
// }

// Write I2S buffer into FIFO
for (uint8_t cnt=0; cnt < 2; cnt++)
{
tud_audio_write_support_ff(cnt, i2s_dummy_buffer[cnt], AUDIO_SAMPLE_RATE/1000 * CFG_TUD_AUDIO_FUNC_1_N_BYTES_PER_SAMPLE_TX * CFG_TUD_AUDIO_FUNC_1_CHANNEL_PER_FIFO_TX);
}
Expand All @@ -416,22 +446,6 @@ bool tud_audio_tx_done_post_load_cb(uint8_t rhport, uint16_t n_bytes_copied, uin
(void) ep_in;
(void) cur_alt_setting;

uint16_t dataVal;

// Generate dummy data
for (uint16_t cnt = 0; cnt < CFG_TUD_AUDIO_FUNC_1_N_TX_SUPP_SW_FIFO; cnt++)
{
uint16_t * p_buff = i2s_dummy_buffer[cnt]; // 2 bytes per sample
dataVal = 1;
for (uint16_t cnt2 = 0; cnt2 < AUDIO_SAMPLE_RATE/1000; cnt2++)
{
for (uint8_t cnt3 = 0; cnt3 < CFG_TUD_AUDIO_FUNC_1_CHANNEL_PER_FIFO_TX; cnt3++)
{
*p_buff++ = dataVal;
}
dataVal++;
}
}
return true;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
# print(sd.query_devices())

fs = 48000 # Sample rate
duration = 100e-3 # Duration of recording
duration = 20e-3 # Duration of recording

if platform.system() == 'Windows':
# WDM-KS is needed since there are more than one MicNode device APIs (at least in Windows)
Expand All @@ -25,9 +25,14 @@
sd.wait() # Wait until recording is finished
print('Done!')


time = np.arange(0, duration, 1 / fs) # time vector
# strip starting zero
myrecording = myrecording[100:]
time = time[100:]
plt.plot(time, myrecording)
plt.xlabel('Time [s]')
plt.ylabel('Amplitude')
plt.title('MicNode 4 Channel')
plt.legend(['CH-1', 'CH-2', 'CH-3','CH-4'])
plt.show()
3 changes: 2 additions & 1 deletion examples/device/audio_4_channel_mic/src/tusb_config.h
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,7 @@ extern "C" {
//--------------------------------------------------------------------

// Have a look into audio_device.h for all configurations
#define CFG_TUD_AUDIO_FUNC_1_SAMPLE_RATE 48000

#define CFG_TUD_AUDIO_FUNC_1_DESC_LEN TUD_AUDIO_MIC_FOUR_CH_DESC_LEN

Expand All @@ -112,7 +113,7 @@ extern "C" {
#define CFG_TUD_AUDIO_ENABLE_EP_IN 1
#define CFG_TUD_AUDIO_FUNC_1_N_BYTES_PER_SAMPLE_TX 2 // This value is not required by the driver, it parses this information from the descriptor once the alternate interface is set by the host - we use it for the setup
#define CFG_TUD_AUDIO_FUNC_1_N_CHANNELS_TX 4 // This value is not required by the driver, it parses this information from the descriptor once the alternate interface is set by the host - we use it for the setup
#define CFG_TUD_AUDIO_EP_SZ_IN (48 + 1) * CFG_TUD_AUDIO_FUNC_1_N_BYTES_PER_SAMPLE_TX * CFG_TUD_AUDIO_FUNC_1_N_CHANNELS_TX // 48 Samples (48 kHz) x 2 Bytes/Sample x CFG_TUD_AUDIO_N_CHANNELS_TX Channels - the Windows driver always needs an extra sample per channel of space more, otherwise it complains... found by trial and error
#define CFG_TUD_AUDIO_EP_SZ_IN TUD_AUDIO_EP_SIZE(CFG_TUD_AUDIO_FUNC_1_SAMPLE_RATE, CFG_TUD_AUDIO_FUNC_1_N_BYTES_PER_SAMPLE_TX, CFG_TUD_AUDIO_FUNC_1_N_CHANNELS_TX)
#define CFG_TUD_AUDIO_FUNC_1_EP_IN_SZ_MAX CFG_TUD_AUDIO_EP_SZ_IN
#define CFG_TUD_AUDIO_FUNC_1_EP_IN_SW_BUF_SZ CFG_TUD_AUDIO_EP_SZ_IN

Expand Down
Loading