Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Dependents: TYBLE16_simple_data_logger TYBLE16_MP3_Air
USBAudio.h
00001 /* 00002 * Copyright (c) 2018-2019, Arm Limited and affiliates. 00003 * SPDX-License-Identifier: Apache-2.0 00004 * 00005 * Licensed under the Apache License, Version 2.0 (the "License"); 00006 * you may not use this file except in compliance with the License. 00007 * You may obtain a copy of the License at 00008 * 00009 * http://www.apache.org/licenses/LICENSE-2.0 00010 * 00011 * Unless required by applicable law or agreed to in writing, software 00012 * distributed under the License is distributed on an "AS IS" BASIS, 00013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 00014 * See the License for the specific language governing permissions and 00015 * limitations under the License. 00016 */ 00017 00018 #ifndef USBAudio_H 00019 #define USBAudio_H 00020 00021 /* These headers are included for child class. */ 00022 #include "USBDescriptor.h" 00023 #include "USBDevice_Types.h" 00024 00025 #include "USBDevice.h" 00026 #include "Callback.h" 00027 #include "OperationList.h" 00028 #include "ByteBuffer.h" 00029 #include "rtos/EventFlags.h" 00030 00031 /** \defgroup drivers-public-api-usb USB 00032 * \ingroup drivers-public-api 00033 */ 00034 00035 /** 00036 * \defgroup drivers_USBAudio USBAudio class 00037 * \ingroup drivers-public-api-usb 00038 * @{ 00039 */ 00040 00041 00042 /** 00043 * USBAudio example 00044 * 00045 * @code 00046 * #include "mbed.h" 00047 * #include "USBAudio.h" 00048 * 00049 * // Audio loopback example use: 00050 * // 1. Select "Mbed Audio" as your sound device 00051 * // 2. Play a song or audio file 00052 * // 3. Record the output using a program such as Audacity 00053 * 00054 * int main() { 00055 * 00056 * USBAudio audio(true, 44100, 2, 44100, 2); 00057 * 00058 * printf("Looping audio\r\n"); 00059 * static uint8_t buf[128]; 00060 * while (true) { 00061 * if (!audio.read(buf, sizeof(buf))) { 00062 * memset(buf, 0, sizeof(buf)); 00063 * } 00064 * audio.write(buf, sizeof(buf)); 00065 * } 00066 * } 00067 * @endcode 00068 */ 00069 class USBAudio: protected USBDevice { 00070 public: 00071 00072 enum AudioEvent { 00073 Start, 00074 Transfer, 00075 End 00076 }; 00077 00078 /** 00079 * Basic constructor 00080 * 00081 * Construct this object optionally connecting. 00082 * 00083 * @note Do not use this constructor in derived classes. 00084 * 00085 * @param connect Call connect on initialization 00086 * @param frequency_rx frequency in Hz (default: 48000) 00087 * @param channel_count_rx channel number (1 or 2) (default: 1) 00088 * @param frequency_tx frequency in Hz (default: 8000) 00089 * @param channel_count_tx channel number (1 or 2) (default: 1) 00090 * @param buffer_ms time audio can be buffered without overflowing in milliseconds 00091 * @param vendor_id Your vendor_id 00092 * @param product_id Your product_id 00093 * @param product_release Your product_release 00094 */ 00095 USBAudio(bool connect = true, uint32_t frequency_rx = 48000, uint8_t channel_count_rx = 1, uint32_t frequency_tx = 8000, uint8_t channel_count_tx = 1, uint32_t buffer_ms = 10, uint16_t vendor_id = 0x7bb8, uint16_t product_id = 0x1111, uint16_t product_release = 0x0100); 00096 00097 /** 00098 * Fully featured constructor 00099 * 00100 * Construct this object with the supplied USBPhy and parameters. The user 00101 * this object is responsible for calling connect() or init(). 00102 * 00103 * @note Derived classes must use this constructor and call init() or 00104 * connect() themselves. Derived classes should also call deinit() in 00105 * their destructor. This ensures that no interrupts can occur when the 00106 * object is partially constructed or destroyed. 00107 * 00108 * @param phy USB phy to use 00109 * @param frequency_rx frequency in Hz (default: 48000) 00110 * @param channel_count_rx channel number (1 or 2) (default: 1) 00111 * @param frequency_tx frequency in Hz (default: 8000) 00112 * @param channel_count_tx channel number (1 or 2) (default: 1) 00113 * @param buffer_ms time audio can be buffered without overflowing in milliseconds 00114 * @param vendor_id Your vendor_id 00115 * @param product_id Your product_id 00116 * @param product_release Your product_release 00117 */ 00118 USBAudio(USBPhy *phy, uint32_t frequency_rx, uint8_t channel_count_rx, uint32_t frequency_tx, uint8_t channel_count_tx, uint32_t buffer_ms, uint16_t vendor_id, uint16_t product_id, uint16_t product_release); 00119 00120 /** 00121 * Destroy this object 00122 * 00123 * Any classes which inherit from this class must call deinit 00124 * before this destructor runs. 00125 */ 00126 virtual ~USBAudio(); 00127 00128 /** 00129 * Connect USBAudio 00130 */ 00131 void connect(); 00132 00133 /** 00134 * Disconnect USBAudio 00135 * 00136 * This unblocks all calls to read_ready and write_ready. 00137 */ 00138 void disconnect(); 00139 00140 /** 00141 * Read audio data 00142 * 00143 * @param buf pointer on a buffer which will be filled with audio data 00144 * @param size size to read 00145 * 00146 * @returns true if successful 00147 */ 00148 bool read(uint8_t *buf, uint32_t size); 00149 00150 /** 00151 * Nonblocking audio data read 00152 * 00153 * Read the available audio data. 00154 * 00155 * @param buf pointer on a buffer which will be filled with audio data 00156 * @param size size to read 00157 * @param actual size actually read 00158 * @note This function is safe to call from USBAudio callbacks. 00159 */ 00160 void read_nb(uint8_t *buf, uint32_t size, uint32_t *actual); 00161 00162 /** 00163 * Return the number read packets dropped due to overflow 00164 * 00165 * @param clear Reset the overflow count back to 0 00166 * @return Number of packets dropped due to overflow 00167 */ 00168 uint32_t read_overflows(bool clear = false); 00169 00170 /** 00171 * Check if the audio read channel is open 00172 * 00173 * @return true if the audio read channel open, false otherwise 00174 */ 00175 bool read_ready(); 00176 00177 /** 00178 * Wait until the audio read channel is open 00179 */ 00180 void read_wait_ready(); 00181 00182 /** 00183 * Write audio data 00184 * 00185 * @param buf pointer to audio data to write 00186 * @param size size to write 00187 * 00188 * @returns true if successful 00189 */ 00190 bool write(uint8_t *buf, uint32_t size); 00191 00192 /** 00193 * Nonblocking audio data write 00194 * 00195 * Write the available audio data. 00196 * 00197 * @param buf pointer to audio data to write 00198 * @param size size to write 00199 * @param actual actual size written 00200 * @note This function is safe to call from USBAudio callbacks. 00201 */ 00202 void write_nb(uint8_t *buf, uint32_t size, uint32_t *actual); 00203 00204 /** 00205 * Return the number write packets not sent due to underflow 00206 * 00207 * @param clear Reset the underflow count back to 0 00208 * @return Number of packets that should have been 00209 * sent but weren't due to overflow 00210 */ 00211 uint32_t write_underflows(bool clear = false); 00212 00213 /** 00214 * Check if the audio write channel is open 00215 * 00216 * @return true if the audio write channel open, false otherwise 00217 */ 00218 bool write_ready(); 00219 00220 /** 00221 * Wait until the audio write channel is open 00222 */ 00223 void write_wait_ready(); 00224 00225 /** 00226 * Get current volume between 0.0 and 1.0 00227 * 00228 * @returns volume 00229 */ 00230 float get_volume(); 00231 00232 /** Attach a Callback to update the volume 00233 * 00234 * @param cb Callback to attach 00235 * 00236 */ 00237 void attach(mbed::Callback<void()> &cb); 00238 00239 /** attach a Callback to Tx Done 00240 * 00241 * @param cb Callback to attach 00242 * 00243 */ 00244 void attach_tx(mbed::Callback<void(AudioEvent)> &cb); 00245 00246 /** attach a Callback to Rx Done 00247 * 00248 * @param cb Callback to attach 00249 * 00250 */ 00251 void attach_rx(mbed::Callback<void(AudioEvent)> &cb); 00252 00253 protected: 00254 00255 virtual void callback_state_change(DeviceState new_state); 00256 virtual void callback_request(const setup_packet_t *setup); 00257 virtual void callback_request_xfer_done(const setup_packet_t *setup, bool aborted); 00258 virtual void callback_set_configuration(uint8_t configuration); 00259 virtual void callback_set_interface(uint16_t interface, uint8_t alternate); 00260 00261 virtual const uint8_t *string_iproduct_desc(); 00262 virtual const uint8_t *string_iinterface_desc(); 00263 virtual const uint8_t *configuration_desc(uint8_t index); 00264 00265 private: 00266 00267 class AsyncWrite; 00268 class AsyncRead; 00269 00270 enum ChannelState { 00271 Powerdown, 00272 Closed, 00273 Opened 00274 }; 00275 00276 void _init(uint32_t frequency_rx, uint8_t channel_count_rx, uint32_t frequency_tx, uint8_t channel_count_tx, uint32_t buffer_ms); 00277 00278 /* 00279 * Call to rebuild the configuration descriptor 00280 * 00281 * This function should be called on creation or when any 00282 * value that is part of the configuration descriptor 00283 * changes. 00284 * @note This function uses ~200 bytes of stack so 00285 * make sure your stack is big enough for it. 00286 */ 00287 void _build_configuration_desc(); 00288 00289 void _receive_change(ChannelState new_state); 00290 void _receive_isr(); 00291 void _send_change(ChannelState new_state); 00292 void _send_isr_start(); 00293 void _send_isr_next_sync(); 00294 void _send_isr(); 00295 00296 // has connect been called 00297 bool _connected; 00298 00299 // audio volume 00300 float _volume; 00301 00302 // mute state 00303 uint8_t _mute; 00304 00305 // Volume Current Value 00306 uint16_t _vol_cur; 00307 00308 // Volume Minimum Value 00309 uint16_t _vol_min; 00310 00311 // Volume Maximum Value 00312 uint16_t _vol_max; 00313 00314 // Volume Resolution 00315 uint16_t _vol_res; 00316 00317 // callback to update volume 00318 mbed::Callback<void()> _update_vol; 00319 00320 // callback transmit Done 00321 mbed::Callback<void(AudioEvent)> _tx_done; 00322 00323 // callback receive Done 00324 mbed::Callback<void(AudioEvent)> _rx_done; 00325 00326 // Number of times data was dropped due to an overflow 00327 uint32_t _rx_overflow; 00328 00329 // Number of times data was not sent due to an underflow 00330 uint32_t _tx_underflow; 00331 00332 // frequency in Hz 00333 uint32_t _tx_freq; 00334 uint32_t _rx_freq; 00335 00336 // mono, stereo,... 00337 uint8_t _rx_channel_count; 00338 uint8_t _tx_channel_count; 00339 00340 bool _tx_idle; 00341 uint16_t _tx_frame_fract; 00342 uint16_t _tx_whole_frames_per_xfer; 00343 uint16_t _tx_fract_frames_per_xfer; 00344 00345 // size of the maximum packet for the isochronous endpoint 00346 uint16_t _tx_packet_size_max; 00347 uint16_t _rx_packet_size_max; 00348 00349 // Buffer used for the isochronous transfer 00350 uint8_t *_tx_packet_buf; 00351 uint8_t *_rx_packet_buf; 00352 00353 // Holding buffer 00354 ByteBuffer _tx_queue; 00355 ByteBuffer _rx_queue; 00356 00357 // State of the audio channels 00358 ChannelState _tx_state; 00359 ChannelState _rx_state; 00360 00361 00362 // sample - a single PCM audio sample 00363 // frame - a group of samples from each channel 00364 // packet - a group of frames sent over USB in one transfer 00365 00366 // Blocking primitives 00367 OperationList<AsyncWrite> _write_list; 00368 OperationList<AsyncRead> _read_list; 00369 rtos::EventFlags _flags; 00370 00371 // endpoint numbers 00372 usb_ep_t _episo_out; // rx endpoint 00373 usb_ep_t _episo_in; // tx endpoint 00374 00375 // channel config in the configuration descriptor: master, left, right 00376 uint16_t _channel_config_rx; 00377 uint16_t _channel_config_tx; 00378 00379 // configuration descriptor 00380 uint8_t _config_descriptor[183]; 00381 00382 // buffer for control requests 00383 uint8_t _control_receive[2]; 00384 00385 }; 00386 00387 /** @}*/ 00388 00389 #endif
Generated on Tue Jul 12 2022 13:55:02 by
