1 TinyUSB(UAC)音頻簡介
UAC是USB Audio Class的縮寫,USB音頻類,一個像USB這樣的通用數(shù)據(jù)接口,可以有很多種實現(xiàn)數(shù)字音頻數(shù)據(jù)傳輸?shù)姆绞?。不同?a target="_blank">開發(fā)者可以根據(jù)自己的喜好和需求,定義任意的控制方式,傳輸模式,音頻格式等等參數(shù)。
在上一節(jié)我們在MM32F0163D7P 平臺上成功的移植了TinyUSB,基于這個平臺,今天我們來實現(xiàn)一個 uac2_headset 音頻設(shè)備,這個設(shè)備支持基礎(chǔ)的錄音和放音功能,如果要支持音量調(diào)節(jié)/靜音功能,還需要再添加一個 HID 變成復(fù)合設(shè)備。
2 快速移植一個UAC+HID復(fù)合設(shè)備
按照前面兩篇文章,我們可以快速的移植出一個基于TinyUSB的UAC+HID復(fù)合設(shè)備,主要的代碼片段如下:
/*------------- MAIN -------------*/
int main(void)
{
USB_DeviceClockInit();//board_init();
CONSOLE_Init(460800); //enable printf debug
// init device stack on configured roothub port
tud_init(BOARD_TUD_RHPORT);
TU_LOG1("UAC Headset & HID runningrn"); // CFG_TUSB_DEBUG for debugging #if CFG_TUSB_DEBUG
// 0 : no debug
// 1 : print error
// 2 : print warning
// 3 : print info
while (1)
{
tud_task(); // TinyUSB device task
audio_task();
hid_task();
}
return 0;
}
#define EPNUM_AUDIO_IN 0x01
#define EPNUM_AUDIO_OUT 0x01
#define EPNUM_HID 0x03
uint8_t const desc_configuration[] =
{
// Interface count, string index, total length, attribute, power in mA
TUD_CONFIG_DESCRIPTOR(1, ITF_NUM_TOTAL, 0, CONFIG_TOTAL_LEN, TUSB_DESC_CONFIG_ATT_REMOTE_WAKEUP, 100),
// Interface number, string index, EP Out & EP In address, EP size
TUD_AUDIO_HEADSET_STEREO_DESCRIPTOR(2, EPNUM_AUDIO_OUT, EPNUM_AUDIO_IN | 0x80),
// Interface number, string index, protocol, report descriptor len, EP Out & In address, size & polling interval
TUD_HID_INOUT_DESCRIPTOR(ITF_NUM_HID, 6, HID_ITF_PROTOCOL_NONE, sizeof(desc_hid_report), EPNUM_HID, 0x80 | EPNUM_HID, CFG_TUD_HID_EP_BUFSIZE, 10),
};
//--------------------------------------------------------------------+
// String Descriptors
//--------------------------------------------------------------------+
// array of pointer to string descriptors
char const* string_desc_arr [] =
{
(const char[]) { 0x09, 0x04 }, // 0: is supported language is English (0x0409)
"TinyUSB", // 1: Manufacturer
"TinyUSB headset", // 2: Product
"000001", // 3: Serials, should use chip ID
"TinyUSB Speakers", // 4: Audio Interface
"TinyUSB Microphone", // 5: Audio Interface
"TinyUSB HID", // 6: HID Interface
};
圖1 枚舉過程
圖2 枚舉設(shè)備
工程文件樹:
3 耳機設(shè)備設(shè)置修改音量
在耳機屬性里面可以操作修改音量大小,同時通過抓包工具可以抓到主機下發(fā)的SET CUR命令。
圖3 設(shè)置音量
4 耳機設(shè)備設(shè)置修改采樣頻率和位深度
在耳機屬性高級里面默認格式可以看到下拉框有兩種格式,一個是2通道 16位48000Hz,另外一個是2通道 24位 48000Hz,播放聲音下發(fā)ISOC包的時候根據(jù)這個選擇傳輸。
圖4 設(shè)置采樣頻率和位深度
通過設(shè)置,下位機可以在播放或者錄音時處理不同的采樣頻率和位深度。樣例中全局變量current_resolution是位深度,current_sample_rate是采樣頻率。
5 音頻數(shù)據(jù)的收發(fā)處理
播放時ISOC下發(fā)的數(shù)據(jù)包緩存在spk_buf里面。
錄用時麥克風(fēng)的聲音采樣數(shù)據(jù)寫入mic_buf,通過ISOC同步上傳到電腦端。(例程是將播放的數(shù)據(jù)包處理后通過接口又返回電腦端,由tud_audio_write((uint8_t * ) mic_buf, (uint16_t) (spk_data_size / 2))實現(xiàn))
//--------------------------------------------------------------------+
// AUDIO Task
//--------------------------------------------------------------------+
void audio_task(void)
{
// When new data arrived, copy data from speaker buffer, to microphone buffer
// and send it over
// Only support speaker & headphone both have the same resolution
// If one is 16bit another is 24bit be care of LOUD noise !
if (spk_data_size)
{
if (current_resolution == 16)
{
int16_t *src = (int16_t*)spk_buf;
int16_t *limit = (int16_t*)spk_buf + spk_data_size / 2;
int16_t *dst = (int16_t*)mic_buf;
while (src < limit)
{
// Combine two channels into one
int32_t left = *src++;
int32_t right = *src++;
*dst++ = (int16_t) ((left > > 1) + (right > > 1));
}
memset(mic_buf,0xCC,sizeof(mic_buf)); //mm32 test code
tud_audio_write((uint8_t *)mic_buf, (uint16_t) (spk_data_size / 2));
spk_data_size = 0;
}
else if (current_resolution == 24)
{
int32_t *src = spk_buf;
int32_t *limit = spk_buf + spk_data_size / 4;
int32_t *dst = mic_buf;
while (src < limit)
{
// Combine two channels into one
int32_t left = *src++;
int32_t right = *src++;
*dst++ = (int32_t) ((uint32_t) ((left > > 1) + (right > > 1)) & 0xffffff00ul);
}
tud_audio_write((uint8_t *)mic_buf, (uint16_t) (spk_data_size / 2));
spk_data_size = 0;
}
}
}
6 功能驗證測試
將uac2_headset 音頻設(shè)備插入PC,在計算機管理->設(shè)備管理器->音頻輸入和輸出里面出現(xiàn)耳機和麥克風(fēng)兩個TinyUSB headset設(shè)備證明枚舉成功。
圖5 設(shè)備管理器音頻設(shè)備
電腦端播放音樂使用抓包工具抓到ISOC的數(shù)據(jù)包:
圖6 ISOC數(shù)據(jù)包
-
處理器
+關(guān)注
關(guān)注
68文章
19100瀏覽量
228814 -
控制器
+關(guān)注
關(guān)注
112文章
16103瀏覽量
177074 -
USB接口
+關(guān)注
關(guān)注
9文章
699瀏覽量
55537 -
HID設(shè)備
+關(guān)注
關(guān)注
0文章
5瀏覽量
6324
發(fā)布評論請先 登錄
相關(guān)推薦
評論