您的位置:首页 > 其它

关于如何编写指向内存插放的音频解码器

2008-10-26 15:05 225 查看


[align=center]关于如何编写指向内存插放的音频解码器[/align]

前不久没事研究了一下音频无损压缩,在想出压缩算法后,压缩后的文件格式没有专门的解码器,所以就研究了一下解码器,我的思路是在插放时,从文件中读取压缩码,在内存中解压,然后再用插放的指针指向我还原码的内存区进行插放.由于压缩算法的代码和解压算法的代码比较多,在这先讲一下如何实现直接从内存区中插放文件,下面的代码是把WAV文件读到内存中,再把内存中的音频数据送去插放.(代码是用C++写的,因本人比较懒,没有写出代码的注释)
#include
<vcl.h>
#pragma hdrstop
#include
"Unit1.h"
//---------------------------------------------------------------------------
#pragma
package(smart_init)
#pragma resource "*.dfm"
TForm1
*Form1;
//---------------------------------------------------------------------------
__fastcall
TForm1::TForm1(TComponent* Owner)
:
TForm(Owner)
{
}
//---------------------------------------------------------------------------
void
__fastcall TForm1::btnEixtClick(TObject *Sender)
{
bExit=true;
Close();

}
//---------------------------------------------------------------------------
void
__fastcall TForm1::btnOpenClick(TObject *Sender)
{
if(pVoiceBuffer)
  
pVoiceBuffer=NULL;
   if(f)
   {
    f=NULL;
   }
  
bExit=false;
   OpenDialog1->InitialDir =GetCurrentDir();
  
if(OpenDialog1->Execute()==false)
   {
    btnOpen->Enabled
=true;
    return;
   }
   btnPlay->Enabled==true;
  
sOpenFileName=OpenDialog1->FileName ;
   Label5->Caption
=sOpenFileName.SubString(sOpenFileName.LastDelimiter('//')+1,sOpenFileName.Length()
);
   Form1->Caption =Label5->Caption ;
   f=new
TFileStream(sOpenFileName,fmShareDenyWrite);
   cpHeader=new char[44];
  
f->ReadBuffer(cpHeader,44);
   f->Seek(22,soFromBeginning);
  
f->Read(&sChannels,sizeof(short));
   Label10->Caption
=IntToStr(sChannels);
   f->Seek(24,soFromBeginning);
  
f->Read(&lSamplingRate,sizeof(long));
   Label6->Caption
=IntToStr(lSamplingRate)+"samples/second";
  
f->Seek(34,soFromBeginning);
  
f->Read(&sBitsPerSample,sizeof(short));
   Label8->Caption
=IntToStr(sBitsPerSample)+"bits/sample";
  
/*f->Seek(40,soFromBeginning);
  
f->Read(&lFileSize,sizeof(long));
   Label7->Caption
=IntToStr(lFileSize)+"bytes"; */
   f->Seek(4,soFromBeginning);
  
f->Read(&lFileSize,sizeof(long));
   lFileSize-=44;
  
Label7->Caption =IntToStr(lFileSize)+"bytes";
  
if(sBitsPerSample==8)
   iSampleSize=lFileSize;
   else
if(sBitsPerSample==16)
   iSampleSize=lFileSize/2;
   else
  
{
    MessageDlg("not pcm
formats",mtInformation,TMsgDlgButtons()<<mbOK,0);
    return;
  
}
   pVoiceBuffer=new short[iSampleSize];
  
f->Seek(44,soFromBeginning);
  
f->Read(pVoiceBuffer,lFileSize);
}
//---------------------------------------------------------------------------
void
__fastcall TForm1::btnStopClick(TObject
*Sender)
{
if(pVoiceBuffer==NULL)
{
MessageDlg("no data for
playing",mtWarning,TMsgDlgButtons()<<mbOK,0);
return;
}
waveOutUnprepareHeader(hWaveOut,lpWaveHdr,sizeof(WAVEHDR));
if(waveOutReset(hWaveOut)!=MMSYSERR_NOERROR)
{
MessageDlg("waveoutreset
error",mtInformation,TMsgDlgButtons()<<mbOK,0);
return;
}
if(waveOutClose(hWaveOut)!=MMSYSERR_NOERROR)
{
MessageDlg("waveoutClose
error",mtInformation,TMsgDlgButtons()<<mbOK,0);
return;
}
if(lpWaveHdr)
{
GlobalUnlock(hWaveHdr);
GlobalFree(hWaveHdr);
hWaveHdr=NULL;
}
btnPlay->Enabled=true;
btnStop->Enabled=false;
}
//---------------------------------------------------------------------------
void
__fastcall TForm1::btnPlayClick(TObject *Sender)
{
char
szOpenError[]="Open device Error
!";
if(pVoiceBuffer==NULL)
{
MessageDlg("no data for
playing",mtWarning,TMsgDlgButtons()<<mbOK,0);
return;
}
btnStop->Enabled=true;
dwDataSize=lFileSize;
pFormat.wFormatTag
=WAVE_FORMAT_PCM;
pFormat.nChannels =sChannels;
pFormat.nSamplesPerSec
=lSamplingRate;
if(sBitsPerSample==8)
{
pFormat.nAvgBytesPerSec
=lSamplingRate*sChannels*(sBitsPerSample/8);
pFormat.nBlockAlign
=sChannels*(sBitsPerSample/8);
pFormat.wBitsPerSample
=8;
}else{
pFormat.nAvgBytesPerSec
=lSamplingRate*sChannels*(sBitsPerSample/8);
pFormat.nBlockAlign
=sChannels*(sBitsPerSample/8);
pFormat.wBitsPerSample
=16;
}
pFormat.cbSize
=0;
if(!(waveOutOpen((LPHWAVEOUT)&hWaveOut,WAVE_MAPPER,(LPWAVEFORMATEX)&pFormat,(DWORD)Form1->Handle
,0,0)==MMSYSERR_NOERROR))
{
  
MessageDlg(szOpenError,mtInformation,TMsgDlgButtons()<<mbOK,0);
  
return;
}else{
btnPlay->Enabled=false;
hWaveHdr=GlobalAlloc(GMEM_MOVEABLE
|
GMEM_SHARE,(DWORD)sizeof(WAVEHDR));
if(hWaveHdr==NULL)
{
    MessageDlg("not
enough menory for
header.",mtInformation,TMsgDlgButtons()<<mbOK,0);
    return;
}
lpWaveHdr=(LPWAVEHDR)GlobalLock(hWaveHdr);
if(lpWaveHdr==NULL)
{
  MessageDlg("Failed
to lock memory for
header..",mtInformation,TMsgDlgButtons()<<mbOK,0);
    return;
}
lpWaveHdr->lpData=(char*)pVoiceBuffer;
lpWaveHdr->dwBufferLength
=lFileSize;
lpWaveHdr->dwFlags =0L;
lpWaveHdr->dwLoops
=0L;
if(waveOutPrepareHeader(hWaveOut,lpWaveHdr,sizeof(WAVEHDR))!=MMSYSERR_NOERROR)
{
  MessageDlg("WAVEOUTPREPAREHEADER
ERROR
.",mtInformation,TMsgDlgButtons()<<mbOK,0);
    return;
}
wResult=waveOutWrite(hWaveOut,lpWaveHdr,sizeof(WAVEHDR));
if(wResult!=0)
{
  waveOutUnprepareHeader(hWaveOut,lpWaveHdr,sizeof(WAVEHDR));
  GlobalUnlock(lpWaveHdr);
  GlobalFree(hWaveHdr);
  MessageDlg("waveoutwrite
error.",mtInformation,TMsgDlgButtons()<<mbOK,0);
    return;
}
else
while(waveOutUnprepareHeader(hWaveOut,lpWaveHdr,sizeof(WAVEHDR))!=MMSYSERR_NOERROR)
{
  if(bExit)
  break;
  Application->ProcessMessages();
}
if(waveOutReset(hWaveOut)!=MMSYSERR_NOERROR)
{
  MessageDlg("waveoutreset
error",mtInformation,TMsgDlgButtons()<<mbOK,0);
    return;
}
if(waveOutClose(hWaveOut)!=MMSYSERR_NOERROR)
{
  MessageDlg("waveoutclose
error",mtInformation,TMsgDlgButtons()<<mbOK,0);
    return;
}
if(lpWaveHdr)
{
  GlobalUnlock(hWaveHdr);
  GlobalFree(hWaveHdr);
}
btnPlay->Enabled=true;
btnStop->Enabled=false;
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  null 算法 c
相关文章推荐