Keine Beschreibung
Du kannst nicht mehr als 25 Themen auswählen Themen müssen mit entweder einem Buchstaben oder einer Ziffer beginnen. Sie können Bindestriche („-“) enthalten und bis zu 35 Zeichen lang sein.

usb_audio.rs 19KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568
  1. //! USB audio class for asynchronous, bidirectional (microphone + speakers) 48kHz audio.
  2. //!
  3. //! See "Universal Serial Bus Device Class Definition for Audio Devices", release 1.0 (March 18,
  4. //! 1998) for a specification of the USB audio class.
  5. use usb_device::class_prelude::*;
  6. use usb_device::endpoint::{IsochronousSynchronizationType, IsochronousUsageType};
  7. use usb_device::Result;
  8. const DEVICE_CLASS_AUDIO: u8 = 0x01;
  9. const AUDIO_SUBCLASS_CONTROL: u8 = 0x01;
  10. const AUDIO_SUBCLASS_STREAMING: u8 = 0x02;
  11. const AUDIO_PROTOCOL_NONE: u8 = 0x00;
  12. const AUDIO_INTERFACE_DESC_TYPE: u8 = 0x24;
  13. const AUDIO_ENDPOINT_DESC_TYPE: u8 = 0x25;
  14. const AUDIO_CONTROL_HEADER: u8 = 0x01;
  15. const AUDIO_CONTROL_INPUT_TERMINAL: u8 = 0x02;
  16. const AUDIO_CONTROL_OUTPUT_TERMINAL: u8 = 0x03;
  17. const AUDIO_CONTROL_FEATURE_UNIT: u8 = 0x06;
  18. const AUDIO_STREAMING_GENERAL: u8 = 0x01;
  19. const AUDIO_STREAMING_FORMAT_TYPE: u8 = 0x02;
  20. const AUDIO_ENDPOINT_GENERAL: u8 = 0x01;
  21. // TODO: Update bDelay.
  22. pub struct UsbAudioClass<'a, B: UsbBus, OUTBUF: AsRef<[u32]>> {
  23. audio_control: InterfaceNumber,
  24. audio_streaming_inactive: InterfaceNumber,
  25. audio_streaming: InterfaceNumber,
  26. audio_out: EndpointOut<'a, B>,
  27. audio_out_sync: EndpointIn<'a, B>,
  28. //audio_in: EndpointIn<'a, B>,
  29. samples_per_frame: [u8; 3],
  30. audio_out_buf: Option<OUTBUF>,
  31. }
  32. impl<'a, B: UsbBus, OUTBUF: AsRef<[u32]>> UsbAudioClass<'a, B, OUTBUF> {
  33. pub fn new(bus_alloc: &'a UsbBusAllocator<B>) -> Self {
  34. UsbAudioClass {
  35. audio_control: bus_alloc.interface(),
  36. audio_streaming_inactive: bus_alloc.interface(),
  37. audio_streaming: bus_alloc.interface(),
  38. // 48kHz * 2 * 16bit = 192B per packet. We allocate a bit more in case the device clock
  39. // is faster than the host clock.
  40. /*audio_out: bus_alloc.isochronous(
  41. IsochronousSynchronizationType::Asynchronous,
  42. IsochronousUsageType::Data,
  43. 256,
  44. 1,
  45. ),*/
  46. audio_out: bus_alloc.isochronous(
  47. IsochronousSynchronizationType::Synchronous,
  48. IsochronousUsageType::Data,
  49. 256,
  50. 1,
  51. ),
  52. audio_out_sync: bus_alloc.isochronous(
  53. IsochronousSynchronizationType::Asynchronous,
  54. IsochronousUsageType::Feedback,
  55. 3,
  56. 1,
  57. ),
  58. /*audio_in: bus_alloc.isochronous(
  59. IsochronousSynchronizationType::Asynchronous,
  60. IsochronousUsageType::Data,
  61. 256,
  62. 1,
  63. ),*/
  64. samples_per_frame: [48 >> 2, 48 << 6, 0], // 48 kHz
  65. audio_out_buf: None,
  66. }
  67. }
  68. // TODO: Functions to read and write data?
  69. }
  70. impl<B: UsbBus, OUTBUF: AsRef<[u32]>> UsbClass<B> for UsbAudioClass<'_, B, OUTBUF> {
  71. fn get_configuration_descriptors(&self, writer: &mut DescriptorWriter) -> Result<()> {
  72. writer.iad(
  73. self.audio_control,
  74. 2, // Two interfaces (control + streaming).
  75. 0x0, // Each interface specifies its own class.
  76. 0x0, // Each interface specifies its own subclass.
  77. 0x0, // No class-specific protocols for this device.
  78. )?;
  79. // Audio control interface.
  80. writer.interface(
  81. self.audio_control,
  82. DEVICE_CLASS_AUDIO,
  83. AUDIO_SUBCLASS_CONTROL,
  84. AUDIO_PROTOCOL_NONE,
  85. )?;
  86. writer.write(
  87. AUDIO_INTERFACE_DESC_TYPE,
  88. &[
  89. AUDIO_CONTROL_HEADER, // bDescriptorSubtype
  90. 0x00, // bcdADC
  91. 0x01, //
  92. 37, // wTotalLength
  93. 0, //
  94. 0x01, // bInCollection
  95. self.audio_streaming.into(), // baInterfaceNr
  96. ],
  97. )?;
  98. // Input terminal (USB streaming).
  99. writer.write(
  100. AUDIO_INTERFACE_DESC_TYPE,
  101. &[
  102. AUDIO_CONTROL_INPUT_TERMINAL, // bDescriptorSubtype
  103. 0x01, // bTerminalID
  104. 0x01, // wTerminalType
  105. 0x01, //
  106. 0x00, // bAssocTerminal
  107. 0x02, // bNrChannels
  108. 0x03, // wChannelConfig
  109. 0x00, //
  110. 0x00, // iChannelNames
  111. 0x00, // iTerminal
  112. ],
  113. )?;
  114. // Feature unit (volume and mute).
  115. writer.write(
  116. AUDIO_INTERFACE_DESC_TYPE,
  117. &[
  118. AUDIO_CONTROL_FEATURE_UNIT, // bDescriptorSubtype
  119. 0x02, // bUnitID
  120. 0x01, // bSourceID
  121. 0x01, // bControlSize
  122. 0x03, // bmaControls(0)
  123. 0x00, // iFeature
  124. ],
  125. )?;
  126. // Output terminal (speaker).
  127. writer.write(
  128. AUDIO_INTERFACE_DESC_TYPE,
  129. &[
  130. AUDIO_CONTROL_OUTPUT_TERMINAL, // bDescriptorSubtype
  131. 0x03, // bTerminalID
  132. 0x01, // wTerminalType
  133. 0x03, //
  134. 0x00, // bAssocTerminal
  135. 0x02, // bSourceID
  136. 0x00, // iTerminal
  137. ],
  138. )?;
  139. // Audio streaming interface (zero-bandwidth).
  140. writer.interface(
  141. self.audio_streaming_inactive,
  142. DEVICE_CLASS_AUDIO,
  143. AUDIO_SUBCLASS_STREAMING,
  144. AUDIO_PROTOCOL_NONE,
  145. )?;
  146. // Audio streaming interface (operational).
  147. writer.interface_alt(
  148. self.audio_streaming,
  149. 1,
  150. DEVICE_CLASS_AUDIO,
  151. AUDIO_SUBCLASS_STREAMING,
  152. AUDIO_PROTOCOL_NONE,
  153. None,
  154. )?;
  155. writer.write(
  156. AUDIO_INTERFACE_DESC_TYPE,
  157. &[
  158. AUDIO_STREAMING_GENERAL, // bDescriptorSubtype
  159. 0x01, // bTerminalLink
  160. 0x03, // bDelay
  161. 0x01, // wFormatTag
  162. 0x00, //
  163. ],
  164. )?;
  165. writer.write(
  166. AUDIO_INTERFACE_DESC_TYPE,
  167. &[
  168. AUDIO_STREAMING_FORMAT_TYPE, // bDescriptorSubtype
  169. 0x01, // bFormatType
  170. 0x02, // bNrChannels
  171. 0x02, // bSubframeSize
  172. 0x10, // bBitResolution
  173. 0x01, // bSamFreqType
  174. ],
  175. )?;
  176. /*writer.endpoint_ex(&self.audio_out, |data| {
  177. // TODO: Faster refresh
  178. data[0] = 0x09; // bRefresh
  179. data[1] = self.audio_out_sync.address().into(); // bSynchAddress
  180. Ok(2)
  181. })?;*/
  182. writer.endpoint(&self.audio_out)?;
  183. writer.write(
  184. AUDIO_ENDPOINT_DESC_TYPE,
  185. &[
  186. AUDIO_ENDPOINT_GENERAL, // bDescriptorSubtype
  187. 0x00, // bmAttributes
  188. 0x01, // bLockDelayUnits
  189. 0x00, // wLockDelay
  190. 0x00,
  191. ],
  192. )?;
  193. /*writer.endpoint_ex(&self.audio_out_sync, |data| {
  194. data[0] = 0x00; // bRefresh
  195. data[1] = 0x00; // bSynchAddress
  196. Ok(2)
  197. })?;*/
  198. Ok(())
  199. }
  200. fn get_string(&self, _index: StringIndex, _lang_id: u16) -> Option<&str> {
  201. // TODO
  202. None
  203. }
  204. fn reset(&mut self) {
  205. // Start sending synchronization data.
  206. self.endpoint_in_complete(self.audio_out_sync.address());
  207. }
  208. fn control_out(&mut self, xfer: ControlOut<B>) {
  209. let req = xfer.request();
  210. if !(req.request_type == control::RequestType::Class
  211. && req.recipient == control::Recipient::Interface
  212. && req.index == u8::from(self.audio_control) as u16)
  213. {
  214. return;
  215. }
  216. match req.request {
  217. // TODO
  218. _ => {
  219. xfer.reject().ok();
  220. }
  221. };
  222. }
  223. fn control_in(&mut self, xfer: ControlIn<B>) {
  224. let req = xfer.request();
  225. if !(req.request_type == control::RequestType::Class
  226. && req.recipient == control::Recipient::Interface
  227. && req.index == u8::from(self.audio_control) as u16)
  228. {
  229. return;
  230. }
  231. match req.request {
  232. // TODO
  233. _ => {
  234. xfer.reject().ok();
  235. }
  236. };
  237. }
  238. fn endpoint_out(&mut self, addr: EndpointAddress) {
  239. if addr == self.audio_out.address() {
  240. if self.audio_out_buf.is_some() {
  241. // TODO: Write data into buffer, move buffer somewhere else.
  242. } else {
  243. // TODO
  244. }
  245. // TODO: Process incoming audio data.
  246. let mut buffer = [0u8; 256];
  247. self.audio_out.read(&mut buffer);
  248. }
  249. }
  250. fn endpoint_in_complete(&mut self, addr: EndpointAddress) {
  251. if addr == self.audio_out_sync.address() {
  252. // Immediately write the next sync value.
  253. //self.audio_out_sync.write(&self.samples_per_frame).unwrap();
  254. }
  255. }
  256. }
  257. /*use usb_device::class_prelude::*;
  258. use usb_device::endpoint::{IsochronousSynchronizationType, IsochronousUsageType};
  259. use usb_device::Result;
  260. /// This should be used as `device_class` when building the `UsbDevice`.
  261. pub const USB_INTERFACE_CLASS_AUDIO: u8 = 0x01;
  262. const USB_AUDIO_SUBCLASS_UNDEFINED: u8 = 0x0;
  263. const USB_AUDIO_SUBCLASS_AUDIOCONTROL: u8 = 0x01;
  264. const USB_AUDIO_SUBCLASS_AUDIOSTREAMING: u8 = 0x02;
  265. const USB_AUDIO_SUBCLASS_MIDISTREAMING: u8 = 0x03;
  266. const USB_CLASS_CDC_DATA: u8 = 0x0a;
  267. const CDC_SUBCLASS_ACM: u8 = 0x02;
  268. const USB_AUDIO_PROTOCOL_NONE: u8 = 0x00;
  269. const CS_DEVICE: u8 = 0x21;
  270. const CS_CONFIGURATION: u8 = 0x22;
  271. const CS_STRING: u8 = 0x23;
  272. const CS_INTERFACE: u8 = 0x24;
  273. const CS_ENDPOINT: u8 = 0x25;
  274. const EP_GENERAL: u8 = 0x1;
  275. const AC_DESC_TYPE_HEADER: u8 = 0x1;
  276. const AC_DESC_TYPE_INPUT_TERMINAL: u8 = 0x2;
  277. const AC_DESC_TYPE_OUTPUT_TERMINAL: u8 = 0x3;
  278. const AC_DESC_TYPE_MIXER_UNIT: u8 = 0x4;
  279. const AC_DESC_TYPE_SELECTOR_UNIT: u8 = 0x5;
  280. const AC_DESC_TYPE_FEATURE_UNIT: u8 = 0x6;
  281. const AC_DESC_TYPE_PROCESSING_UNIT: u8 = 0x7;
  282. const AC_DESC_TYPE_EXTENSION_UNIT: u8 = 0x8;
  283. const AC_DESC_ST_GENERAL: u8 = 0x1;
  284. const AC_DESC_ST_FORMAT_TYPE: u8 = 0x2;
  285. const AC_DESC_ST_FORMAT_SPECIFIC: u8 = 0x3;
  286. const AUDIO_SUB_TYPE_HEADER: u8 = 0x01;
  287. const AUDIO_SUB_TYPE_INPUT_TERMINAL: u8 = 0x02;
  288. const AUDIO_SUB_TYPE_FEATURE_UNIT: u8 = 0x06;
  289. const AUDIO_SUB_TYPE_OUTPUT_TERMINAL: u8 = 0x03;
  290. const AUDIO_SUB_TYPE_AS_GENERAL: u8 = 0x01;
  291. const AUDIO_SUB_TYPE_FORMAT_TYPE: u8 = 0x02;
  292. pub struct UsbAudioClass<'a, B: UsbBus> {
  293. audio_control_if: InterfaceNumber,
  294. audio_stream: InterfaceNumber,
  295. alt_audio_stream: InterfaceNumber,
  296. audio_in_ep: EndpointIn<'a, B>,
  297. }
  298. impl<B: UsbBus> UsbAudioClass<'_, B> {
  299. /// Creates a new UsbAudioClass with the provided UsbBus and max_packet_size in bytes. For
  300. /// full-speed devices, max_packet_size has to be one of 8, 16, 32 or 64.
  301. pub fn new(alloc: &UsbBusAllocator<B>, max_packet_size: u16) -> UsbAudioClass<'_, B> {
  302. UsbAudioClass {
  303. audio_control_if: alloc.interface(),
  304. audio_stream: alloc.interface(),
  305. alt_audio_stream: alloc.interface(),
  306. audio_in_ep: alloc.isochronous(
  307. IsochronousSynchronizationType::Synchronous,
  308. IsochronousUsageType::Data,
  309. max_packet_size,
  310. 4,
  311. ),
  312. }
  313. }
  314. /// Gets the maximum packet size in bytes.
  315. pub fn max_packet_size(&self) -> u16 {
  316. self.audio_in_ep.max_packet_size()
  317. }
  318. /// Writes a single packet into the IN endpoint.
  319. pub fn write_packet(&mut self, data: &[u8]) -> Result<usize> {
  320. //defmt::info!("write_packet");
  321. self.audio_in_ep.write(data)
  322. }
  323. /// Gets the address of the IN endpoint.
  324. pub(crate) fn write_ep_address(&self) -> EndpointAddress {
  325. self.audio_in_ep.address()
  326. }
  327. }
  328. impl<B: UsbBus> UsbClass<B> for UsbAudioClass<'_, B> {
  329. fn get_configuration_descriptors(&self, writer: &mut DescriptorWriter) -> Result<()> {
  330. writer.iad(
  331. self.audio_control_if,
  332. 3,
  333. 0x0, // device defined at interface level
  334. 0x0, // subclass unused
  335. USB_AUDIO_PROTOCOL_NONE,
  336. )?;
  337. writer.interface(
  338. self.audio_control_if,
  339. USB_INTERFACE_CLASS_AUDIO,
  340. USB_AUDIO_SUBCLASS_AUDIOCONTROL,
  341. USB_AUDIO_PROTOCOL_NONE,
  342. )?;
  343. writer.write(
  344. CS_INTERFACE,
  345. &[
  346. AUDIO_SUB_TYPE_HEADER, // bDescriptorSubtype
  347. 0x00,
  348. 0x1, // bcdADC (1.0),
  349. 43,
  350. 0, // wTotalLength (Compute this!)
  351. 0x01, // bInCollection (1 streaming interface)
  352. 0x01, // baInterfaceNr (Interface 1 is stream)
  353. ],
  354. )?;
  355. writer.write(
  356. CS_INTERFACE,
  357. &[
  358. AUDIO_SUB_TYPE_INPUT_TERMINAL, // bDescriptorSubtype
  359. 0x01, // bTerminalID 1,
  360. 0x10,
  361. 0x07, // wTerminalType (radio receiver)
  362. 0x00, // bAssocTerminal (none)
  363. 0x02, // bNrChannels - 2 for I and Q
  364. 0x03,
  365. 0x00, // wChannelConfig (left, right)
  366. 0x00, // iChannelNames (none)
  367. 0x00, // iTerminal (none)
  368. ],
  369. )?;
  370. writer.write(
  371. CS_INTERFACE,
  372. &[
  373. AUDIO_SUB_TYPE_FEATURE_UNIT, // bDescriptorSubtype
  374. 0x02, // bUnitID,
  375. 0x01, // bSourceID (input terminal 1)
  376. 0x02, // bControlSize (2 bytes)
  377. 0x01,
  378. 0x00, // Master controls
  379. 0x00,
  380. 0x00, // Channel 0 controls
  381. 0x00,
  382. 0x00, // Channel 1 controls
  383. 0x00, // iFeature (none)
  384. ],
  385. )?;
  386. writer.write(
  387. CS_INTERFACE,
  388. &[
  389. AUDIO_SUB_TYPE_OUTPUT_TERMINAL, // bDescriptorSubtype
  390. 0x03, // bTerminalID,
  391. 0x01,
  392. 0x01, // wTerminalType (USB Streaming)
  393. 0x00, // bAssocTerminal (none)
  394. 0x02, // bSourceID (feature unit 2)
  395. 0x00, // iTerminal (none)
  396. ],
  397. )?;
  398. writer.interface(
  399. self.audio_stream,
  400. USB_INTERFACE_CLASS_AUDIO,
  401. USB_AUDIO_SUBCLASS_AUDIOSTREAMING,
  402. USB_AUDIO_PROTOCOL_NONE,
  403. )?;
  404. //alternate audio stream
  405. /*writer.interface_alt(
  406. self.alt_audio_stream,
  407. 1,
  408. USB_INTERFACE_CLASS_AUDIO,
  409. USB_AUDIO_SUBCLASS_AUDIOSTREAMING,
  410. USB_AUDIO_PROTOCOL_NONE,
  411. None,
  412. )?;*/
  413. // Audio Stream Audio Class Descriptor
  414. writer.write(
  415. CS_INTERFACE,
  416. &[
  417. AUDIO_SUB_TYPE_AS_GENERAL, // bDescriptorSubtype
  418. 0x03, // bTerminalID,
  419. 0x00, // bDelay
  420. 0x01,
  421. 0x00, // wFormatTag (PCM Format)
  422. ],
  423. )?;
  424. // Format Type Audio Descriptor
  425. writer.write(
  426. CS_INTERFACE,
  427. &[
  428. AUDIO_SUB_TYPE_FORMAT_TYPE, // bDescriptorSubtype
  429. 0x01, // bFormatType (TYPE_I)
  430. 0x02, // bNrChannels (2)
  431. 0x02, // bSubFrameSize (2)
  432. 0x10, // bBitResolution (16 bits)
  433. 0x01, // bSamFreqType (1 sample frequency)
  434. 0x80, // 8*2 = 16 KHz byte 0
  435. 0x3E, // 8*2 = 16 KHz byte 1
  436. 0x00, // 8*2 = 16 KHz byte 2
  437. ],
  438. )?;
  439. // TODO: Set the necessary flags for Isochronous
  440. writer.endpoint(&self.audio_in_ep)?;
  441. // Isochronous endpoint Audio Class descriptor
  442. writer.write(
  443. CS_ENDPOINT,
  444. &[
  445. EP_GENERAL, // bDescriptorSubtype
  446. 0x00, // bmAttributes (none)
  447. 0x02, // bLockDelayUnits (PCM Samples)
  448. 0x00, 0x00, // wLockDelay (0) - should be zero for asynchronous
  449. ],
  450. )?;
  451. Ok(())
  452. }
  453. fn reset(&mut self) {}
  454. fn control_in(&mut self, xfer: ControlIn<B>) {
  455. let req = xfer.request();
  456. if !(req.request_type == control::RequestType::Class
  457. && req.recipient == control::Recipient::Interface
  458. && req.index == u8::from(self.audio_control_if) as u16)
  459. {
  460. return;
  461. }
  462. //defmt::info!("control_in - req : {:?}", req.request);
  463. match req.request {
  464. /*
  465. REQ_GET_LINE_CODING if req.length == 7 => {
  466. xfer.accept(|data| {
  467. data[0..4].copy_from_slice(&self.line_coding.data_rate.to_le_bytes());
  468. data[4] = self.line_coding.stop_bits as u8;
  469. data[5] = self.line_coding.parity_type as u8;
  470. data[6] = self.line_coding.data_bits;
  471. Ok(7)
  472. }).ok();
  473. },
  474. */
  475. _ => {
  476. xfer.reject().ok();
  477. }
  478. }
  479. }
  480. fn control_out(&mut self, xfer: ControlOut<B>) {
  481. let req = xfer.request();
  482. if !(req.request_type == control::RequestType::Class
  483. && req.recipient == control::Recipient::Interface
  484. && req.index == u8::from(self.audio_control_if) as u16)
  485. {
  486. return;
  487. }
  488. match req.request {
  489. /*
  490. REQ_SEND_ENCAPSULATED_COMMAND => {
  491. // We don't actually support encapsulated commands but pretend we do for standards
  492. // compatibility.
  493. xfer.accept().ok();
  494. },*/
  495. _ => {
  496. xfer.reject().ok();
  497. }
  498. };
  499. }
  500. }*/