USB Audio 音频流同步问题

10 篇文章 2 订阅

笔者最近开发USB Audio遇到了同步相关问题,通过搜集相关资料和项目实验,解决了其问题,现分享一番:

因为笔者只开发设备相关,所以USB主机音频流同步问题就不分析了。

废话说完,现在步入正题。。。。。。

        当USB主机向设备发送数据时,如果主机发送数据过快,USB设备来不及接收,音频数据来不及处理或溢出,将产生噪声;同理,USB注意发送数据过慢,USB数据接收不完整,也会产生噪声。那么怎么解决这类问题呢?

关于USB主机与设备间的同步,有两种方法:

1.设备可以根据缓冲区空间剩余大小,动态调整设备时钟频率,使得USB主机和设备双方频率能一致。

2.利用设备的反馈端点(Feedback Endpoint),向主机定时发送设备当前需要的频率(动态的数据),这样能调整USB主机发送数据的数量。比如说,如果当前主机默认按照44.1K发送数据,若设备返回44.2K,那么主机将会在某个时间多发几个数据,将其调整为44.2K。

描述符注意事项:

    /**********************INTERFACE Descriptor:0x04**********************/
    USB_DESCRIPTOR_LENGTH_INTERFACE,   /* Size of this descriptor in bytes */
    USB_DESCRIPTOR_TYPE_INTERFACE,     /* INTERFACE Descriptor Type */
    USB_AUDIO_CONTROL_INTERFACE_INDEX, /* Number of this interface. */
    0x00U,                             /* Value used to select this alternate setting
                                          for the interface identified in the prior field */
    0x01U,                             /* Number of endpoints used by this
                                          interface (excluding endpoint zero). */
    USB_AUDIO_CLASS,                   /*The interface implements the Audio Interface class  */
    USB_SUBCLASS_AUDIOCONTROL,         /*The interface implements the AUDIOCONTROL Subclass  */
    0x00U,                             /*The interface doesn't use any class-specific protocols  */
    0x00U,                             /* The device doesn't have a string descriptor describing this iInterface  */

    /*******************AC HEADER of INTERFACE Descriptor:0x24 0x01*************************/      
    USB_AUDIO_CONTROL_INTERFACE_HEADER_LENGTH,   /* Size of the descriptor, in bytes  */
    USB_DESCRIPTOR_TYPE_AUDIO_CS_INTERFACE,      /* CS_INTERFACE Descriptor Type   */
    USB_DESCRIPTOR_SUBTYPE_AUDIO_CONTROL_HEADER, /* HEADER descriptor subtype   */
    0x00U, 0x01U, /* Audio Device compliant to the USB Audio specification version 1.00  */
    0x48, 0x00U,  /* Total number of bytes returned for the class-specific AudioControl interface descriptor. Includes
                     the combined length of this descriptor header and all Unit and Terminal descriptors. */
    0x02U, /* The number of AudioStreaming and MIDIStreaming interfaces in the Audio Interface Collection to which this
              AudioControl interface belongs   */
    0x01U, /* The number of AudioStreaming and MIDIStreaming interfaces in the Audio Interface baNumber */
    0x02U, /* The number of AudioStreaming and MIDIStreaming interfaces in the Audio Interface baNumber */

    /******************* Audio Class Specific type of Input Terminal:0x24 0x02*************************/  
    USB_AUDIO_INPUT_TERMINAL_ONLY_DESC_SIZE, /* Size of the descriptor, in bytes  */
    USB_DESCRIPTOR_TYPE_AUDIO_CS_INTERFACE,  /* CS_INTERFACE Descriptor Type   */
    USB_DESCRIPTOR_SUBTYPE_AUDIO_CONTROL_INPUT_TERMINAL,
    /* INPUT_TERMINAL descriptor subtype  */
    USB_AUDIO_RECORDER_CONTROL_INPUT_TERMINAL_ID, /* Constant uniquely identifying the Terminal within the audio
                 function. This value is used in all requests
                 to address this Terminal.  */
    0x01U, 0x02,  /* A generic microphone that does not fit under any of the other classifications.  */
    0x00U,        /* This Input Terminal has no association  */
    0x02U,        /* This Terminal's output audio channel cluster has 1 logical output channels  */
    0x03U, 0x00U, /* Spatial locations present in the cluster */
    0x00U,        /* Index of a string descriptor, describing the name of the first logical channel.   */
    0x00U,        /* Index of a string descriptor, describing the Input Terminal.   */

    /*******************Audio Class Specific type of Feature Unit:0x24 0x06*************************/  
    /*Feature Unit 用于确定Audio 开放什么功能,下面开放了静音,左右声道调节*/ 
    USB_AUDIO_FEATURE_UNIT_ONLY_DESC_SIZE(2, 1),       /* Size of the descriptor, in bytes   */
    USB_DESCRIPTOR_TYPE_AUDIO_CS_INTERFACE,            /* CS_INTERFACE Descriptor Type  */
    USB_DESCRIPTOR_SUBTYPE_AUDIO_CONTROL_FEATURE_UNIT, /* FEATURE_UNIT descriptor subtype   */
    USB_AUDIO_RECORDER_CONTROL_FEATURE_UNIT_ID,   /* Constant uniquely identifying the Unit within the audio function.
                  This value is used in all requests to
                  address this Unit.  */
    USB_AUDIO_RECORDER_CONTROL_INPUT_TERMINAL_ID, /* ID of the Unit or Terminal to which this Feature Unit is connected.
                                                     */
    0x01U,                                        /* Size in bytes of an element of the bmaControls() array:  */
    0x01U,                                       /* Master channel0: Mute */
    0x02U,                                       /* Left  channel1: Volume*/
    0x02U,                                       /* Right channel2: Volume */
    0x00U,                                        /* Index of a string descriptor, describing this Feature Unit.   */

    /*******************Audio Class Specific type of  Output Terminal:0x24 0x03*************************/      
    USB_AUDIO_OUTPUT_TERMINAL_ONLY_DESC_SIZE, /* Size of the descriptor, in bytes  */
    USB_DESCRIPTOR_TYPE_AUDIO_CS_INTERFACE,   /* CS_INTERFACE Descriptor Type   */
    USB_DESCRIPTOR_SUBTYPE_AUDIO_CONTROL_OUTPUT_TERMINAL,
    /* OUTPUT_TERMINAL descriptor subtype  */
    USB_AUDIO_RECORDER_CONTROL_OUTPUT_TERMINAL_ID, /* Constant uniquely identifying the Terminal within the audio
                                                      function*/
    0x01U, 0x01U, /* A Terminal dealing with a signal carried over an endpoint in an AudioStreaming interface */
    0x00U,        /*  This Output Terminal has no association   */
    USB_AUDIO_RECORDER_CONTROL_FEATURE_UNIT_ID, /* ID of the Unit or Terminal to which this Terminal is connected.   */
    0x00U,                                      /* Index of a string descriptor, describing the Output Terminal.  */

    /******************* Audio Class Specific type of Input Terminal:0x24 0x02*************************/  
    USB_AUDIO_INPUT_TERMINAL_ONLY_DESC_SIZE, /* Size of the descriptor, in bytes  */
    USB_DESCRIPTOR_TYPE_AUDIO_CS_INTERFACE,  /* CS_INTERFACE Descriptor Type   */
    USB_DESCRIPTOR_SUBTYPE_AUDIO_CONTROL_INPUT_TERMINAL,
    /* INPUT_TERMINAL descriptor subtype  */
    USB_AUDIO_SPEAKER_CONTROL_INPUT_TERMINAL_ID, /* Constant uniquely identifying the Terminal within the audio
              function. This value is used in all requests
              to address this Terminal.  */
    0x01U, 0x01,  /* A Terminal dealing with a signal carried over an endpoint in an AudioStreaming interface.  */
    0x00U,        /* This Input Terminal has no association  */
    0x02U,        /* This Terminal's output audio channel cluster has 1 logical output channels  */
    0x03U, 0x00U, /* Spatial locations present in the cluster */
    0x00U,        /* Index of a string descriptor, describing the name of the first logical channel.   */
    0x00U,        /* Index of a string descriptor, describing the Input Terminal.   */


    /*******************Audio Class Specific type of Feature Unit:0x24 0x06*************************/  
    /*Feature Unit 用于确定Audio 开放什么功能,下面开放了静音,左右声道调节*/    
    USB_AUDIO_FEATURE_UNIT_ONLY_DESC_SIZE(2, 1),       /* Size of the descriptor, in bytes   */
    USB_DESCRIPTOR_TYPE_AUDIO_CS_INTERFACE,            /* CS_INTERFACE Descriptor Type  */
    USB_DESCRIPTOR_SUBTYPE_AUDIO_CONTROL_FEATURE_UNIT, /* FEATURE_UNIT descriptor subtype   */
    USB_AUDIO_SPEAKER_CONTROL_FEATURE_UNIT_ID, /* Constant uniquely identifying the Unit within the audio function. This
             value is used in all requests to
             address this Unit.  */
    USB_AUDIO_SPEAKER_CONTROL_INPUT_TERMINAL_ID, /* ID of the Unit or Terminal to which this Feature Unit is connected.
                                                    */
    0x01U,                                       /* Size in bytes of an element of the bmaControls() array:  */
    0x01U,                                       /* Master channel0: Mute */
    0x02U,                                       /* Left  channel1: Volume*/
    0x02U,                                       /* Right channel2: Volume */
    0x00U,                                       /* Index of a string descriptor, describing this Feature Unit.   */

    /*******************Audio Class Specific type of Output Terminal:0x24 0x03*************************/      
    USB_AUDIO_OUTPUT_TERMINAL_ONLY_DESC_SIZE, /* Size of the descriptor, in bytes  */
    USB_DESCRIPTOR_TYPE_AUDIO_CS_INTERFACE,   /* CS_INTERFACE Descriptor Type   */
    USB_DESCRIPTOR_SUBTYPE_AUDIO_CONTROL_OUTPUT_TERMINAL,
    /* OUTPUT_TERMINAL descriptor subtype  */
    USB_AUDIO_SPEAKER_CONTROL_OUTPUT_TERMINAL_ID, /* Constant uniquely identifying the Terminal within the audio
                                                     function*/
    0x01U, 0x03U, /* A generic speaker or set of speakers that does not fit under any of the other classifications. */
    0x00U,        /*  This Output Terminal has no association   */
    USB_AUDIO_SPEAKER_CONTROL_FEATURE_UNIT_ID, /* ID of the Unit or Terminal to which this Terminal is connected.   */
    0x00U,                                     /* Index of a string descriptor, describing the Output Terminal.  */

    /******************************* Audio Control ENDPOINT descriptor: 0x05 *******************************/ 	
    USB_DESCRIPTOR_LENGTH_AC_INTERRUPT_ENDPOINT, /* Size of this descriptor, in bytes: 9U */
    USB_DESCRIPTOR_TYPE_ENDPOINT,                /* ENDPOINT descriptor type */
    USB_AUDIO_CONTROL_ENDPOINT | (USB_IN << USB_DESCRIPTOR_ENDPOINT_ADDRESS_DIRECTION_SHIFT),
    /* Endpoint address */
    USB_ENDPOINT_INTERRUPT, /* Transfer type */
    USB_SHORT_GET_LOW(FS_AUDIO_INTERRUPT_IN_PACKET_SIZE), USB_SHORT_GET_HIGH(FS_AUDIO_INTERRUPT_IN_PACKET_SIZE),
    /* Max Packet Size */
    FS_AUDIO_INTERRUPT_IN_INTERVAL, /* Interval */
    0, 0,

	/*****************Audio Recorder INTERFACE descriptor:0x04***********alternative interface 0************/      
    USB_DESCRIPTOR_LENGTH_INTERFACE,           /* Descriptor size is 9 bytes  */
    USB_DESCRIPTOR_TYPE_INTERFACE,             /* INTERFACE Descriptor Type   */
    USB_AUDIO_RECORDER_STREAM_INTERFACE_INDEX, /* The number of this interface is 1.  */
    0x00U,                    /* The value used to select the alternate setting for this interface is 0   */
    0x00U,                    /* The number of endpoints used by this interface is 0 (excluding endpoint zero)   */
    USB_AUDIO_CLASS,          /* The interface implements the Audio Interface class   */
    USB_SUBCLASS_AUDIOSTREAM, /* The interface implements the AUDIOSTREAMING Subclass   */
    0x00U,                    /* The interface doesn't use any class-specific protocols   */
    0x00U,                    /* The device doesn't have a string descriptor describing this iInterface  */

	/*****************Audio Recorder INTERFACE descriptor:0x04***********alternative interface 1************/  	    
    USB_DESCRIPTOR_LENGTH_INTERFACE,           /* Descriptor size is 9 bytes  */
    USB_DESCRIPTOR_TYPE_INTERFACE,             /* INTERFACE Descriptor Type  */
    USB_AUDIO_RECORDER_STREAM_INTERFACE_INDEX, /*The number of this interface is 1.  */
    0x01U,                    /* The value used to select the alternate setting for this interface is 1  */
    0x01U,                    /* The number of endpoints used by this interface is 1 (excluding endpoint zero)    */
    USB_AUDIO_CLASS,          /* The interface implements the Audio Interface class   */
    USB_SUBCLASS_AUDIOSTREAM, /* The interface implements the AUDIOSTREAMING Subclass   */
    0x00U,                    /* The interface doesn't use any class-specific protocols  */
    0x00U,                    /* The device doesn't have a string descriptor describing this iInterface  */

    /*******************AS_GENERAL descriptor subtype Descriptor:0x24 0x01*************************/      
    USB_AUDIO_STREAMING_IFACE_DESC_SIZE,            /* Size of the descriptor, in bytes  */
    USB_DESCRIPTOR_TYPE_AUDIO_CS_INTERFACE,         /* CS_INTERFACE Descriptor Type  */
    USB_DESCRIPTOR_SUBTYPE_AUDIO_STREAMING_GENERAL, /* AS_GENERAL descriptor subtype  */
    USB_AUDIO_RECORDER_CONTROL_OUTPUT_TERMINAL_ID,  /* The Terminal ID of the Terminal to which the endpoint of this
                                                       interface is connected. */
    0x00U,        /* Delay introduced by the data path. Expressed in number of frames.  */
    0x01U, 0x00U, /* PCM  */

    /****************** Audio Class Specific type I format INTERFACE Descriptor: 0x24 0X02 ***********/      
    USB_AUDIO_STREAMING_TYPE_I_DESC_SIZE,   /* Size of the descriptor, in bytes  */
    USB_DESCRIPTOR_TYPE_AUDIO_CS_INTERFACE, /* CS_INTERFACE Descriptor Type   */
    USB_DESCRIPTOR_SUBTYPE_AUDIO_STREAMING_FORMAT_TYPE,
    /* FORMAT_TYPE descriptor subtype  */
    USB_AUDIO_FORMAT_TYPE_I, /* FORMAT_TYPE_I  */
    AUDIO_FORMAT_CHANNELS,   /* Indicates the number of physical channels in the audio data stream.  */
    AUDIO_FORMAT_SIZE,       /* The number of bytes occupied by one audio subframe. Can be 1, 2, 3 or 4.   */
    AUDIO_FORMAT_BITS,       /* The number of effectively used bits from the available bits in an audio subframe.*/
    0x01U,                   /* Indicates how the sampling frequency can be programmed:   */
    AUDIO_SAMPLE_FREQ(44100),

    /******************************* Audio Recorder IN ENDPOINT descriptor: 0x05 *******************************/
    USB_ENDPOINT_AUDIO_DESCRIPTOR_LENGTH,               /* Descriptor size is 9 bytes  */
    USB_DESCRIPTOR_TYPE_ENDPOINT,                       /* ENDPOINT Descriptor Type   */
    USB_AUDIO_RECORDER_STREAM_ENDPOINT | (USB_IN << 7), /* This is an IN endpoint with endpoint number 2   */
    USB_ENDPOINT_ISOCHRONOUS | 0x04 | (0x2 << 4U),      /*   Types - Transfer: ISOCHRONOUS
                                                                     Sync: Async
                                                                     Usage: Implicit Feedback EP   */
    USB_SHORT_GET_LOW(FS_ISO_IN_ENDP_PACKET_SIZE + AUDIO_FORMAT_CHANNELS * AUDIO_FORMAT_SIZE),
    USB_SHORT_GET_HIGH(FS_ISO_IN_ENDP_PACKET_SIZE +
                       AUDIO_FORMAT_CHANNELS *
                           AUDIO_FORMAT_SIZE), /* Maximum packet size for this endpoint is 8 Bytes.  */
    FS_ISO_IN_ENDP_INTERVAL, /* The polling interval value is every 1 Frames. If Hi-Speed, every 1 uFrames   */
    0x00U,                   /* Refresh Rate 2**n ms where n = 0   */
    0x00U,                   /* Synchronization Endpoint (if used) is endpoint 0   */

    /******************************* Audio Class Specific ENDPOINT Descriptor: 0x25 0x01*******************************/        
    USB_AUDIO_STREAMING_ENDP_DESC_SIZE,      /*  Size of the descriptor, in bytes  */
    USB_AUDIO_STREAM_ENDPOINT_DESCRIPTOR,    /* CS_ENDPOINT Descriptor Type  */
    USB_AUDIO_EP_GENERAL_DESCRIPTOR_SUBTYPE, /* AUDIO_EP_GENERAL descriptor subtype  */
    0x00U,                                   /* Bit 0: Sampling Frequency 0
                                                Bit 1: Pitch 0
                                                Bit 7: MaxPacketsOnly 0   */
    0x00U,                                   /* Indicates the units used for the wLockDelay field: 0: Undefined  */
    0x00U,
    0x00U, /* Indicates the time it takes this endpoint to reliably lock its internal clock recovery
              circuitry */

	/*****************Audio Speaker INTERFACE descriptor:0x04***********alternative interface 0************/  	
    USB_DESCRIPTOR_LENGTH_INTERFACE,          /* Descriptor size is 9 bytes  */
    USB_DESCRIPTOR_TYPE_INTERFACE,            /* INTERFACE Descriptor Type   */
    USB_AUDIO_SPEAKER_STREAM_INTERFACE_INDEX, /* The number of this interface is 1.  */
    0x00U,                    /* The value used to select the alternate setting for this interface is 0   */
    0x00U,                    /* The number of endpoints used by this interface is 0 (excluding endpoint zero)   */
    USB_AUDIO_CLASS,          /* The interface implements the Audio Interface class   */
    USB_SUBCLASS_AUDIOSTREAM, /* The interface implements the AUDIOSTREAMING Subclass   */
    0x00U,                    /* The interface doesn't use any class-specific protocols   */
    0x00U,                    /* The device doesn't have a string descriptor describing this iInterface  */

	/*****************Audio Speaker INTERFACE descriptor:0x04*********alternative interface 1 **************/  
    USB_DESCRIPTOR_LENGTH_INTERFACE,          /* Descriptor size is 9 bytes  */
    USB_DESCRIPTOR_TYPE_INTERFACE,            /* INTERFACE Descriptor Type  */
    USB_AUDIO_SPEAKER_STREAM_INTERFACE_INDEX, /*The number of this interface is 1.  */
    0x01U,                    /* The value used to select the alternate setting for this interface is 1  */
    0x02U,                    /* The number of endpoints used by this interface is 2 (excluding endpoint zero)    */
    USB_AUDIO_CLASS,          /* The interface implements the Audio Interface class   */
    USB_SUBCLASS_AUDIOSTREAM, /* The interface implements the AUDIOSTREAMING Subclass   */
    0x00U,                    /* The interface doesn't use any class-specific protocols  */
    0x00U,                    /* The device doesn't have a string descriptor describing this iInterface  */

    /*******************AS_GENERAL descriptor subtype Descriptor:0x24 0x01*************************/  
    USB_AUDIO_STREAMING_IFACE_DESC_SIZE,            /* Size of the descriptor, in bytes  */
    USB_DESCRIPTOR_TYPE_AUDIO_CS_INTERFACE,         /* CS_INTERFACE Descriptor Type  */
    USB_DESCRIPTOR_SUBTYPE_AUDIO_STREAMING_GENERAL, /* AS_GENERAL descriptor subtype  */
    USB_AUDIO_SPEAKER_CONTROL_INPUT_TERMINAL_ID,    /* The Terminal ID of the Terminal to which the endpoint of this
                                                       interface is connected. */
    0x01U,        /* Delay introduced by the data path. Expressed in number of frames.  */
    0x01U, 
	0x00U, /* PCM  */


    /****************** Audio Class Specific type I format INTERFACE Descriptor: 0x24 0X02 ***********/   
    USB_AUDIO_STREAMING_TYPE_I_DESC_SIZE,               /* bLength (11) */
    USB_DESCRIPTOR_TYPE_AUDIO_CS_INTERFACE,             /* bDescriptorType (CS_INTERFACE) */
    USB_DESCRIPTOR_SUBTYPE_AUDIO_STREAMING_FORMAT_TYPE, /* DescriptorSubtype: AUDIO STREAMING FORMAT TYPE */
    USB_AUDIO_FORMAT_TYPE_I,                            /* Format Type: Type I */
    AUDIO_FORMAT_CHANNELS,                              /* Number of Channels: one channel */
    AUDIO_FORMAT_SIZE,                                  /* SubFrame Size: one byte per audio subframe */
    AUDIO_FORMAT_BITS,                                  /* Bit Resolution: 8 bits per sample */
    0x01U,                                              /* One frequency supported */
    AUDIO_SAMPLE_FREQ(44100),

    /******************************* Audio Speaker OUT ENDPOINT descriptor: 0x05 *******************************/ 	
    USB_ENDPOINT_AUDIO_DESCRIPTOR_LENGTH, /* Descriptor size is 9 bytes  */
    USB_DESCRIPTOR_TYPE_ENDPOINT,         /* Descriptor type (endpoint descriptor) */
    USB_AUDIO_SPEAKER_STREAM_ENDPOINT |
        (USB_OUT << USB_DESCRIPTOR_ENDPOINT_ADDRESS_DIRECTION_SHIFT), /* OUT endpoint address 1 */
    USB_ENDPOINT_ISOCHRONOUS | 0x04,                                  /* Isochronous endpoint */
    USB_SHORT_GET_LOW(FS_ISO_OUT_ENDP_PACKET_SIZE + AUDIO_FORMAT_CHANNELS * AUDIO_FORMAT_SIZE),
    USB_SHORT_GET_HIGH(FS_ISO_OUT_ENDP_PACKET_SIZE + AUDIO_FORMAT_CHANNELS * AUDIO_FORMAT_SIZE), /* 16 bytes  */
    0x01,                     /* bInterval(0x01U): x ms */
    0x00U,                    /* Unused */
    USB_AUDIO_SPEAKER_FEEDBACK_ENDPOINT |
        (USB_IN
         << USB_DESCRIPTOR_ENDPOINT_ADDRESS_DIRECTION_SHIFT), /* Synchronization Endpoint:用于调整主机发送频率*/

    /******************************* Audio Class Specific ENDPOINT Descriptor: 0x25 0x01*******************************/    
    USB_AUDIO_STREAMING_ENDP_DESC_SIZE,      /*  Size of the descriptor, in bytes  */
    USB_AUDIO_STREAM_ENDPOINT_DESCRIPTOR,    /* CS_ENDPOINT Descriptor Type  */
    USB_AUDIO_EP_GENERAL_DESCRIPTOR_SUBTYPE, /* AUDIO_EP_GENERAL descriptor subtype  */
    0x00U,                                   /* Bit 0: Sampling Frequency 0
                                                Bit 1: Pitch 0
                                                Bit 7: MaxPacketsOnly 0   */
    0x00U,                                   /* Indicates the units used for the wLockDelay field: 0: Undefined  */
    0x00U,
    0x00U, /* Indicates the time it takes this endpoint to reliably lock its internal clock recovery circuitry */

    /******************************* Audio feedback IN ENDPOINT descriptor: 0x05 *******************************/
    USB_ENDPOINT_AUDIO_DESCRIPTOR_LENGTH, /* bLength */
    USB_DESCRIPTOR_TYPE_ENDPOINT,         /* bDescriptorType */
    USB_AUDIO_SPEAKER_FEEDBACK_ENDPOINT |
        (USB_IN << USB_DESCRIPTOR_ENDPOINT_ADDRESS_DIRECTION_SHIFT), /* This is an IN endpoint with endpoint number 3 */
    USB_ENDPOINT_ISOCHRONOUS | 0x04 | 0x10,                          /*  Types -
                                                                         Transfer: ISOCHRONOUS
                                                                         Sync: Async
                                                                         Usage: Feedback EP   */
    0x04,  //FS_ISO_FEEDBACK_ENDP_PACKET_SIZE
    0x00, /* wMaxPacketSize */
    0x01, /* interval polling(2^x ms) */
    0x05, /*反馈速率 2^n ms,提交feedback的周期*/
    0x00, /* unused */

 

如描述符所示,需要注意的是设备的采样率,通道数量,采样精度,是否需要反馈端点(是否支持Asynchronous模式)等。

那么端点大小我们需要怎么确定呢?就拿上图描述符为例,采样率44.1K 双通道 24bit。可以计算出设备每秒处理能力为:

44100*2*3 byte,又因同步传输每1ms传输一次,即每毫秒主机需要传输:44100*2*3/6=264.6 byte数据。当然我们包大小不能填为:264 或者 265,又因为主机实际跳针能力为2% ,所以包大小最少得为:264.6*1.02 = 270 byte。当然你填512也没人阻止你,这个视项目而定。

其实两种方法都有一个类似的地方,判断用户缓冲区变化情况,如果缓冲区大小稳定,说明主机和设备基本同步。如果不稳定,对USB主机来说,就是发快了或者主机发慢了;对USB设备来说,就是处理慢了或者处理过快。

接下来就具体讲讲Feedback端点的用处。。。。。。在USB1.0手册中有提到:

 

就是说反馈端点数据,返回是3byte数据反应的是设备需要的频率值,其格式为10.14格式。那么一个44.1k怎么表示呢?

feedbackValue = ((44100/1000)<<14)|((44100%1000)<<4);   

这里多废话一句,USB Audio 2.0格式为(包大小4Byte):

#define FEEADBACK_DATA    ((AUDIO_SAMPLE_RATE_HZ/1000)<<13|(AUDIO_SAMPLE_RATE_HZ%1000)<<3)

下面是相关处理算法,笔者使用PID形成动态调控,实测很稳定:

void USB_AudioFeedbackDataUpdate(void)
{ 
    int32_t spaceSize;   //记录缓冲区大小
    int32_t pidAudioData;

	static float audioKp = 3.6,audioKi = 0.4,audioKd = 0.6;

    if(g_deviceAudioComposite->audioUnified.curMute == 1)
    {
        /*如果为静音,不需要计算feedback,*/
        g_deviceAudioComposite->audioUnified.timesFeedbackCalculate = 0;
        return;  
    }
	
    if (g_deviceAudioComposite->audioUnified.speakerIntervalCount != AUDIO_CALCULATE_Ff_INTERVAL)
    {
        g_deviceAudioComposite->audioUnified.speakerIntervalCount++;
        return;
    }

    g_deviceAudioComposite->audioUnified.timesFeedbackCalculate++;  

    if(g_deviceAudioComposite->audioUnified.timesFeedbackCalculate >= AUDIO_CALCULATE_PID_MS)
    {	
		spaceSize = USB_AudioSpeakerBufferSpaceUsed();	
		
		pidAudioData = xUSB_AudioPid(audioKp,audioKi,audioKd,spaceSize);
		
		feedbackValue += pidAudioData; 	
	
	    AUDIO_UPDATE_FEEDBACK_DATA(audioFeedBackBuffer, feedbackValue);	
		
		g_deviceAudioComposite->audioUnified.timesFeedbackCalculate = 0;
    }

    g_deviceAudioComposite->audioUnified.speakerIntervalCount = 1;
	
	/*可用于判断USB 强制断开现象*/
    g_deviceAudioComposite->audioUnified.lastAudioSendCount = g_deviceAudioComposite->audioUnified.audioSendCount;
}

好了解决方案就是这样的,也确实解决了项目中USB Audio噪声问题,若有更好的看法欢迎大家分享。。。。。。

  • 2
    点赞
  • 24
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
要在Vue中播放后端传输的MP3音频文件,你可以使用HTML5的`<audio>`元素和JavaScript的`Audio`对象。以下是实现的步骤: 1. 在Vue组件中,使用`<audio>`元素来创建一个播放器: ```html <audio ref="audioPlayer" controls></audio> ``` 2. 在Vue组件的`created`钩子函数中,通过后端API获取MP3音频,并将其传递给`Audio`对象: ```javascript created() { // 调用后端API获取MP3音频 this.getAudioStream().then(stream => { this.playAudio(stream); }); }, methods: { getAudioStream() { // 使用axios或其他库来发送请求获取MP3音频 return axios.get('/api/audio/stream', { responseType: 'arraybuffer' }).then(response => { return response.data; }); }, playAudio(stream) { const audioContext = new AudioContext(); audioContext.decodeAudioData(stream, buffer => { const source = audioContext.createBufferSource(); source.buffer = buffer; source.connect(audioContext.destination); source.start(); this.$refs.audioPlayer.srcObject = source; }); } } ``` 在上述代码中,我们使用了`AudioContext`来解码音频,并通过`createBufferSource`创建一个音频源。然后,我们将音频源连接到`AudioContext`的目标(通常是扬声器),并开始播放音频。最后,我们将音频源赋值给`<audio>`元素的`srcObject`属性,以便在浏览器中显示播放控件和音频。 请注意,由于涉及到音频的解码,这可能会在一些旧版本的浏览器中存在兼容性问题。此外,你需要根据你的后端API返回的音频格式进行适当的解码和处理。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值