diff options
Diffstat (limited to 'docs/reference/class/audio.rst')
| -rw-r--r-- | docs/reference/class/audio.rst | 159 |
1 files changed, 154 insertions, 5 deletions
diff --git a/docs/reference/class/audio.rst b/docs/reference/class/audio.rst index 6e86dff8c..9a7422324 100644 --- a/docs/reference/class/audio.rst +++ b/docs/reference/class/audio.rst @@ -2,12 +2,17 @@ Audio ***** -Role: device only. TinyUSB supports USB Audio Class 1.0 and 2.0 streaming. +TinyUSB supports USB Audio Class 1.0 and 2.0 streaming in device and host +roles. + +Device driver +============= + The descriptors define the topology, formats, channels, rates, controls, and alternate settings; the application supplies or consumes the audio samples. Start from an example -===================== +--------------------- Audio descriptors and buffer sizes are tightly coupled. Copy the closest example, confirm that it enumerates, and then change one property at a time: @@ -20,7 +25,7 @@ example, confirm that it enumerates, and then change one property at a time: UAC2 at high speed, with multiple rates. Configuration -============= +------------- Set ``CFG_TUD_AUDIO`` to the number of audio functions. The principal options are: @@ -71,7 +76,7 @@ advertised alternate setting, for example intervals per millisecond than full-speed audio. Data path -========= +--------- .. list-table:: :header-rows: 1 @@ -112,7 +117,7 @@ merely because the device is mounted; wait until the streaming interface is active. Control requests -================ +---------------- Implement the ``tud_audio_get_req_*_cb()`` and ``tud_audio_set_req_*_cb()`` callbacks for every control advertised by the descriptors, such as clock @@ -129,3 +134,147 @@ rates match. Specifications used: *USB Device Class Definition for Audio Devices*, Release 1.0 and Release 2.0, plus *Audio Data Formats*, Release 2.0. + +Host driver +=========== + +The host driver discovers one playback stream and one capture stream in each +supported AudioControl function. It presents each usable alternate setting +and discrete sample rate as a complete ``format``, ``sample_rate``, and +``channels`` configuration. The application selects one of these tuples; +TinyUSB manages interface alternate settings, endpoints, packet sizing, and +explicit feedback. + +Start from :doc:`../../examples/host/audio_host`. It discovers configurations, +selects signed 16-bit capture and playback streams, and cycles through +microphone, speaker, and loopback operation. + +Configuration +------------- + +Set ``CFG_TUH_AUDIO`` to enable the driver. The principal options are: + +.. list-table:: + :header-rows: 1 + :widths: 36 18 46 + + * - Option + - Default + - What it controls + * - ``CFG_TUH_AUDIO`` + - ``0`` + - Enables the Audio host class. A nonzero value includes the driver. + * - ``CFG_TUH_AUDIO_PROTOCOLS`` + - UAC1 + - Bitmask of ``TUH_AUDIO_PROTOCOL_UAC1`` and + ``TUH_AUDIO_PROTOCOL_UAC2``. Combine them to accept both versions. + * - ``CFG_TUH_AUDIO_MAX`` + - ``1`` + - Maximum number of mounted AudioControl functions. + * - ``CFG_TUH_AUDIO_MAX_AS`` + - ``4`` + - Maximum number of nonzero-bandwidth alternate settings retained per + logical stream. + * - ``CFG_TUH_AUDIO_MAX_SAM_FREQ`` + - ``5`` + - Maximum discrete sample rates retained per UAC1 alternate setting or + UAC2 Clock Source. + * - ``CFG_TUH_AUDIO_EPIN_BUFSIZE`` / + ``CFG_TUH_AUDIO_EPOUT_BUFSIZE`` + - ``256`` bytes + - Largest capture/playback packet the driver can submit. A configuration + whose packet for one polling interval is larger is rejected. + * - ``CFG_TUH_AUDIO_STREAM_BUFSIZE`` + - ``1024`` bytes + - Per-stream FIFO depth. Playback sends silence when a complete packet + is unavailable; capture overwrites the oldest complete frames when the + FIFO is full. + +Increase the endpoint buffers for high channel counts, sample rates, or sample +widths. All buffers are statically allocated, so these maxima directly affect +RAM use. + +Stream lifecycle +---------------- + +After ``tuh_audio_mount_cb()``, enumerate stream indices from zero through +``tuh_audio_stream_count() - 1``. Use ``tuh_audio_stream_direction()`` to +distinguish ``TUH_AUDIO_STREAM_PLAYBACK`` (host to device) from +``TUH_AUDIO_STREAM_CAPTURE`` (device to host). Then enumerate the stream's +configurations with ``tuh_audio_config_count()`` and +``tuh_audio_config_get()``. + +For each stream: + +1. Call ``tuh_audio_configure()`` with a supported configuration index while + the stream is stopped. +2. Call ``tuh_audio_start()``. A ``true`` return means that startup was + submitted, not that it completed. +3. Wait for ``TUH_AUDIO_EVENT_START_COMPLETE`` in ``tuh_audio_event_cb()`` and + check that its transfer result is successful before handling samples. +4. Use the non-blocking frame FIFO APIs while the stream runs. +5. Call ``tuh_audio_stop()`` and wait for + ``TUH_AUDIO_EVENT_STOP_COMPLETE`` before reconfiguring the stream. + +Capture and playback streams in the same AudioControl function must use the +same sample rate while they run concurrently. ``tuh_audio_active_config()`` +returns ``TUSB_INDEX_INVALID_8`` when no configuration is selected. + +Audio data is counted in frames, not bytes. One frame contains one sample for +every channel; obtain its byte size with ``tuh_audio_config_frame_size()``. +``tuh_audio_read()`` removes whole frames from a capture FIFO, while +``tuh_audio_write()`` queues whole frames for playback. Their return values +may be shorter than requested. Use ``tuh_audio_read_available()`` and +``tuh_audio_write_available()`` to service the FIFOs from the application task; +the transfer callbacks are notifications and need not drive FIFO servicing. + +Callbacks and failures +---------------------- + +``tuh_audio_descriptor_cb()`` runs during enumeration, before the mount +callback. Its descriptor pointers are valid only during the call. Copy any +entity IDs or descriptor fields needed for later raw controls, but do not +submit control transfers from this callback. + +``tuh_audio_capture_cb()`` and ``tuh_audio_playback_cb()`` report successful +isochronous transfers. ``tuh_audio_event_cb()`` reports asynchronous start and +stop completion and ``TUH_AUDIO_EVENT_XFER_FAILED``. A failed stream has been +stopped; the application may reconfigure or restart it. Clear all saved +indices and associated state in ``tuh_audio_umount_cb()`` because an index may +be reused by a later device. + +Run ``tuh_task()`` continuously. Isochronous transfers follow the endpoint's +polling interval, and delaying the host task can exhaust the FIFO even when its +average producer and consumer rates match. + +Feature Unit controls +--------------------- + +The driver discovers master mute and volume capabilities before the mount +callback. Test mute with ``tuh_audio_mute_supported()`` and retrieve the +cached volume range with ``tuh_audio_volume_range_get()``. Volume values use +signed 1/256 dB units; ``TUH_AUDIO_VOLUME_SILENCE`` represents silence, and +``TUH_AUDIO_CHANNEL_MASTER`` selects the master channel. + +The asynchronous ``tuh_audio_mute_*()`` and ``tuh_audio_volume_*()`` APIs use +a completion callback. Their synchronous helpers block until completion and +should only be used while audio streaming is stopped; synchronous transfers +can disrupt isochronous traffic. Use ``tuh_audio_control_xfer()`` for other +class-specific entity controls. Buffers passed to asynchronous controls must +remain valid until their completion callbacks run. + +Supported formats and limitations +--------------------------------- + +The host accepts Type-I PCM in signed 8-, 16-, packed 24-, 24-in-32-, and +32-bit little-endian formats. UAC1 descriptors must list discrete sample +rates; continuous ranges are not supported. UAC2 requires a directly +connected Clock Source. Clock Selectors, Clock Multipliers, Sampling Rate +Converters, Clock Validity, and Valid Alternate Settings controls are not +handled. + +Explicit feedback endpoints using 10.14 or 16.16 values are supported. +Implicit-feedback IN endpoints are treated as ordinary capture endpoints and +do not pace playback. ``MaxPacketsOnly`` endpoints are not supported: OUT +packets are not padded to ``wMaxPacketSize``, and padding in IN packets is not +removed from the captured data. |
