?? vadout.c
字號:
/*
//
// 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 + -