Kenji Arai / mbed-os_TYBLE16

Dependents:   TYBLE16_simple_data_logger TYBLE16_MP3_Air

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers USBAudio.h Source File

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