zenilib  0.5.3.0
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Groups Pages
alreverb.c
Go to the documentation of this file.
1 /*
2  * OpenAL Reverb Example
3  *
4  * Copyright (c) 2012 by Chris Robinson <chris.kcat@gmail.com>
5  *
6  * Permission is hereby granted, free of charge, to any person obtaining a copy
7  * of this software and associated documentation files (the "Software"), to deal
8  * in the Software without restriction, including without limitation the rights
9  * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10  * copies of the Software, and to permit persons to whom the Software is
11  * furnished to do so, subject to the following conditions:
12  *
13  * The above copyright notice and this permission notice shall be included in
14  * all copies or substantial portions of the Software.
15  *
16  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19  * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22  * THE SOFTWARE.
23  */
24 
25 /* This file contains an example for applying reverb to a sound. */
26 
27 #include <stdio.h>
28 #include <assert.h>
29 #ifdef _WIN32
30 #define WIN32_LEAN_AND_MEAN
31 #include <windows.h>
32 #else
33 #include <unistd.h>
34 #define Sleep(x) usleep((x)*1000)
35 #endif
36 
37 #include "AL/al.h"
38 #include "AL/alc.h"
39 #include "AL/alext.h"
40 #include "AL/efx-presets.h"
41 
42 #include "common/alhelpers.h"
43 #include "common/alffmpeg.h"
44 
45 
48 
49 /* Effect object functions */
61 
62 /* Auxiliary Effect Slot object functions */
74 
75 
76 /* LoadEffect loads the given reverb properties into a new OpenAL effect
77  * object, and returns the new effect ID. */
79 {
80  ALuint effect = 0;
81  ALenum err;
82 
83  /* Create the effect object and check if we can do EAX reverb. */
84  alGenEffects(1, &effect);
85  if(alGetEnumValue("AL_EFFECT_EAXREVERB") != 0)
86  {
87  printf("Using EAX Reverb\n");
88 
89  /* EAX Reverb is available. Set the EAX effect type then load the
90  * reverb properties. */
92 
93  alEffectf(effect, AL_EAXREVERB_DENSITY, reverb->flDensity);
95  alEffectf(effect, AL_EAXREVERB_GAIN, reverb->flGain);
96  alEffectf(effect, AL_EAXREVERB_GAINHF, reverb->flGainHF);
97  alEffectf(effect, AL_EAXREVERB_GAINLF, reverb->flGainLF);
107  alEffectf(effect, AL_EAXREVERB_ECHO_TIME, reverb->flEchoTime);
116  }
117  else
118  {
119  printf("Using Standard Reverb\n");
120 
121  /* No EAX Reverb. Set the standard reverb effect type then load the
122  * available reverb properties. */
124 
125  alEffectf(effect, AL_REVERB_DENSITY, reverb->flDensity);
126  alEffectf(effect, AL_REVERB_DIFFUSION, reverb->flDiffusion);
127  alEffectf(effect, AL_REVERB_GAIN, reverb->flGain);
128  alEffectf(effect, AL_REVERB_GAINHF, reverb->flGainHF);
129  alEffectf(effect, AL_REVERB_DECAY_TIME, reverb->flDecayTime);
138  }
139 
140  /* Check if an error occured, and clean up if so. */
141  err = alGetError();
142  if(err != AL_NO_ERROR)
143  {
144  fprintf(stderr, "OpenAL error: %s\n", alGetString(err));
145  if(alIsEffect(effect))
146  alDeleteEffects(1, &effect);
147  return 0;
148  }
149 
150  return effect;
151 }
152 
153 
154 /* LoadBuffer loads the named audio file into an OpenAL buffer object, and
155  * returns the new buffer ID. */
156 static ALuint LoadSound(const char *filename)
157 {
158  ALenum err, format, type, channels;
159  ALuint rate, buffer;
160  size_t datalen;
161  void *data;
162  FilePtr audiofile;
163  StreamPtr sound;
164 
165  /* Open the file and get the first stream from it */
166  audiofile = openAVFile(filename);
167  sound = getAVAudioStream(audiofile, 0);
168  if(!sound)
169  {
170  fprintf(stderr, "Could not open audio in %s\n", filename);
171  closeAVFile(audiofile);
172  return 0;
173  }
174 
175  /* Get the sound format, and figure out the OpenAL format */
176  if(getAVAudioInfo(sound, &rate, &channels, &type) != 0)
177  {
178  fprintf(stderr, "Error getting audio info for %s\n", filename);
179  closeAVFile(audiofile);
180  return 0;
181  }
182 
183  format = GetFormat(channels, type, alIsBufferFormatSupportedSOFT);
184  if(format == AL_NONE)
185  {
186  fprintf(stderr, "Unsupported format (%s, %s) for %s\n",
187  ChannelsName(channels), TypeName(type), filename);
188  closeAVFile(audiofile);
189  return 0;
190  }
191 
192  /* Decode the whole audio stream to a buffer. */
193  data = decodeAVAudioStream(sound, &datalen);
194  if(!data)
195  {
196  fprintf(stderr, "Failed to read audio from %s\n", filename);
197  closeAVFile(audiofile);
198  return 0;
199  }
200 
201  /* Buffer the audio data into a new buffer object, then free the data and
202  * close the file. */
203  buffer = 0;
204  alGenBuffers(1, &buffer);
205  alBufferSamplesSOFT(buffer, rate, format, BytesToFrames(datalen, channels, type),
206  channels, type, data);
207  free(data);
208  closeAVFile(audiofile);
209 
210  /* Check if an error occured, and clean up if so. */
211  err = alGetError();
212  if(err != AL_NO_ERROR)
213  {
214  fprintf(stderr, "OpenAL Error: %s\n", alGetString(err));
215  if(alIsBuffer(buffer))
216  alDeleteBuffers(1, &buffer);
217  return 0;
218  }
219 
220  return buffer;
221 }
222 
223 
224 int main(int argc, char **argv)
225 {
227  ALuint source, buffer, effect, slot;
228  ALenum state;
229 
230  /* Print out usage if no file was specified */
231  if(argc < 2)
232  {
233  fprintf(stderr, "Usage: %s <filename>\n", argv[0]);
234  return 1;
235  }
236 
237  /* Initialize OpenAL with the default device, and check for EFX support. */
238  if(InitAL() != 0)
239  return 1;
240 
242  {
243  fprintf(stderr, "Error: EFX not supported\n");
244  CloseAL();
245  return 1;
246  }
247 
248  /* Define a macro to help load the function pointers. */
249 #define LOAD_PROC(x) ((x) = alGetProcAddress(#x))
261 
273 
274  if(alIsExtensionPresent("AL_SOFT_buffer_samples"))
275  {
278  }
279 #undef LOAD_PROC
280 
281  /* Load the sound into a buffer. */
282  buffer = LoadSound(argv[1]);
283  if(!buffer)
284  {
285  CloseAL();
286  return 1;
287  }
288 
289  /* Load the reverb into an effect. */
290  effect = LoadEffect(&reverb);
291  if(!effect)
292  {
293  alDeleteBuffers(1, &buffer);
294  CloseAL();
295  return 1;
296  }
297 
298  /* Create the effect slot object. This is what "plays" an effect on sources
299  * that connect to it. */
300  slot = 0;
301  alGenAuxiliaryEffectSlots(1, &slot);
302 
303  /* Tell the effect slot to use the loaded effect object. Note that the this
304  * effectively copies the effect properties. You can modify or delete the
305  * effect object afterward without affecting the effect slot.
306  */
308  assert(alGetError()==AL_NO_ERROR && "Failed to set effect slot");
309 
310  /* Create the source to play the sound with. */
311  source = 0;
312  alGenSources(1, &source);
313  alSourcei(source, AL_BUFFER, buffer);
314 
315  /* Connect the source to the effect slot. This tells the source to use the
316  * effect slot 'slot', on send #0 with the AL_FILTER_NULL filter object.
317  */
319  assert(alGetError()==AL_NO_ERROR && "Failed to setup sound source");
320 
321  /* Play the sound until it finishes. */
322  alSourcePlay(source);
323  do {
324  Sleep(10);
325  alGetSourcei(source, AL_SOURCE_STATE, &state);
326  } while(alGetError() == AL_NO_ERROR && state == AL_PLAYING);
327 
328  /* All done. Delete resources, and close OpenAL. */
329  alDeleteSources(1, &source);
331  alDeleteEffects(1, &effect);
332  alDeleteBuffers(1, &buffer);
333 
334  CloseAL();
335 
336  return 0;
337 }
AL_API void AL_APIENTRY alSourcePlay(ALuint source)
Definition: alSource.c:1894
#define AL_EAXREVERB_LATE_REVERB_DELAY
Definition: efx.h:63
#define AL_EAXREVERB_LATE_REVERB_GAIN
Definition: efx.h:62
AL_API void AL_APIENTRY alSource3i(ALuint source, ALenum param, ALint value1, ALint value2, ALint value3)
Definition: alSource.c:1499
#define AL_REVERB_GAIN
Definition: efx.h:38
#define AL_EFFECT_TYPE
Definition: efx.h:151
LPALBUFFERSAMPLESSOFT alBufferSamplesSOFT
Definition: allatency.c:45
struct MyFile * FilePtr
Definition: alffmpeg.h:13
void(AL_APIENTRY * LPALGETAUXILIARYEFFECTSLOTFV)(ALuint, ALenum, ALfloat *)
Definition: efx.h:242
LPALGETAUXILIARYEFFECTSLOTF alGetAuxiliaryEffectSlotf
Definition: alreverb.c:72
#define AL_REVERB_REFLECTIONS_GAIN
Definition: efx.h:42
#define AL_NONE
Definition: al.h:80
#define AL_EAXREVERB_DIFFUSION
Definition: efx.h:52
GLint GLenum GLsizei GLsizei GLsizei GLint GLenum GLenum type
Definition: gl2ext.h:845
int main(int argc, char **argv)
Definition: bootstrap.cpp:102
FilePtr openAVFile(const char *fname)
Definition: alffmpeg.c:161
LPALDELETEAUXILIARYEFFECTSLOTS alDeleteAuxiliaryEffectSlots
Definition: alreverb.c:64
#define AL_REVERB_LATE_REVERB_DELAY
Definition: efx.h:45
void(AL_APIENTRY * LPALAUXILIARYEFFECTSLOTIV)(ALuint, ALenum, const ALint *)
Definition: efx.h:236
void(AL_APIENTRY * LPALGENAUXILIARYEFFECTSLOTS)(ALsizei, ALuint *)
Definition: efx.h:232
#define AL_EAXREVERB_ECHO_TIME
Definition: efx.h:65
#define AL_EAXREVERB_REFLECTIONS_DELAY
Definition: efx.h:60
void CloseAL(void)
Definition: alhelpers.c:71
void(AL_APIENTRY * LPALGETAUXILIARYEFFECTSLOTIV)(ALuint, ALenum, ALint *)
Definition: efx.h:240
void(AL_APIENTRY * LPALEFFECTIV)(ALuint, ALenum, const ALint *)
Definition: efx.h:210
void * decodeAVAudioStream(StreamPtr stream, size_t *length)
Definition: alffmpeg.c:611
AL_API ALenum AL_APIENTRY alGetError(void)
Definition: alError.c:46
LPALISEFFECT alIsEffect
Definition: alreverb.c:52
LPALAUXILIARYEFFECTSLOTF alAuxiliaryEffectSlotf
Definition: alreverb.c:68
SDL_EventEntry * free
Definition: SDL_events.c:80
#define AL_EAXREVERB_DECAY_HFRATIO
Definition: efx.h:57
#define AL_REVERB_DECAY_HFRATIO
Definition: efx.h:41
AL_API void AL_APIENTRY alGetSourcei(ALuint source, ALenum param, ALint *value)
Definition: alSource.c:1754
#define AL_EAXREVERB_HFREFERENCE
Definition: efx.h:70
#define AL_EAXREVERB_MODULATION_DEPTH
Definition: efx.h:68
#define AL_REVERB_GAINHF
Definition: efx.h:39
#define AL_SOURCE_STATE
Definition: al.h:235
LPALGETAUXILIARYEFFECTSLOTIV alGetAuxiliaryEffectSlotiv
Definition: alreverb.c:71
LPALGETAUXILIARYEFFECTSLOTI alGetAuxiliaryEffectSloti
Definition: alreverb.c:70
void AL_APIENTRY wrap_BufferSamples(ALuint buffer, ALuint samplerate, ALenum internalformat, ALsizei samples, ALenum channels, ALenum type, const ALvoid *data)
Definition: alhelpers.c:253
#define AL_REVERB_DECAY_TIME
Definition: efx.h:40
LPALGETEFFECTI alGetEffecti
Definition: alreverb.c:57
#define assert(x)
Definition: SDL_malloc.c:1234
LPALGETEFFECTF alGetEffectf
Definition: alreverb.c:59
#define AL_EAXREVERB_LATE_REVERB_PAN
Definition: efx.h:64
AL_API void AL_APIENTRY alGenSources(ALsizei n, ALuint *sources)
Definition: alSource.c:1216
#define AL_REVERB_AIR_ABSORPTION_GAINHF
Definition: efx.h:46
StreamPtr getAVAudioStream(FilePtr file, int streamnum)
Definition: alffmpeg.c:318
AL_API ALenum AL_APIENTRY alGetEnumValue(const ALchar *ename)
Definition: alExtension.c:95
#define AL_EFFECTSLOT_EFFECT
Definition: efx.h:170
#define AL_REVERB_DECAY_HFLIMIT
Definition: efx.h:48
#define Sleep(x)
Definition: allatency.c:34
#define AL_EAXREVERB_REFLECTIONS_GAIN
Definition: efx.h:59
void(AL_APIENTRY * LPALEFFECTI)(ALuint, ALenum, ALint)
Definition: efx.h:209
ALboolean(AL_APIENTRY * LPALISBUFFERFORMATSUPPORTEDSOFT)(ALenum)
Definition: alext.h:261
ALC_API ALCcontext *ALC_APIENTRY alcGetCurrentContext(void)
Definition: ALc.c:2563
void(AL_APIENTRY * LPALEFFECTF)(ALuint, ALenum, ALfloat)
Definition: efx.h:211
EGLContext EGLenum EGLClientBuffer buffer
Definition: eglext.h:87
LPALEFFECTF alEffectf
Definition: alreverb.c:55
#define AL_REVERB_DIFFUSION
Definition: efx.h:37
#define AL_FILTER_NULL
Definition: efx.h:199
const char * TypeName(ALenum type)
Definition: alhelpers.c:279
void(AL_APIENTRY * LPALGETAUXILIARYEFFECTSLOTF)(ALuint, ALenum, ALfloat *)
Definition: efx.h:241
#define AL_REVERB_REFLECTIONS_DELAY
Definition: efx.h:43
void(AL_APIENTRY * LPALBUFFERSAMPLESSOFT)(ALuint, ALuint, ALenum, ALsizei, ALenum, ALenum, const ALvoid *)
Definition: alext.h:258
void(AL_APIENTRY * LPALGETAUXILIARYEFFECTSLOTI)(ALuint, ALenum, ALint *)
Definition: efx.h:239
void(AL_APIENTRY * LPALGETEFFECTFV)(ALuint, ALenum, ALfloat *)
Definition: efx.h:216
#define AL_PLAYING
Definition: al.h:239
static ALuint LoadEffect(const EFXEAXREVERBPROPERTIES *reverb)
Definition: alreverb.c:78
void(AL_APIENTRY * LPALDELETEAUXILIARYEFFECTSLOTS)(ALsizei, const ALuint *)
Definition: efx.h:233
GLint GLenum GLsizei GLsizei GLsizei GLint GLsizei const GLvoid * data
Definition: gl2ext.h:848
#define AL_EFFECT_REVERB
Definition: efx.h:155
#define AL_EAXREVERB_MODULATION_TIME
Definition: efx.h:67
struct MyStream * StreamPtr
Definition: alffmpeg.h:14
LPALGETAUXILIARYEFFECTSLOTFV alGetAuxiliaryEffectSlotfv
Definition: alreverb.c:73
void(AL_APIENTRY * LPALEFFECTFV)(ALuint, ALenum, const ALfloat *)
Definition: efx.h:212
#define AL_REVERB_DENSITY
Definition: efx.h:36
#define AL_EAXREVERB_GAIN
Definition: efx.h:53
int ALenum
Definition: al.h:65
LPALGETEFFECTIV alGetEffectiv
Definition: alreverb.c:58
GLint GLenum GLsizei GLsizei GLsizei GLint GLenum format
Definition: gl2ext.h:845
unsigned int ALuint
Definition: al.h:59
AL_API void AL_APIENTRY alGenBuffers(ALsizei n, ALuint *buffers)
Definition: alBuffer.c:183
#define AL_BUFFER
Definition: al.h:182
#define LOAD_PROC(x)
#define AL_EAXREVERB_GAINHF
Definition: efx.h:54
static ALuint LoadSound(const char *filename)
Definition: alreverb.c:156
#define AL_EAXREVERB_DECAY_LFRATIO
Definition: efx.h:58
ALsizei BytesToFrames(ALsizei size, ALenum channels, ALenum type)
Definition: alhelpers.c:324
void(AL_APIENTRY * LPALDELETEEFFECTS)(ALsizei, const ALuint *)
Definition: efx.h:207
#define AL_EAXREVERB_ROOM_ROLLOFF_FACTOR
Definition: efx.h:72
#define AL_EAXREVERB_DECAY_TIME
Definition: efx.h:56
#define AL_EAXREVERB_AIR_ABSORPTION_GAINHF
Definition: efx.h:69
void(AL_APIENTRY * LPALGETEFFECTF)(ALuint, ALenum, ALfloat *)
Definition: efx.h:215
#define AL_EAXREVERB_DECAY_HFLIMIT
Definition: efx.h:73
ALC_API ALCdevice *ALC_APIENTRY alcGetContextsDevice(ALCcontext *Context)
Definition: ALc.c:2638
ALenum GetFormat(ALenum channels, ALenum type, LPALISBUFFERFORMATSUPPORTEDSOFT palIsBufferFormatSupportedSOFT)
Definition: alhelpers.c:93
ALboolean(AL_APIENTRY * LPALISEFFECT)(ALuint)
Definition: efx.h:208
#define AL_EAXREVERB_DENSITY
Definition: efx.h:51
LPALAUXILIARYEFFECTSLOTI alAuxiliaryEffectSloti
Definition: alreverb.c:66
#define AL_EAXREVERB_REFLECTIONS_PAN
Definition: efx.h:61
const char * ChannelsName(ALenum chans)
Definition: alhelpers.c:264
void(AL_APIENTRY * LPALAUXILIARYEFFECTSLOTF)(ALuint, ALenum, ALfloat)
Definition: efx.h:237
AL_API ALboolean AL_APIENTRY alIsExtensionPresent(const ALchar *extname)
Definition: alExtension.c:49
AL_API const ALchar *AL_APIENTRY alGetString(ALenum param)
Definition: alState.c:437
LPALAUXILIARYEFFECTSLOTFV alAuxiliaryEffectSlotfv
Definition: alreverb.c:69
#define AL_REVERB_LATE_REVERB_GAIN
Definition: efx.h:44
void(AL_APIENTRY * LPALAUXILIARYEFFECTSLOTI)(ALuint, ALenum, ALint)
Definition: efx.h:235
void(AL_APIENTRY * LPALAUXILIARYEFFECTSLOTFV)(ALuint, ALenum, const ALfloat *)
Definition: efx.h:238
int InitAL(void)
Definition: alhelpers.c:42
#define EFX_REVERB_PRESET_GENERIC
Definition: efx-presets.h:37
#define AL_EAXREVERB_LFREFERENCE
Definition: efx.h:71
LPALEFFECTIV alEffectiv
Definition: alreverb.c:54
LPALGENEFFECTS alGenEffects
Definition: alreverb.c:50
#define AL_EAXREVERB_GAINLF
Definition: efx.h:55
ALboolean(AL_APIENTRY * LPALISAUXILIARYEFFECTSLOT)(ALuint)
Definition: efx.h:234
void(AL_APIENTRY * LPALGENEFFECTS)(ALsizei, ALuint *)
Definition: efx.h:206
LPALGETEFFECTFV alGetEffectfv
Definition: alreverb.c:60
AL_API void AL_APIENTRY alDeleteBuffers(ALsizei n, const ALuint *buffers)
Definition: alBuffer.c:229
void closeAVFile(FilePtr file)
Definition: alffmpeg.c:271
#define AL_EFFECT_EAXREVERB
Definition: efx.h:167
LPALEFFECTI alEffecti
Definition: alreverb.c:53
AL_API void AL_APIENTRY alSourcei(ALuint source, ALenum param, ALint value)
Definition: alSource.c:1481
int getAVAudioInfo(StreamPtr stream, ALuint *rate, ALenum *channels, ALenum *type)
Definition: alffmpeg.c:392
GLsizei GLsizei GLchar * source
Definition: gl2ext.h:994
LPALAUXILIARYEFFECTSLOTIV alAuxiliaryEffectSlotiv
Definition: alreverb.c:67
#define AL_EAXREVERB_ECHO_DEPTH
Definition: efx.h:66
LPALGENAUXILIARYEFFECTSLOTS alGenAuxiliaryEffectSlots
Definition: alreverb.c:63
void(AL_APIENTRY * LPALGETEFFECTI)(ALuint, ALenum, ALint *)
Definition: efx.h:213
LPALEFFECTFV alEffectfv
Definition: alreverb.c:56
#define AL_NO_ERROR
Definition: al.h:364
#define AL_REVERB_ROOM_ROLLOFF_FACTOR
Definition: efx.h:47
ALC_API ALCboolean ALC_APIENTRY alcIsExtensionPresent(ALCdevice *device, const ALCchar *extName)
Definition: ALc.c:2373
#define AL_AUXILIARY_SEND_FILTER
Definition: efx.h:24
LPALISBUFFERFORMATSUPPORTEDSOFT alIsBufferFormatSupportedSOFT
Definition: allatency.c:46
LPALDELETEEFFECTS alDeleteEffects
Definition: alreverb.c:51
void(AL_APIENTRY * LPALGETEFFECTIV)(ALuint, ALenum, ALint *)
Definition: efx.h:214
AL_API ALboolean AL_APIENTRY alIsBuffer(ALuint buffer)
Definition: alBuffer.c:272
AL_API void AL_APIENTRY alDeleteSources(ALsizei n, const ALuint *sources)
Definition: alSource.c:1262
LPALISAUXILIARYEFFECTSLOT alIsAuxiliaryEffectSlot
Definition: alreverb.c:65