11#pragma push_macro("abs")
22#pragma pop_macro("abs")
28#ifndef ARDUINO_USB_MODE
29#error This Microcontroller has no Native USB interface
31#if ARDUINO_USB_MODE == 1
32#error This sketch should be used when USB is in OTG mode
36#if !defined(USE_TINYUSB) && !defined(ARDUINO_ARCH_STM32) && \
37 !defined(ARDUINO_ARCH_RENESAS) && !defined(IS_ZEPHYR)
38#error This Microcontroller has no Native USB interface
42#include "AudioLogger.h"
47#define USB_DESCR_MAX_LEN 512
92static inline uint8_t
u16Low(uint16_t v) {
return (uint8_t)(v & 0xFF); }
93static inline uint8_t
u16High(uint16_t v) {
return (uint8_t)(v >> 8); }
270 LOGE(
"Unsupported bits_per_sample: %d (must be 16, 24, or 32)",
286 "Could not change channel count from %d to %d: channel count is "
292 "Could not change bits per sample from %d to %d: bits per sample is "
330 LOGE(
"Unsupported bits_per_sample: %d (must be 16, 24, or 32)",
344 uint16_t cb_sz = 64u;
348 if (needed > cb_sz) cb_sz = needed;
359 mute_.assign(vol_sz,
false);
365 LOGE(
"beginUSB failed");
375 for (uint8_t ch = 0; ch < (uint8_t)
volume_.size(); ch++) {
428 LOGW(
"setVolume %f channel: %d", vol, channel);
429 if (channel >=
volume_.size())
return false;
440 return (channel <
mute_.size()) ?
mute_[channel] :
false;
448 LOGW(
"setMute %s channel: %d", m ?
"true" :
"false", channel);
449 if (channel >=
mute_.size())
return false;
494 if (fct.ep_in != 0)
return true;
502 if (fct.ep_out != 0)
return true;
671 int normalized = percent;
672 if (normalized < 0) normalized = 0;
673 if (normalized > 100) normalized = 100;
684 size_t write(
const uint8_t* data,
size_t len) {
699 while (written < len) {
723 if (start_fill > 0 &&
bufferRx().levelPercent() < start_fill)
return 0;
753 std::fill(audio.lin_buf_in.begin(), audio.lin_buf_in.end(), 0);
754 std::fill(audio.lin_buf_out.begin(), audio.lin_buf_out.end(), 0);
863 uint16_t xferred_bytes)>
955 processVolume<int8_t>((int8_t*)data, len);
958 processVolume<int16_t>((int16_t*)data, len / 2);
964 processVolume<int32_t>((int32_t*)data, len / 4);
975 if (
volume_.empty())
return 1.0f;
976 if (
mute_[0])
return 0.0f;
978 if (channel >=
volume_.size())
return master;
979 if (
mute_[channel])
return 0.0f;
980 return master *
volume_[channel];
983 template <
typename T>
986 for (
size_t i = 0; i < sample_count; i++) {
987 uint8_t ch = (uint8_t)(i % ch_count) + 1;
989 data[i] = (T)(data[i] * vol);
1004 LOGW(
"Sample rate changed to %u Hz", rate);
1009 for (
auto& fct :
audiod_fct_) fct.sample_rate_tx = rate;
1035 if (vol <= 0.0f)
return (int16_t)0x8000;
1036 if (vol >= 1.0f)
return 0;
1043 if (v == (int16_t)0x8000)
return 0.0f;
1044 if (v >= 0)
return 1.0f;
1066 for (uint8_t i = 0; i < (uint8_t)
audiod_fct_.size(); i++) {
1092 return bps == 16 || bps == 24 || bps == 32;
1114 uint8_t frame_shift) {
1139 ((uint32_t)ff_count << 8);
1176 (
float)(1UL << (16u - (frame_shift - 1u))));
1252 uint8_t
const* raw_desc, uint16_t max_len) {
1271 uint8_t ep_in = 0, ep_out = 0, ep_fb = 0;
1272 uint16_t ep_in_size = 0, ep_out_size = 0;
1274 bool has_ep_out_view =
false;
1276 uint8_t
const* p_desc_end =
1278 while (p_desc_end - p_desc > 0) {
1285 if (desc_ep.
usage == 0) {
1289 ep_in_size = sz > ep_in_size ? sz : ep_in_size;
1294 ep_out_size = sz > ep_out_size ? sz : ep_out_size;
1295 desc_ep_out = desc_ep;
1296 has_ep_out_view =
true;
1305 LOGD(
"iso_alloc IN ep=0x%02x sz=%u: %s", ep_in, ep_in_size,
1306 alloc_ok ?
"OK" :
"FAIL");
1310 LOGD(
"iso_alloc OUT ep=0x%02x sz=%u: %s", ep_out, ep_out_size,
1311 alloc_ok ?
"OK" :
"FAIL");
1312 if (has_ep_out_view)
audiod_fct_[i].ep_out_view = desc_ep_out;
1322 LOGD(
"iso_activate OUT: done");
1337 uint8_t
const* p_desc_end =
1339 while (p_desc_end - p_desc > 0) {
1365 uint8_t
const* p_desc_end =
1367 while (p_desc_end - p_desc > 0) {
1376 LOGE(
" UAC2: interrupt EP 0x%02x open failed", ep_addr);
1416 if (entityID != 0) {
1419 uint8_t* cb =
audiod_fct_[func_id].ctrl_buf.data();
1453 this, rhport, p_request,
1468 this, rhport, p_request,
audiod_fct_[func_id].ctrl_buf.data());
1481 uint32_t xferred_bytes) {
1483 (void)xferred_bytes;
1484 for (uint8_t func_id = 0; func_id <
getAudioCount(); func_id++) {
1508 if (n < frame_bytes) memset(dst + n, 0, frame_bytes - n);
1517 if (xferred_bytes > 0) {
1519 (
int)xferred_bytes);
1520 if ((uint32_t)written < xferred_bytes)
1534 rx_done_cb_(
this, rhport, audio, (uint16_t)xferred_bytes);
1552 if (audio->
ep_fb != 0) {
1554 uint32_t
const interval =
1556 if (0 == (frame_count & (interval - 1))) {
1579 memcpy(cb, &rate, 4);
1586 uint16_t cnt = (uint16_t)rates.size();
1587 memcpy(cb, &cnt, 2);
1588 for (
size_t i = 0; i < rates.size(); i++) {
1589 uint32_t r = rates[i];
1591 memcpy(cb + 2 + i * 12, &r, 4);
1592 memcpy(cb + 2 + i * 12 + 4, &r, 4);
1593 memcpy(cb + 2 + i * 12 + 8, &z, 4);
1596 rhport, p_request, cb,
1597 (uint16_t)(2 + rates.size() * 12));
1602 memcpy(cb, &cnt, 2);
1603 memcpy(cb + 2, &rate, 4);
1604 memcpy(cb + 6, &rate, 4);
1605 memcpy(cb + 10, &z, 4);
1621 cb[0] =
isMute(channel) ? 1 : 0;
1632 int16_t vmin = -25600, vmax = 0, vres = 256;
1633 memcpy(cb + 0, &cnt, 2);
1634 memcpy(cb + 2, &vmin, 2);
1635 memcpy(cb + 4, &vmax, 2);
1636 memcpy(cb + 6, &vres, 2);
1647 uint8_t func_id = 0;
1648 uint8_t* cb =
audiod_fct_[func_id].ctrl_buf.data();
1727 return (entityID != 0)
1753 uint8_t
const* p_desc =
1758 uint8_t
const* p_desc_end =
descU16(p_desc + 6) + p_desc;
1763 while (p_desc_end - p_desc > 0) {
1764 if (p_desc[3] == entityID)
1781 uint8_t
const* p_desc_end =
1786 p_desc +=
descU16(p_desc + 6);
1790 while (p_desc_end - p_desc > 0) {
1809 uint8_t
const* p_desc_end =
audiod_fct_[i].p_desc +
1814 while (p_desc_end - p_desc > 0) {
1828 uint8_t
const* p_desc) {
1875 uint8_t
const** pp_desc_int) {
1878 uint8_t
const* p_desc_end =
1883 p_desc +=
descU16(p_desc + 6);
1888 while (p_desc_end - p_desc > 0) {
1895 *pp_desc_int = p_desc;
1915 uint8_t
const** pp_desc_int) {
1934 uint8_t func_id, idxItf;
1935 uint8_t
const* dummy;
1939 if (!
backend().controlTransfer(
1940 rhport, p_request, &
audiod_fct_[func_id].alt_setting[idxItf], 1))
1943 LOGI(
" Get itf: %u - current alt: %u", itf,
1950 bool apply_correction =
1953 if (apply_correction) {
1954 uint8_t* fb = (uint8_t*)audio->
fb_buf.data();
1980 (uint8_t*)audio->
fb_buf.data(),
1981 apply_correction ? 3 : 4);
2006 if (!
backend().usesIsoAlloc()) {
2036 if (
backend().usesIsoAlloc()) {
2052 uint8_t
const* p_desc_for_params) {
2113 switch (fb_param.
method) {
2123 if (fifo_depth == 0) fifo_depth = 1;
2124 uint16_t fifo_lvl_thr = fifo_depth / 2;
2134 ((uint32_t)fifo_lvl_thr) << 8;
2136 ((fb_param.
sample_freq / 100) << 16) / (frame_div / 100);
2154 uint8_t func_id, uint8_t itf, uint8_t alt) {
2155 uint8_t
const* p_desc = audio->
p_desc;
2156 uint8_t
const* p_desc_end =
2158 LOGD(
" openEPs: p_desc=%p end=%p len=%u itf=%u alt=%u",
2159 p_desc, p_desc_end, audio->
desc_length, itf, alt);
2161 while (p_desc_end - p_desc > 0) {
2165 uint8_t
const* p_desc_for_params =
2167 uint8_t foundEPs = 0;
2169 LOGD(
" matched itf=%u alt=%u nEps=%u", itf, alt, nEps);
2171 while (foundEPs < nEps && (p_desc_end - p_desc > 0)) {
2172 LOGD(
" scan: type=0x%02x len=%u offset=%d",
2173 p_desc[1], p_desc[0], (
int)(p_desc - audio->
p_desc));
2177 LOGD(
" activating ep=0x%02x type=%u...",
2180 LOGD(
" activateEndpoint FAILED");
2184 LOGD(
" activated OK");
2193 desc_ep.
usage == 0x00)
2194 openEpIn(rhport, audio, itf, desc_ep, p_desc_for_params);
2208 if (foundEPs != nEps)
return true;
2226 LOGD(
"SET_ITF itf=%u alt=%u [start]", itf, alt);
2228 uint8_t func_id, idxItf;
2229 uint8_t
const* p_desc;
2232 LOGD(
" AS interface %u not found", itf);
2236 LOGD(
" found func=%u idx=%u", func_id, idxItf);
2242 closeEpIn(rhport, audio, itf, p_request);
2253 bool enable_sof =
false;
2269 return value != 0 && (value & (value - 1)) == 0;
2274 while ((value >>= 1u) != 0u) result++;
2279 uint32_t mclk_freq) {
2289 if ((((1UL << k) * sample_freq / mclk_freq) + 1) > n_frame) {
2290 LOGE(
" UAC2 feedback interval too small");
2295 if ((mclk_freq % sample_freq) == 0 &&
2305 (float)sample_freq / (
float)mclk_freq *
2326 const uint8_t interval =
2329 const uint16_t sample_normimal = (uint16_t)(audio->
sample_rate_tx *
2330 interval / (full_speed ? 1000 : 8000));
2331 const uint16_t sample_reminder = (uint16_t)(audio->
sample_rate_tx *
2332 interval % (full_speed ? 1000 : 8000));
2334 const uint16_t packet_sz_tx_min =
2337 const uint16_t packet_sz_tx_norm =
2340 const uint16_t packet_sz_tx_max =
2345 if (packet_sz_tx_max > audio->
ep_in_sz)
return false;
2348 if (sample_reminder) {
2377 const uint32_t denom = full_speed ? 1000u : 8000u;
2379 const uint32_t interval = full_speed ? iv : (1u << (iv - 1));
2388 return (uint16_t)bytes;
#define LOGW(...)
Definition AudioLoggerIDF.h:29
#define LOGI(...)
Definition AudioLoggerIDF.h:28
#define LOGD(...)
Definition AudioLoggerIDF.h:27
#define LOGE(...)
Definition AudioLoggerIDF.h:30
#define USB_DESCR_MAX_LEN
Definition USBAudioDeviceBase.h:47
RxTxMode
The Microcontroller is the Audio Source (TX_MODE) or Audio Sink (RX_MODE). RXTX_MODE is Source and Si...
Definition AudioTypes.h:26
@ RXTX_MODE
Definition AudioTypes.h:26
@ TX_MODE
Definition AudioTypes.h:26
@ RX_MODE
Definition AudioTypes.h:26