aboutsummaryrefslogtreecommitdiff
path: root/embassy-usb/src/class/uac1/speaker.rs
diff options
context:
space:
mode:
Diffstat (limited to 'embassy-usb/src/class/uac1/speaker.rs')
-rw-r--r--embassy-usb/src/class/uac1/speaker.rs778
1 files changed, 778 insertions, 0 deletions
diff --git a/embassy-usb/src/class/uac1/speaker.rs b/embassy-usb/src/class/uac1/speaker.rs
new file mode 100644
index 000000000..96456d94a
--- /dev/null
+++ b/embassy-usb/src/class/uac1/speaker.rs
@@ -0,0 +1,778 @@
1//! USB Audio Class 1.0 - Speaker device
2//!
3//! Provides a class with a single audio streaming interface (host to device),
4//! that advertises itself as a speaker. Includes explicit sample rate feedback.
5//!
6//! Various aspects of the audio stream can be configured, for example:
7//! - sample rate
8//! - sample resolution
9//! - audio channel count and assignment
10//!
11//! The class provides volume and mute controls for each channel.
12
13use core::cell::{Cell, RefCell};
14use core::future::poll_fn;
15use core::marker::PhantomData;
16use core::sync::atomic::{AtomicBool, AtomicU32, Ordering};
17use core::task::Poll;
18
19use embassy_sync::blocking_mutex::CriticalSectionMutex;
20use embassy_sync::waitqueue::WakerRegistration;
21use heapless::Vec;
22
23use super::class_codes::*;
24use super::terminal_type::TerminalType;
25use super::{Channel, ChannelConfig, FeedbackRefresh, SampleWidth, MAX_AUDIO_CHANNEL_COUNT, MAX_AUDIO_CHANNEL_INDEX};
26use crate::control::{self, InResponse, OutResponse, Recipient, Request, RequestType};
27use crate::descriptor::{SynchronizationType, UsageType};
28use crate::driver::{Driver, Endpoint, EndpointError, EndpointIn, EndpointOut, EndpointType};
29use crate::types::InterfaceNumber;
30use crate::{Builder, Handler};
31
32/// Maximum allowed sampling rate (3 bytes) in Hz.
33const MAX_SAMPLE_RATE_HZ: u32 = 0x7FFFFF;
34
35/// Arbitrary unique identifier for the input unit.
36const INPUT_UNIT_ID: u8 = 0x01;
37
38/// Arbitrary unique identifier for the feature unit.
39const FEATURE_UNIT_ID: u8 = 0x02;
40
41/// Arbitrary unique identifier for the output unit.
42const OUTPUT_UNIT_ID: u8 = 0x03;
43
44// Volume settings go from -25600 to 0, in steps of 256.
45// Therefore, the volume settings are 8q8 values in units of dB.
46const VOLUME_STEPS_PER_DB: i16 = 256;
47const MIN_VOLUME_DB: i16 = -100;
48const MAX_VOLUME_DB: i16 = 0;
49
50// Maximum number of supported discrete sample rates.
51const MAX_SAMPLE_RATE_COUNT: usize = 10;
52
53/// The volume of an audio channel.
54#[derive(Debug, Clone, Copy)]
55#[cfg_attr(feature = "defmt", derive(defmt::Format))]
56pub enum Volume {
57 /// The channel is muted.
58 Muted,
59 /// The channel volume in dB. Ranges from `MIN_VOLUME_DB` (quietest) to `MAX_VOLUME_DB` (loudest).
60 DeciBel(f32),
61}
62
63/// Internal state for the USB Audio Class.
64pub struct State<'d> {
65 control: Option<Control<'d>>,
66 shared: SharedControl<'d>,
67}
68
69impl<'d> Default for State<'d> {
70 fn default() -> Self {
71 Self::new()
72 }
73}
74
75impl<'d> State<'d> {
76 /// Create a new `State`.
77 pub fn new() -> Self {
78 Self {
79 control: None,
80 shared: SharedControl::default(),
81 }
82 }
83}
84
85/// Implementation of the USB audio class 1.0.
86pub struct Speaker<'d, D: Driver<'d>> {
87 phantom: PhantomData<&'d D>,
88}
89
90impl<'d, D: Driver<'d>> Speaker<'d, D> {
91 /// Creates a new [`Speaker`] device, split into a stream, feedback, and a control change notifier.
92 ///
93 /// The packet size should be chosen, based on the expected transfer size of samples per (micro)frame.
94 /// For example, a stereo stream at 32 bit resolution and 48 kHz sample rate yields packets of 384 byte for
95 /// full-speed USB (1 ms frame interval) or 48 byte for high-speed USB (125 us microframe interval).
96 /// When using feedback, the packet size varies and thus, the `max_packet_size` should be increased (e.g. to double).
97 ///
98 /// # Arguments
99 ///
100 /// * `builder` - The builder for the class.
101 /// * `state` - The internal state of the class.
102 /// * `max_packet_size` - The maximum packet size per (micro)frame.
103 /// * `resolution` - The audio sample resolution.
104 /// * `sample_rates_hz` - The supported sample rates in Hz.
105 /// * `channels` - The advertised audio channels (up to 12). Entries must be unique, or this function panics.
106 /// * `feedback_refresh_period` - The refresh period for the feedback value.
107 pub fn new(
108 builder: &mut Builder<'d, D>,
109 state: &'d mut State<'d>,
110 max_packet_size: u16,
111 resolution: SampleWidth,
112 sample_rates_hz: &[u32],
113 channels: &'d [Channel],
114 feedback_refresh_period: FeedbackRefresh,
115 ) -> (Stream<'d, D>, Feedback<'d, D>, ControlMonitor<'d>) {
116 // The class and subclass fields of the IAD aren't required to match the class and subclass fields of
117 // the interfaces in the interface collection that the IAD describes. Microsoft recommends that
118 // the first interface of the collection has class and subclass fields that match the class and
119 // subclass fields of the IAD.
120 let mut func = builder.function(USB_AUDIO_CLASS, USB_AUDIOCONTROL_SUBCLASS, PROTOCOL_NONE);
121
122 // Audio control interface (mandatory) [UAC 4.3.1]
123 let mut interface = func.interface();
124 let control_interface = interface.interface_number().into();
125 let streaming_interface = u8::from(control_interface) + 1;
126 let mut alt = interface.alt_setting(USB_AUDIO_CLASS, USB_AUDIOCONTROL_SUBCLASS, PROTOCOL_NONE, None);
127
128 // Terminal topology:
129 // Input terminal (receives audio stream) -> Feature Unit (mute and volume) -> Output terminal (e.g. towards speaker)
130
131 // =======================================
132 // Input Terminal Descriptor [UAC 3.3.2.1]
133 // Audio input
134 let terminal_type: u16 = TerminalType::UsbStreaming.into();
135
136 // Assemble channel configuration field
137 let mut channel_config: u16 = ChannelConfig::None.into();
138 for channel in channels {
139 let channel: u16 = channel.get_channel_config().into();
140
141 if channel_config & channel != 0 {
142 panic!("Invalid channel config, duplicate channel {}.", channel);
143 }
144 channel_config |= channel;
145 }
146
147 let input_terminal_descriptor = [
148 INPUT_TERMINAL, // bDescriptorSubtype
149 INPUT_UNIT_ID, // bTerminalID
150 terminal_type as u8,
151 (terminal_type >> 8) as u8, // wTerminalType
152 0x00, // bAssocTerminal (none)
153 channels.len() as u8, // bNrChannels
154 channel_config as u8,
155 (channel_config >> 8) as u8, // wChannelConfig
156 0x00, // iChannelNames (none)
157 0x00, // iTerminal (none)
158 ];
159
160 // ========================================
161 // Output Terminal Descriptor [UAC 4.3.2.2]
162 // Speaker output
163 let terminal_type: u16 = TerminalType::OutSpeaker.into();
164 let output_terminal_descriptor = [
165 OUTPUT_TERMINAL, // bDescriptorSubtype
166 OUTPUT_UNIT_ID, // bTerminalID
167 terminal_type as u8,
168 (terminal_type >> 8) as u8, // wTerminalType
169 0x00, // bAssocTerminal (none)
170 FEATURE_UNIT_ID, // bSourceID (the feature unit)
171 0x00, // iTerminal (none)
172 ];
173
174 // =====================================
175 // Feature Unit Descriptor [UAC 4.3.2.5]
176 // Mute and volume control
177 let controls = MUTE_CONTROL | VOLUME_CONTROL;
178
179 const FEATURE_UNIT_DESCRIPTOR_SIZE: usize = 5;
180 let mut feature_unit_descriptor: Vec<u8, { FEATURE_UNIT_DESCRIPTOR_SIZE + MAX_AUDIO_CHANNEL_COUNT + 1 }> =
181 Vec::from_slice(&[
182 FEATURE_UNIT, // bDescriptorSubtype (Feature Unit)
183 FEATURE_UNIT_ID, // bUnitID
184 INPUT_UNIT_ID, // bSourceID
185 1, // bControlSize (one byte per control)
186 FU_CONTROL_UNDEFINED, // Master controls (disabled, use only per-channel control)
187 ])
188 .unwrap();
189
190 // Add per-channel controls
191 for _channel in channels {
192 feature_unit_descriptor.push(controls).unwrap();
193 }
194 feature_unit_descriptor.push(0x00).unwrap(); // iFeature (none)
195
196 // ===============================================
197 // Format desciptor [UAC 4.5.3]
198 // Used later, for operational streaming interface
199 let mut format_descriptor: Vec<u8, { 6 + 3 * MAX_SAMPLE_RATE_COUNT }> = Vec::from_slice(&[
200 FORMAT_TYPE, // bDescriptorSubtype
201 FORMAT_TYPE_I, // bFormatType
202 channels.len() as u8, // bNrChannels
203 resolution as u8, // bSubframeSize
204 resolution.in_bit() as u8, // bBitResolution
205 ])
206 .unwrap();
207
208 format_descriptor.push(sample_rates_hz.len() as u8).unwrap();
209
210 for sample_rate_hz in sample_rates_hz {
211 assert!(*sample_rate_hz <= MAX_SAMPLE_RATE_HZ);
212 format_descriptor.push((sample_rate_hz & 0xFF) as u8).unwrap();
213 format_descriptor.push(((sample_rate_hz >> 8) & 0xFF) as u8).unwrap();
214 format_descriptor.push(((sample_rate_hz >> 16) & 0xFF) as u8).unwrap();
215 }
216
217 // ==================================================
218 // Class-specific AC Interface Descriptor [UAC 4.3.2]
219 const DESCRIPTOR_HEADER_SIZE: usize = 2;
220 const INTERFACE_DESCRIPTOR_SIZE: usize = 7;
221
222 let mut total_descriptor_length = 0;
223
224 for size in [
225 INTERFACE_DESCRIPTOR_SIZE,
226 input_terminal_descriptor.len(),
227 feature_unit_descriptor.len(),
228 output_terminal_descriptor.len(),
229 ] {
230 total_descriptor_length += size + DESCRIPTOR_HEADER_SIZE;
231 }
232
233 let interface_descriptor: [u8; INTERFACE_DESCRIPTOR_SIZE] = [
234 HEADER_SUBTYPE, // bDescriptorSubtype (Header)
235 ADC_VERSION as u8,
236 (ADC_VERSION >> 8) as u8, // bcdADC
237 total_descriptor_length as u8,
238 (total_descriptor_length >> 8) as u8, // wTotalLength
239 0x01, // bInCollection (1 streaming interface)
240 streaming_interface, // baInterfaceNr
241 ];
242
243 alt.descriptor(CS_INTERFACE, &interface_descriptor);
244 alt.descriptor(CS_INTERFACE, &input_terminal_descriptor);
245 alt.descriptor(CS_INTERFACE, &feature_unit_descriptor);
246 alt.descriptor(CS_INTERFACE, &output_terminal_descriptor);
247
248 // =====================================================
249 // Audio streaming interface, zero-bandwidth [UAC 4.5.1]
250 let mut interface = func.interface();
251 let alt = interface.alt_setting(USB_AUDIO_CLASS, USB_AUDIOSTREAMING_SUBCLASS, PROTOCOL_NONE, None);
252 drop(alt);
253
254 // ==================================================
255 // Audio streaming interface, operational [UAC 4.5.1]
256 let mut alt = interface.alt_setting(USB_AUDIO_CLASS, USB_AUDIOSTREAMING_SUBCLASS, PROTOCOL_NONE, None);
257
258 alt.descriptor(
259 CS_INTERFACE,
260 &[
261 AS_GENERAL, // bDescriptorSubtype
262 INPUT_UNIT_ID, // bTerminalLink
263 0x00, // bDelay (none)
264 PCM as u8,
265 (PCM >> 8) as u8, // wFormatTag (PCM format)
266 ],
267 );
268
269 alt.descriptor(CS_INTERFACE, &format_descriptor);
270
271 let streaming_endpoint = alt.alloc_endpoint_out(EndpointType::Isochronous, max_packet_size, 1);
272 let feedback_endpoint = alt.alloc_endpoint_in(
273 EndpointType::Isochronous,
274 4, // Feedback packets are 24 bit (10.14 format).
275 1,
276 );
277
278 // Write the descriptor for the streaming endpoint, after knowing the address of the feedback endpoint.
279 alt.endpoint_descriptor(
280 streaming_endpoint.info(),
281 SynchronizationType::Asynchronous,
282 UsageType::DataEndpoint,
283 &[
284 0x00, // bRefresh (0)
285 feedback_endpoint.info().addr.into(), // bSynchAddress (the feedback endpoint)
286 ],
287 );
288
289 alt.descriptor(
290 CS_ENDPOINT,
291 &[
292 AS_GENERAL, // bDescriptorSubtype (General)
293 SAMPLING_FREQ_CONTROL, // bmAttributes (support sampling frequency control)
294 0x02, // bLockDelayUnits (PCM)
295 0x0000 as u8,
296 (0x0000 >> 8) as u8, // wLockDelay (0)
297 ],
298 );
299
300 // Write the feedback endpoint descriptor after the streaming endpoint descriptor
301 // This is demanded by the USB audio class specification.
302 alt.endpoint_descriptor(
303 feedback_endpoint.info(),
304 SynchronizationType::NoSynchronization,
305 UsageType::FeedbackEndpoint,
306 &[
307 feedback_refresh_period as u8, // bRefresh
308 0x00, // bSynchAddress (none)
309 ],
310 );
311
312 // Free up the builder.
313 drop(func);
314
315 // Store channel information
316 state.shared.channels = channels;
317
318 state.control = Some(Control {
319 shared: &state.shared,
320 streaming_endpoint_address: streaming_endpoint.info().addr.into(),
321 control_interface_number: control_interface,
322 });
323
324 builder.handler(state.control.as_mut().unwrap());
325
326 let control = &state.shared;
327
328 (
329 Stream { streaming_endpoint },
330 Feedback { feedback_endpoint },
331 ControlMonitor { shared: control },
332 )
333 }
334}
335
336/// Audio settings for the feature unit.
337///
338/// Contains volume and mute control.
339#[derive(Clone, Copy, Debug)]
340#[cfg_attr(feature = "defmt", derive(defmt::Format))]
341pub struct AudioSettings {
342 /// Channel mute states.
343 muted: [bool; MAX_AUDIO_CHANNEL_COUNT],
344 /// Channel volume levels in 8.8 format (in dB).
345 volume_8q8_db: [i16; MAX_AUDIO_CHANNEL_COUNT],
346}
347
348impl Default for AudioSettings {
349 fn default() -> Self {
350 AudioSettings {
351 muted: [true; MAX_AUDIO_CHANNEL_COUNT],
352 volume_8q8_db: [MAX_VOLUME_DB * VOLUME_STEPS_PER_DB; MAX_AUDIO_CHANNEL_COUNT],
353 }
354 }
355}
356
357struct Control<'d> {
358 control_interface_number: InterfaceNumber,
359 streaming_endpoint_address: u8,
360 shared: &'d SharedControl<'d>,
361}
362
363/// Shared data between [`Control`] and the [`Speaker`] class.
364struct SharedControl<'d> {
365 /// The collection of audio settings (volumes, mute states).
366 audio_settings: CriticalSectionMutex<Cell<AudioSettings>>,
367
368 /// Channel assignments.
369 channels: &'d [Channel],
370
371 /// The audio sample rate in Hz.
372 sample_rate_hz: AtomicU32,
373
374 // Notification mechanism.
375 waker: RefCell<WakerRegistration>,
376 changed: AtomicBool,
377}
378
379impl<'d> Default for SharedControl<'d> {
380 fn default() -> Self {
381 SharedControl {
382 audio_settings: CriticalSectionMutex::new(Cell::new(AudioSettings::default())),
383 channels: &[],
384 sample_rate_hz: AtomicU32::new(0),
385 waker: RefCell::new(WakerRegistration::new()),
386 changed: AtomicBool::new(false),
387 }
388 }
389}
390
391impl<'d> SharedControl<'d> {
392 async fn changed(&self) {
393 poll_fn(|context| {
394 if self.changed.load(Ordering::Relaxed) {
395 self.changed.store(false, Ordering::Relaxed);
396 Poll::Ready(())
397 } else {
398 self.waker.borrow_mut().register(context.waker());
399 Poll::Pending
400 }
401 })
402 .await;
403 }
404}
405
406/// Used for reading audio frames.
407pub struct Stream<'d, D: Driver<'d>> {
408 streaming_endpoint: D::EndpointOut,
409}
410
411impl<'d, D: Driver<'d>> Stream<'d, D> {
412 /// Reads a single packet from the OUT endpoint
413 pub async fn read_packet(&mut self, data: &mut [u8]) -> Result<usize, EndpointError> {
414 self.streaming_endpoint.read(data).await
415 }
416
417 /// Waits for the USB host to enable this interface
418 pub async fn wait_connection(&mut self) {
419 self.streaming_endpoint.wait_enabled().await;
420 }
421}
422
423/// Used for writing sample rate information over the feedback endpoint.
424pub struct Feedback<'d, D: Driver<'d>> {
425 feedback_endpoint: D::EndpointIn,
426}
427
428impl<'d, D: Driver<'d>> Feedback<'d, D> {
429 /// Writes a single packet into the IN endpoint.
430 pub async fn write_packet(&mut self, data: &[u8]) -> Result<(), EndpointError> {
431 self.feedback_endpoint.write(data).await
432 }
433
434 /// Waits for the USB host to enable this interface.
435 pub async fn wait_connection(&mut self) {
436 self.feedback_endpoint.wait_enabled().await;
437 }
438}
439
440/// Control status change monitor
441///
442/// Await [`ControlMonitor::changed`] for being notified of configuration changes. Afterwards, the updated
443/// configuration settings can be read with [`ControlMonitor::volume`] and [`ControlMonitor::sample_rate_hz`].
444pub struct ControlMonitor<'d> {
445 shared: &'d SharedControl<'d>,
446}
447
448impl<'d> ControlMonitor<'d> {
449 fn audio_settings(&self) -> AudioSettings {
450 let audio_settings = self.shared.audio_settings.lock(|x| x.get());
451
452 audio_settings
453 }
454
455 fn get_logical_channel(&self, search_channel: Channel) -> Option<usize> {
456 let index = self.shared.channels.iter().position(|&c| c == search_channel)?;
457
458 // The logical channels start at one (zero is the master channel).
459 Some(index + 1)
460 }
461
462 /// Get the volume of a selected channel.
463 pub fn volume(&self, channel: Channel) -> Option<Volume> {
464 let channel_index = self.get_logical_channel(channel)?;
465
466 if self.audio_settings().muted[channel_index] {
467 return Some(Volume::Muted);
468 }
469
470 Some(Volume::DeciBel(
471 (self.audio_settings().volume_8q8_db[channel_index] as f32) / 256.0f32,
472 ))
473 }
474
475 /// Get the streaming endpoint's sample rate in Hz.
476 pub fn sample_rate_hz(&self) -> u32 {
477 self.shared.sample_rate_hz.load(Ordering::Relaxed)
478 }
479
480 /// Return a future for when the control settings change.
481 pub async fn changed(&self) {
482 self.shared.changed().await;
483 }
484}
485
486impl<'d> Control<'d> {
487 fn changed(&mut self) {
488 self.shared.changed.store(true, Ordering::Relaxed);
489 self.shared.waker.borrow_mut().wake();
490 }
491
492 fn interface_set_mute_state(
493 &mut self,
494 audio_settings: &mut AudioSettings,
495 channel_index: u8,
496 data: &[u8],
497 ) -> OutResponse {
498 let mute_state = data[0] != 0;
499
500 match channel_index as usize {
501 ..=MAX_AUDIO_CHANNEL_INDEX => {
502 audio_settings.muted[channel_index as usize] = mute_state;
503 }
504 _ => {
505 debug!("Failed to set channel {} mute state: {}", channel_index, mute_state);
506 return OutResponse::Rejected;
507 }
508 }
509
510 debug!("Set channel {} mute state: {}", channel_index, mute_state);
511 OutResponse::Accepted
512 }
513
514 fn interface_set_volume(
515 &mut self,
516 audio_settings: &mut AudioSettings,
517 channel_index: u8,
518 data: &[u8],
519 ) -> OutResponse {
520 let volume = i16::from_ne_bytes(data[..2].try_into().expect("Failed to read volume."));
521
522 match channel_index as usize {
523 ..=MAX_AUDIO_CHANNEL_INDEX => {
524 audio_settings.volume_8q8_db[channel_index as usize] = volume;
525 }
526 _ => {
527 debug!("Failed to set channel {} volume: {}", channel_index, volume);
528 return OutResponse::Rejected;
529 }
530 }
531
532 debug!("Set channel {} volume: {}", channel_index, volume);
533 OutResponse::Accepted
534 }
535
536 fn interface_set_request(&mut self, req: control::Request, data: &[u8]) -> Option<OutResponse> {
537 let interface_number = req.index as u8;
538 let entity_index = (req.index >> 8) as u8;
539 let channel_index = req.value as u8;
540 let control_unit = (req.value >> 8) as u8;
541
542 if interface_number != self.control_interface_number.into() {
543 debug!("Unhandled interface set request for interface {}", interface_number);
544 return None;
545 }
546
547 if entity_index != FEATURE_UNIT_ID {
548 debug!("Unsupported interface set request for entity {}", entity_index);
549 return Some(OutResponse::Rejected);
550 }
551
552 if req.request != SET_CUR {
553 debug!("Unsupported interface set request type {}", req.request);
554 return Some(OutResponse::Rejected);
555 }
556
557 let mut audio_settings = self.shared.audio_settings.lock(|x| x.get());
558 let response = match control_unit {
559 MUTE_CONTROL => self.interface_set_mute_state(&mut audio_settings, channel_index, data),
560 VOLUME_CONTROL => self.interface_set_volume(&mut audio_settings, channel_index, data),
561 _ => OutResponse::Rejected,
562 };
563
564 if response == OutResponse::Rejected {
565 return Some(response);
566 }
567
568 // Store updated settings
569 self.shared.audio_settings.lock(|x| x.set(audio_settings));
570
571 self.changed();
572
573 Some(OutResponse::Accepted)
574 }
575
576 fn endpoint_set_request(&mut self, req: control::Request, data: &[u8]) -> Option<OutResponse> {
577 let control_selector = (req.value >> 8) as u8;
578 let endpoint_address = req.index as u8;
579
580 if endpoint_address != self.streaming_endpoint_address {
581 debug!(
582 "Unhandled endpoint set request for endpoint {} and control {} with data {}",
583 endpoint_address, control_selector, data
584 );
585 return None;
586 }
587
588 if control_selector != SAMPLING_FREQ_CONTROL {
589 debug!(
590 "Unsupported endpoint set request for control selector {}",
591 control_selector
592 );
593 return Some(OutResponse::Rejected);
594 }
595
596 let sample_rate_hz: u32 = (data[0] as u32) | (data[1] as u32) << 8 | (data[2] as u32) << 16;
597 self.shared.sample_rate_hz.store(sample_rate_hz, Ordering::Relaxed);
598
599 debug!("Set endpoint {} sample rate to {} Hz", endpoint_address, sample_rate_hz);
600
601 self.changed();
602
603 Some(OutResponse::Accepted)
604 }
605
606 fn interface_get_request<'r>(&'r mut self, req: Request, buf: &'r mut [u8]) -> Option<InResponse<'r>> {
607 let interface_number = req.index as u8;
608 let entity_index = (req.index >> 8) as u8;
609 let channel_index = req.value as u8;
610 let control_unit = (req.value >> 8) as u8;
611
612 if interface_number != self.control_interface_number.into() {
613 debug!("Unhandled interface get request for interface {}.", interface_number);
614 return None;
615 }
616
617 if entity_index != FEATURE_UNIT_ID {
618 // Only this function unit can be handled at the moment.
619 debug!("Unsupported interface get request for entity {}.", entity_index);
620 return Some(InResponse::Rejected);
621 }
622
623 let audio_settings = self.shared.audio_settings.lock(|x| x.get());
624
625 match req.request {
626 GET_CUR => match control_unit {
627 VOLUME_CONTROL => {
628 let volume: i16;
629
630 match channel_index as usize {
631 ..=MAX_AUDIO_CHANNEL_INDEX => volume = audio_settings.volume_8q8_db[channel_index as usize],
632 _ => return Some(InResponse::Rejected),
633 }
634
635 buf[0] = volume as u8;
636 buf[1] = (volume >> 8) as u8;
637
638 debug!("Got channel {} volume: {}.", channel_index, volume);
639 return Some(InResponse::Accepted(&buf[..2]));
640 }
641 MUTE_CONTROL => {
642 let mute_state: bool;
643
644 match channel_index as usize {
645 ..=MAX_AUDIO_CHANNEL_INDEX => mute_state = audio_settings.muted[channel_index as usize],
646 _ => return Some(InResponse::Rejected),
647 }
648
649 buf[0] = mute_state.into();
650 debug!("Got channel {} mute state: {}.", channel_index, mute_state);
651 return Some(InResponse::Accepted(&buf[..1]));
652 }
653 _ => return Some(InResponse::Rejected),
654 },
655 GET_MIN => match control_unit {
656 VOLUME_CONTROL => {
657 let min_volume = MIN_VOLUME_DB * VOLUME_STEPS_PER_DB;
658 buf[0] = min_volume as u8;
659 buf[1] = (min_volume >> 8) as u8;
660 return Some(InResponse::Accepted(&buf[..2]));
661 }
662 _ => return Some(InResponse::Rejected),
663 },
664 GET_MAX => match control_unit {
665 VOLUME_CONTROL => {
666 let max_volume = MAX_VOLUME_DB * VOLUME_STEPS_PER_DB;
667 buf[0] = max_volume as u8;
668 buf[1] = (max_volume >> 8) as u8;
669 return Some(InResponse::Accepted(&buf[..2]));
670 }
671 _ => return Some(InResponse::Rejected),
672 },
673 GET_RES => match control_unit {
674 VOLUME_CONTROL => {
675 buf[0] = VOLUME_STEPS_PER_DB as u8;
676 buf[1] = (VOLUME_STEPS_PER_DB >> 8) as u8;
677 return Some(InResponse::Accepted(&buf[..2]));
678 }
679 _ => return Some(InResponse::Rejected),
680 },
681 _ => return Some(InResponse::Rejected),
682 }
683 }
684
685 fn endpoint_get_request<'r>(&'r mut self, req: Request, buf: &'r mut [u8]) -> Option<InResponse<'r>> {
686 let control_selector = (req.value >> 8) as u8;
687 let endpoint_address = req.index as u8;
688
689 if endpoint_address != self.streaming_endpoint_address {
690 debug!("Unhandled endpoint get request for endpoint {}.", endpoint_address);
691 return None;
692 }
693
694 if control_selector != SAMPLING_FREQ_CONTROL as u8 {
695 debug!(
696 "Unsupported endpoint get request for control selector {}.",
697 control_selector
698 );
699 return Some(InResponse::Rejected);
700 }
701
702 let sample_rate_hz = self.shared.sample_rate_hz.load(Ordering::Relaxed);
703
704 buf[0] = (sample_rate_hz & 0xFF) as u8;
705 buf[1] = ((sample_rate_hz >> 8) & 0xFF) as u8;
706 buf[2] = ((sample_rate_hz >> 16) & 0xFF) as u8;
707
708 Some(InResponse::Accepted(&buf[..3]))
709 }
710}
711
712impl<'d> Handler for Control<'d> {
713 /// Called when the USB device has been enabled or disabled.
714 fn enabled(&mut self, enabled: bool) {
715 debug!("USB device enabled: {}", enabled);
716 }
717
718 /// Called when the host has set the address of the device to `addr`.
719 fn addressed(&mut self, addr: u8) {
720 debug!("Host set address to: {}", addr);
721 }
722
723 /// Called when the host has enabled or disabled the configuration of the device.
724 fn configured(&mut self, configured: bool) {
725 debug!("USB device configured: {}", configured);
726 }
727
728 /// Called when remote wakeup feature is enabled or disabled.
729 fn remote_wakeup_enabled(&mut self, enabled: bool) {
730 debug!("USB remote wakeup enabled: {}", enabled);
731 }
732
733 /// Called when a "set alternate setting" control request is done on the interface.
734 fn set_alternate_setting(&mut self, iface: InterfaceNumber, alternate_setting: u8) {
735 debug!(
736 "USB set interface number {} to alt setting {}.",
737 iface, alternate_setting
738 );
739 }
740
741 /// Called after a USB reset after the bus reset sequence is complete.
742 fn reset(&mut self) {
743 let shared = self.shared;
744 shared.audio_settings.lock(|x| x.set(AudioSettings::default()));
745
746 shared.changed.store(true, Ordering::Relaxed);
747 shared.waker.borrow_mut().wake();
748 }
749
750 /// Called when the bus has entered or exited the suspend state.
751 fn suspended(&mut self, suspended: bool) {
752 debug!("USB device suspended: {}", suspended);
753 }
754
755 // Handle control set requests.
756 fn control_out(&mut self, req: control::Request, data: &[u8]) -> Option<OutResponse> {
757 match req.request_type {
758 RequestType::Class => match req.recipient {
759 Recipient::Interface => self.interface_set_request(req, data),
760 Recipient::Endpoint => self.endpoint_set_request(req, data),
761 _ => Some(OutResponse::Rejected),
762 },
763 _ => None,
764 }
765 }
766
767 // Handle control get requests.
768 fn control_in<'a>(&'a mut self, req: Request, buf: &'a mut [u8]) -> Option<InResponse<'a>> {
769 match req.request_type {
770 RequestType::Class => match req.recipient {
771 Recipient::Interface => self.interface_get_request(req, buf),
772 Recipient::Endpoint => self.endpoint_get_request(req, buf),
773 _ => None,
774 },
775 _ => None,
776 }
777 }
778}