久久精品99久久_亚洲一区二区综合_狠狠色伊人亚洲综合成人_亚洲综合爱爱久久网

您好,歡迎進入深圳市穎特新科技有限公司官方網(wǎng)站!

您現(xiàn)在的位置:首頁 新聞資訊 >> 新聞頭條 >> ISD9160學習筆記03_ISD9160音頻解碼代碼分析
新聞資訊
NEWS INFORMATION

ISD9160學習筆記03_ISD9160音頻解碼代碼分析

發(fā)布時間:2019-05-22

錄音例程涉及了錄音和播放兩大塊內(nèi)容,這篇筆記就先來說說播放,暫且先擊破解碼這部分功能。

我的錘子便簽中有上個月記下的一句話,“斯蒂芬·平克說,寫作之難,在于把網(wǎng)狀思考,用樹狀結(jié)構(gòu),體現(xiàn)在線性展開的語句里。”這篇代碼解析也有類似的困難,代碼的網(wǎng)狀結(jié)構(gòu),如何用文章這種線性載體來體現(xiàn)。我盡量挑出了主干,來講解自己的理解。另外在文章最后添加了一個模塊拓撲圖來幫助消化。

我還是建議大家還是多琢磨下源碼,代碼的事還是讓代碼來說話,筆記是一個輔助的概括梳理。

本文作者twowinter,轉(zhuǎn)載請注明:http://blog.csdn.net/iotisan/

查看代碼主邏輯,主要是App_StartPlay和App_ProcessPlay這兩個函數(shù)。下面就分別進行分析。

第一部分 App_StartPlay

BOOL App_StartPlay(void)
{
    // Initiate NuLiteEx audio decode lib with callback functions stored in g_asAppCallBack[0]
    NuLiteExApp_DecodeInitiate(&g_sApp.sNuLiteExAppDecode, (UINT8 *)&g_sApp.uTempBuf, 0);

    // Start NuLiteEx decode lib to decode NuLiteEx file stored from address and played from audio channel 0.
    // And decode the first frame of PCMs.
    if ( NuLiteExApp_DecodeStartPlayByAddr(&g_sApp.sNuLiteExAppDecode, AUDIOROM_STORAGE_START_ADDR, 0) == FALSE )
        return FALSE;

    // Light playback led(PB9) for display status.
    OUT4(0);

    // Start Ultraio Timer & HW pwm for UltraIO curve output
    ULTRAIO_START();

    // Start to playback audio. 
    Playback_StartPlay();
}

可以看到App_StartPlay主要牽扯了NuLiteExApp和Playback兩部分子函數(shù)。

重中之重 NuLiteExApp_DecodeStartPlayByAddr

由于對音頻編解碼這塊比較陌生,我還是給對應(yīng)代碼做了中文注解方便消化。

BOOL NuLiteExApp_DecodeStartPlayByAddr(S_NULITEEX_APP_DECODE *psNuLiteExAppDecode, UINT32 u32NuLiteExStorageStartAddr, UINT8 u8PlaybackChannel)
{
    UINT16 u16SampleRate;
    // NuLiteEx解碼庫初始化對應(yīng)的工作緩沖區(qū),應(yīng)用層傳入temp緩存來方便解碼庫內(nèi)部工作。另外根據(jù)傳入的SPI地址從SPI取文件,獲取采樣率。
    // NuLiteEx decoder initiates work buffer and returns sample rate.
    if ( (u16SampleRate = NuLiteEx_DecodeInitiate(  (UINT8*)psNuLiteExAppDecode->au32DecodeWorkBuf, 
                                                    psNuLiteExAppDecode->pau8TempBuf, 
                                                    u32NuLiteExStorageStartAddr, 
                                                    g_asAppCallBack[psNuLiteExAppDecode->u8CallbackIndex].pfnReadDataCallback )) == 0 )
        return FALSE;   

    // 給Playback模塊對接對應(yīng)的工作緩沖區(qū),方便其下一步播放。
    // Initiate and set output buffer variable(include frame size, buffer size etc.) 
    Playback_SetOutputBuf(  &psNuLiteExAppDecode->sOutBufCtrl,
                            NULITEEXAPP_OUT_BUF_SIZE,
                            psNuLiteExAppDecode->i16OutBuf,
                            NULITEEXAPP_OUT_SAMPLES_PER_FRAME,
                            u16SampleRate );

    // 工作緩沖區(qū),置有效位。
    // Trigger active flag of output buffer for NuLiteEx decoding
    BUF_CTRL_SET_ACTIVE(&psNuLiteExAppDecode->sOutBufCtrl);

    // 工作緩沖區(qū)中的讀寫指針賦值。
    // Pre-decode one frame
    psNuLiteExAppDecode->sOutBufCtrl.u16BufWriteIdx = NULITEEXAPP_OUT_SAMPLES_PER_FRAME;
    if ( NuLiteExApp_DecodeProcess(psNuLiteExAppDecode) == FALSE )
    {
        BUF_CTRL_SET_INACTIVE(&psNuLiteExAppDecode->sOutBufCtrl);
        return FALSE;
    }
    psNuLiteExAppDecode->sOutBufCtrl.u16BufReadIdx = NULITEEXAPP_OUT_SAMPLES_PER_FRAME;

    // 記錄當前播放的channel,用來停止播放。
    // Record play channel index for stopping to play.
    psNuLiteExAppDecode->u8PlaybackChannel = u8PlaybackChannel;
    // 準備播放,把這里的循環(huán)緩沖區(qū)同playback共用。
    // Add audio codec into channel and preper to play codec.
    Playback_Add(psNuLiteExAppDecode->u8PlaybackChannel, &psNuLiteExAppDecode->sOutBufCtrl);

    return TRUE;
}

也很重要的Playback_StartPlay

void Playback_StartPlay(void)
{
    INT16 *pi16PcmBuf;

    if( s_u8PlayCtrl == PLAYBACK_NOACTION ) // 這個s_u8PlayCtrl是playback模塊內(nèi)部處理的。
    {
        #if ( PLAYBACK_CHANNEL_COUNT > 1)
        pi16PcmBuf = g_ai16DACSamples;
        #else
        pi16PcmBuf = &g_psDacBufCtrl->pi16Buf[g_psDacBufCtrl->u16BufReadIdx];// PCM數(shù)據(jù)緩沖區(qū)復制。
        #endif

        #if ((APU_FILTER_ENABLE == 1)&&(APU_UPSAMPLE == 2))
        NuDACFilterEx_Up2Initial(g_au8Up2WorkBuf);
        #elif ((APU_FILTER_ENABLE == 1)&&(APU_UPSAMPLE == 4))
        NuDACFilterEx_Up4Initial(g_au8Up4WorkBuf);
        #endif
        g_u8AppCtrl|=APPCTRL_PLAY;
        s_u8PlayCtrl |= PLAYBACK_START;
        #if (APU_ENABLE)
        {
            UINT8 u8Count;

            for( u8Count = 0; u8Count < 8; u8Count ++)
                g_ai16DACSamples[u8Count] = 0;      //Clear virtual buffer
        }
        #endif

        Playback_ResetChannelVolume(0);

        SPK_Start(); // 這里頭開始調(diào)用DPWM來播放DPWM->DATA,DPWM_START_PLAY(DPWM);

        #if (APU_PDMA_ENABLE)
        PdmaCtrl_Start(APU_PDMA_CH, (uint32_t *)pi16PcmBuf, (uint32_t *)&DPWM->DATA, 8);// 將PCM緩沖數(shù)據(jù)傳到DPWM->DATA中。
        #endif

    }
}

第二部分 App_ProcessPlay

App_ProcessPlay只調(diào)用了如下這個函數(shù)

BOOL NuLiteExApp_DecodeProcess(S_NULITEEX_APP_DECODE *psNuLiteExAppDecode)
{
    INT16 *pi16OutBuf;

    // 環(huán)形緩沖區(qū)非激活狀態(tài),這個只有在應(yīng)用層置位(按鍵停止、或者啟動失敗等情況)
    if (BUF_CTRL_IS_INACTIVE(&psNuLiteExAppDecode->sOutBufCtrl))
        return FALSE;

    // 環(huán)形緩沖區(qū)還有未讀數(shù)據(jù)
    if ( Playback_NeedUpdateOutputBuf(&psNuLiteExAppDecode->sOutBufCtrl) )
    {
        // 由核心庫來判斷這個文件是否解析完了
        // Check end of file
        if(NuLiteEx_DecodeIsEnd((UINT8*)psNuLiteExAppDecode->au32DecodeWorkBuf))
        {
            // Trigger inactive flag of output buffer to stop NuLiteEx decoding
            BUF_CTRL_SET_INACTIVE(&psNuLiteExAppDecode->sOutBufCtrl);
            // Use to represnt no active(or end) of decoding
            psNuLiteExAppDecode->sOutBufCtrl.u16SampleRate = 0;
            return FALSE;
        }

        // Record output data buffer pointer(for duplicate & process)
        pi16OutBuf = (PINT16)&psNuLiteExAppDecode->sOutBufCtrl.pi16Buf[psNuLiteExAppDecode->sOutBufCtrl.u16BufWriteIdx];

        // 核心庫繼續(xù)發(fā)揮其巨大作用,開足馬力讀取文件中PCM數(shù)據(jù)轉(zhuǎn)到緩沖區(qū)。
        NuLiteEx_DecodeProcess( (UINT8*)psNuLiteExAppDecode->au32DecodeWorkBuf, 
                                psNuLiteExAppDecode->pau8TempBuf, 
                                pi16OutBuf, 
                                g_asAppCallBack[psNuLiteExAppDecode->u8CallbackIndex].pfnReadDataCallback, 
                                g_asAppCallBack[psNuLiteExAppDecode->u8CallbackIndex].pfnUserEventCallback);

        // PlayBack依舊共享這個緩沖區(qū),準備對數(shù)據(jù)進行進一步處理
        // Update write index of output buffer and avoid buffer overflow
        Playback_UpdateOutputBuf(&psNuLiteExAppDecode->sOutBufCtrl);

        // Duplicate data into buffer for using duplication callback function.
        if ( psNuLiteExAppDecode->u8CtrlFlag&(NULITEEXAPP_CTRL_DUPLICATE_TO_BUF|NULITEEXAPP_CTRL_DUPLICATE_TO_FUNC) )
        {
            if ( psNuLiteExAppDecode->u8CtrlFlag & NULITEEXAPP_CTRL_DUPLICATE_TO_BUF )
                BufCtrl_WriteWithCount(psNuLiteExAppDecode->psDuplicateOutBufCtrl, NULITEEXAPP_OUT_SAMPLES_PER_FRAME, pi16OutBuf );
            else 
                psNuLiteExAppDecode->pfnDuplicateFunc(NULITEEXAPP_OUT_SAMPLES_PER_FRAME, pi16OutBuf);
        }       
    }   
    return TRUE;
}

總結(jié)

源碼拓撲結(jié)構(gòu)

 

聯(lián)系方式0755-82591179

郵箱:ivy@yingtexin.net

地址:深圳市南山區(qū)桃源街道平山社區(qū)平山一路2號南山云谷創(chuàng)業(yè)園二期11棟410-411

久久精品99久久_亚洲一区二区综合_狠狠色伊人亚洲综合成人_亚洲综合爱爱久久网
激情六月天婷婷| 欧美视频在线播放一区| 成年人黄色片视频| 乱妇乱女熟妇熟女网站| 国产精品videossex国产高清| 奇米影音第四色| 天天插天天操天天射| 五月婷婷深爱五月| 污网站在线免费| 亚洲三级在线观看视频| 91 视频免费观看| 91xxx视频| 99er在线视频| av免费中文字幕| 日韩手机在线观看视频| 午夜免费看视频| 欧美美女黄色网| 日本三级免费网站| 中文字幕永久有效| 大荫蒂性生交片| 国产日韩一区二区在线观看| 亚洲欧美在线精品| 成人午夜视频免费观看| 99精品视频在线看| 91免费视频污| 两根大肉大捧一进一出好爽视频| 亚洲人成无码www久久久| 8x8x成人免费视频| 精品视频免费在线播放| 91制片厂毛片| 欧美日韩dvd| 亚洲视频在线a| 99久久免费观看| 91高清国产视频| 欧美视频在线观看网站| 天天影视色综合| 免费国产黄色网址| 在线观看日本www| 人妻熟妇乱又伦精品视频| 一二三级黄色片| 欧美xxxxx在线视频| 国产精品国三级国产av| 97人人爽人人| 韩国中文字幕av| 免费看黄在线看| 超碰人人爱人人| 成人黄色一区二区| 久久久久久久久久网| 永久av免费在线观看| 虎白女粉嫩尤物福利视频| 欧美 日韩 国产精品| 免费精品99久久国产综合精品应用| 青草青青在线视频| 欧美少妇在线观看| 亚洲色图欧美自拍| 永久免费黄色片| 国产高清999| 欧美日韩一区二区三区69堂| 99蜜桃臀久久久欧美精品网站| 特级西西人体www高清大胆| 在线免费看v片| 久久精品国产99久久99久久久| 色悠悠久久综合网| 亚洲欧美另类动漫| 凹凸日日摸日日碰夜夜爽1| 日本免费黄视频| 99精品视频播放| 久久精品影视大全| 奇米视频888| 午夜影院免费观看视频| 国产麻豆电影在线观看| japanese在线视频| 欧美 亚洲 视频| 久久精品无码中文字幕| 国产一区二区三区小说| 免费一级特黄毛片| 999香蕉视频| 国产精品嫩草影院8vv8 | 欧美日韩视频免费| 免费无码毛片一区二三区| 国产高清av在线播放| 国产日韩一区二区在线| av五月天在线| 亚洲美女自拍偷拍| 青青草成人免费在线视频| 777久久久精品一区二区三区| 日韩av资源在线| 中文字幕资源在线观看| 女人色极品影院| 少妇一级淫免费播放| 欧美一级中文字幕| 黄色一级大片在线观看| 国产999免费视频| 丰满的少妇愉情hd高清果冻传媒| 97xxxxx| 日本高清免费在线视频| 成人毛片视频网站| 国产免费色视频| 男人靠女人免费视频网站| 一二三av在线| 99视频免费播放| 黄色a级片免费看| 日本在线播放一区二区| 免费黄色日本网站| 免费观看黄色大片| 午夜免费看视频| 99精品视频播放| 日本一区午夜艳熟免费| 久久精品视频在线观看免费| 欧美色图色综合| 男女啪啪免费观看| 91福利免费观看| 国产wwwxx| 免费毛片网站在线观看| 蜜桃网站在线观看| 婷婷激情小说网| 污污动漫在线观看| 亚洲精品乱码久久久久久自慰| 国产精品88久久久久久妇女| 在线视频观看91| 在线观看免费av网址| 欧美精品色婷婷五月综合| 你真棒插曲来救救我在线观看| 精品日韩在线播放| 美女黄色片网站| 欧美h视频在线观看| 三级av免费看| 国产xxxxhd| 潘金莲一级淫片aaaaa免费看| 欧美国产日韩另类| 亚洲国产午夜精品| 国产又大又长又粗又黄| 一区二区三区国产好的精华液| 精品久久久久久中文字幕2017| 国产精彩免费视频| 无码少妇一区二区三区芒果| 国产l精品国产亚洲区久久| 黄www在线观看| 麻豆av免费在线| 欧美成年人视频在线观看| 国产一级特黄a大片免费| 一级在线免费视频| 黄色三级视频在线播放| 男人天堂网站在线| 精品无码国模私拍视频| 日韩在线xxx| 色中文字幕在线观看| 国产精品视频二| 99999精品视频| 国产91色在线观看| 久久免费视频2| 久久国产亚洲精品无码| 欧美第一页浮力影院| 中文字幕在线乱| 国产精品-区区久久久狼| 一区二区三区入口| 日韩一区二区高清视频| 久久精品午夜福利| 中文字幕在线乱| 男人操女人逼免费视频| 日韩视频在线观看一区二区三区| 轻点好疼好大好爽视频| 密臀av一区二区三区| 久久最新免费视频| 国产女大学生av| 亚洲精品中文字幕乱码无线| 国产 日韩 亚洲 欧美| www.51色.com| 妺妺窝人体色www在线小说| 国产乱码一区二区三区四区| 国产精品入口芒果| 制服丝袜中文字幕第一页 | www.超碰com| 国产xxxx振车| 三上悠亚av一区二区三区| 国产女女做受ⅹxx高潮| 91精品国产毛片武则天| 黄色一级视频在线播放| 天美星空大象mv在线观看视频| 亚洲人成无码网站久久99热国产 | 国产wwwxx| 日本三级福利片| 中国丰满人妻videoshd | 色婷婷综合在线观看| wwwxxx黄色片| 一区二区传媒有限公司| 人妻无码一区二区三区四区| 日韩av片专区| 在线免费观看视频黄| 日韩欧美xxxx| 成人午夜视频免费在线观看| 欧美极品欧美精品欧美| 成人在线播放网址| 蜜臀av性久久久久蜜臀av| 欧美性视频在线播放| 日日夜夜精品视频免费观看| 在线视频一二区| 精品国产三级a∨在线| 色撸撸在线观看| 女同性恋一区二区|