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


    使用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 "openalincludeal.h"
    #include "openalincludealc.h"
    #include <stdio.h>
    #include <Windows.h>
    #define NUM_BUFFERS 4
    #include "mpg123mpg123.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
    ");
            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
    ");
            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
    ");
            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
    ", 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
    ");
        //wait for key press
        while(!_kbhit())
        {
            Sleep(20);
            iBuffersProcessed = 0;
            alGetSourcei(uiSource, AL_BUFFERS_PROCESSED, &iBuffersProcessed);
    
            iTotalBuffersProcessed += iBuffersProcessed;
            printf("Buffers total Processed %d
    ", 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

  • 相关阅读:
    抓取当前界面上任意控件图像的C#代码
    Visual Studio 2005各版本之间的区别
    CSDN上一个问题的回答
    RichTextBox的线程安全问题
    2005年LOGO设计趋势
    VB中的奇怪错误
    吴裕雄天生自然SPRINGSpring MVC的基本配置
    吴裕雄天生自然SPRING基于Java配置的Spring MVC应用
    吴裕雄天生自然SPRINGJSON数据交互
    吴裕雄天生自然SPRING基于注解的控制器
  • 原文地址:https://www.cnblogs.com/wainiwann/p/3464572.html
Copyright © 2020-2023  润新知