Teensy 4.1 core updated for C++20
Du kan inte välja fler än 25 ämnen Ämnen måste starta med en bokstav eller siffra, kan innehålla bindestreck ('-') och vara max 35 tecken långa.

usb_audio.cpp 14KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524
  1. /* Teensyduino Core Library
  2. * http://www.pjrc.com/teensy/
  3. * Copyright (c) 2017 PJRC.COM, LLC.
  4. *
  5. * Permission is hereby granted, free of charge, to any person obtaining
  6. * a copy of this software and associated documentation files (the
  7. * "Software"), to deal in the Software without restriction, including
  8. * without limitation the rights to use, copy, modify, merge, publish,
  9. * distribute, sublicense, and/or sell copies of the Software, and to
  10. * permit persons to whom the Software is furnished to do so, subject to
  11. * the following conditions:
  12. *
  13. * 1. The above copyright notice and this permission notice shall be
  14. * included in all copies or substantial portions of the Software.
  15. *
  16. * 2. If the Software is incorporated into a build system that allows
  17. * selection among a list of target devices, then similar target
  18. * devices manufactured by PJRC.COM must be included in the list of
  19. * target devices and selectable in the same manner.
  20. *
  21. * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
  22. * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
  23. * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
  24. * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
  25. * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
  26. * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
  27. * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
  28. * SOFTWARE.
  29. */
  30. #include <Arduino.h>
  31. #include "usb_dev.h"
  32. #include "usb_audio.h"
  33. #include "debug/printf.h"
  34. #ifdef AUDIO_INTERFACE
  35. bool AudioInputUSB::update_responsibility;
  36. audio_block_t * AudioInputUSB::incoming_left;
  37. audio_block_t * AudioInputUSB::incoming_right;
  38. audio_block_t * AudioInputUSB::ready_left;
  39. audio_block_t * AudioInputUSB::ready_right;
  40. uint16_t AudioInputUSB::incoming_count;
  41. uint8_t AudioInputUSB::receive_flag;
  42. struct usb_audio_features_struct AudioInputUSB::features = {0,0,FEATURE_MAX_VOLUME/2};
  43. extern volatile uint8_t usb_high_speed;
  44. static void rx_event(transfer_t *t);
  45. static void tx_event(transfer_t *t);
  46. /*static*/ transfer_t rx_transfer __attribute__ ((used, aligned(32)));
  47. /*static*/ transfer_t sync_transfer __attribute__ ((used, aligned(32)));
  48. /*static*/ transfer_t tx_transfer __attribute__ ((used, aligned(32)));
  49. DMAMEM static uint8_t rx_buffer[AUDIO_RX_SIZE] __attribute__ ((aligned(32)));
  50. DMAMEM static uint8_t tx_buffer[AUDIO_RX_SIZE] __attribute__ ((aligned(32)));
  51. DMAMEM uint32_t usb_audio_sync_feedback __attribute__ ((aligned(32)));
  52. uint8_t usb_audio_receive_setting=0;
  53. uint8_t usb_audio_transmit_setting=0;
  54. uint8_t usb_audio_sync_nbytes;
  55. uint8_t usb_audio_sync_rshift;
  56. uint32_t feedback_accumulator;
  57. volatile uint32_t usb_audio_underrun_count;
  58. volatile uint32_t usb_audio_overrun_count;
  59. static void rx_event(transfer_t *t)
  60. {
  61. if (t) {
  62. int len = AUDIO_RX_SIZE - ((rx_transfer.status >> 16) & 0x7FFF);
  63. printf("rx %u\n", len);
  64. usb_audio_receive_callback(len);
  65. }
  66. usb_prepare_transfer(&rx_transfer, rx_buffer, AUDIO_RX_SIZE, 0);
  67. arm_dcache_delete(&rx_buffer, AUDIO_RX_SIZE);
  68. usb_receive(AUDIO_RX_ENDPOINT, &rx_transfer);
  69. }
  70. static void sync_event(transfer_t *t)
  71. {
  72. // USB 2.0 Specification, 5.12.4.2 Feedback, pages 73-75
  73. //printf("sync %x\n", sync_transfer.status); // too slow, can't print this much
  74. usb_audio_sync_feedback = feedback_accumulator >> usb_audio_sync_rshift;
  75. usb_prepare_transfer(&sync_transfer, &usb_audio_sync_feedback, usb_audio_sync_nbytes, 0);
  76. arm_dcache_flush(&usb_audio_sync_feedback, usb_audio_sync_nbytes);
  77. usb_transmit(AUDIO_SYNC_ENDPOINT, &sync_transfer);
  78. }
  79. void usb_audio_configure(void)
  80. {
  81. printf("usb_audio_configure\n");
  82. usb_audio_underrun_count = 0;
  83. usb_audio_overrun_count = 0;
  84. feedback_accumulator = 739875226; // 44.1 * 2^24
  85. if (usb_high_speed) {
  86. usb_audio_sync_nbytes = 4;
  87. usb_audio_sync_rshift = 8;
  88. } else {
  89. usb_audio_sync_nbytes = 3;
  90. usb_audio_sync_rshift = 10;
  91. }
  92. memset(&rx_transfer, 0, sizeof(rx_transfer));
  93. usb_config_rx_iso(AUDIO_RX_ENDPOINT, AUDIO_RX_SIZE, 1, rx_event);
  94. rx_event(NULL);
  95. memset(&sync_transfer, 0, sizeof(sync_transfer));
  96. usb_config_tx_iso(AUDIO_SYNC_ENDPOINT, usb_audio_sync_nbytes, 1, sync_event);
  97. sync_event(NULL);
  98. memset(&tx_transfer, 0, sizeof(tx_transfer));
  99. usb_config_tx_iso(AUDIO_TX_ENDPOINT, AUDIO_TX_SIZE, 1, tx_event);
  100. tx_event(NULL);
  101. }
  102. void AudioInputUSB::begin(void)
  103. {
  104. incoming_count = 0;
  105. incoming_left = NULL;
  106. incoming_right = NULL;
  107. ready_left = NULL;
  108. ready_right = NULL;
  109. receive_flag = 0;
  110. // update_responsibility = update_setup();
  111. // TODO: update responsibility is tough, partly because the USB
  112. // interrupts aren't sychronous to the audio library block size,
  113. // but also because the PC may stop transmitting data, which
  114. // means we no longer get receive callbacks from usb.c
  115. update_responsibility = false;
  116. }
  117. static void copy_to_buffers(const uint32_t *src, int16_t *left, int16_t *right, unsigned int len)
  118. {
  119. uint32_t *target = (uint32_t*) src + len;
  120. while ((src < target) && (((uintptr_t) left & 0x02) != 0)) {
  121. uint32_t n = *src++;
  122. *left++ = n & 0xFFFF;
  123. *right++ = n >> 16;
  124. }
  125. while ((src < target - 2)) {
  126. uint32_t n1 = *src++;
  127. uint32_t n = *src++;
  128. *(uint32_t *)left = (n1 & 0xFFFF) | ((n & 0xFFFF) << 16);
  129. left+=2;
  130. *(uint32_t *)right = (n1 >> 16) | ((n & 0xFFFF0000)) ;
  131. right+=2;
  132. }
  133. while ((src < target)) {
  134. uint32_t n = *src++;
  135. *left++ = n & 0xFFFF;
  136. *right++ = n >> 16;
  137. }
  138. }
  139. // Called from the USB interrupt when an isochronous packet arrives
  140. // we must completely remove it from the receive buffer before returning
  141. //
  142. #if 1
  143. void usb_audio_receive_callback(unsigned int len)
  144. {
  145. unsigned int count, avail;
  146. audio_block_t *left, *right;
  147. const uint32_t *data;
  148. AudioInputUSB::receive_flag = 1;
  149. len >>= 2; // 1 sample = 4 bytes: 2 left, 2 right
  150. data = (const uint32_t *)rx_buffer;
  151. count = AudioInputUSB::incoming_count;
  152. left = AudioInputUSB::incoming_left;
  153. right = AudioInputUSB::incoming_right;
  154. if (left == NULL) {
  155. left = AudioStream::allocate();
  156. if (left == NULL) return;
  157. AudioInputUSB::incoming_left = left;
  158. }
  159. if (right == NULL) {
  160. right = AudioStream::allocate();
  161. if (right == NULL) return;
  162. AudioInputUSB::incoming_right = right;
  163. }
  164. while (len > 0) {
  165. avail = AUDIO_BLOCK_SAMPLES - count;
  166. if (len < avail) {
  167. copy_to_buffers(data, left->data + count, right->data + count, len);
  168. AudioInputUSB::incoming_count = count + len;
  169. return;
  170. } else if (avail > 0) {
  171. copy_to_buffers(data, left->data + count, right->data + count, avail);
  172. data += avail;
  173. len -= avail;
  174. if (AudioInputUSB::ready_left || AudioInputUSB::ready_right) {
  175. // buffer overrun, PC sending too fast
  176. AudioInputUSB::incoming_count = count + avail;
  177. if (len > 0) {
  178. usb_audio_overrun_count++;
  179. printf("!");
  180. //serial_phex(len);
  181. }
  182. return;
  183. }
  184. send:
  185. AudioInputUSB::ready_left = left;
  186. AudioInputUSB::ready_right = right;
  187. //if (AudioInputUSB::update_responsibility) AudioStream::update_all();
  188. left = AudioStream::allocate();
  189. if (left == NULL) {
  190. AudioInputUSB::incoming_left = NULL;
  191. AudioInputUSB::incoming_right = NULL;
  192. AudioInputUSB::incoming_count = 0;
  193. return;
  194. }
  195. right = AudioStream::allocate();
  196. if (right == NULL) {
  197. AudioStream::release(left);
  198. AudioInputUSB::incoming_left = NULL;
  199. AudioInputUSB::incoming_right = NULL;
  200. AudioInputUSB::incoming_count = 0;
  201. return;
  202. }
  203. AudioInputUSB::incoming_left = left;
  204. AudioInputUSB::incoming_right = right;
  205. count = 0;
  206. } else {
  207. if (AudioInputUSB::ready_left || AudioInputUSB::ready_right) return;
  208. goto send; // recover from buffer overrun
  209. }
  210. }
  211. AudioInputUSB::incoming_count = count;
  212. }
  213. #endif
  214. void AudioInputUSB::update(void)
  215. {
  216. audio_block_t *left, *right;
  217. __disable_irq();
  218. left = ready_left;
  219. ready_left = NULL;
  220. right = ready_right;
  221. ready_right = NULL;
  222. uint16_t c = incoming_count;
  223. uint8_t f = receive_flag;
  224. receive_flag = 0;
  225. __enable_irq();
  226. if (f) {
  227. int diff = AUDIO_BLOCK_SAMPLES/2 - (int)c;
  228. feedback_accumulator += diff * 1;
  229. //uint32_t feedback = (feedback_accumulator >> 8) + diff * 100;
  230. //usb_audio_sync_feedback = feedback;
  231. //printf(diff >= 0 ? "." : "^");
  232. }
  233. //serial_phex(c);
  234. //serial_print(".");
  235. if (!left || !right) {
  236. usb_audio_underrun_count++;
  237. //printf("#"); // buffer underrun - PC sending too slow
  238. if (f) feedback_accumulator += 3500;
  239. }
  240. if (left) {
  241. transmit(left, 0);
  242. release(left);
  243. }
  244. if (right) {
  245. transmit(right, 1);
  246. release(right);
  247. }
  248. }
  249. #if 1
  250. bool AudioOutputUSB::update_responsibility;
  251. audio_block_t * AudioOutputUSB::left_1st;
  252. audio_block_t * AudioOutputUSB::left_2nd;
  253. audio_block_t * AudioOutputUSB::right_1st;
  254. audio_block_t * AudioOutputUSB::right_2nd;
  255. uint16_t AudioOutputUSB::offset_1st;
  256. /*DMAMEM*/ uint16_t usb_audio_transmit_buffer[AUDIO_TX_SIZE/2] __attribute__ ((used, aligned(32)));
  257. static void tx_event(transfer_t *t)
  258. {
  259. int len = usb_audio_transmit_callback();
  260. usb_audio_sync_feedback = feedback_accumulator >> usb_audio_sync_rshift;
  261. usb_prepare_transfer(&tx_transfer, usb_audio_transmit_buffer, len, 0);
  262. arm_dcache_flush_delete(usb_audio_transmit_buffer, len);
  263. usb_transmit(AUDIO_TX_ENDPOINT, &tx_transfer);
  264. }
  265. void AudioOutputUSB::begin(void)
  266. {
  267. update_responsibility = false;
  268. left_1st = NULL;
  269. right_1st = NULL;
  270. }
  271. static void copy_from_buffers(uint32_t *dst, int16_t *left, int16_t *right, unsigned int len)
  272. {
  273. // TODO: optimize...
  274. while (len > 0) {
  275. *dst++ = (*right++ << 16) | (*left++ & 0xFFFF);
  276. len--;
  277. }
  278. }
  279. void AudioOutputUSB::update(void)
  280. {
  281. audio_block_t *left, *right;
  282. // TODO: we shouldn't be writing to these......
  283. //left = receiveReadOnly(0); // input 0 = left channel
  284. //right = receiveReadOnly(1); // input 1 = right channel
  285. left = receiveWritable(0); // input 0 = left channel
  286. right = receiveWritable(1); // input 1 = right channel
  287. if (usb_audio_transmit_setting == 0) {
  288. if (left) release(left);
  289. if (right) release(right);
  290. if (left_1st) { release(left_1st); left_1st = NULL; }
  291. if (left_2nd) { release(left_2nd); left_2nd = NULL; }
  292. if (right_1st) { release(right_1st); right_1st = NULL; }
  293. if (right_2nd) { release(right_2nd); right_2nd = NULL; }
  294. offset_1st = 0;
  295. return;
  296. }
  297. if (left == NULL) {
  298. left = allocate();
  299. if (left == NULL) {
  300. if (right) release(right);
  301. return;
  302. }
  303. memset(left->data, 0, sizeof(left->data));
  304. }
  305. if (right == NULL) {
  306. right = allocate();
  307. if (right == NULL) {
  308. release(left);
  309. return;
  310. }
  311. memset(right->data, 0, sizeof(right->data));
  312. }
  313. __disable_irq();
  314. if (left_1st == NULL) {
  315. left_1st = left;
  316. right_1st = right;
  317. offset_1st = 0;
  318. } else if (left_2nd == NULL) {
  319. left_2nd = left;
  320. right_2nd = right;
  321. } else {
  322. // buffer overrun - PC is consuming too slowly
  323. audio_block_t *discard1 = left_1st;
  324. left_1st = left_2nd;
  325. left_2nd = left;
  326. audio_block_t *discard2 = right_1st;
  327. right_1st = right_2nd;
  328. right_2nd = right;
  329. offset_1st = 0; // TODO: discard part of this data?
  330. //serial_print("*");
  331. release(discard1);
  332. release(discard2);
  333. }
  334. __enable_irq();
  335. }
  336. // Called from the USB interrupt when ready to transmit another
  337. // isochronous packet. If we place data into the transmit buffer,
  338. // the return is the number of bytes. Otherwise, return 0 means
  339. // no data to transmit
  340. unsigned int usb_audio_transmit_callback(void)
  341. {
  342. static uint32_t count=5;
  343. uint32_t avail, num, target, offset, len=0;
  344. audio_block_t *left, *right;
  345. if (++count < 10) { // TODO: dynamic adjust to match USB rate
  346. target = 44;
  347. } else {
  348. count = 0;
  349. target = 45;
  350. }
  351. while (len < target) {
  352. num = target - len;
  353. left = AudioOutputUSB::left_1st;
  354. if (left == NULL) {
  355. // buffer underrun - PC is consuming too quickly
  356. memset(usb_audio_transmit_buffer + len, 0, num * 4);
  357. //serial_print("%");
  358. break;
  359. }
  360. right = AudioOutputUSB::right_1st;
  361. offset = AudioOutputUSB::offset_1st;
  362. avail = AUDIO_BLOCK_SAMPLES - offset;
  363. if (num > avail) num = avail;
  364. copy_from_buffers((uint32_t *)usb_audio_transmit_buffer + len,
  365. left->data + offset, right->data + offset, num);
  366. len += num;
  367. offset += num;
  368. if (offset >= AUDIO_BLOCK_SAMPLES) {
  369. AudioStream::release(left);
  370. AudioStream::release(right);
  371. AudioOutputUSB::left_1st = AudioOutputUSB::left_2nd;
  372. AudioOutputUSB::left_2nd = NULL;
  373. AudioOutputUSB::right_1st = AudioOutputUSB::right_2nd;
  374. AudioOutputUSB::right_2nd = NULL;
  375. AudioOutputUSB::offset_1st = 0;
  376. } else {
  377. AudioOutputUSB::offset_1st = offset;
  378. }
  379. }
  380. return target * 4;
  381. }
  382. #endif
  383. struct setup_struct {
  384. union {
  385. struct {
  386. uint8_t bmRequestType;
  387. uint8_t bRequest;
  388. union {
  389. struct {
  390. uint8_t bChannel; // 0=main, 1=left, 2=right
  391. uint8_t bCS; // Control Selector
  392. };
  393. uint16_t wValue;
  394. };
  395. union {
  396. struct {
  397. uint8_t bIfEp; // type of entity
  398. uint8_t bEntityId; // UnitID, TerminalID, etc.
  399. };
  400. uint16_t wIndex;
  401. };
  402. uint16_t wLength;
  403. };
  404. };
  405. };
  406. int usb_audio_get_feature(void *stp, uint8_t *data, uint32_t *datalen)
  407. {
  408. struct setup_struct setup = *((struct setup_struct *)stp);
  409. if (setup.bmRequestType==0xA1) { // should check bRequest, bChannel, and UnitID
  410. if (setup.bCS==0x01) { // mute
  411. data[0] = AudioInputUSB::features.mute; // 1=mute, 0=unmute
  412. *datalen = 1;
  413. return 1;
  414. }
  415. else if (setup.bCS==0x02) { // volume
  416. if (setup.bRequest==0x81) { // GET_CURR
  417. data[0] = AudioInputUSB::features.volume & 0xFF;
  418. data[1] = (AudioInputUSB::features.volume>>8) & 0xFF;
  419. }
  420. else if (setup.bRequest==0x82) { // GET_MIN
  421. //serial_print("vol get_min\n");
  422. data[0] = 0; // min level is 0
  423. data[1] = 0;
  424. }
  425. else if (setup.bRequest==0x83) { // GET_MAX
  426. data[0] = FEATURE_MAX_VOLUME & 0xFF; // max level, for range of 0 to MAX
  427. data[1] = (FEATURE_MAX_VOLUME>>8) & 0x0F;
  428. }
  429. else if (setup.bRequest==0x84) { // GET_RES
  430. data[0] = 1; // increment vol by by 1
  431. data[1] = 0;
  432. }
  433. else { // pass over SET_MEM, etc.
  434. return 0;
  435. }
  436. *datalen = 2;
  437. return 1;
  438. }
  439. }
  440. return 0;
  441. }
  442. int usb_audio_set_feature(void *stp, uint8_t *buf)
  443. {
  444. struct setup_struct setup = *((struct setup_struct *)stp);
  445. if (setup.bmRequestType==0x21) { // should check bRequest, bChannel and UnitID
  446. if (setup.bCS==0x01) { // mute
  447. if (setup.bRequest==0x01) { // SET_CUR
  448. AudioInputUSB::features.mute = buf[0]; // 1=mute,0=unmute
  449. AudioInputUSB::features.change = 1;
  450. return 1;
  451. }
  452. }
  453. else if (setup.bCS==0x02) { // volume
  454. if (setup.bRequest==0x01) { // SET_CUR
  455. AudioInputUSB::features.volume = buf[0] + (buf[1]<<8);
  456. AudioInputUSB::features.change = 1;
  457. return 1;
  458. }
  459. }
  460. }
  461. return 0;
  462. }
  463. #endif // AUDIO_INTERFACE