zoukankan      html  css  js  c++  java
  • OpenAL音频库例程

      Windows下C++可用的OpenAL demo。

      基于alut工具库的OpenAL例程,涵盖了基本的OpenAL指令,对部分作出了注释,并且可以播放(当然得把对应的音频文件放到正确的路径下)。

      1 #include <iostream>
      2 #include <al/alut.h>//alut includes al.h
      3 #include <math.h>
      4 #include <windows.h>
      5 using namespace std;
      6 
      7 #define PI 3.14159265359
      8 
      9 #define TEST_ERROR(_msg)        
     10     error = alGetError();        
     11     if (error != AL_NO_ERROR) {    
     12         fprintf(stderr, _msg "
    ");    
     13         return -1;        
     14             }
     15 
     16 //ALboolean EnableSource2 = AL_TRUE;    //是否播放第二组声音
     17 ALboolean EnableSource2 = AL_FALSE;    //是否播放第二组声音
     18 ALboolean EnableSource3 = AL_FALSE;    //是否播放第三组声音
     19 
     20 ALuint buffer2,buffer3;
     21 
     22 void Init(){
     23     alutInit(NULL, NULL);
     24 }
     25 
     26 //OS音量40,windows7
     27 void main()
     28 {
     29     ALuint source1[10];     //buffer source
     30 
     31     //Init();//分离到一个单独的函数或类成员中
     32     alutInit(NULL, NULL);
     33 
     34     //ALuint source1;
     35     alGenSources(1, &source1[0]);
     36     //短哔声:10217,Music:RevolvingDoorMONO,中国军魂
     37     ALuint buffer1 = alutCreateBufferFromFile("RevolvingDoorMONO.WAV");//要实现空间化效果,必须为单声道文件(monaural)RevolvingDoorMONO
     38 
     39     if ((alGetError()) != AL_NO_ERROR)std::cout << "Buffer Create error!" << std::endl;
     40 
     41     alSourcei(source1[0], AL_BUFFER, buffer1);
     42 
     43     if (EnableSource2){
     44         alGenSources(2, &source1[1]);
     45         buffer2 = alutCreateBufferFromFile("E:\VS2013\Projects2013\OpenALtest\OpenALtest\10217.WAV");
     46         alSourcei(source1[1], AL_BUFFER, buffer2);
     47         alSourcePlay(source1[1]);
     48         alSourcei(source1[1], AL_LOOPING, AL_TRUE);//第二个音频是否循环
     49     }
     50 
     51     if (EnableSource3){
     52         alGenSources(3, &source1[2]);
     53         ALuint temp = buffer1;
     54         alSourcei(source1[2], AL_BUFFER, temp);
     55         alSourcePlay(source1[2]);
     56         alSourcei(source1[2], AL_LOOPING, AL_TRUE);//第二个音频是否循环
     57     }
     58 
     59     alSourcei(source1[0], AL_SOURCE_RELATIVE, 0); // set to relative positioning so we can set everything to 0
     60     if ((alGetError()) != AL_NO_ERROR)std::cout << "AL_SOURCE_RELATIVE error" << std::endl;
     61     /*AL_SOURCE_RELATIVE设为1时,没有衰减,也没有空间化。
     62     */
     63 
     64     alSourcef(source1[0], AL_ROLLOFF_FACTOR, 1.0); // 0 to disable attenuation  滚降衰减模型
     65     /*AL_ROLLOFF_FACTOR设为1时,开启衰减,设为0时,没有衰减
     66     */
     67 
     68     if ((alGetError()) != AL_NO_ERROR)std::cout << "AL_ROLLOFF_FACTOR error" << std::endl;
     69     alSourcef(source1[0], AL_REFERENCE_DISTANCE, 1); // doesn't matter
     70 
     71     alSourcef(source1[0], AL_MAX_DISTANCE, 5.f);//超过AL_MAX_DISTANCE个单位后,将声音gain值限制在AL_MIN_GAIN(如果在cone之外,好像是再乘以AL_MIN_GAIN) 
     72     alSourcef(source1[0], AL_MIN_GAIN, 0.0f);//设置AL_MIN_GAIN
     73     alSourcef(source1[0], AL_MAX_GAIN, 5.f);//设置AL_MAX_GAIN,即使设得比1大,也会自动回成1,并报输出ERROR
     74 
     75     alDistanceModel(AL_INVERSE_DISTANCE);//距离模型
     76     //alDistanceModel(AL_NONE);//距离模型
     77     //gain = AL_REFERENCE_DISTANCE / (AL_REFERENCE_DISTANCE + AL_ROLLOFF_FACTOR * (distance – AL_REFERENCE_DISTANCE));
     78 
     79     alSourcef(source1[0], AL_PITCH, 1.f);//调节音高乘数
     80     if ((alGetError()) != AL_NO_ERROR)std::cout << "AL_PITCH error" << std::endl;
     81     alSourcef(source1[0], AL_GAIN, 1.f);//调节音量,但是受AL_MIN_GAIN影响,即使设得比min低,实际gain也会保持min设的值
     82     if ((alGetError()) != AL_NO_ERROR)std::cout << "AL_GAIN error" << std::endl;
     83 
     84     //set source direction
     85     alSource3f(source1[0], AL_DIRECTION, 0.f, 0.f, 1.f);//朝z轴正方向
     86     //set source position
     87     alSource3f(source1[0], AL_POSITION, 0.f, 0.f, 0.f);//初始位置为原点
     88     //set source velocity
     89     alSource3f(source1[0], AL_VELOCITY, 0.f, 0.f, 0.f);//多普勒效应影响频率
     90 
     91     alSourcef(source1[0], AL_CONE_OUTER_GAIN, 0.0f);//the gain when outside the oriented cone
     92     if ((alGetError()) != AL_NO_ERROR)std::cout << "AL_CONE_OUTER_GAIN error" << std::endl;
     93     alSourcef(source1[0], AL_CONE_INNER_ANGLE, 90.f);//内角    *PI / 180.f
     94     if ((alGetError()) != AL_NO_ERROR)std::cout << "AL_CONE_INNER_ANGLE error" << std::endl;
     95     alSourcef(source1[0], AL_CONE_OUTER_ANGLE, 150.f);
     96     if ((alGetError()) != AL_NO_ERROR)std::cout << "AL_CONE_OUTER_ANGLE error" << std::endl;
     97 
     98     //set current listener position
     99     alListener3f(AL_POSITION, -1.f,0.f,0.f);
    100     //-1.f,0.f,1.f 监听者在左,右耳音量较大
    101     //1.f,0.f,1.f 监听者在右,左耳音量较大
    102     //0.f,0.f,-1.f 监听者在后,在外角之外,声音为原来的AL_CONE_OUTER_GAIN倍,好像还要乘以AL_MIN_GAIN系数
    103 
    104     //set current listener orientation
    105     ALfloat orivec[] = { 0.0f, 0.0f, -1.0f, 0.0f, 1.0f, 0.0f };
    106     alListenerfv(AL_ORIENTATION, orivec);
    107     //设置好listener位置
    108     //////////////////////////////////////////////////////////////////////////
    109 
    110     //tell the sound to loop continuously  
    111     alSourcei(source1[0], AL_LOOPING, AL_TRUE);
    112     
    113     //play the sound  
    114     alSourcePlay(source1[0]);//have its state changed to AL_PLAYING,重新播放
    115 
    116     ALfloat gain,outer_gain,min_gain,max_gain,max_distance; 
    117     alGetSourcef(source1[0], AL_GAIN, &gain); std::cout << "AL_GAIN: " << gain << std::endl;
    118     alGetSourcef(source1[0], AL_CONE_OUTER_GAIN, &outer_gain); std::cout << "AL_CONE_OUTER_GAIN: " << outer_gain << std::endl;
    119     alGetSourcef(source1[0], AL_MIN_GAIN, &min_gain); std::cout << "AL_MIN_GAIN: " << min_gain << std::endl;
    120     alGetSourcef(source1[0], AL_MAX_GAIN, &max_gain); std::cout << "AL_MAX_GAIN: " << max_gain << std::endl;
    121     alGetSourcef(source1[0], AL_MAX_DISTANCE, &max_distance); std::cout << "AL_MAX_DISTANCE: " << max_distance << std::endl;
    122     std::cout << std::endl << "在音锥外角和最远衰减距离之外 gain * outer_gain * min_gain: " << gain*outer_gain*min_gain << std::endl;
    123     std::cout << std::endl;
    124 
    125     ALint sourceID;
    126     alGetSourcei(source1[0], AL_SOURCE_TYPE, &sourceID);
    127     std::cout << "AL_SOURCE_TYPE的ID: "<<sourceID << endl<<endl;
    128 
    129     ALint state;
    130     ALfloat tick = 0;
    131     ALfloat moveStart_posx = -2.f, moveStart_posy = 0.f, moveStart_posz = 0.f;
    132     do{
    133         std::cout << "playing......" << "";
    134 
    135         ////旋转音锥
    136         //float updatex = -sinf(play_it*PI / 180.f);
    137         //float upadtez = cosf(play_it*PI / 180.f);
    138         //alSource3f(source1, AL_DIRECTION, updatex, 0.f, upadtez);
    139         //if ((alGetError()) != AL_NO_ERROR)std::cout << "AL_POSITION error" << std::endl;
    140         //play_it=play_it+0.1f;
    141 
    142         ////平移声源
    143         //alSource3f(source1, AL_POSITION, moveStart_posx, moveStart_posy, moveStart_posz);
    144         //moveStart_posx = moveStart_posx + 0.00000011f; moveStart_posz = moveStart_posz + 0.00000015f;
    145 
    146         alGetSourcei(source1[0], AL_SOURCE_STATE, &state);
    147 
    148         //是否播第二个音频资源
    149         if (EnableSource2)
    150             alGetSourcei(source1[1], AL_SOURCE_STATE, &state);
    151 
    152         if (EnableSource3)
    153             alGetSourcei(source1[2], AL_SOURCE_STATE, &state);
    154 
    155     } while (state == AL_PLAYING || state==AL_PAUSED);//结束时state自动变成AL_STOPPED,source1、2共享一个state
    156 
    157     // To stop the sound  
    158     alSourceStop(source1[0]);
    159     //delete our source  
    160     alDeleteSources(1, &source1[0]);
    161     ////delete our buffer  
    162     alDeleteBuffers(1, &buffer1);
    163     if ((alGetError()) != AL_NO_ERROR)std::cout << "delete buffer1 error " << std::endl;
    164 
    165     if (EnableSource2){
    166         alSourceStop(source1[1]);
    167         alDeleteBuffers(1, &buffer2);
    168         if ((alGetError()) != AL_NO_ERROR)std::cout << "delete buffer2 error" << std::endl;
    169         alDeleteSources(1, &source1[1]);
    170         if ((alGetError()) != AL_NO_ERROR)std::cout << "delete source error" << std::endl;
    171     }
    172 }
  • 相关阅读:
    xcode调试技巧
    iOS应用崩溃日志揭秘(二)
    iOS应用崩溃日志揭秘(一)
    排序算法
    Java中的Reference
    windows环境中mysql数据库重置root用户密码
    了解浮点数的编码形式
    读《深入理解计算机系统》Chapter1
    枚举学习
    Charles抓包工具在mac上配置
  • 原文地址:https://www.cnblogs.com/zeppelin5/p/10019395.html
Copyright © 2011-2022 走看看