📄 g723_oal_win32.cpp
字号:
/******************************************************************************
// 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) 2000-03 Intel Corporation. All Rights Reserved.
//
// VSS:
// $Workfile: g723_oal.cpp $
// $Revision: 1.00 $
// $Date: 07/28/2003 $
// $Archive: $
//
// Description:
// OS adaptation layer for the cross-platform IPP G.723.1 sample program.
// Provides interface to OS services such as memory allocation, file I/O,
// performance timer(s), audio I/O, and GUI.
//
// External interface:
// Name Purpose
// -----------------------------------------------------------------------------------------------------
// timerSetNum() configure timer set
// timerGetNum() get number of timers defined
// timerInit(n) initialize timer n
// timerReset(n) reset timer n
// timerStart(n) start timer n
// timerStop(n) stop timer n
// timerDeltaAcc(n) add to accumulator stop-start delta on timer n, update block count
// timerSetBlockSize(n) set block size for timer n
// timerGetBlockSize(n) get block size for timer n
// timerSetNumBlocks(n) set number of blocks for timer n
// timerGetNumBlocks(n) get number of blocks for timer n
// timerGetAcc(n) get accumulator value for timer n
// timerGetLabel(n) get label for timer n
// timerSetFreq(n) set clock frequency for timer n
// timerGetFreq(n) get clock frequency for timer n
// getCpuUtilization(n,m) compute CPU utilization
//
************************************************************************************************/
/* Ipp definitions */
#include <ippdefs.h>
#include <ippSC.h>
/* Platform-specific definitions */
#include <g723_platform_config.h>
/* Codec and platform definitions */
#include <g723_codec.h>
/* OS adaptation layer */
#include <g723_oal_win32.h>
/* Globals */
#include <g723_globals.h>
/* Timer globals */
performanceTimer timer[TIMER_NUM_MAX];
int totalTimers;
// Add timer n, including all necessary memory allocation
int timerInit(int n, char *label)
{
int i=0;
while(label[i]!='\0')
timer[n].label[i]=label[i++];
timer[n].label[i]='\0';
timerSetFreq(n,0);
timer[n].acc.QuadPart=0;
timer[n].blockCount=0;
return(1);
}
// Set number of performance timers
int timerSetNum(int numTimers)
{
totalTimers=numTimers;
return(1);
}
// Get number of performance timers
int timerGetNum(int *numTimers)
{
*numTimers=totalTimers;
return(1);
}
// Reset timer n
int timerReset(int n)
{
timer[n].acc.QuadPart=0;
timerSetNumBlocks(n,0);
return(1);
}
// Record start time, timer n
int timerStart(int n)
{
QueryPerformanceCounter(&(timer[n].tStart));
return(1);
}
// Record stop time, timer n
int timerStop(int n)
{
QueryPerformanceCounter(&(timer[n].tStop));
return(1);
}
// Accumulate tStop-tStart, increment block counter
int timerDeltaAcc(int n)
{
timer[n].acc.QuadPart+=(timer[n].tStop.QuadPart-timer[n].tStart.QuadPart);
timer[n].blockCount++;
return(1);
}
// Set block size for timer n
int timerSetBlockSize(int n, int size)
{
timer[n].blockSize = size;
return(1);
}
// Query block size for timer n
int timerGetBlockSize(int n, int *blockSize)
{
*blockSize=timer[n].blockSize;
return(1);
}
// Set number blocks for timer n
int timerSetNumBlocks(int n, int newBlockCount)
{
timer[n].blockCount=newBlockCount;
return(1);
}
// Get number blocks for timer n
int timerGetNumBlocks(int n, int *blockCount)
{
*blockCount=timer[n].blockCount;
return(1);
}
// Query accumulator for timer n
int timerGetAcc(int n, int *timerAcc)
{
*timerAcc = (int)(timer[n].acc.QuadPart & 0xffffffff);
return(1);
}
// Get label of timer n
int timerGetLabel(int n, void *label)
{
strcpy((TCHAR *)label,timer[n].label);
return(1);
}
// Set timer n frequency
int timerSetFreq(int n, int freq)
{
QueryPerformanceFrequency(&(timer[n].freq));
return(1);
}
// Get timer n frequency
int timerGetFreq(int n, int *timerFreq)
{
*timerFreq = (int) (timer[n].freq.QuadPart & 0xffffffff);
return(1);
}
// Compute CPU utilization (%) given sample rate, block size, and timer measurements
float getCpuUtilization(int n, int sampleRate)
{
float percentCpu=0.0;
int acc;
int blkSize;
int numBlocks;
int freq;
/* %CPU = Avg CPU time per frame / frame duration
tcpu (seconds) = acc/(frameNum*timerFreq) = avg frame CPU time
tframe (seconds) = # samples / fs
%CPU = 100 * (tcpu/tframe)
= 100 * acc * fs / (frameNum * # samples per frame * timerFreq)
*/
timerGetAcc(n,&acc);
timerGetNumBlocks(n,&numBlocks);
timerGetBlockSize(n,&blkSize);
timerGetFreq(n,&freq);
if (numBlocks>0)
{
percentCpu = ( (float) 100.0 * (float) acc * (float) sampleRate ) /
( (float) numBlocks * (float) blkSize *
(float) freq );
}
return(percentCpu);
}
// Get input file path
LRESULT CALLBACK GetFilePath(HWND hWnd, TCHAR *path, TCHAR *prompt, TCHAR *ext)
{
OPENFILENAME ofn;
DWORD zsize;
static TCHAR pszName[256], filter[256];
HWND hWndd;
/* Init ofn */
zsize=sizeof(ofn);
lstrcpy(pszName,ext);
memset(&ofn,0,zsize);
ofn.hwndOwner=hWnd;
ofn.lStructSize=zsize;
sprintf(filter,TEXT("%s"),prompt);
sprintf(&(filter[strlen(filter)+1]),TEXT("%s \0\0"),ext);
ofn.lpstrFilter=filter;
ofn.lpstrFile=pszName;
ofn.nMaxFile=MAXFN;
/* Request test vector path from user */
if (GetOpenFileName(&ofn))
{
strcpy(path,(TCHAR *)ofn.lpstrFile);
hWndd=GetActiveWindow();
EndDialog(hWndd,0);
ShowWindow(g_hwnd, SW_SHOW);
SetForegroundWindow(g_hwnd);
SetActiveWindow(g_hwnd);
return TRUE;
}
return FALSE;
}
void startCodec_G723(IppPcmStream *inputSpeech,
IppBitstream *outputBits,
IppG723EncoderState *encState,
IppG723DecoderState *decState)
{
int len;
IppPcmStream audioOutA, audioOutB;
/* Init buffer length */
g_WaveBufLen=WAVEBUF_LEN;
/* Update properties display */
g_propertiesDisplayed=0;
/* Destroy audio buffers from playback of any previous files */
if (g_FirstTime)
g_FirstTime=0;
else
DestroySound();
/* Lockout parallel threads */
g_G723Done=0;
/* Init audio device */
InitAudioOutput(g_sampleRate,g_channels,g_bitsPerSample);
audioOutA.pBuf = (Ipp16s *)g_waveMixBufferA->lpData;
audioOutB.pBuf = (Ipp16s *)g_waveMixBufferB->lpData;
/* Open PCM input stream */
openPcmStream(inputSpeech);
/* Init performance timers */
timerSetNum(TIMER_NUM);
timerInit(T_ENC,"Encoder");
timerInit(T_DEC,"Decoder");
timerSetBlockSize(T_ENC,IPP_G723_FRAME_LEN);
timerSetBlockSize(T_DEC,IPP_G723_FRAME_LEN);
/* Start double-buffered audio callbacks */
/* Buffer A */
len=inputSpeech->len;
readPcmStream(inputSpeech);
/* Encode + decode */
EncodeBlock_G723_16s8u(inputSpeech,outputBits,g_dtxEnable,g_bitrate,encState);
DecodeBlock_G723_8u16s(outputBits,&audioOutA,decState);
/* Start callback thread A */
waveOutWrite(hWaveOut,g_waveMixBufferA,sizeof(WAVEHDR));
/* Buffer B */
inputSpeech->len=len;
readPcmStream(inputSpeech);
/* Encode + decode */
EncodeBlock_G723_16s8u(inputSpeech,outputBits,g_dtxEnable,g_bitrate,encState);
DecodeBlock_G723_8u16s(outputBits,&audioOutB,decState);
/* Start callback thread B */
waveOutWrite(hWaveOut,g_waveMixBufferB,sizeof(WAVEHDR));
/* Start CPU utilization display timer */
SetTimer(g_hwnd,PERF_TIMER_ID,PERF_TIMER_PERIOD,(TIMERPROC)PerfDisplayTimer);
}
void initCodec_G723( int pcmFrameLen, int compressedFrameLen, int framesPerBlk,
IppPcmStream *pcm, IppBitstream *bits,
IppG723EncoderState *encState, IppG723DecoderState *decState )
{
/* Init PCM and compressed bitstream buffers */
pcm->pBuf = (Ipp16s *)malloc(sizeof(Ipp16s)*pcmFrameLen*framesPerBlk);
bits->pBuf = (Ipp8u *)malloc(sizeof(Ipp8u)*compressedFrameLen*framesPerBlk);
pcm->len = framesPerBlk * pcmFrameLen;
bits->len = framesPerBlk * compressedFrameLen;
/* Init PCM and compressed bitstream ID buffers */
pcm->pId = (char *)malloc(sizeof(char)*MAXFN);
bits->pId = (char *)malloc(sizeof(char)*MAXFN);
/* Init encoder and decoder */
EncoderInit_G723(encState);
DecoderInit_G723(decState);
}
void destroyCodec_G723( IppPcmStream *pcm, IppBitstream *bits)
{
free(pcm->pBuf);
free(pcm->pId);
free(bits->pBuf);
free(bits->pId);
}
int openPcmStream(IppPcmStream *s)
{
if ( (s->pStream=(void *)fopen(s->pId,"rb")) == NULL )
return(0);
else
return(1);
}
int closePcmStream(IppPcmStream *s)
{
fclose((FILE *)s->pStream);
return(1);
}
int readPcmStream(IppPcmStream *s)
{
return((s->len=fread(s->pBuf,sizeof(Ipp16s),s->len,(FILE *)s->pStream)));
}
/* Create audio output buffers */
LPWAVEHDR CreateAudioOutputBuffer(DWORD dwUser)
{
WORD wErr;
LPDWORD lpData;
LPWAVEHDR lpWaveHdr;
lpData = (LPDWORD) malloc(g_WaveBufLen);
if (!lpData)
{
return NULL;
} /* if */
memset(lpData, 0, g_WaveBufLen);
lpWaveHdr = (LPWAVEHDR )malloc(sizeof(WAVEHDR));
if(!lpWaveHdr)
{
return NULL;
} /* if */
memset(lpWaveHdr, 0, sizeof(WAVEHDR));
/*
// Construct the WAVEHDR structure.
*/
lpWaveHdr->lpData = (char *)lpData;
lpWaveHdr->dwBufferLength = g_WaveBufLen;
lpWaveHdr->dwFlags = 0L;
lpWaveHdr->dwUser = dwUser;
/*
// Prepare buffer
*/
if(wErr = waveOutPrepareHeader(hWaveOut, lpWaveHdr, sizeof(WAVEHDR)))
{
free(lpData);
free(lpWaveHdr);
return NULL;
} /* if */
return lpWaveHdr;
}
/* Streaming input and output audio callbacks */
void CALLBACK WaveCallbackFunction(HANDLE hdrvr, UINT uMsg, DWORD dwUser, DWORD dw1, DWORD dw2)
{
switch(uMsg)
{
case WOM_OPEN:
break;
case WOM_CLOSE:
break;
case WOM_DONE:
FillAudioOutputBuffer(hWaveOut,(LPWAVEHDR)dw1);
break;
case WIM_DATA:
break;
default:
break;
}
}
/* Initialize streaming audio output */
void InitAudioOutput(int SampleRate, int Channels, int BitsPerSample)
{
WAVEFORMATEX wf;
WORD nBitsPerSample;
WORD nHz;
WORD nChannels;
UINT wErr;
hWaveOut = NULL;
if(waveOutGetNumDevs()<1)
{
MessageBox(NULL,TEXT("No Wave Devices"), TEXT("Warning"), MB_OK);
}
else
{
WAVEOUTCAPS woc;
waveOutGetDevCaps(0, &woc, sizeof(woc));
nBitsPerSample = BitsPerSample;
nHz = SampleRate;
nChannels = Channels;
wf.wFormatTag = WAVE_FORMAT_PCM;
wf.nChannels = nChannels;
wf.nSamplesPerSec = nHz;
wf.nAvgBytesPerSec = nHz * nChannels * nBitsPerSample / 8;
wf.nBlockAlign = nBitsPerSample / 8 * nChannels;
wf.wBitsPerSample = nBitsPerSample;
wf.cbSize = sizeof(WAVEFORMATEX);
if (wErr = waveOutOpen((LPHWAVEOUT)&hWaveOut, WAVE_MAPPER,
&wf, (UINT )WaveCallbackFunction, 0, CALLBACK_FUNCTION))
{
TCHAR tstr[256];
waveOutGetErrorText(wErr, tstr, sizeof(tstr));
MessageBox(NULL,TEXT("Error opening wave device"),tstr,MB_OK);
return;
} /* if */
/* Create audio buffers */
g_waveMixBufferA = CreateAudioOutputBuffer((DWORD )g_waveMixBufferA);
g_waveMixBufferB = CreateAudioOutputBuffer((DWORD )g_waveMixBufferB);
waveOutPause(hWaveOut);
if(NULL == g_waveMixBufferA || NULL == g_waveMixBufferB)
MessageBox(NULL,TEXT("Error creating sound buffers"),TEXT("Error"),MB_OK);
waveOutRestart(hWaveOut);
}
}
/* Audio output shutdown */
void DestroySound(void)
{
waveOutReset(hWaveOut);
//unprepare and free audio buffers
waveOutUnprepareHeader(hWaveOut, g_waveMixBufferA, sizeof(WAVEHDR));
free(g_waveMixBufferA->lpData);
free(g_waveMixBufferA);
waveOutUnprepareHeader(hWaveOut, g_waveMixBufferB, sizeof(WAVEHDR));
free(g_waveMixBufferB->lpData);
free(g_waveMixBufferB);
waveOutClose(hWaveOut);
}
/* Audio output empty buffer callback */
void FillAudioOutputBuffer(HWAVEOUT hWaveOut,LPWAVEHDR dw1)
{
int samples;
Ipp16s *audioDev=(Ipp16s *)dw1->lpData;
IppPcmStream audioOutput;
audioOutput.pBuf=audioDev;
/* get next PCM block from input stream */
if (!g_G723Done)
{
samples = readPcmStream(&g_inputPcmStream);
g_G723Done = (samples==0);
/* process PCM block */
if (samples>0)
{
/* Encode + decode first PCM block */
EncodeBlock_G723_16s8u(&g_inputPcmStream,&g_outputBitstream,g_dtxEnable,g_bitrate,&g_G723encState);
DecodeBlock_G723_8u16s(&g_outputBitstream,&audioOutput,&g_G723decState);
/* Set buffer length to match decoder output
Last block in a file is typically truncated
and contains fewer then FRAMES_PER_BLOCK * FRAME_LEN samples
since most file lengths are not evenly divisible by
FRAMES_PER_BLOCK * FRAME_LEN */
dw1->dwBufferLength = audioOutput.len*sizeof(Ipp16s);
/* Fill audio buffer */
waveOutWrite(hWaveOut, dw1, sizeof(WAVEHDR));
}
else
{
ClearStreamProperties();
g_propertiesDisplayed=0;
closePcmStream(&g_inputPcmStream);
destroyCodec_G723(&g_inputPcmStream,&g_outputBitstream);
g_busy=0;
g_G723Done=1;
}
}
}
void ShowPerformance(HWND hWnd)
{
RECT rt;
HDC hdc;
TCHAR tstr[MAXFN];
hdc = GetDC(g_hwnd);
rt.left=TXT_LEFT; rt.right=240; rt.top=GUI_TOP+55; rt.bottom=140;
int i,n;
TCHAR id[MAXFN];
/* Display label */
sprintf(tstr,_T("CPU Utilization"));
DrawText(hdc,tstr,-1,&rt,DT_LEFT);
rt.top+=15;
rt.bottom+=15;
/* Display CPU utilization */
timerGetNum(&n);
for(i=0;i<n;i++)
{
timerGetLabel(i,&id);
sprintf(tstr,_T("%s: %2.2f %%"),id,getCpuUtilization(i,g_sampleRate));
DrawText(hdc,tstr,-1,&rt,DT_LEFT);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -