Don't try to use the non-standard alloca.h
[openal-soft.git] / examples / allatency.c
blobdeb13d3b05d8d75dc2416b956c02fa7e6713d3f9
1 /*
2 * OpenAL Source Latency Example
4 * Copyright (c) 2012 by Chris Robinson <chris.kcat@gmail.com>
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:
13 * The above copyright notice and this permission notice shall be included in
14 * all copies or substantial portions of the Software.
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.
25 /* This file contains an example for checking the latency of a sound. */
27 #include <stdio.h>
28 #include <assert.h>
30 #include "AL/al.h"
31 #include "AL/alc.h"
32 #include "AL/alext.h"
34 #include "common/alhelpers.h"
35 #include "common/sdl_sound.h"
38 static LPALBUFFERSAMPLESSOFT alBufferSamplesSOFT = wrap_BufferSamples;
39 static LPALISBUFFERFORMATSUPPORTEDSOFT alIsBufferFormatSupportedSOFT;
41 static LPALSOURCEDSOFT alSourcedSOFT;
42 static LPALSOURCE3DSOFT alSource3dSOFT;
43 static LPALSOURCEDVSOFT alSourcedvSOFT;
44 static LPALGETSOURCEDSOFT alGetSourcedSOFT;
45 static LPALGETSOURCE3DSOFT alGetSource3dSOFT;
46 static LPALGETSOURCEDVSOFT alGetSourcedvSOFT;
47 static LPALSOURCEI64SOFT alSourcei64SOFT;
48 static LPALSOURCE3I64SOFT alSource3i64SOFT;
49 static LPALSOURCEI64VSOFT alSourcei64vSOFT;
50 static LPALGETSOURCEI64SOFT alGetSourcei64SOFT;
51 static LPALGETSOURCE3I64SOFT alGetSource3i64SOFT;
52 static LPALGETSOURCEI64VSOFT alGetSourcei64vSOFT;
54 /* LoadBuffer loads the named audio file into an OpenAL buffer object, and
55 * returns the new buffer ID. */
56 static ALuint LoadSound(const char *filename)
58 ALenum err, format, type, channels;
59 ALuint rate, buffer;
60 size_t datalen;
61 void *data;
62 FilePtr sound;
64 /* Open the audio file */
65 sound = openAudioFile(filename, 1000);
66 if(!sound)
68 fprintf(stderr, "Could not open audio in %s\n", filename);
69 closeAudioFile(sound);
70 return 0;
73 /* Get the sound format, and figure out the OpenAL format */
74 if(getAudioInfo(sound, &rate, &channels, &type) != 0)
76 fprintf(stderr, "Error getting audio info for %s\n", filename);
77 closeAudioFile(sound);
78 return 0;
81 format = GetFormat(channels, type, alIsBufferFormatSupportedSOFT);
82 if(format == AL_NONE)
84 fprintf(stderr, "Unsupported format (%s, %s) for %s\n",
85 ChannelsName(channels), TypeName(type), filename);
86 closeAudioFile(sound);
87 return 0;
90 /* Decode the whole audio stream to a buffer. */
91 data = decodeAudioStream(sound, &datalen);
92 if(!data)
94 fprintf(stderr, "Failed to read audio from %s\n", filename);
95 closeAudioFile(sound);
96 return 0;
99 /* Buffer the audio data into a new buffer object, then free the data and
100 * close the file. */
101 buffer = 0;
102 alGenBuffers(1, &buffer);
103 alBufferSamplesSOFT(buffer, rate, format, BytesToFrames(datalen, channels, type),
104 channels, type, data);
105 free(data);
106 closeAudioFile(sound);
108 /* Check if an error occured, and clean up if so. */
109 err = alGetError();
110 if(err != AL_NO_ERROR)
112 fprintf(stderr, "OpenAL Error: %s\n", alGetString(err));
113 if(alIsBuffer(buffer))
114 alDeleteBuffers(1, &buffer);
115 return 0;
118 return buffer;
122 int main(int argc, char **argv)
124 ALuint source, buffer;
125 ALdouble offsets[2];
126 ALenum state;
128 /* Print out usage if no file was specified */
129 if(argc < 2)
131 fprintf(stderr, "Usage: %s <filename>\n", argv[0]);
132 return 1;
135 /* Initialize OpenAL with the default device, and check for EFX support. */
136 if(InitAL() != 0)
137 return 1;
139 if(!alIsExtensionPresent("AL_SOFT_source_latency"))
141 fprintf(stderr, "Error: AL_SOFT_source_latency not supported\n");
142 CloseAL();
143 return 1;
146 /* Define a macro to help load the function pointers. */
147 #define LOAD_PROC(x) ((x) = alGetProcAddress(#x))
148 LOAD_PROC(alSourcedSOFT);
149 LOAD_PROC(alSource3dSOFT);
150 LOAD_PROC(alSourcedvSOFT);
151 LOAD_PROC(alGetSourcedSOFT);
152 LOAD_PROC(alGetSource3dSOFT);
153 LOAD_PROC(alGetSourcedvSOFT);
154 LOAD_PROC(alSourcei64SOFT);
155 LOAD_PROC(alSource3i64SOFT);
156 LOAD_PROC(alSourcei64vSOFT);
157 LOAD_PROC(alGetSourcei64SOFT);
158 LOAD_PROC(alGetSource3i64SOFT);
159 LOAD_PROC(alGetSourcei64vSOFT);
161 if(alIsExtensionPresent("AL_SOFT_buffer_samples"))
163 LOAD_PROC(alBufferSamplesSOFT);
164 LOAD_PROC(alIsBufferFormatSupportedSOFT);
166 #undef LOAD_PROC
168 /* Load the sound into a buffer. */
169 buffer = LoadSound(argv[1]);
170 if(!buffer)
172 CloseAL();
173 return 1;
176 /* Create the source to play the sound with. */
177 source = 0;
178 alGenSources(1, &source);
179 alSourcei(source, AL_BUFFER, buffer);
180 assert(alGetError()==AL_NO_ERROR && "Failed to setup sound source");
182 /* Play the sound until it finishes. */
183 alSourcePlay(source);
184 do {
185 Sleep(10);
186 alGetSourcei(source, AL_SOURCE_STATE, &state);
188 /* Get the source offset and latency. AL_SEC_OFFSET_LATENCY_SOFT will
189 * place the offset (in seconds) in offsets[0], and the time until that
190 * offset will be heard (in seconds) in offsets[1]. */
191 alGetSourcedvSOFT(source, AL_SEC_OFFSET_LATENCY_SOFT, offsets);
192 printf("\rOffset: %f - Latency:%3u ms ", offsets[0], (ALuint)(offsets[1]*1000));
193 fflush(stdout);
194 } while(alGetError() == AL_NO_ERROR && state == AL_PLAYING);
195 printf("\n");
197 /* All done. Delete resources, and close OpenAL. */
198 alDeleteSources(1, &source);
199 alDeleteBuffers(1, &buffer);
201 CloseAL();
203 return 0;