关于如何编写指向内存插放的音频解码器
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; } } |
相关文章推荐
- 关于域名如何指向WordPress homepage问题的解决
- IAR for MSP430时,如何查看编写代码占用字节数、内存占用情况、堆栈溢出
- 关于PE病毒编写的学习(五)——病毒如何做标记和记录信息
- 关于Excel操作编写的一个软件设计构思案例[连载] --如何实现从字符串中提取需要的字符并赋值给指定单元格内
- 如何用Java编写一段代码引发内存泄露
- 关于各种音频&视频解码器的使用
- 12-3-10关于gcc一些知识,如何编写makefile
- 19_Android中图片处理原理篇,关于人脸识别网站,图片加载到内存,图片缩放,图片翻转倒置,网上撕衣服游戏案例编写
- 关于浮点数的小数部分的二进制表示、精度以及浮点数如何在内存中存放问题
- C++类中静态STL容器中的指针所指向的动态内存空间如何释放!
- 如何让IntPtr指向一块内存,以及托管内存与非托管内存的相互转化
- Java中关于内存泄漏出现的原因以及如何避免内存泄漏
- oc 关于对象release后 指向它的指针如何处理的问题
- 关于如何编写与调用java的JNI程序
- 关于Excel操作编写的一个软件设计构思案例[连载] --如何创建快捷菜单执行人机交互操作、软件初始化设置
- 关于Excel操作编写的一个软件设计构思案例[连载] --如何把处理好后的数据导出Excel文件中(含背景\字体颜色设置)
- 解决关于sipdroid导入eclipse后编译完成,发布的apk安装之后出现音频解码器出现问题的情况!
- 关于如何在开机的时候运行自己编写的脚本
- 关于如何发现Delphi程序的内存泄漏
- iOS指南系列:如何解决奔溃问题-关于内存访问续