Teensy 4.1 core updated for C++20
Nevar pievienot vairāk kā 25 tēmas Tēmai ir jāsākas ar burtu vai ciparu, tā var saturēt domu zīmes ('-') un var būt līdz 35 simboliem gara.

pirms 8 gadiem
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448
  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. #ifdef AUDIO_INTERFACE // defined by usb_dev.h -> usb_desc.h
  33. #if F_CPU >= 20000000
  34. // Uncomment this to work around a limitation in Macintosh adaptive rates
  35. // This is not a perfect solution. Details here:
  36. // https://forum.pjrc.com/threads/34855-Distorted-audio-when-using-USB-input-on-Teensy-3-1
  37. //#define MACOSX_ADAPTIVE_LIMIT
  38. bool AudioInputUSB::update_responsibility;
  39. audio_block_t * AudioInputUSB::incoming_left;
  40. audio_block_t * AudioInputUSB::incoming_right;
  41. audio_block_t * AudioInputUSB::ready_left;
  42. audio_block_t * AudioInputUSB::ready_right;
  43. uint16_t AudioInputUSB::incoming_count;
  44. uint8_t AudioInputUSB::receive_flag;
  45. struct usb_audio_features_struct AudioInputUSB::features = {0,0,FEATURE_MAX_VOLUME/2};
  46. #define DMABUFATTR __attribute__ ((section(".dmabuffers"), aligned (4)))
  47. uint16_t usb_audio_receive_buffer[AUDIO_RX_SIZE/2] DMABUFATTR;
  48. uint32_t usb_audio_sync_feedback DMABUFATTR;
  49. uint8_t usb_audio_receive_setting=0;
  50. static uint32_t feedback_accumulator = 185042824;
  51. void AudioInputUSB::begin(void)
  52. {
  53. incoming_count = 0;
  54. incoming_left = NULL;
  55. incoming_right = NULL;
  56. ready_left = NULL;
  57. ready_right = NULL;
  58. receive_flag = 0;
  59. // update_responsibility = update_setup();
  60. // TODO: update responsibility is tough, partly because the USB
  61. // interrupts aren't sychronous to the audio library block size,
  62. // but also because the PC may stop transmitting data, which
  63. // means we no longer get receive callbacks from usb_dev.
  64. update_responsibility = false;
  65. usb_audio_sync_feedback = feedback_accumulator >> 8;
  66. }
  67. static void copy_to_buffers(const uint32_t *src, int16_t *left, int16_t *right, unsigned int len)
  68. {
  69. uint32_t *target = (uint32_t*) src + len;
  70. while ((src < target) && (((uintptr_t) left & 0x02) != 0)) {
  71. uint32_t n = *src++;
  72. *left++ = n & 0xFFFF;
  73. *right++ = n >> 16;
  74. }
  75. while ((src < target - 2)) {
  76. uint32_t n1 = *src++;
  77. uint32_t n = *src++;
  78. *(uint32_t *)left = (n1 & 0xFFFF) | ((n & 0xFFFF) << 16);
  79. left+=2;
  80. *(uint32_t *)right = (n1 >> 16) | ((n & 0xFFFF0000)) ;
  81. right+=2;
  82. }
  83. while ((src < target)) {
  84. uint32_t n = *src++;
  85. *left++ = n & 0xFFFF;
  86. *right++ = n >> 16;
  87. }
  88. }
  89. // Called from the USB interrupt when an isochronous packet arrives
  90. // we must completely remove it from the receive buffer before returning
  91. //
  92. void usb_audio_receive_callback(unsigned int len)
  93. {
  94. unsigned int count, avail;
  95. audio_block_t *left, *right;
  96. const uint32_t *data;
  97. AudioInputUSB::receive_flag = 1;
  98. len >>= 2; // 1 sample = 4 bytes: 2 left, 2 right
  99. data = (const uint32_t *)usb_audio_receive_buffer;
  100. count = AudioInputUSB::incoming_count;
  101. left = AudioInputUSB::incoming_left;
  102. right = AudioInputUSB::incoming_right;
  103. if (left == NULL) {
  104. left = AudioStream::allocate();
  105. if (left == NULL) return;
  106. AudioInputUSB::incoming_left = left;
  107. }
  108. if (right == NULL) {
  109. right = AudioStream::allocate();
  110. if (right == NULL) return;
  111. AudioInputUSB::incoming_right = right;
  112. }
  113. while (len > 0) {
  114. avail = AUDIO_BLOCK_SAMPLES - count;
  115. if (len < avail) {
  116. copy_to_buffers(data, left->data + count, right->data + count, len);
  117. AudioInputUSB::incoming_count = count + len;
  118. return;
  119. } else if (avail > 0) {
  120. copy_to_buffers(data, left->data + count, right->data + count, avail);
  121. data += avail;
  122. len -= avail;
  123. if (AudioInputUSB::ready_left || AudioInputUSB::ready_right) {
  124. // buffer overrun, PC sending too fast
  125. AudioInputUSB::incoming_count = count + avail;
  126. //if (len > 0) {
  127. //serial_print("!");
  128. //serial_phex(len);
  129. //}
  130. return;
  131. }
  132. send:
  133. AudioInputUSB::ready_left = left;
  134. AudioInputUSB::ready_right = right;
  135. //if (AudioInputUSB::update_responsibility) AudioStream::update_all();
  136. left = AudioStream::allocate();
  137. if (left == NULL) {
  138. AudioInputUSB::incoming_left = NULL;
  139. AudioInputUSB::incoming_right = NULL;
  140. AudioInputUSB::incoming_count = 0;
  141. return;
  142. }
  143. right = AudioStream::allocate();
  144. if (right == NULL) {
  145. AudioStream::release(left);
  146. AudioInputUSB::incoming_left = NULL;
  147. AudioInputUSB::incoming_right = NULL;
  148. AudioInputUSB::incoming_count = 0;
  149. return;
  150. }
  151. AudioInputUSB::incoming_left = left;
  152. AudioInputUSB::incoming_right = right;
  153. count = 0;
  154. } else {
  155. if (AudioInputUSB::ready_left || AudioInputUSB::ready_right) return;
  156. goto send; // recover from buffer overrun
  157. }
  158. }
  159. AudioInputUSB::incoming_count = count;
  160. }
  161. void AudioInputUSB::update(void)
  162. {
  163. audio_block_t *left, *right;
  164. __disable_irq();
  165. left = ready_left;
  166. ready_left = NULL;
  167. right = ready_right;
  168. ready_right = NULL;
  169. uint16_t c = incoming_count;
  170. uint8_t f = receive_flag;
  171. receive_flag = 0;
  172. __enable_irq();
  173. if (f) {
  174. int diff = AUDIO_BLOCK_SAMPLES/2 - (int)c;
  175. feedback_accumulator += diff / 3;
  176. uint32_t feedback = (feedback_accumulator >> 8) + diff * 100;
  177. #ifdef MACOSX_ADAPTIVE_LIMIT
  178. if (feedback > 722698) feedback = 722698;
  179. #endif
  180. usb_audio_sync_feedback = feedback;
  181. //if (diff > 0) {
  182. //serial_print(".");
  183. //} else if (diff < 0) {
  184. //serial_print("^");
  185. //}
  186. }
  187. //serial_phex(c);
  188. //serial_print(".");
  189. if (!left || !right) {
  190. //serial_print("#"); // buffer underrun - PC sending too slow
  191. //if (f) feedback_accumulator += 10 << 8;
  192. }
  193. if (left) {
  194. transmit(left, 0);
  195. release(left);
  196. }
  197. if (right) {
  198. transmit(right, 1);
  199. release(right);
  200. }
  201. }
  202. bool AudioOutputUSB::update_responsibility;
  203. audio_block_t * AudioOutputUSB::left_1st;
  204. audio_block_t * AudioOutputUSB::left_2nd;
  205. audio_block_t * AudioOutputUSB::right_1st;
  206. audio_block_t * AudioOutputUSB::right_2nd;
  207. uint16_t AudioOutputUSB::offset_1st;
  208. uint16_t usb_audio_transmit_buffer[AUDIO_TX_SIZE/2] DMABUFATTR;
  209. uint8_t usb_audio_transmit_setting=0;
  210. void AudioOutputUSB::begin(void)
  211. {
  212. update_responsibility = false;
  213. left_1st = NULL;
  214. right_1st = NULL;
  215. }
  216. static void copy_from_buffers(uint32_t *dst, int16_t *left, int16_t *right, unsigned int len)
  217. {
  218. // TODO: optimize...
  219. while (len > 0) {
  220. *dst++ = (*right++ << 16) | (*left++ & 0xFFFF);
  221. len--;
  222. }
  223. }
  224. void AudioOutputUSB::update(void)
  225. {
  226. audio_block_t *left, *right;
  227. // TODO: we shouldn't be writing to these......
  228. //left = receiveReadOnly(0); // input 0 = left channel
  229. //right = receiveReadOnly(1); // input 1 = right channel
  230. left = receiveWritable(0); // input 0 = left channel
  231. right = receiveWritable(1); // input 1 = right channel
  232. if (usb_audio_transmit_setting == 0) {
  233. if (left) release(left);
  234. if (right) release(right);
  235. if (left_1st) { release(left_1st); left_1st = NULL; }
  236. if (left_2nd) { release(left_2nd); left_2nd = NULL; }
  237. if (right_1st) { release(right_1st); right_1st = NULL; }
  238. if (right_2nd) { release(right_2nd); right_2nd = NULL; }
  239. offset_1st = 0;
  240. return;
  241. }
  242. if (left == NULL) {
  243. left = allocate();
  244. if (left == NULL) {
  245. if (right) release(right);
  246. return;
  247. }
  248. memset(left->data, 0, sizeof(left->data));
  249. }
  250. if (right == NULL) {
  251. right = allocate();
  252. if (right == NULL) {
  253. release(left);
  254. return;
  255. }
  256. memset(right->data, 0, sizeof(right->data));
  257. }
  258. __disable_irq();
  259. if (left_1st == NULL) {
  260. left_1st = left;
  261. right_1st = right;
  262. offset_1st = 0;
  263. } else if (left_2nd == NULL) {
  264. left_2nd = left;
  265. right_2nd = right;
  266. } else {
  267. // buffer overrun - PC is consuming too slowly
  268. audio_block_t *discard1 = left_1st;
  269. left_1st = left_2nd;
  270. left_2nd = left;
  271. audio_block_t *discard2 = right_1st;
  272. right_1st = right_2nd;
  273. right_2nd = right;
  274. offset_1st = 0; // TODO: discard part of this data?
  275. //serial_print("*");
  276. release(discard1);
  277. release(discard2);
  278. }
  279. __enable_irq();
  280. }
  281. // Called from the USB interrupt when ready to transmit another
  282. // isochronous packet. If we place data into the transmit buffer,
  283. // the return is the number of bytes. Otherwise, return 0 means
  284. // no data to transmit
  285. unsigned int usb_audio_transmit_callback(void)
  286. {
  287. static uint32_t count=5;
  288. uint32_t avail, num, target, offset, len=0;
  289. audio_block_t *left, *right;
  290. if (++count < 9) { // TODO: dynamic adjust to match USB rate
  291. target = 44;
  292. } else {
  293. count = 0;
  294. target = 45;
  295. }
  296. while (len < target) {
  297. num = target - len;
  298. left = AudioOutputUSB::left_1st;
  299. if (left == NULL) {
  300. // buffer underrun - PC is consuming too quickly
  301. memset(usb_audio_transmit_buffer + len, 0, num * 4);
  302. //serial_print("%");
  303. break;
  304. }
  305. right = AudioOutputUSB::right_1st;
  306. offset = AudioOutputUSB::offset_1st;
  307. avail = AUDIO_BLOCK_SAMPLES - offset;
  308. if (num > avail) num = avail;
  309. copy_from_buffers((uint32_t *)usb_audio_transmit_buffer + len,
  310. left->data + offset, right->data + offset, num);
  311. len += num;
  312. offset += num;
  313. if (offset >= AUDIO_BLOCK_SAMPLES) {
  314. AudioStream::release(left);
  315. AudioStream::release(right);
  316. AudioOutputUSB::left_1st = AudioOutputUSB::left_2nd;
  317. AudioOutputUSB::left_2nd = NULL;
  318. AudioOutputUSB::right_1st = AudioOutputUSB::right_2nd;
  319. AudioOutputUSB::right_2nd = NULL;
  320. AudioOutputUSB::offset_1st = 0;
  321. } else {
  322. AudioOutputUSB::offset_1st = offset;
  323. }
  324. }
  325. return target * 4;
  326. }
  327. struct setup_struct {
  328. union {
  329. struct {
  330. uint8_t bmRequestType;
  331. uint8_t bRequest;
  332. union {
  333. struct {
  334. uint8_t bChannel; // 0=main, 1=left, 2=right
  335. uint8_t bCS; // Control Selector
  336. };
  337. uint16_t wValue;
  338. };
  339. union {
  340. struct {
  341. uint8_t bIfEp; // type of entity
  342. uint8_t bEntityId; // UnitID, TerminalID, etc.
  343. };
  344. uint16_t wIndex;
  345. };
  346. uint16_t wLength;
  347. };
  348. };
  349. };
  350. int usb_audio_get_feature(void *stp, uint8_t *data, uint32_t *datalen)
  351. {
  352. struct setup_struct setup = *((struct setup_struct *)stp);
  353. if (setup.bmRequestType==0xA1) { // should check bRequest, bChannel, and UnitID
  354. if (setup.bCS==0x01) { // mute
  355. data[0] = AudioInputUSB::features.mute; // 1=mute, 0=unmute
  356. *datalen = 1;
  357. return 1;
  358. }
  359. else if (setup.bCS==0x02) { // volume
  360. if (setup.bRequest==0x81) { // GET_CURR
  361. data[0] = AudioInputUSB::features.volume & 0xFF;
  362. data[1] = (AudioInputUSB::features.volume>>8) & 0xFF;
  363. }
  364. else if (setup.bRequest==0x82) { // GET_MIN
  365. //serial_print("vol get_min\n");
  366. data[0] = 0; // min level is 0
  367. data[1] = 0;
  368. }
  369. else if (setup.bRequest==0x83) { // GET_MAX
  370. data[0] = FEATURE_MAX_VOLUME & 0xFF; // max level, for range of 0 to MAX
  371. data[1] = (FEATURE_MAX_VOLUME>>8) & 0x0F;
  372. }
  373. else if (setup.bRequest==0x84) { // GET_RES
  374. data[0] = 1; // increment vol by by 1
  375. data[1] = 0;
  376. }
  377. else { // pass over SET_MEM, etc.
  378. return 0;
  379. }
  380. *datalen = 2;
  381. return 1;
  382. }
  383. }
  384. return 0;
  385. }
  386. int usb_audio_set_feature(void *stp, uint8_t *buf)
  387. {
  388. struct setup_struct setup = *((struct setup_struct *)stp);
  389. if (setup.bmRequestType==0x21) { // should check bRequest, bChannel and UnitID
  390. if (setup.bCS==0x01) { // mute
  391. if (setup.bRequest==0x01) { // SET_CUR
  392. AudioInputUSB::features.mute = buf[0]; // 1=mute,0=unmute
  393. AudioInputUSB::features.change = 1;
  394. return 1;
  395. }
  396. }
  397. else if (setup.bCS==0x02) { // volume
  398. if (setup.bRequest==0x01) { // SET_CUR
  399. AudioInputUSB::features.volume = buf[0] + (buf[1]<<8);
  400. AudioInputUSB::features.change = 1;
  401. return 1;
  402. }
  403. }
  404. }
  405. return 0;
  406. }
  407. #endif // F_CPU
  408. #endif // AUDIO_INTERFACE