86 LOGE(
"Unsupported bits_per_sample: %d (must be 16, 24, or 32)",
96 LOGE(
"Only the sample rate can be changed after begin()");
127 LOGE(
"Unsupported bits_per_sample: %d (must be 16, 24, or 32)",
132 LOGE(
"Neither RX (enable_ep_in) nor TX (enable_ep_out) is enabled");
144 LOGE(
"beginUSB failed");
397 const uint8_t* desc, uint16_t len)
override {
410 LOGW(
"USB audio device %04x:%04x has no PCM streaming interface",
vid,
419 LOGI(
"USB audio device %04x:%04x (UAC%d) attached: mic=%d speaker=%d",
436 LOGI(
"USB audio device detached");
455 uint16_t len)
override {
462 if (len == 0)
return;
468 uint16_t
onIsoOut(uint8_t* data, uint16_t max)
override {
472 if (frame == 0)
return 0;
473 uint32_t samples = 0;
484 uint16_t bytes = (uint16_t)(samples * frame);
485 uint16_t max_aligned = (uint16_t)(max - (max % frame));
486 if (bytes > max_aligned) bytes = max_aligned;
491 memset(data, 0, bytes);
498 uint16_t to_read = bytes;
499 if (avail < to_read) to_read = (uint16_t)(avail - (avail % frame));
502 memset(data + read, 0, bytes - read);
533 if (tx > needed) needed = tx;
545 if (e.id ==
id)
return &e;
553 const uint8_t* p = desc;
554 const uint8_t*
end = desc + len;
560 bool has_pending =
false;
561 std::vector<AltSetting> all;
564 if (has_pending && pending.
has_ep && pending.
is_pcm) all.push_back(pending);
570 while (p + 2 <=
end && p[0] >= 2 && p + p[0] <=
end) {
600 bool is_feedback = ep.
usage == 1 ||
606 }
else if (!cur->
has_ep) {
616 for (
auto& a : all) {
618 LOGI(
"Ignoring alt %d of itf %d: %d channels, %d bytes/sample", a.alt,
619 a.itf, a.channels, a.subslot);
627 if (s.
present() && s.
alts[0].itf != a.itf)
continue;
632 return (uint16_t)(p - desc);
648 auto addSources = [&](uint8_t count_pos) {
649 if (n <= count_pos)
return;
650 uint8_t cnt = p[count_pos];
652 (uint16_t)(count_pos + 1 + j) < n;
719 for (uint8_t ch = 0; ch <=
kMaxChannels && 5 + ch * 4 + 4 <= n - 1;
721 uint32_t ctrl =
descU32(p + 5 + ch * 4);
722 if ((ctrl & 0x03) == 0x03) e.
mute_mask |= (1u << ch);
723 if (((ctrl >> 2) & 0x03) == 0x03) e.
volume_mask |= (1u << ch);
727 if (size == 0 || n < 7)
return;
728 for (uint8_t ch = 0; ch <=
kMaxChannels && 6 + (ch + 1) * size <= n - 1;
730 uint8_t ctrl = p[6 + ch * size];
731 if (ctrl & 0x01) e.
mute_mask |= (1u << ch);
764 uint8_t freq_type = p[7];
765 if (freq_type == 0 && n >= 14) {
771 for (uint8_t j = 0; j < freq_type && j <
kMaxRates &&
772 8 + (j + 1) * 3 <= n;
782 return (uint32_t)p[0] | ((uint32_t)p[1] << 8) | ((uint32_t)p[2] << 16);
789 uint8_t link = s.
alts[0].terminal_link;
791 if (term ==
nullptr)
return;
799 for (
int depth = 0; depth < 8 && e && e->
source_count > 0; depth++) {
808 uint8_t
id = term->
id;
809 for (
int depth = 0; depth < 8 && fu ==
nullptr; depth++) {
815 for (uint8_t j = 0; j < e.source_count; j++) {
816 if (e.sources[j] ==
id)
next = &e;
820 if (
next ==
nullptr)
break;
830 LOGI(
"%s: itf %d, %d alt settings, feature unit %d, clock %d",
831 is_rx ?
"mic" :
"speaker", s.
alts[0].itf, (int)s.
alts.size(),
837 for (
int depth = 0; depth < 4 &&
id != 0; depth++) {
839 if (e ==
nullptr)
return id;
851 const std::vector<RateRange>& clock, uint32_t rate) {
854 if (clock.empty())
return true;
855 for (
auto& r : clock) {
856 if (rate < r.min || rate > r.max)
continue;
857 if (r.res == 0 || (rate - r.min) % r.res == 0)
return true;
864 if (a.
rates[j] == rate)
return true;
871 uint32_t samples = (rate + pps - 1) / pps;
878 if (interval > 4) interval = 4;
880 return (uint16_t)(base >> (interval - 1));
885 const std::vector<RateRange>& clock,
888 static const uint32_t common[] = {48000, 44100, 32000, 24000, 22050,
889 16000, 11025, 8000, 96000, 88200};
891 uint32_t best_diff = UINT32_MAX;
892 auto consider = [&](uint32_t r) {
894 uint32_t diff = r > wanted ? r - wanted : wanted - r;
895 if (diff < best_diff) {
901 for (
auto& r : clock) {
908 for (
auto r : common) consider(r);
916 if (!s.
present())
return false;
919 uint32_t best_rate = 0;
920 for (
int j = 0; j < (int)s.
alts.size(); j++) {
923 if (rate == 0)
continue;
929 if (score > best_score ||
930 (score == best_score &&
937 if (best < 0)
return false;
939 LOGE(
"The attached device does not support %d Hz, %d channels, %d bits",
948 LOGI(
"Selected itf %d alt %d: %d Hz, %d channels, %d bits",
949 s.
alts[best].itf, s.
alts[best].alt, (
int)best_rate,
956 bool issueControl(uint8_t request_type, uint8_t request, uint16_t value,
957 uint16_t index, uint16_t length) {
997 for (
int j = 0; j < 4; j++)
ctrl_buf_[j] = (uint8_t)(rate >> (8 * j));
1005 for (
int j = 0; j < 3; j++)
ctrl_buf_[j] = (uint8_t)(rate >> (8 * j));
1035 ctrl_buf_[1] = (uint8_t)((uint16_t)value >> 8);
1041 (uint16_t)((selector << 8) | ch),
1050 for (uint16_t j = 0; j < count && 2 + (j + 1) * 12 <=
ctrl_len_; j++) {
1055 ranges.push_back(r);
1061 if (vol <= 0.0f)
return s.
vol_min;
1062 if (vol >= 1.0f)
return s.
vol_max;
1073 LOGW(
"USB audio control request timed out");
1146 if (!rx_ok && !tx_ok) {
1147 LOGE(
"No usable audio stream on the attached device");
1156 LOGW(
"Shared clock: using %d Hz for both streams",
1249 uint32_t len = 2 + 12u * count;
1254 for (
auto& r : ranges) {
1255 LOGI(
"Clock %d: %d - %d Hz (res %d)", s.
clock_id, (
int)r.min,
1256 (
int)r.max, (
int)r.res);
1301 if (ok && !is_rx && a.
has_fb) {
1359 LOGE(
"USB audio device could not be started");
1364 if (!(negotiated ==
info)) {
1418 if ((mask & (1u << ch)) == 0) {
1422 if (mask & (1u << c)) {
1443 if (!
ctrl_ok_)
LOGW(
"USB audio feature unit request failed");
1452 }
else if (len >= 4) {
1460 if (nom == 0)
return;
1461 uint32_t delta = nom >> 3;
1462 auto plausible = [&](uint32_t v) {
return v > nom - delta && v < nom + delta; };
1463 if (plausible(value)) {
1465 }
else if (len >= 4 && plausible(value << 2)) {
#define LOGW(...)
Definition AudioLoggerIDF.h:29
#define LOGI(...)
Definition AudioLoggerIDF.h:28
#define LOGE(...)
Definition AudioLoggerIDF.h:30
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