98国产精品综合一区二区三区,国产福利视频,男人添女人囗交做爰视频,日本免费一区二区三区视频观看

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

您現(xiàn)在的位置:首頁(yè) 新聞資訊 >> 新聞?lì)^條 >> ISD9160學(xué)習(xí)筆記03_ISD9160音頻解碼代碼分析
新聞資訊
NEWS INFORMATION

ISD9160學(xué)習(xí)筆記03_ISD9160音頻解碼代碼分析

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

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

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

我還是建議大家還是多琢磨下源碼,代碼的事還是讓代碼來(lái)說(shuō)話,筆記是一個(gè)輔助的概括梳理。

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

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

第一部分 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

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

BOOL NuLiteExApp_DecodeStartPlayByAddr(S_NULITEEX_APP_DECODE *psNuLiteExAppDecode, UINT32 u32NuLiteExStorageStartAddr, UINT8 u8PlaybackChannel)
{
    UINT16 u16SampleRate;
    // NuLiteEx解碼庫(kù)初始化對(duì)應(yīng)的工作緩沖區(qū),應(yīng)用層傳入temp緩存來(lái)方便解碼庫(kù)內(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模塊對(duì)接對(duì)應(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ū)中的讀寫(xiě)指針賦值。
    // 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;

    // 記錄當(dāng)前播放的channel,用來(lái)停止播放。
    // Record play channel index for stopping to play.
    psNuLiteExAppDecode->u8PlaybackChannel = u8PlaybackChannel;
    // 準(zhǔn)備播放,把這里的循環(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 ) // 這個(gè)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ū)復(fù)制。
        #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(); // 這里頭開(kāi)始調(diào)用DPWM來(lái)播放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)用了如下這個(gè)函數(shù)

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

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

    // 環(huán)形緩沖區(qū)還有未讀數(shù)據(jù)
    if ( Playback_NeedUpdateOutputBuf(&psNuLiteExAppDecode->sOutBufCtrl) )
    {
        // 由核心庫(kù)來(lái)判斷這個(gè)文件是否解析完了
        // 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];

        // 核心庫(kù)繼續(xù)發(fā)揮其巨大作用,開(kāi)足馬力讀取文件中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依舊共享這個(gè)緩沖區(qū),準(zhǔn)備對(duì)數(shù)據(jù)進(jìn)行進(jìn)一步處理
        // 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é)

源碼拓?fù)浣Y(jié)構(gòu)

 

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

傳真:0755-82591176

郵箱:vicky@yingtexin.net

地址:深圳市龍華區(qū)民治街道民治大道973萬(wàn)眾潤(rùn)豐創(chuàng)業(yè)園A棟2樓A08

护士扒下内裤让我爽一夜| 久久久综合香蕉尹人综合网| 久久国产欧美国日产综合抖音| 破了亲妺妺的处免费视频国产| 少妇的肉体k8经典| 日本16岁rapper| 疼~别放了~装不下了不下载| 99精品免费久久久久久久久日本| 性兴奋流出来白色粘稠液体| 一本大道无码av天堂欧美| 国产精品99久久久久久人四虎| 亚洲精品久久一区二区三区777| 任你躁国语自产在线播放| 亚洲av无码成人精品久久久蜜| 老农民里老干棒媳妇回来了吗| 大战丰满人妻性色av偷偷红豆| 朋友人妻翘臀迎接粗大撞击| 久久精品午夜一区二区福利| 国内夫妇交换自拍视频| 性一交一乱一乱一视一频| 亚洲色欲啪啪久久www综合网| 国产成人一区二区三区传媒| 欧美性猛交aaaa片黑人| 青青草视频在线观看| 亚洲精品国产成人| 免费看人妻换人妻互换a片爽| 中文乱码字慕人妻熟女人妻| 胖老太bbwbbwbbwbbw| 人善交video另类hd| 女人和拘发生性关| 太粗大进不去倒刺带钩| 亚洲区色情区激情区小说| 女士全透毛三角透明内裤| 他含着她的乳奶揉搓揉视频捏| 国产精品人人妻人色五月| 国产精品视频在线观看| 老牛精品亚洲成av人片| 少妇bbwbbw性生话| 成全视频在线观看免费观看| 侵犯人妻教师波多野吉衣| 高清dvd碟片 播放|