每羊杨

https://github.com/Zeppelin5 (Kinfu讨论群:563741937)

导航

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 "\n");    \
 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......" << "\b\b\b\b\b\b\b\b\b\b\b\b\b";
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 }

 

posted on 2018-11-26 11:31  每羊杨  阅读(1282)  评论(0编辑  收藏  举报