⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 vadout.c

📁 Intel开发的IPP库的应用实例
💻 C
📖 第 1 页 / 共 2 页
字号:
/*
//
//                  INTEL CORPORATION PROPRIETARY INFORMATION
//  This software is supplied under the terms of a license agreement or
//  nondisclosure agreement with Intel Corporation and may not be copied
//  or disclosed except in accordance with the terms of that agreement.
//        Copyright(c) 2002-2006 Intel Corporation. All Rights Reserved.
//
//  Intel(R) Integrated Performance Primitives Audio Processing
//  Sample for Windows*
//
//  By downloading and installing this sample, you hereby agree that the
//  accompanying Materials are being provided to you under the terms and
//  conditions of the End User License Agreement for the Intel(R) Integrated
//  Performance Primitives product previously accepted by you. Please refer
//  to the file ippEULA.rtf located in the root directory of your Intel(R) IPP
//  product installation for more information.
//
//  Description:
//  This source file is part of example code and contains the output buffer/file
//  operations for the Voice Activity Detector. The output PCM data constains the actual
//  speech samples wherever voice activity is detected but zeroed out samples in detected
//  "silence-regions". However, there is an inherent latency in the output
//  due to the delayed utterance start/end decisions of the implemented VAD algorithm.
//  Hence the output data is held in a buffer until such a decision is indicated by the VAD
//  state machine.
//
*/

/* headers */
#include <stdio.h>
#include <ipps.h>
#include "VADout.h"

//#define CHOP_SILENCE 1 /* chop the silence frames instead of the default zeroing the data */

/********************************************************************************
// Name:             OUT_Init
// Description:      Initialize the output buffer
//
// Input Arguments:
//                   len     - the length of the output circular buffer
// Input/Output Arguments:
//                   pOutBuf - pointer to the structure containing the output circular
//                             buffer that has to be initialized.
// Returns:          None
// Notes:
********************************************************************************/
void OUT_Init(int len, CircBufStruct16s* pOutBuf)
{
    pOutBuf->headIdx = 0;
    pOutBuf->tailIdx = -1;
    pOutBuf->len = len;
}

/********************************************************************************
// Name:             OUT_AppendSamples
// Description:      Save the input buffer of data in the output circular buffer for writing
//                   to the output file when a VAD decision is made.
//
// Input Arguments:
//                   pBuf    - pointer to input buffer
//                   len     - the length in samples of the input buffer
// Input/Output Arguments:
//                   pOutBuf - pointer to the output circular buffer
//
// Returns:          None
// Notes:
********************************************************************************/
void OUT_AppendSamples(Ipp16s* pBuf,int len, CircBufStruct16s* pOutBuf)
{
    if (len > 0)
    {
        /* find the location in the output buffer where the input buffer needs to be saved */
        if ( pOutBuf->tailIdx >= (pOutBuf->len - 1))
        {
            pOutBuf->tailIdx = -1;
        }
        ippsCopy_16s(pBuf,&(pOutBuf->pBuf[pOutBuf->tailIdx+1]),len);
        pOutBuf->tailIdx += len; /* new tailIdx location in buffer */
    }

}

/********************************************************************************
// Name:             OUT_ConditionalFlushBuffer
// Description:      Write the data in the output buffer to the binary output  file based on the state
//                   of the VAD decision. See additional description in Arguments/curDecisionState section.
//
// Input Arguments:
//                   decisionSampNum- absolute sample number where either the start/end
//                                    of utterance has been detected. (-1) otherwise.
//                   curDecisionState- indicates the state of the VAD decision. It can have one
//                                     of the following values -
//                      1) ACTIVE        - utterance start has been detected.
//                                         Flush out the entire output buffer except the
//                                         last frame (lookahead frame). All samples before
//                                         the decisionSampNum are zeroed (for silence). All samples
//                                         after the decisionSampNum (including decisionSampNum) are written
//                                         as-is to the output file.
//
//                      2) INACTIVE      - utterance end has been detected.
//                                         Flush out the entire output buffer except the
//                                         last frame (lookahead frame). All samples before
//                                         the decisionSampNum are written as-is to the output file.
//                                         All samples after the decisionSampNum (including decisionSampNum)
//                                         are zeroed out (silence) before being written to output.
//
//                      3) NODECISION    - no decision has been made w.r.t start/end of utterance.
//                                         If the output buffer is full, one frame of data is
//                                         written to the output to make space for the next input
//                                         frame. The data written out depends on the previous
//                                         state (pPrevDecisionState) of the VAD decision. If it was
//                                         ACTIVE, the frame is written as-is to the output. If
//                                         it was INACTIVE, the frame is zeroed out before being written
//                                         to the output.
//
//                      4) END_OF_STREAM - input data has ended.
//                                         All the remaining data in the output buffer is written to
//                                         the output file based on the previous
//                                         state (pPrevDecisionState) of the VAD decision. If it was
//                                         ACTIVE, all data is written as-is to the output. If
//                                         it was INACTIVE, all data is zeroed out before being written
//                                         to the output.
//                   cLookAheadSamps     - the size in samples of the lookahead data
// Input/Output Arguments:
//                   pOutBuf - pointer the structure containing the output circular buffer
//                   pPrevDecisionState- pointer to the previous state of the VAD decision (ACTIVE/INACTIVE).
//                                       Its value is updated only if the current curDecisionState is either
//                                       ACTIVE/INACTIVE.
// Output Arguments:
//                   pOutputPCMFile - file pointer of the output file
//
// Returns:          None
// Notes:
********************************************************************************/
#ifdef CHOP_SILENCE

void OUT_ConditionalFlushBuffer(
  CircBufStruct16s*   pOutBuf,
  int                 decisionSampNum,
  VADDecisionState    curDecisionState,
  VADDecisionState*   pPrevDecisionState,
  int                 cLookAheadSamps,
  FILE*               pOutputPCMFile)
{
    int  sampIdx;                         /* the sample position in the output circular buffer */
    int  k1, k2, k3;                      /* position in output buffer for next write operation */
    int  numSamps1, numSamps2, numSamps3; /* number of samples that have to written out*/
    int  cSampsWritten;                   /* return of fwrite call */
    int  tmpDiff;                         /* temporary variable */

    /* find the sample position of the start/end sample of the utterance in the circular buffer */
    sampIdx = decisionSampNum % pOutBuf->len;

    switch (curDecisionState)
    {
        case ACTIVE:
            /* Flush out all but the last buffer with the appropriate decision logic */

            /* update the value of previous decision state */
            *pPrevDecisionState = curDecisionState;

            if (sampIdx < pOutBuf->headIdx)
            {
                /* Circular buffer wrapped around. Index positions (sampIdx < tailIdx < headIdx) */
                k3 = sampIdx;
                numSamps3 = (pOutBuf->tailIdx - cLookAheadSamps) - sampIdx + 1;
                cSampsWritten = fwrite(&(pOutBuf->pBuf[k3]), sizeof(Ipp16s), numSamps3, pOutputPCMFile);
            }
            else
            {
                /* Circular buffer pointer positions are (headIdx < sampIdx) */
                k2 = sampIdx;
                if (pOutBuf->tailIdx < pOutBuf->headIdx)
                {
                    /* Circular buffer wrapped around. Index positions are (tailIdx < headIdx < sampIdx) */
                    numSamps2 = pOutBuf->len - sampIdx;
                    cSampsWritten = fwrite(&(pOutBuf->pBuf[k2]), sizeof(Ipp16s), numSamps2, pOutputPCMFile);

                    k3 = 0;
                    numSamps3 = (pOutBuf->tailIdx - cLookAheadSamps) + 1;
                    cSampsWritten = fwrite(&(pOutBuf->pBuf[k3]), sizeof(Ipp16s), numSamps3, pOutputPCMFile);
                }
                else
                {
                    /* Circular buffer pointer positions are (headIdx < sampIdx < tailIdx) */
                    numSamps2 = (pOutBuf->tailIdx - cLookAheadSamps) - sampIdx + 1;
                    cSampsWritten = fwrite(&(pOutBuf->pBuf[k2]), sizeof(Ipp16s), numSamps2, pOutputPCMFile);
                }
            }
            /* reset the headIdx after data has been flushed out */
            pOutBuf->headIdx = (pOutBuf->tailIdx - cLookAheadSamps) + 1;

            break;

        case INACTIVE:
            /* Flush out all but the last buffer with the appropriate decision logic */

            /* update the value of previous decision state */
            *pPrevDecisionState = curDecisionState;

            if (sampIdx < pOutBuf->headIdx)
            {
                /* Circular buffer wrapped around. Index positions (sampIdx < tailIdx < headIdx) */
                k1 = pOutBuf->headIdx;
                numSamps1 = (pOutBuf->len - pOutBuf->headIdx);
                cSampsWritten = fwrite(&(pOutBuf->pBuf[k1]), sizeof(Ipp16s), numSamps1, pOutputPCMFile);

                k2 = 0;
                numSamps2 = sampIdx;
                cSampsWritten = fwrite(&(pOutBuf->pBuf[k2]), sizeof(Ipp16s), numSamps2, pOutputPCMFile);
            }
            else
            {
                /* Circular buffer pointer positions are (headIdx < sampIdx) */
                k1 = pOutBuf->headIdx;
                numSamps1 = (sampIdx - pOutBuf->headIdx);
                cSampsWritten = fwrite(&(pOutBuf->pBuf[k1]), sizeof(Ipp16s), numSamps1, pOutputPCMFile);
            }
            /* reset the headIdx after data has been flushed out */
            pOutBuf->headIdx = (pOutBuf->tailIdx - cLookAheadSamps) + 1;

            break;

        case NODECISION:
            /* If the output buffer is full flush out one frame to make space for the next input frame */

            tmpDiff = pOutBuf->tailIdx - pOutBuf->headIdx;
            if ( (-1 == tmpDiff)  || ((pOutBuf->len - 1) == tmpDiff) )
            {
                /* buffer full, so flush one buffer to make room for the next buffer*/
                k1 = pOutBuf->headIdx;
                numSamps1 = cLookAheadSamps;
                if (ACTIVE == *pPrevDecisionState)
                {
                    cSampsWritten = fwrite(&(pOutBuf->pBuf[k1]), sizeof(Ipp16s), numSamps1, pOutputPCMFile);
                }
                /* adjust the head pointer */
                pOutBuf->headIdx += cLookAheadSamps;
                if (pOutBuf->headIdx >= pOutBuf->len)
                {
                    pOutBuf->headIdx = 0;
                }
            }
            break;

        case END_OF_STREAM:
            /* flush out all remaining data in output buffer since the input stream has ended */
            if (pOutBuf->tailIdx < pOutBuf->headIdx)
            {

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -