Improve gain/hf/lf packing when processing voice updates
[openal-soft.git] / examples / allatency.c
bloba61fb8209356dce7baf5ced07df4b0ec37d03672
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 "SDL_sound.h"
31 #include "SDL_audio.h"
32 #include "SDL_stdinc.h"
34 #include "AL/al.h"
35 #include "AL/alext.h"
37 #include "common/alhelpers.h"
40 static LPALSOURCEDSOFT alSourcedSOFT;
41 static LPALSOURCE3DSOFT alSource3dSOFT;
42 static LPALSOURCEDVSOFT alSourcedvSOFT;
43 static LPALGETSOURCEDSOFT alGetSourcedSOFT;
44 static LPALGETSOURCE3DSOFT alGetSource3dSOFT;
45 static LPALGETSOURCEDVSOFT alGetSourcedvSOFT;
46 static LPALSOURCEI64SOFT alSourcei64SOFT;
47 static LPALSOURCE3I64SOFT alSource3i64SOFT;
48 static LPALSOURCEI64VSOFT alSourcei64vSOFT;
49 static LPALGETSOURCEI64SOFT alGetSourcei64SOFT;
50 static LPALGETSOURCE3I64SOFT alGetSource3i64SOFT;
51 static LPALGETSOURCEI64VSOFT alGetSourcei64vSOFT;
53 /* LoadBuffer loads the named audio file into an OpenAL buffer object, and
54 * returns the new buffer ID.
56 static ALuint LoadSound(const char *filename)
58 Sound_Sample *sample;
59 ALenum err, format;
60 ALuint buffer;
61 Uint32 slen;
63 /* Open the audio file */
64 sample = Sound_NewSampleFromFile(filename, NULL, 65536);
65 if(!sample)
67 fprintf(stderr, "Could not open audio in %s\n", filename);
68 return 0;
71 /* Get the sound format, and figure out the OpenAL format */
72 if(sample->actual.channels == 1)
74 if(sample->actual.format == AUDIO_U8)
75 format = AL_FORMAT_MONO8;
76 else if(sample->actual.format == AUDIO_S16SYS)
77 format = AL_FORMAT_MONO16;
78 else
80 fprintf(stderr, "Unsupported sample format: 0x%04x\n", sample->actual.format);
81 Sound_FreeSample(sample);
82 return 0;
85 else if(sample->actual.channels == 2)
87 if(sample->actual.format == AUDIO_U8)
88 format = AL_FORMAT_STEREO8;
89 else if(sample->actual.format == AUDIO_S16SYS)
90 format = AL_FORMAT_STEREO16;
91 else
93 fprintf(stderr, "Unsupported sample format: 0x%04x\n", sample->actual.format);
94 Sound_FreeSample(sample);
95 return 0;
98 else
100 fprintf(stderr, "Unsupported channel count: %d\n", sample->actual.channels);
101 Sound_FreeSample(sample);
102 return 0;
105 /* Decode the whole audio stream to a buffer. */
106 slen = Sound_DecodeAll(sample);
107 if(!sample->buffer || slen == 0)
109 fprintf(stderr, "Failed to read audio from %s\n", filename);
110 Sound_FreeSample(sample);
111 return 0;
114 /* Buffer the audio data into a new buffer object, then free the data and
115 * close the file. */
116 buffer = 0;
117 alGenBuffers(1, &buffer);
118 alBufferData(buffer, format, sample->buffer, (ALsizei)slen, (ALsizei)sample->actual.rate);
119 Sound_FreeSample(sample);
121 /* Check if an error occured, and clean up if so. */
122 err = alGetError();
123 if(err != AL_NO_ERROR)
125 fprintf(stderr, "OpenAL Error: %s\n", alGetString(err));
126 if(buffer && alIsBuffer(buffer))
127 alDeleteBuffers(1, &buffer);
128 return 0;
131 return buffer;
135 int main(int argc, char **argv)
137 ALuint source, buffer;
138 ALdouble offsets[2];
139 ALenum state;
141 /* Print out usage if no arguments were specified */
142 if(argc < 2)
144 fprintf(stderr, "Usage: %s [-device <name>] <filename>\n", argv[0]);
145 return 1;
148 /* Initialize OpenAL, and check for source_latency support. */
149 argv++; argc--;
150 if(InitAL(&argv, &argc) != 0)
151 return 1;
153 if(!alIsExtensionPresent("AL_SOFT_source_latency"))
155 fprintf(stderr, "Error: AL_SOFT_source_latency not supported\n");
156 CloseAL();
157 return 1;
160 /* Define a macro to help load the function pointers. */
161 #define LOAD_PROC(T, x) ((x) = (T)alGetProcAddress(#x))
162 LOAD_PROC(LPALSOURCEDSOFT, alSourcedSOFT);
163 LOAD_PROC(LPALSOURCE3DSOFT, alSource3dSOFT);
164 LOAD_PROC(LPALSOURCEDVSOFT, alSourcedvSOFT);
165 LOAD_PROC(LPALGETSOURCEDSOFT, alGetSourcedSOFT);
166 LOAD_PROC(LPALGETSOURCE3DSOFT, alGetSource3dSOFT);
167 LOAD_PROC(LPALGETSOURCEDVSOFT, alGetSourcedvSOFT);
168 LOAD_PROC(LPALSOURCEI64SOFT, alSourcei64SOFT);
169 LOAD_PROC(LPALSOURCE3I64SOFT, alSource3i64SOFT);
170 LOAD_PROC(LPALSOURCEI64VSOFT, alSourcei64vSOFT);
171 LOAD_PROC(LPALGETSOURCEI64SOFT, alGetSourcei64SOFT);
172 LOAD_PROC(LPALGETSOURCE3I64SOFT, alGetSource3i64SOFT);
173 LOAD_PROC(LPALGETSOURCEI64VSOFT, alGetSourcei64vSOFT);
174 #undef LOAD_PROC
176 /* Initialize SDL_sound. */
177 Sound_Init();
179 /* Load the sound into a buffer. */
180 buffer = LoadSound(argv[0]);
181 if(!buffer)
183 Sound_Quit();
184 CloseAL();
185 return 1;
188 /* Create the source to play the sound with. */
189 source = 0;
190 alGenSources(1, &source);
191 alSourcei(source, AL_BUFFER, (ALint)buffer);
192 assert(alGetError()==AL_NO_ERROR && "Failed to setup sound source");
194 /* Play the sound until it finishes. */
195 alSourcePlay(source);
196 do {
197 al_nssleep(10000000);
198 alGetSourcei(source, AL_SOURCE_STATE, &state);
200 /* Get the source offset and latency. AL_SEC_OFFSET_LATENCY_SOFT will
201 * place the offset (in seconds) in offsets[0], and the time until that
202 * offset will be heard (in seconds) in offsets[1]. */
203 alGetSourcedvSOFT(source, AL_SEC_OFFSET_LATENCY_SOFT, offsets);
204 printf("\rOffset: %f - Latency:%3u ms ", offsets[0], (ALuint)(offsets[1]*1000));
205 fflush(stdout);
206 } while(alGetError() == AL_NO_ERROR && state == AL_PLAYING);
207 printf("\n");
209 /* All done. Delete resources, and close down SDL_sound and OpenAL. */
210 alDeleteSources(1, &source);
211 alDeleteBuffers(1, &buffer);
213 Sound_Quit();
214 CloseAL();
216 return 0;