mpg123解码MP3,使用DirectSound播放乐曲

#include <iostream>using namespace std;#include <windows.h>#include "mpg123.h"#include <dsound.h>#pragma comment (lib,"dsound.lib")BYTE *buffer;int err = MPG123_OK;//mpg123的工作状态long rate=0;bool hasFile=false;int channels=0, enc=0;mpg123_handle *mh=NULL;LPDIRECTSOUND g_pD3DSound=NULL;//DirectSound的设备指针LPDIRECTSOUNDBUFFER g_pD3DSoundBuffer=NULL;//指向音乐数据缓存的指针DSBUFFERDESC dsbd;//音乐数据的缓存格式WAVEFORMATEX waveform;//当前mp3的音乐格式HWND hwnd=CreateWindowA("Button","aaa",0,0,0,0,0,0,0,0,0);//一定要创建一个窗口句柄,不然没办法播放void D3DInit(long n){DirectSoundCreate(NULL,&g_pD3DSound,NULL);//创建播放设备g_pD3DSound->SetCooperativeLevel(hwnd,DSSCL_NORMAL); //设定协同等级,就是缓存的写入级别memset(&dsbd,0,sizeof(dsbd));dsbd.dwSize=sizeof(dsbd);dsbd.dwFlags=DSBCAPS_GLOBALFOCUS;//这么设置保证在后台也能播放dsbd.dwBufferBytes=n;//解码后的数据大小,以字节计算dsbd.lpwfxFormat=(WAVEFORMATEX*)malloc(sizeof(WAVEFORMATEX));}void CleanUp(){//一些清理工作,顺序不要颠倒mpg123_close(mh);mpg123_delete(mh);mpg123_exit();//此处顺序也不能乱if(g_pD3DSoundBuffer){g_pD3DSoundBuffer->Release();g_pD3DSoundBuffer=NULL;};if(g_pD3DSound){g_pD3DSound->Release();g_pD3DSound=NULL;};}void Open(CHAR* FileName){//mpg123初始化mpg123_init();mh = mpg123_new(NULL, &err);//检测格式是否正确mpg123_open(mh,FileName);//获得每秒采样率,,声道数,以及编码格式mpg123_getformat(mh,&rate,&channels,&enc);//mpg123只支持这两种MP3编码格式,已经够了,大部分就是这样的if(enc != MPG123_ENC_SIGNED_16 && enc != MPG123_ENC_FLOAT_32){fprintf(stderr, "Bad encoding: 0x%x!\n", enc);return;}//设置音频的格式waveform.wFormatTag =WAVE_FORMAT_PCM;//PCM类型的声音waveform.nChannels =channels;//声道waveform.nSamplesPerSec =rate;//每秒采样率waveform.nAvgBytesPerSec=rate*channels*2; //每秒多少字节waveform.nBlockAlign =4;//我不太清楚,反正4没错waveform.wBitsPerSample =16;//signed16编码格式的每采样大小waveform.cbSize =0;//额外信息,一般是0//告诉系统文件打开正常hasFile=true;}void D3DPlay(long n){LPVOID lpPtr1=new LPVOID;LPVOID lpPtr2=new LPVOID;DWORD length1=0,length2=0,state=0;D3DInit(n);//传递解码后的数据文件大小,便于缓存格式变量创建dsbd.lpwfxFormat=&waveform;//将读取到的格式传给缓存格式变量g_pD3DSound->CreateSoundBuffer(&dsbd,&g_pD3DSoundBuffer,NULL);//打开缓存以便写入,返回两个缓存可写入地址和他们的长度,一般来说第二个地址是没有的g_pD3DSoundBuffer->Lock(0,n,&lpPtr1,&length1,&lpPtr2,&length2,0); memcpy(lpPtr1,buffer,n);//拷贝数据g_pD3DSoundBuffer->Unlock(lpPtr1,length1,0,0); //关闭缓存g_pD3DSoundBuffer->SetCurrentPosition(0);//设定播放位置从0开始g_pD3DSoundBuffer->Play(0,0,DSBPLAY_LOOPING); //播放,循环//等待播放完成g_pD3DSoundBuffer->GetStatus(&state);while ((state==1)||(state==5))//1代表只放一次,5代表循环播放{Sleep(200);//每隔200ms检测一次状态g_pD3DSoundBuffer->GetStatus(&state);};printf("Play Over\n");}void Play(){if(hasFile){long n=mpg123_length(mh)*16*2/8;//通过采样总数*每采样比特数*声道/8获得字节数size_t done=0;buffer=(BYTE*)malloc(n);err=mpg123_read(mh,buffer,n,&done);//读取文件并解码,是的,一句话就完成了if (err==MPG123_ERR) return;if ((err==MPG123_DONE)||(err==MPG123_OK)) D3DPlay(done);//若正常解码结束,开始播放}}int main(){//读入文件名,只支持英文CHAR path[30];cout<<"请输入要播放的mp3文件(带后缀名),请和程序放在同一个目录下"<<endl;cin>>path;Open(path);Play();CleanUp();//不至于播放完了一闪而过return system("pause");}

不要再以任何人说你,因为你不是为任何人而活,你只为自己而活,

mpg123解码MP3,使用DirectSound播放乐曲

相关文章:

你感兴趣的文章:

标签云: