您的位置:首页 > 运维架构

使用openal与mpg123播放MP3,附带工程文件(转)

2013-12-09 01:47 302 查看

使用openal与mpg123播放MP3,附带工程文件

使用openal和mpg123播放MP3文件

使用静态编译,相关文件都在附件里

相关工程文件:openal_mpg123_player.7z

使用visual studio 2010编译,理论上是跨平台的

相关说明请看源代码注释以及mpg123.h和openal文档

/*AUTHOR bowman han
* NOTE  this is a test program for mpg123 basic usage
* EMAIL  fancycode+blogcn123@gmail.com
* DATA 6/2 2012
* Please DO NOT REMOVE THIS
*/

#include "openal\include\al.h"
#include "openal\include\alc.h"
#include <stdio.h>
#include <Windows.h>
#define NUM_BUFFERS 4
#include "mpg123\mpg123.h"
#include <conio.h>

#pragma comment (lib, "./mpg123/libmpg123.lib")
#pragma comment (lib, "./openal/lib/OpenAL32.lib")
int main()
{
ALuint g_Buffers[NUM_BUFFERS];
ALuint uiSource;
ALuint uiBuffer;
ALCdevice * pDevice = NULL;
ALCcontext *pContext = NULL;
ALboolean g_bEAX;
ALenum error, eBufferFormat;
ALint iDataSize, iFrequency;
ALuint ulFormat;
int iLoop,iBuffersProcessed, iTotalBuffersProcessed;
unsigned long ulDataSize = 0;
unsigned long ulFrequency = 0;
unsigned long ulBufferSize;
unsigned long ulBytesWritten;
long lRate;
int iEncoding, iChannels;
int encoding;
void *        pData = NULL;
WAVEFORMATEX *pwfex;
int iState, iQueuedBuffers;
mpg123_handle *mpg123 ;
int iMpg123_error;
//init mpg123 library
if(MPG123_OK != (iMpg123_error = mpg123_init()))
{
printf("failed to init mpg123\n");
return -1;
}

//open a default mpg123 decoder
mpg123 = mpg123_new(mpg123_decoders()[0], &iMpg123_error);

//open a openal default device
pDevice = alcOpenDevice(NULL); //select the perfered device

if(pDevice){
pContext = alcCreateContext(pDevice, NULL);
alcMakeContextCurrent(pContext);
}else
{
printf("failed to get a openal decice\n");
return -2;
}

g_bEAX = alIsExtensionPresent("EAX2.0");

//Generate openal  Buffers
alGetError();  //clear all error code

alGenBuffers(NUM_BUFFERS, g_Buffers);

if((error = alGetError()) != AL_NO_ERROR)
{
fprintf(stderr, "alGenBuffers :%s", error);
}

alGenSources(1, &uiSource);

//try to open a mp3 file, modify to your own mp3 files
if(MPG123_OK != (iMpg123_error = mpg123_open(mpg123,"D:\\sound\\320k.mp3")))
{
fprintf(stderr,"error in open mp3 file\n");
return -1;
}
//get mp3 format infomation
mpg123_getformat(mpg123, &lRate, &iChannels,  &iEncoding);

//there only parse stereo mp3 file
if(iChannels ==2)
{
ulFormat = alGetEnumValue("AL_FORMAT_STEREO16");
ulBufferSize = lRate;  //set buffer to 250ms
ulBufferSize -= (ulBufferSize % 4);  //set pcm Block align
ulFrequency = lRate;  //set pcm sample rate

}
else
{
printf("channels info%i\n", iChannels);
return -3;
}

pData = malloc(ulBufferSize);
//feed data to openal buffer
for(iLoop= 0; iLoop < 4; iLoop++)
{
mpg123_read(mpg123, (char *)pData, ulBufferSize,&ulBytesWritten);
alBufferData(g_Buffers[iLoop], ulFormat, pData, ulBytesWritten, ulFrequency);
alSourceQueueBuffers(uiSource, 1, &g_Buffers[iLoop]);
}
alSourcePlay(uiSource);
iTotalBuffersProcessed = 0;
printf("playing\n");
//wait for key press
while(!_kbhit())
{
Sleep(20);
iBuffersProcessed = 0;
alGetSourcei(uiSource, AL_BUFFERS_PROCESSED, &iBuffersProcessed);

iTotalBuffersProcessed += iBuffersProcessed;
printf("Buffers total Processed %d\r", iTotalBuffersProcessed);
while(iBuffersProcessed)
{
uiBuffer = 0;
alSourceUnqueueBuffers(uiSource, 1, &uiBuffer);

mpg123_read(mpg123, (char *)pData, ulBufferSize, &ulBytesWritten);
if(ulBytesWritten)
{
alBufferData(uiBuffer, ulFormat, pData, ulBytesWritten, ulFrequency);
alSourceQueueBuffers(uiSource, 1, &uiBuffer);
}                iBuffersProcessed--;

}
alGetSourcei(uiSource, AL_SOURCE_STATE, &iState);
if(iState != AL_PLAYING)
{
alGetSourcei(uiSource, AL_BUFFERS_QUEUED, &iQueuedBuffers);

if(iQueuedBuffers)
{
alSourcePlay(uiSource);//buffers have data, play it
}
else
{
//there is no data any more
break;
}
}
}
//close mpg123
mpg123_close(mpg123);
//stop the source and clear the queue
alSourceStop(uiSource);
alSourcei(uiSource, AL_BUFFER, 0);

free(pData);
pData = NULL;

return 0;
}


其他一些openAL相关的资料:http://blog.csdn.net/zxc110110/article/details/7188054
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: