首頁(yè) > 評(píng)測(cè) > PSoC 6評(píng)測(cè)第四篇-錄音與放音
PSoC 6評(píng)測(cè)第四篇-錄音與放音
- [導(dǎo)讀]
- 寫上一篇關(guān)于EInk的文章的時(shí)候,就想著要寫這一篇了.因?yàn)樽髡弑救顺讼矚g閱讀之外,還比較喜歡音樂(lè).也喜歡聽(tīng)也喜歡唱K,故此對(duì)音頻相關(guān)的技術(shù)也較為感興趣,至于水平只能說(shuō)稍知一二.看到這個(gè)CY8CKIT開(kāi)發(fā)套件上帶有數(shù)字麥克風(fēng),就動(dòng)了心思.本文使用開(kāi)發(fā)板子上的資源做一個(gè)簡(jiǎn)單的錄音與放音實(shí)驗(yàn),研究一下相關(guān)知識(shí).
圖 8 KHz定時(shí)器用作播放更新
注意產(chǎn)生的頻率有一定的誤差,只要在一定范圍內(nèi)是可以接受的.某些要求苛刻的音頻設(shè)備使用比較不常見(jiàn)的晶體頻率即是為了最大程度提高播放精度.
根據(jù)現(xiàn)有條件,直接將耳機(jī)的兩個(gè)通道分別接在VDAC與PWM輸出上:
圖 硬件連接細(xì)節(jié)
根據(jù)實(shí)驗(yàn),阻抗大的耳機(jī)效果好一點(diǎn)點(diǎn),因?yàn)橐_驅(qū)動(dòng)有限的緣故.
圖 入耳式的耳機(jī)阻抗稍大一點(diǎn)
軟件
因?yàn)橹饕K都是硬件生成的,所以軟件上也只是控制一個(gè)流程而已.流程就是錄制-播放兩個(gè)過(guò)程進(jìn)行循環(huán).此例子與上一篇的例子不同,僅僅使用了Cortex M4的內(nèi)核,M0+內(nèi)核除了使能Cortex M4之外沒(méi)有做任何事情.
初始化各模塊:
/* Enable global interrupts. */
__enable_irq();
/* Initialize the PCM interrupt and enable it */
Cy_SysInt_Init(&PCM_ISR_cfg, PCM_ISR_Handler);
NVIC_EnableIRQ(PCM_ISR_cfg.intrSrc);
//The Audio Play ISR
Cy_SysInt_Init(&AudioPlayISR_cfg, AudioPlay_ISR_Handler);
NVIC_EnableIRQ(AudioPlayISR_cfg.intrSrc);
/* Start the UART component for reporting the volume */
UART_Start();
AudioTimer_Start();
VDAC_Start();
AudioPWM_Start();
/* Star the PCM component */
Cy_PDM_PCM_Init(PDM_PCM_HW, &PDM_PCM_config);
Cy_PDM_PCM_Enable(PDM_PCM_HW);
此時(shí)各模塊已經(jīng)開(kāi)始工作,剛剛開(kāi)始是錄音模式.
PDM_PCM的ISR:
void PCM_ISR_Handler(void)
{
/* Set the PCM flag */
flag = 1;
/* Disable PCM ISR to avoid multiple calls to this ISR */
NVIC_DisableIRQ(PCM_ISR_cfg.intrSrc);
}
此處做標(biāo)記表示有一個(gè)FIFO的數(shù)據(jù)轉(zhuǎn)換為PCM完成需要拿走.主循環(huán)中將其放入播放buffer:
for (uint32_t i = 0; i < PDM_PCM_RX_FIFO_TRG_LVL; i++)
{
g_AudioBuff[g_RecIdx++]=(int16_t)PDM_PCM_ReadFifo();
}
一旦buffer滿了即轉(zhuǎn)為播放模式,當(dāng)中需要用戶按下SW2按鈕:
printf("To Enter Play Mode.\n");
printf("Press SW2\n");
/* Clear SW2 interrupt */
Cy_GPIO_ClearInterrupt(SW2_PORT, SW2_NUM);
while(0 == (Cy_GPIO_GetInterruptStatus(SW2_PORT, SW2_NUM)))
{
__WFI();
}
printf("Play...\n");
g_playRecFlag = true;
g_PlayIdx = 0;
在Audio Timer的ISR中更新播放Sample:
void AudioPlay_ISR_Handler(void)
{
if((true == g_playRecFlag) && (g_PlayIdx < SAMPLE_SIZE))
{
int16_t tmpV16 = g_AudioBuff[g_PlayIdx++];
VDAC_SetValueBuffered(tmpV16>>4);
int8_t tmpV8 = tmpV16/256;
if(tmpV8 < 0)
{
AudioPWM_SetCompare0(256 - tmpV8);
}
else
{
AudioPWM_SetCompare0(127 + tmpV8);
}
}
AudioTimer_ClearInterrupt(CY_TCPWM_INT_ON_CC_OR_TC);
}
注意采集進(jìn)來(lái)的數(shù)據(jù)為16bit有符號(hào)數(shù)據(jù),而DAC為12bit,PWM為8bit,需要加以轉(zhuǎn)換.一旦播放完畢需要用戶按下SW2重新開(kāi)始錄音.過(guò)程與上面的過(guò)程類似,反復(fù)循環(huán).
根據(jù)實(shí)際體驗(yàn),目前這個(gè)PDM_PCM轉(zhuǎn)換結(jié)果不是很完美,噪音較多,也有可能是本人使用不當(dāng).如有進(jìn)一步的研究結(jié)果再來(lái)匯報(bào).
總結(jié),資源與參考
Cypress的這個(gè)開(kāi)發(fā)板子CY8CKIT能玩的點(diǎn)較多,拿到板子忍不住做了不少實(shí)驗(yàn).其實(shí)編輯說(shuō)搞一兩篇就算交差了,這次也算超額完成任務(wù).官方也有一篇音頻例程,講的是檢測(cè)當(dāng)前環(huán)境的噪音水平,本人認(rèn)為過(guò)于簡(jiǎn)單于是在此基礎(chǔ)上完成了本文的實(shí)驗(yàn).
關(guān)于音頻,本人一向很感興趣,以前也寫過(guò)不少此方面的文章.包括本文做的一些實(shí)驗(yàn)其實(shí)是之前文章的延伸,故此一些過(guò)于細(xì)節(jié)的部分不想贅述,感興趣的讀者可以在本站找一下之前的文章配合閱讀.目前人工智能,語(yǔ)音識(shí)別比較熱門,作者也有心再做一點(diǎn)此方面的實(shí)驗(yàn),但是這個(gè)話題就太大,不知道能否寫出文章來(lái).
代碼下載連接:
鏈接: https://pan.baidu.com/s/1nw4o2Pr 密碼: cjtc
- 本文系21ic原創(chuàng),未經(jīng)許可禁止轉(zhuǎn)載!
網(wǎng)友評(píng)論
- 聯(lián)系人:巧克力娃娃
- 郵箱:board@21ic.com
- 我要投稿
-
歡迎入駐,開(kāi)放投稿
- NRF52810藍(lán)牙數(shù)字耳機(jī)找人定制
預(yù)算:¥30005天前
- 125KW模塊式PCS軟硬件外包開(kāi)發(fā)
預(yù)算:¥1100000015小時(shí)前
- 12V汽車啟動(dòng)電源項(xiàng)目BMS設(shè)計(jì)
預(yù)算:¥50000023小時(shí)前
- 數(shù)據(jù)可視化軟件 開(kāi)發(fā)
預(yù)算:¥5000023小時(shí)前
- PLC項(xiàng)目調(diào)試修改
預(yù)算:¥100001天前
- 起動(dòng)電機(jī)控制器開(kāi)發(fā)
預(yù)算:¥1100001天前