Mercurial > mplayer.hg
annotate libao2/ao_openal.c @ 34594:c20ac9b80ea5
Don't destroy list pointers while saving list items.
Use temporary pointers instead.
author | ib |
---|---|
date | Fri, 10 Feb 2012 15:06:59 +0000 |
parents | 32725ca88fed |
children |
rev | line source |
---|---|
27509
d97a607821f1
Replace casual GPL notices by proper license headers.
diego
parents:
25910
diff
changeset
|
1 /* |
d97a607821f1
Replace casual GPL notices by proper license headers.
diego
parents:
25910
diff
changeset
|
2 * OpenAL audio output driver for MPlayer |
17633
e0ef5688cce7
OpenAL audio support, actual output is mono-only (no positioning yet).
reimar
parents:
diff
changeset
|
3 * |
23734 | 4 * Copyleft 2006 by Reimar Döffinger (Reimar.Doeffinger@stud.uni-karlsruhe.de) |
27509
d97a607821f1
Replace casual GPL notices by proper license headers.
diego
parents:
25910
diff
changeset
|
5 * |
d97a607821f1
Replace casual GPL notices by proper license headers.
diego
parents:
25910
diff
changeset
|
6 * This file is part of MPlayer. |
d97a607821f1
Replace casual GPL notices by proper license headers.
diego
parents:
25910
diff
changeset
|
7 * |
d97a607821f1
Replace casual GPL notices by proper license headers.
diego
parents:
25910
diff
changeset
|
8 * MPlayer is free software; you can redistribute it and/or modify |
d97a607821f1
Replace casual GPL notices by proper license headers.
diego
parents:
25910
diff
changeset
|
9 * it under the terms of the GNU General Public License as published by |
d97a607821f1
Replace casual GPL notices by proper license headers.
diego
parents:
25910
diff
changeset
|
10 * the Free Software Foundation; either version 2 of the License, or |
d97a607821f1
Replace casual GPL notices by proper license headers.
diego
parents:
25910
diff
changeset
|
11 * (at your option) any later version. |
d97a607821f1
Replace casual GPL notices by proper license headers.
diego
parents:
25910
diff
changeset
|
12 * |
d97a607821f1
Replace casual GPL notices by proper license headers.
diego
parents:
25910
diff
changeset
|
13 * MPlayer is distributed in the hope that it will be useful, |
d97a607821f1
Replace casual GPL notices by proper license headers.
diego
parents:
25910
diff
changeset
|
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of |
d97a607821f1
Replace casual GPL notices by proper license headers.
diego
parents:
25910
diff
changeset
|
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
d97a607821f1
Replace casual GPL notices by proper license headers.
diego
parents:
25910
diff
changeset
|
16 * GNU General Public License for more details. |
d97a607821f1
Replace casual GPL notices by proper license headers.
diego
parents:
25910
diff
changeset
|
17 * |
d97a607821f1
Replace casual GPL notices by proper license headers.
diego
parents:
25910
diff
changeset
|
18 * You should have received a copy of the GNU General Public License along |
d97a607821f1
Replace casual GPL notices by proper license headers.
diego
parents:
25910
diff
changeset
|
19 * along with MPlayer; if not, write to the Free Software |
d97a607821f1
Replace casual GPL notices by proper license headers.
diego
parents:
25910
diff
changeset
|
20 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA |
17633
e0ef5688cce7
OpenAL audio support, actual output is mono-only (no positioning yet).
reimar
parents:
diff
changeset
|
21 */ |
e0ef5688cce7
OpenAL audio support, actual output is mono-only (no positioning yet).
reimar
parents:
diff
changeset
|
22 |
21556
283bff578e1c
Support OpenAL headers in OpenAL/ instead of AL/ and OpenAL on MacOSX in general.
reimar
parents:
21550
diff
changeset
|
23 #include "config.h" |
283bff578e1c
Support OpenAL headers in OpenAL/ instead of AL/ and OpenAL on MacOSX in general.
reimar
parents:
21550
diff
changeset
|
24 |
17644
87c049a38c36
include stdlib.h and stdio.h, they tend to be useful :-)
reimar
parents:
17633
diff
changeset
|
25 #include <stdlib.h> |
87c049a38c36
include stdlib.h and stdio.h, they tend to be useful :-)
reimar
parents:
17633
diff
changeset
|
26 #include <stdio.h> |
17633
e0ef5688cce7
OpenAL audio support, actual output is mono-only (no positioning yet).
reimar
parents:
diff
changeset
|
27 #include <inttypes.h> |
21556
283bff578e1c
Support OpenAL headers in OpenAL/ instead of AL/ and OpenAL on MacOSX in general.
reimar
parents:
21550
diff
changeset
|
28 #ifdef OPENAL_AL_H |
283bff578e1c
Support OpenAL headers in OpenAL/ instead of AL/ and OpenAL on MacOSX in general.
reimar
parents:
21550
diff
changeset
|
29 #include <OpenAL/alc.h> |
283bff578e1c
Support OpenAL headers in OpenAL/ instead of AL/ and OpenAL on MacOSX in general.
reimar
parents:
21550
diff
changeset
|
30 #include <OpenAL/al.h> |
283bff578e1c
Support OpenAL headers in OpenAL/ instead of AL/ and OpenAL on MacOSX in general.
reimar
parents:
21550
diff
changeset
|
31 #else |
17633
e0ef5688cce7
OpenAL audio support, actual output is mono-only (no positioning yet).
reimar
parents:
diff
changeset
|
32 #include <AL/alc.h> |
e0ef5688cce7
OpenAL audio support, actual output is mono-only (no positioning yet).
reimar
parents:
diff
changeset
|
33 #include <AL/al.h> |
21556
283bff578e1c
Support OpenAL headers in OpenAL/ instead of AL/ and OpenAL on MacOSX in general.
reimar
parents:
21550
diff
changeset
|
34 #endif |
17633
e0ef5688cce7
OpenAL audio support, actual output is mono-only (no positioning yet).
reimar
parents:
diff
changeset
|
35 |
e0ef5688cce7
OpenAL audio support, actual output is mono-only (no positioning yet).
reimar
parents:
diff
changeset
|
36 #include "mp_msg.h" |
e0ef5688cce7
OpenAL audio support, actual output is mono-only (no positioning yet).
reimar
parents:
diff
changeset
|
37 #include "help_mp.h" |
e0ef5688cce7
OpenAL audio support, actual output is mono-only (no positioning yet).
reimar
parents:
diff
changeset
|
38 |
e0ef5688cce7
OpenAL audio support, actual output is mono-only (no positioning yet).
reimar
parents:
diff
changeset
|
39 #include "audio_out.h" |
e0ef5688cce7
OpenAL audio support, actual output is mono-only (no positioning yet).
reimar
parents:
diff
changeset
|
40 #include "audio_out_internal.h" |
e0ef5688cce7
OpenAL audio support, actual output is mono-only (no positioning yet).
reimar
parents:
diff
changeset
|
41 #include "libaf/af_format.h" |
e0ef5688cce7
OpenAL audio support, actual output is mono-only (no positioning yet).
reimar
parents:
diff
changeset
|
42 #include "osdep/timer.h" |
e0ef5688cce7
OpenAL audio support, actual output is mono-only (no positioning yet).
reimar
parents:
diff
changeset
|
43 #include "subopt-helper.h" |
e0ef5688cce7
OpenAL audio support, actual output is mono-only (no positioning yet).
reimar
parents:
diff
changeset
|
44 |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
28823
diff
changeset
|
45 static const ao_info_t info = |
17633
e0ef5688cce7
OpenAL audio support, actual output is mono-only (no positioning yet).
reimar
parents:
diff
changeset
|
46 { |
e0ef5688cce7
OpenAL audio support, actual output is mono-only (no positioning yet).
reimar
parents:
diff
changeset
|
47 "OpenAL audio output", |
e0ef5688cce7
OpenAL audio support, actual output is mono-only (no positioning yet).
reimar
parents:
diff
changeset
|
48 "openal", |
23734 | 49 "Reimar Döffinger <Reimar.Doeffinger@stud.uni-karlsruhe.de>", |
17633
e0ef5688cce7
OpenAL audio support, actual output is mono-only (no positioning yet).
reimar
parents:
diff
changeset
|
50 "" |
e0ef5688cce7
OpenAL audio support, actual output is mono-only (no positioning yet).
reimar
parents:
diff
changeset
|
51 }; |
e0ef5688cce7
OpenAL audio support, actual output is mono-only (no positioning yet).
reimar
parents:
diff
changeset
|
52 |
e0ef5688cce7
OpenAL audio support, actual output is mono-only (no positioning yet).
reimar
parents:
diff
changeset
|
53 LIBAO_EXTERN(openal) |
e0ef5688cce7
OpenAL audio support, actual output is mono-only (no positioning yet).
reimar
parents:
diff
changeset
|
54 |
29500 | 55 #define MAX_CHANS 8 |
17633
e0ef5688cce7
OpenAL audio support, actual output is mono-only (no positioning yet).
reimar
parents:
diff
changeset
|
56 #define NUM_BUF 128 |
e0ef5688cce7
OpenAL audio support, actual output is mono-only (no positioning yet).
reimar
parents:
diff
changeset
|
57 #define CHUNK_SIZE 512 |
e0ef5688cce7
OpenAL audio support, actual output is mono-only (no positioning yet).
reimar
parents:
diff
changeset
|
58 static ALuint buffers[MAX_CHANS][NUM_BUF]; |
e0ef5688cce7
OpenAL audio support, actual output is mono-only (no positioning yet).
reimar
parents:
diff
changeset
|
59 static ALuint sources[MAX_CHANS]; |
e0ef5688cce7
OpenAL audio support, actual output is mono-only (no positioning yet).
reimar
parents:
diff
changeset
|
60 |
e0ef5688cce7
OpenAL audio support, actual output is mono-only (no positioning yet).
reimar
parents:
diff
changeset
|
61 static int cur_buf[MAX_CHANS]; |
e0ef5688cce7
OpenAL audio support, actual output is mono-only (no positioning yet).
reimar
parents:
diff
changeset
|
62 static int unqueue_buf[MAX_CHANS]; |
e0ef5688cce7
OpenAL audio support, actual output is mono-only (no positioning yet).
reimar
parents:
diff
changeset
|
63 static int16_t *tmpbuf; |
e0ef5688cce7
OpenAL audio support, actual output is mono-only (no positioning yet).
reimar
parents:
diff
changeset
|
64 |
e0ef5688cce7
OpenAL audio support, actual output is mono-only (no positioning yet).
reimar
parents:
diff
changeset
|
65 |
e0ef5688cce7
OpenAL audio support, actual output is mono-only (no positioning yet).
reimar
parents:
diff
changeset
|
66 static int control(int cmd, void *arg) { |
21570 | 67 switch (cmd) { |
68 case AOCONTROL_GET_VOLUME: | |
69 case AOCONTROL_SET_VOLUME: { | |
70 ALfloat volume; | |
71 ao_control_vol_t *vol = (ao_control_vol_t *)arg; | |
72 if (cmd == AOCONTROL_SET_VOLUME) { | |
73 volume = (vol->left + vol->right) / 200.0; | |
74 alListenerf(AL_GAIN, volume); | |
75 } | |
76 alGetListenerf(AL_GAIN, &volume); | |
77 vol->left = vol->right = volume * 100; | |
78 return CONTROL_TRUE; | |
79 } | |
80 } | |
17633
e0ef5688cce7
OpenAL audio support, actual output is mono-only (no positioning yet).
reimar
parents:
diff
changeset
|
81 return CONTROL_UNKNOWN; |
e0ef5688cce7
OpenAL audio support, actual output is mono-only (no positioning yet).
reimar
parents:
diff
changeset
|
82 } |
e0ef5688cce7
OpenAL audio support, actual output is mono-only (no positioning yet).
reimar
parents:
diff
changeset
|
83 |
e0ef5688cce7
OpenAL audio support, actual output is mono-only (no positioning yet).
reimar
parents:
diff
changeset
|
84 /** |
e0ef5688cce7
OpenAL audio support, actual output is mono-only (no positioning yet).
reimar
parents:
diff
changeset
|
85 * \brief print suboption usage help |
e0ef5688cce7
OpenAL audio support, actual output is mono-only (no positioning yet).
reimar
parents:
diff
changeset
|
86 */ |
e0ef5688cce7
OpenAL audio support, actual output is mono-only (no positioning yet).
reimar
parents:
diff
changeset
|
87 static void print_help(void) { |
e0ef5688cce7
OpenAL audio support, actual output is mono-only (no positioning yet).
reimar
parents:
diff
changeset
|
88 mp_msg(MSGT_AO, MSGL_FATAL, |
e0ef5688cce7
OpenAL audio support, actual output is mono-only (no positioning yet).
reimar
parents:
diff
changeset
|
89 "\n-ao openal commandline help:\n" |
e0ef5688cce7
OpenAL audio support, actual output is mono-only (no positioning yet).
reimar
parents:
diff
changeset
|
90 "Example: mplayer -ao openal\n" |
e0ef5688cce7
OpenAL audio support, actual output is mono-only (no positioning yet).
reimar
parents:
diff
changeset
|
91 "\nOptions:\n" |
e0ef5688cce7
OpenAL audio support, actual output is mono-only (no positioning yet).
reimar
parents:
diff
changeset
|
92 ); |
e0ef5688cce7
OpenAL audio support, actual output is mono-only (no positioning yet).
reimar
parents:
diff
changeset
|
93 } |
e0ef5688cce7
OpenAL audio support, actual output is mono-only (no positioning yet).
reimar
parents:
diff
changeset
|
94 |
e0ef5688cce7
OpenAL audio support, actual output is mono-only (no positioning yet).
reimar
parents:
diff
changeset
|
95 static int init(int rate, int channels, int format, int flags) { |
21527 | 96 float position[3] = {0, 0, 0}; |
21530 | 97 float direction[6] = {0, 0, 1, 0, -1, 0}; |
29500 | 98 float sppos[MAX_CHANS][3] = { |
21530 | 99 {-1, 0, 0.5}, {1, 0, 0.5}, |
100 {-1, 0, -1}, {1, 0, -1}, | |
101 {0, 0, 1}, {0, 0, 0.1}, | |
29500 | 102 {-1, 0, 0}, {1, 0, 0}, |
21527 | 103 }; |
17633
e0ef5688cce7
OpenAL audio support, actual output is mono-only (no positioning yet).
reimar
parents:
diff
changeset
|
104 ALCdevice *dev = NULL; |
e0ef5688cce7
OpenAL audio support, actual output is mono-only (no positioning yet).
reimar
parents:
diff
changeset
|
105 ALCcontext *ctx = NULL; |
21549 | 106 ALCint freq = 0; |
107 ALCint attribs[] = {ALC_FREQUENCY, rate, 0, 0}; | |
17633
e0ef5688cce7
OpenAL audio support, actual output is mono-only (no positioning yet).
reimar
parents:
diff
changeset
|
108 int i; |
29586
2eff450157cd
The suboption parser now takes a const options list, so mark them all const.
reimar
parents:
29500
diff
changeset
|
109 const opt_t subopts[] = { |
17633
e0ef5688cce7
OpenAL audio support, actual output is mono-only (no positioning yet).
reimar
parents:
diff
changeset
|
110 {NULL} |
e0ef5688cce7
OpenAL audio support, actual output is mono-only (no positioning yet).
reimar
parents:
diff
changeset
|
111 }; |
e0ef5688cce7
OpenAL audio support, actual output is mono-only (no positioning yet).
reimar
parents:
diff
changeset
|
112 if (subopt_parse(ao_subdevice, subopts) != 0) { |
e0ef5688cce7
OpenAL audio support, actual output is mono-only (no positioning yet).
reimar
parents:
diff
changeset
|
113 print_help(); |
e0ef5688cce7
OpenAL audio support, actual output is mono-only (no positioning yet).
reimar
parents:
diff
changeset
|
114 return 0; |
e0ef5688cce7
OpenAL audio support, actual output is mono-only (no positioning yet).
reimar
parents:
diff
changeset
|
115 } |
e0ef5688cce7
OpenAL audio support, actual output is mono-only (no positioning yet).
reimar
parents:
diff
changeset
|
116 if (channels > MAX_CHANS) { |
e0ef5688cce7
OpenAL audio support, actual output is mono-only (no positioning yet).
reimar
parents:
diff
changeset
|
117 mp_msg(MSGT_AO, MSGL_FATAL, "[OpenAL] Invalid number of channels: %i\n", channels); |
e0ef5688cce7
OpenAL audio support, actual output is mono-only (no positioning yet).
reimar
parents:
diff
changeset
|
118 goto err_out; |
e0ef5688cce7
OpenAL audio support, actual output is mono-only (no positioning yet).
reimar
parents:
diff
changeset
|
119 } |
e0ef5688cce7
OpenAL audio support, actual output is mono-only (no positioning yet).
reimar
parents:
diff
changeset
|
120 dev = alcOpenDevice(NULL); |
e0ef5688cce7
OpenAL audio support, actual output is mono-only (no positioning yet).
reimar
parents:
diff
changeset
|
121 if (!dev) { |
e0ef5688cce7
OpenAL audio support, actual output is mono-only (no positioning yet).
reimar
parents:
diff
changeset
|
122 mp_msg(MSGT_AO, MSGL_FATAL, "[OpenAL] could not open device\n"); |
e0ef5688cce7
OpenAL audio support, actual output is mono-only (no positioning yet).
reimar
parents:
diff
changeset
|
123 goto err_out; |
e0ef5688cce7
OpenAL audio support, actual output is mono-only (no positioning yet).
reimar
parents:
diff
changeset
|
124 } |
21550 | 125 ctx = alcCreateContext(dev, attribs); |
17633
e0ef5688cce7
OpenAL audio support, actual output is mono-only (no positioning yet).
reimar
parents:
diff
changeset
|
126 alcMakeContextCurrent(ctx); |
21527 | 127 alListenerfv(AL_POSITION, position); |
128 alListenerfv(AL_ORIENTATION, direction); | |
129 alGenSources(channels, sources); | |
17633
e0ef5688cce7
OpenAL audio support, actual output is mono-only (no positioning yet).
reimar
parents:
diff
changeset
|
130 for (i = 0; i < channels; i++) { |
e0ef5688cce7
OpenAL audio support, actual output is mono-only (no positioning yet).
reimar
parents:
diff
changeset
|
131 cur_buf[i] = 0; |
e0ef5688cce7
OpenAL audio support, actual output is mono-only (no positioning yet).
reimar
parents:
diff
changeset
|
132 unqueue_buf[i] = 0; |
e0ef5688cce7
OpenAL audio support, actual output is mono-only (no positioning yet).
reimar
parents:
diff
changeset
|
133 alGenBuffers(NUM_BUF, buffers[i]); |
21527 | 134 alSourcefv(sources[i], AL_POSITION, sppos[i]); |
135 alSource3f(sources[i], AL_VELOCITY, 0, 0, 0); | |
17633
e0ef5688cce7
OpenAL audio support, actual output is mono-only (no positioning yet).
reimar
parents:
diff
changeset
|
136 } |
21530 | 137 if (channels == 1) |
138 alSource3f(sources[0], AL_POSITION, 0, 0, 1); | |
17633
e0ef5688cce7
OpenAL audio support, actual output is mono-only (no positioning yet).
reimar
parents:
diff
changeset
|
139 ao_data.channels = channels; |
21549 | 140 alcGetIntegerv(dev, ALC_FREQUENCY, 1, &freq); |
141 if (alcGetError(dev) == ALC_NO_ERROR && freq) | |
142 rate = freq; | |
143 ao_data.samplerate = rate; | |
17633
e0ef5688cce7
OpenAL audio support, actual output is mono-only (no positioning yet).
reimar
parents:
diff
changeset
|
144 ao_data.format = AF_FORMAT_S16_NE; |
e0ef5688cce7
OpenAL audio support, actual output is mono-only (no positioning yet).
reimar
parents:
diff
changeset
|
145 ao_data.bps = channels * rate * 2; |
e0ef5688cce7
OpenAL audio support, actual output is mono-only (no positioning yet).
reimar
parents:
diff
changeset
|
146 ao_data.buffersize = CHUNK_SIZE * NUM_BUF; |
e0ef5688cce7
OpenAL audio support, actual output is mono-only (no positioning yet).
reimar
parents:
diff
changeset
|
147 ao_data.outburst = channels * CHUNK_SIZE; |
18885 | 148 tmpbuf = malloc(CHUNK_SIZE); |
17633
e0ef5688cce7
OpenAL audio support, actual output is mono-only (no positioning yet).
reimar
parents:
diff
changeset
|
149 return 1; |
e0ef5688cce7
OpenAL audio support, actual output is mono-only (no positioning yet).
reimar
parents:
diff
changeset
|
150 |
e0ef5688cce7
OpenAL audio support, actual output is mono-only (no positioning yet).
reimar
parents:
diff
changeset
|
151 err_out: |
e0ef5688cce7
OpenAL audio support, actual output is mono-only (no positioning yet).
reimar
parents:
diff
changeset
|
152 return 0; |
e0ef5688cce7
OpenAL audio support, actual output is mono-only (no positioning yet).
reimar
parents:
diff
changeset
|
153 } |
e0ef5688cce7
OpenAL audio support, actual output is mono-only (no positioning yet).
reimar
parents:
diff
changeset
|
154 |
e0ef5688cce7
OpenAL audio support, actual output is mono-only (no positioning yet).
reimar
parents:
diff
changeset
|
155 // close audio device |
e0ef5688cce7
OpenAL audio support, actual output is mono-only (no positioning yet).
reimar
parents:
diff
changeset
|
156 static void uninit(int immed) { |
e0ef5688cce7
OpenAL audio support, actual output is mono-only (no positioning yet).
reimar
parents:
diff
changeset
|
157 ALCcontext *ctx = alcGetCurrentContext(); |
e0ef5688cce7
OpenAL audio support, actual output is mono-only (no positioning yet).
reimar
parents:
diff
changeset
|
158 ALCdevice *dev = alcGetContextsDevice(ctx); |
e0ef5688cce7
OpenAL audio support, actual output is mono-only (no positioning yet).
reimar
parents:
diff
changeset
|
159 free(tmpbuf); |
e0ef5688cce7
OpenAL audio support, actual output is mono-only (no positioning yet).
reimar
parents:
diff
changeset
|
160 if (!immed) { |
e0ef5688cce7
OpenAL audio support, actual output is mono-only (no positioning yet).
reimar
parents:
diff
changeset
|
161 ALint state; |
e0ef5688cce7
OpenAL audio support, actual output is mono-only (no positioning yet).
reimar
parents:
diff
changeset
|
162 alGetSourcei(sources[0], AL_SOURCE_STATE, &state); |
e0ef5688cce7
OpenAL audio support, actual output is mono-only (no positioning yet).
reimar
parents:
diff
changeset
|
163 while (state == AL_PLAYING) { |
e0ef5688cce7
OpenAL audio support, actual output is mono-only (no positioning yet).
reimar
parents:
diff
changeset
|
164 usec_sleep(10000); |
e0ef5688cce7
OpenAL audio support, actual output is mono-only (no positioning yet).
reimar
parents:
diff
changeset
|
165 alGetSourcei(sources[0], AL_SOURCE_STATE, &state); |
e0ef5688cce7
OpenAL audio support, actual output is mono-only (no positioning yet).
reimar
parents:
diff
changeset
|
166 } |
e0ef5688cce7
OpenAL audio support, actual output is mono-only (no positioning yet).
reimar
parents:
diff
changeset
|
167 } |
e0ef5688cce7
OpenAL audio support, actual output is mono-only (no positioning yet).
reimar
parents:
diff
changeset
|
168 reset(); |
e0ef5688cce7
OpenAL audio support, actual output is mono-only (no positioning yet).
reimar
parents:
diff
changeset
|
169 alcMakeContextCurrent(NULL); |
e0ef5688cce7
OpenAL audio support, actual output is mono-only (no positioning yet).
reimar
parents:
diff
changeset
|
170 alcDestroyContext(ctx); |
e0ef5688cce7
OpenAL audio support, actual output is mono-only (no positioning yet).
reimar
parents:
diff
changeset
|
171 alcCloseDevice(dev); |
e0ef5688cce7
OpenAL audio support, actual output is mono-only (no positioning yet).
reimar
parents:
diff
changeset
|
172 } |
e0ef5688cce7
OpenAL audio support, actual output is mono-only (no positioning yet).
reimar
parents:
diff
changeset
|
173 |
e0ef5688cce7
OpenAL audio support, actual output is mono-only (no positioning yet).
reimar
parents:
diff
changeset
|
174 static void unqueue_buffers(void) { |
e0ef5688cce7
OpenAL audio support, actual output is mono-only (no positioning yet).
reimar
parents:
diff
changeset
|
175 ALint p; |
25910 | 176 int s; |
17633
e0ef5688cce7
OpenAL audio support, actual output is mono-only (no positioning yet).
reimar
parents:
diff
changeset
|
177 for (s = 0; s < ao_data.channels; s++) { |
25907 | 178 int till_wrap = NUM_BUF - unqueue_buf[s]; |
17633
e0ef5688cce7
OpenAL audio support, actual output is mono-only (no positioning yet).
reimar
parents:
diff
changeset
|
179 alGetSourcei(sources[s], AL_BUFFERS_PROCESSED, &p); |
25907 | 180 if (p >= till_wrap) { |
181 alSourceUnqueueBuffers(sources[s], till_wrap, &buffers[s][unqueue_buf[s]]); | |
182 unqueue_buf[s] = 0; | |
183 p -= till_wrap; | |
184 } | |
185 if (p) { | |
186 alSourceUnqueueBuffers(sources[s], p, &buffers[s][unqueue_buf[s]]); | |
187 unqueue_buf[s] += p; | |
17633
e0ef5688cce7
OpenAL audio support, actual output is mono-only (no positioning yet).
reimar
parents:
diff
changeset
|
188 } |
e0ef5688cce7
OpenAL audio support, actual output is mono-only (no positioning yet).
reimar
parents:
diff
changeset
|
189 } |
e0ef5688cce7
OpenAL audio support, actual output is mono-only (no positioning yet).
reimar
parents:
diff
changeset
|
190 } |
e0ef5688cce7
OpenAL audio support, actual output is mono-only (no positioning yet).
reimar
parents:
diff
changeset
|
191 |
e0ef5688cce7
OpenAL audio support, actual output is mono-only (no positioning yet).
reimar
parents:
diff
changeset
|
192 /** |
e0ef5688cce7
OpenAL audio support, actual output is mono-only (no positioning yet).
reimar
parents:
diff
changeset
|
193 * \brief stop playing and empty buffers (for seeking/pause) |
e0ef5688cce7
OpenAL audio support, actual output is mono-only (no positioning yet).
reimar
parents:
diff
changeset
|
194 */ |
e0ef5688cce7
OpenAL audio support, actual output is mono-only (no positioning yet).
reimar
parents:
diff
changeset
|
195 static void reset(void) { |
25906
ffea6350c511
alSourceRewindv seems to be broken in particular in Creatives Windows-Implementation,
reimar
parents:
23734
diff
changeset
|
196 alSourceStopv(ao_data.channels, sources); |
17633
e0ef5688cce7
OpenAL audio support, actual output is mono-only (no positioning yet).
reimar
parents:
diff
changeset
|
197 unqueue_buffers(); |
e0ef5688cce7
OpenAL audio support, actual output is mono-only (no positioning yet).
reimar
parents:
diff
changeset
|
198 } |
e0ef5688cce7
OpenAL audio support, actual output is mono-only (no positioning yet).
reimar
parents:
diff
changeset
|
199 |
e0ef5688cce7
OpenAL audio support, actual output is mono-only (no positioning yet).
reimar
parents:
diff
changeset
|
200 /** |
e0ef5688cce7
OpenAL audio support, actual output is mono-only (no positioning yet).
reimar
parents:
diff
changeset
|
201 * \brief stop playing, keep buffers (for pause) |
e0ef5688cce7
OpenAL audio support, actual output is mono-only (no positioning yet).
reimar
parents:
diff
changeset
|
202 */ |
e0ef5688cce7
OpenAL audio support, actual output is mono-only (no positioning yet).
reimar
parents:
diff
changeset
|
203 static void audio_pause(void) { |
e0ef5688cce7
OpenAL audio support, actual output is mono-only (no positioning yet).
reimar
parents:
diff
changeset
|
204 alSourcePausev(ao_data.channels, sources); |
e0ef5688cce7
OpenAL audio support, actual output is mono-only (no positioning yet).
reimar
parents:
diff
changeset
|
205 } |
e0ef5688cce7
OpenAL audio support, actual output is mono-only (no positioning yet).
reimar
parents:
diff
changeset
|
206 |
e0ef5688cce7
OpenAL audio support, actual output is mono-only (no positioning yet).
reimar
parents:
diff
changeset
|
207 /** |
e0ef5688cce7
OpenAL audio support, actual output is mono-only (no positioning yet).
reimar
parents:
diff
changeset
|
208 * \brief resume playing, after audio_pause() |
e0ef5688cce7
OpenAL audio support, actual output is mono-only (no positioning yet).
reimar
parents:
diff
changeset
|
209 */ |
e0ef5688cce7
OpenAL audio support, actual output is mono-only (no positioning yet).
reimar
parents:
diff
changeset
|
210 static void audio_resume(void) { |
e0ef5688cce7
OpenAL audio support, actual output is mono-only (no positioning yet).
reimar
parents:
diff
changeset
|
211 alSourcePlayv(ao_data.channels, sources); |
e0ef5688cce7
OpenAL audio support, actual output is mono-only (no positioning yet).
reimar
parents:
diff
changeset
|
212 } |
e0ef5688cce7
OpenAL audio support, actual output is mono-only (no positioning yet).
reimar
parents:
diff
changeset
|
213 |
e0ef5688cce7
OpenAL audio support, actual output is mono-only (no positioning yet).
reimar
parents:
diff
changeset
|
214 static int get_space(void) { |
e0ef5688cce7
OpenAL audio support, actual output is mono-only (no positioning yet).
reimar
parents:
diff
changeset
|
215 ALint queued; |
e0ef5688cce7
OpenAL audio support, actual output is mono-only (no positioning yet).
reimar
parents:
diff
changeset
|
216 unqueue_buffers(); |
e0ef5688cce7
OpenAL audio support, actual output is mono-only (no positioning yet).
reimar
parents:
diff
changeset
|
217 alGetSourcei(sources[0], AL_BUFFERS_QUEUED, &queued); |
25909
f6a0f861f7e6
Fix get_space calculation to always leave some space, esp. for the currently playing buffer.
reimar
parents:
25908
diff
changeset
|
218 queued = NUM_BUF - queued - 3; |
f6a0f861f7e6
Fix get_space calculation to always leave some space, esp. for the currently playing buffer.
reimar
parents:
25908
diff
changeset
|
219 if (queued < 0) return 0; |
f6a0f861f7e6
Fix get_space calculation to always leave some space, esp. for the currently playing buffer.
reimar
parents:
25908
diff
changeset
|
220 return queued * CHUNK_SIZE * ao_data.channels; |
17633
e0ef5688cce7
OpenAL audio support, actual output is mono-only (no positioning yet).
reimar
parents:
diff
changeset
|
221 } |
e0ef5688cce7
OpenAL audio support, actual output is mono-only (no positioning yet).
reimar
parents:
diff
changeset
|
222 |
e0ef5688cce7
OpenAL audio support, actual output is mono-only (no positioning yet).
reimar
parents:
diff
changeset
|
223 /** |
e0ef5688cce7
OpenAL audio support, actual output is mono-only (no positioning yet).
reimar
parents:
diff
changeset
|
224 * \brief write data into buffer and reset underrun flag |
e0ef5688cce7
OpenAL audio support, actual output is mono-only (no positioning yet).
reimar
parents:
diff
changeset
|
225 */ |
e0ef5688cce7
OpenAL audio support, actual output is mono-only (no positioning yet).
reimar
parents:
diff
changeset
|
226 static int play(void *data, int len, int flags) { |
e0ef5688cce7
OpenAL audio support, actual output is mono-only (no positioning yet).
reimar
parents:
diff
changeset
|
227 ALint state; |
e0ef5688cce7
OpenAL audio support, actual output is mono-only (no positioning yet).
reimar
parents:
diff
changeset
|
228 int i, j, k; |
e0ef5688cce7
OpenAL audio support, actual output is mono-only (no positioning yet).
reimar
parents:
diff
changeset
|
229 int ch; |
e0ef5688cce7
OpenAL audio support, actual output is mono-only (no positioning yet).
reimar
parents:
diff
changeset
|
230 int16_t *d = data; |
25908
7cf1b1c1c44c
Change code to also work with different outburst sizes
reimar
parents:
25907
diff
changeset
|
231 len /= ao_data.channels * CHUNK_SIZE; |
17633
e0ef5688cce7
OpenAL audio support, actual output is mono-only (no positioning yet).
reimar
parents:
diff
changeset
|
232 for (i = 0; i < len; i++) { |
e0ef5688cce7
OpenAL audio support, actual output is mono-only (no positioning yet).
reimar
parents:
diff
changeset
|
233 for (ch = 0; ch < ao_data.channels; ch++) { |
e0ef5688cce7
OpenAL audio support, actual output is mono-only (no positioning yet).
reimar
parents:
diff
changeset
|
234 for (j = 0, k = ch; j < CHUNK_SIZE / 2; j++, k += ao_data.channels) |
e0ef5688cce7
OpenAL audio support, actual output is mono-only (no positioning yet).
reimar
parents:
diff
changeset
|
235 tmpbuf[j] = d[k]; |
e0ef5688cce7
OpenAL audio support, actual output is mono-only (no positioning yet).
reimar
parents:
diff
changeset
|
236 alBufferData(buffers[ch][cur_buf[ch]], AL_FORMAT_MONO16, tmpbuf, |
e0ef5688cce7
OpenAL audio support, actual output is mono-only (no positioning yet).
reimar
parents:
diff
changeset
|
237 CHUNK_SIZE, ao_data.samplerate); |
e0ef5688cce7
OpenAL audio support, actual output is mono-only (no positioning yet).
reimar
parents:
diff
changeset
|
238 alSourceQueueBuffers(sources[ch], 1, &buffers[ch][cur_buf[ch]]); |
e0ef5688cce7
OpenAL audio support, actual output is mono-only (no positioning yet).
reimar
parents:
diff
changeset
|
239 cur_buf[ch] = (cur_buf[ch] + 1) % NUM_BUF; |
e0ef5688cce7
OpenAL audio support, actual output is mono-only (no positioning yet).
reimar
parents:
diff
changeset
|
240 } |
e0ef5688cce7
OpenAL audio support, actual output is mono-only (no positioning yet).
reimar
parents:
diff
changeset
|
241 d += ao_data.channels * CHUNK_SIZE / 2; |
e0ef5688cce7
OpenAL audio support, actual output is mono-only (no positioning yet).
reimar
parents:
diff
changeset
|
242 } |
e0ef5688cce7
OpenAL audio support, actual output is mono-only (no positioning yet).
reimar
parents:
diff
changeset
|
243 alGetSourcei(sources[0], AL_SOURCE_STATE, &state); |
e0ef5688cce7
OpenAL audio support, actual output is mono-only (no positioning yet).
reimar
parents:
diff
changeset
|
244 if (state != AL_PLAYING) // checked here in case of an underrun |
e0ef5688cce7
OpenAL audio support, actual output is mono-only (no positioning yet).
reimar
parents:
diff
changeset
|
245 alSourcePlayv(ao_data.channels, sources); |
25908
7cf1b1c1c44c
Change code to also work with different outburst sizes
reimar
parents:
25907
diff
changeset
|
246 return len * ao_data.channels * CHUNK_SIZE; |
17633
e0ef5688cce7
OpenAL audio support, actual output is mono-only (no positioning yet).
reimar
parents:
diff
changeset
|
247 } |
e0ef5688cce7
OpenAL audio support, actual output is mono-only (no positioning yet).
reimar
parents:
diff
changeset
|
248 |
e0ef5688cce7
OpenAL audio support, actual output is mono-only (no positioning yet).
reimar
parents:
diff
changeset
|
249 static float get_delay(void) { |
e0ef5688cce7
OpenAL audio support, actual output is mono-only (no positioning yet).
reimar
parents:
diff
changeset
|
250 ALint queued; |
e0ef5688cce7
OpenAL audio support, actual output is mono-only (no positioning yet).
reimar
parents:
diff
changeset
|
251 unqueue_buffers(); |
e0ef5688cce7
OpenAL audio support, actual output is mono-only (no positioning yet).
reimar
parents:
diff
changeset
|
252 alGetSourcei(sources[0], AL_BUFFERS_QUEUED, &queued); |
e0ef5688cce7
OpenAL audio support, actual output is mono-only (no positioning yet).
reimar
parents:
diff
changeset
|
253 return queued * CHUNK_SIZE / 2 / (float)ao_data.samplerate; |
e0ef5688cce7
OpenAL audio support, actual output is mono-only (no positioning yet).
reimar
parents:
diff
changeset
|
254 } |