Mercurial > mplayer.hg
annotate libao2/ao_openal.c @ 29491:99eda963d27a
Fix incorrect channel ordering for lavc audio codecs (specifically ffac3,
ffdca, ffflac, ffaac, fftruehd). In the process, adds support for 32-bit
samples.
author | tack |
---|---|
date | Tue, 18 Aug 2009 22:24:36 +0000 |
parents | 0f1b5b68af32 |
children | 60819382adfe |
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 |
e0ef5688cce7
OpenAL audio support, actual output is mono-only (no positioning yet).
reimar
parents:
diff
changeset
|
55 #define MAX_CHANS 6 |
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}; |
21527 | 98 float sppos[6][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}, | |
21527 | 102 }; |
17633
e0ef5688cce7
OpenAL audio support, actual output is mono-only (no positioning yet).
reimar
parents:
diff
changeset
|
103 ALCdevice *dev = NULL; |
e0ef5688cce7
OpenAL audio support, actual output is mono-only (no positioning yet).
reimar
parents:
diff
changeset
|
104 ALCcontext *ctx = NULL; |
21549 | 105 ALCint freq = 0; |
106 ALCint attribs[] = {ALC_FREQUENCY, rate, 0, 0}; | |
17633
e0ef5688cce7
OpenAL audio support, actual output is mono-only (no positioning yet).
reimar
parents:
diff
changeset
|
107 int i; |
e0ef5688cce7
OpenAL audio support, actual output is mono-only (no positioning yet).
reimar
parents:
diff
changeset
|
108 opt_t subopts[] = { |
e0ef5688cce7
OpenAL audio support, actual output is mono-only (no positioning yet).
reimar
parents:
diff
changeset
|
109 {NULL} |
e0ef5688cce7
OpenAL audio support, actual output is mono-only (no positioning yet).
reimar
parents:
diff
changeset
|
110 }; |
e0ef5688cce7
OpenAL audio support, actual output is mono-only (no positioning yet).
reimar
parents:
diff
changeset
|
111 if (subopt_parse(ao_subdevice, subopts) != 0) { |
e0ef5688cce7
OpenAL audio support, actual output is mono-only (no positioning yet).
reimar
parents:
diff
changeset
|
112 print_help(); |
e0ef5688cce7
OpenAL audio support, actual output is mono-only (no positioning yet).
reimar
parents:
diff
changeset
|
113 return 0; |
e0ef5688cce7
OpenAL audio support, actual output is mono-only (no positioning yet).
reimar
parents:
diff
changeset
|
114 } |
e0ef5688cce7
OpenAL audio support, actual output is mono-only (no positioning yet).
reimar
parents:
diff
changeset
|
115 if (channels > MAX_CHANS) { |
e0ef5688cce7
OpenAL audio support, actual output is mono-only (no positioning yet).
reimar
parents:
diff
changeset
|
116 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
|
117 goto err_out; |
e0ef5688cce7
OpenAL audio support, actual output is mono-only (no positioning yet).
reimar
parents:
diff
changeset
|
118 } |
e0ef5688cce7
OpenAL audio support, actual output is mono-only (no positioning yet).
reimar
parents:
diff
changeset
|
119 dev = alcOpenDevice(NULL); |
e0ef5688cce7
OpenAL audio support, actual output is mono-only (no positioning yet).
reimar
parents:
diff
changeset
|
120 if (!dev) { |
e0ef5688cce7
OpenAL audio support, actual output is mono-only (no positioning yet).
reimar
parents:
diff
changeset
|
121 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
|
122 goto err_out; |
e0ef5688cce7
OpenAL audio support, actual output is mono-only (no positioning yet).
reimar
parents:
diff
changeset
|
123 } |
21550 | 124 ctx = alcCreateContext(dev, attribs); |
17633
e0ef5688cce7
OpenAL audio support, actual output is mono-only (no positioning yet).
reimar
parents:
diff
changeset
|
125 alcMakeContextCurrent(ctx); |
21527 | 126 alListenerfv(AL_POSITION, position); |
127 alListenerfv(AL_ORIENTATION, direction); | |
128 alGenSources(channels, sources); | |
17633
e0ef5688cce7
OpenAL audio support, actual output is mono-only (no positioning yet).
reimar
parents:
diff
changeset
|
129 for (i = 0; i < channels; i++) { |
e0ef5688cce7
OpenAL audio support, actual output is mono-only (no positioning yet).
reimar
parents:
diff
changeset
|
130 cur_buf[i] = 0; |
e0ef5688cce7
OpenAL audio support, actual output is mono-only (no positioning yet).
reimar
parents:
diff
changeset
|
131 unqueue_buf[i] = 0; |
e0ef5688cce7
OpenAL audio support, actual output is mono-only (no positioning yet).
reimar
parents:
diff
changeset
|
132 alGenBuffers(NUM_BUF, buffers[i]); |
21527 | 133 alSourcefv(sources[i], AL_POSITION, sppos[i]); |
134 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
|
135 } |
21530 | 136 if (channels == 1) |
137 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
|
138 ao_data.channels = channels; |
21549 | 139 alcGetIntegerv(dev, ALC_FREQUENCY, 1, &freq); |
140 if (alcGetError(dev) == ALC_NO_ERROR && freq) | |
141 rate = freq; | |
142 ao_data.samplerate = rate; | |
17633
e0ef5688cce7
OpenAL audio support, actual output is mono-only (no positioning yet).
reimar
parents:
diff
changeset
|
143 ao_data.format = AF_FORMAT_S16_NE; |
e0ef5688cce7
OpenAL audio support, actual output is mono-only (no positioning yet).
reimar
parents:
diff
changeset
|
144 ao_data.bps = channels * rate * 2; |
e0ef5688cce7
OpenAL audio support, actual output is mono-only (no positioning yet).
reimar
parents:
diff
changeset
|
145 ao_data.buffersize = CHUNK_SIZE * NUM_BUF; |
e0ef5688cce7
OpenAL audio support, actual output is mono-only (no positioning yet).
reimar
parents:
diff
changeset
|
146 ao_data.outburst = channels * CHUNK_SIZE; |
18885 | 147 tmpbuf = malloc(CHUNK_SIZE); |
17633
e0ef5688cce7
OpenAL audio support, actual output is mono-only (no positioning yet).
reimar
parents:
diff
changeset
|
148 return 1; |
e0ef5688cce7
OpenAL audio support, actual output is mono-only (no positioning yet).
reimar
parents:
diff
changeset
|
149 |
e0ef5688cce7
OpenAL audio support, actual output is mono-only (no positioning yet).
reimar
parents:
diff
changeset
|
150 err_out: |
e0ef5688cce7
OpenAL audio support, actual output is mono-only (no positioning yet).
reimar
parents:
diff
changeset
|
151 return 0; |
e0ef5688cce7
OpenAL audio support, actual output is mono-only (no positioning yet).
reimar
parents:
diff
changeset
|
152 } |
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 // close audio device |
e0ef5688cce7
OpenAL audio support, actual output is mono-only (no positioning yet).
reimar
parents:
diff
changeset
|
155 static void uninit(int immed) { |
e0ef5688cce7
OpenAL audio support, actual output is mono-only (no positioning yet).
reimar
parents:
diff
changeset
|
156 ALCcontext *ctx = alcGetCurrentContext(); |
e0ef5688cce7
OpenAL audio support, actual output is mono-only (no positioning yet).
reimar
parents:
diff
changeset
|
157 ALCdevice *dev = alcGetContextsDevice(ctx); |
e0ef5688cce7
OpenAL audio support, actual output is mono-only (no positioning yet).
reimar
parents:
diff
changeset
|
158 free(tmpbuf); |
e0ef5688cce7
OpenAL audio support, actual output is mono-only (no positioning yet).
reimar
parents:
diff
changeset
|
159 if (!immed) { |
e0ef5688cce7
OpenAL audio support, actual output is mono-only (no positioning yet).
reimar
parents:
diff
changeset
|
160 ALint state; |
e0ef5688cce7
OpenAL audio support, actual output is mono-only (no positioning yet).
reimar
parents:
diff
changeset
|
161 alGetSourcei(sources[0], AL_SOURCE_STATE, &state); |
e0ef5688cce7
OpenAL audio support, actual output is mono-only (no positioning yet).
reimar
parents:
diff
changeset
|
162 while (state == AL_PLAYING) { |
e0ef5688cce7
OpenAL audio support, actual output is mono-only (no positioning yet).
reimar
parents:
diff
changeset
|
163 usec_sleep(10000); |
e0ef5688cce7
OpenAL audio support, actual output is mono-only (no positioning yet).
reimar
parents:
diff
changeset
|
164 alGetSourcei(sources[0], AL_SOURCE_STATE, &state); |
e0ef5688cce7
OpenAL audio support, actual output is mono-only (no positioning yet).
reimar
parents:
diff
changeset
|
165 } |
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 reset(); |
e0ef5688cce7
OpenAL audio support, actual output is mono-only (no positioning yet).
reimar
parents:
diff
changeset
|
168 alcMakeContextCurrent(NULL); |
e0ef5688cce7
OpenAL audio support, actual output is mono-only (no positioning yet).
reimar
parents:
diff
changeset
|
169 alcDestroyContext(ctx); |
e0ef5688cce7
OpenAL audio support, actual output is mono-only (no positioning yet).
reimar
parents:
diff
changeset
|
170 alcCloseDevice(dev); |
e0ef5688cce7
OpenAL audio support, actual output is mono-only (no positioning yet).
reimar
parents:
diff
changeset
|
171 } |
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 static void unqueue_buffers(void) { |
e0ef5688cce7
OpenAL audio support, actual output is mono-only (no positioning yet).
reimar
parents:
diff
changeset
|
174 ALint p; |
25910 | 175 int s; |
17633
e0ef5688cce7
OpenAL audio support, actual output is mono-only (no positioning yet).
reimar
parents:
diff
changeset
|
176 for (s = 0; s < ao_data.channels; s++) { |
25907 | 177 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
|
178 alGetSourcei(sources[s], AL_BUFFERS_PROCESSED, &p); |
25907 | 179 if (p >= till_wrap) { |
180 alSourceUnqueueBuffers(sources[s], till_wrap, &buffers[s][unqueue_buf[s]]); | |
181 unqueue_buf[s] = 0; | |
182 p -= till_wrap; | |
183 } | |
184 if (p) { | |
185 alSourceUnqueueBuffers(sources[s], p, &buffers[s][unqueue_buf[s]]); | |
186 unqueue_buf[s] += p; | |
17633
e0ef5688cce7
OpenAL audio support, actual output is mono-only (no positioning yet).
reimar
parents:
diff
changeset
|
187 } |
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 * \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
|
193 */ |
e0ef5688cce7
OpenAL audio support, actual output is mono-only (no positioning yet).
reimar
parents:
diff
changeset
|
194 static void reset(void) { |
25906
ffea6350c511
alSourceRewindv seems to be broken in particular in Creatives Windows-Implementation,
reimar
parents:
23734
diff
changeset
|
195 alSourceStopv(ao_data.channels, sources); |
17633
e0ef5688cce7
OpenAL audio support, actual output is mono-only (no positioning yet).
reimar
parents:
diff
changeset
|
196 unqueue_buffers(); |
e0ef5688cce7
OpenAL audio support, actual output is mono-only (no positioning yet).
reimar
parents:
diff
changeset
|
197 } |
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 * \brief stop playing, keep buffers (for pause) |
e0ef5688cce7
OpenAL audio support, actual output is mono-only (no positioning yet).
reimar
parents:
diff
changeset
|
201 */ |
e0ef5688cce7
OpenAL audio support, actual output is mono-only (no positioning yet).
reimar
parents:
diff
changeset
|
202 static void audio_pause(void) { |
e0ef5688cce7
OpenAL audio support, actual output is mono-only (no positioning yet).
reimar
parents:
diff
changeset
|
203 alSourcePausev(ao_data.channels, sources); |
e0ef5688cce7
OpenAL audio support, actual output is mono-only (no positioning yet).
reimar
parents:
diff
changeset
|
204 } |
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 * \brief resume playing, after audio_pause() |
e0ef5688cce7
OpenAL audio support, actual output is mono-only (no positioning yet).
reimar
parents:
diff
changeset
|
208 */ |
e0ef5688cce7
OpenAL audio support, actual output is mono-only (no positioning yet).
reimar
parents:
diff
changeset
|
209 static void audio_resume(void) { |
e0ef5688cce7
OpenAL audio support, actual output is mono-only (no positioning yet).
reimar
parents:
diff
changeset
|
210 alSourcePlayv(ao_data.channels, sources); |
e0ef5688cce7
OpenAL audio support, actual output is mono-only (no positioning yet).
reimar
parents:
diff
changeset
|
211 } |
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 static int get_space(void) { |
e0ef5688cce7
OpenAL audio support, actual output is mono-only (no positioning yet).
reimar
parents:
diff
changeset
|
214 ALint queued; |
e0ef5688cce7
OpenAL audio support, actual output is mono-only (no positioning yet).
reimar
parents:
diff
changeset
|
215 unqueue_buffers(); |
e0ef5688cce7
OpenAL audio support, actual output is mono-only (no positioning yet).
reimar
parents:
diff
changeset
|
216 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
|
217 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
|
218 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
|
219 return queued * CHUNK_SIZE * ao_data.channels; |
17633
e0ef5688cce7
OpenAL audio support, actual output is mono-only (no positioning yet).
reimar
parents:
diff
changeset
|
220 } |
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 * \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
|
224 */ |
e0ef5688cce7
OpenAL audio support, actual output is mono-only (no positioning yet).
reimar
parents:
diff
changeset
|
225 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
|
226 ALint state; |
e0ef5688cce7
OpenAL audio support, actual output is mono-only (no positioning yet).
reimar
parents:
diff
changeset
|
227 int i, j, k; |
e0ef5688cce7
OpenAL audio support, actual output is mono-only (no positioning yet).
reimar
parents:
diff
changeset
|
228 int ch; |
e0ef5688cce7
OpenAL audio support, actual output is mono-only (no positioning yet).
reimar
parents:
diff
changeset
|
229 int16_t *d = data; |
25908
7cf1b1c1c44c
Change code to also work with different outburst sizes
reimar
parents:
25907
diff
changeset
|
230 len /= ao_data.channels * CHUNK_SIZE; |
17633
e0ef5688cce7
OpenAL audio support, actual output is mono-only (no positioning yet).
reimar
parents:
diff
changeset
|
231 for (i = 0; i < len; i++) { |
e0ef5688cce7
OpenAL audio support, actual output is mono-only (no positioning yet).
reimar
parents:
diff
changeset
|
232 for (ch = 0; ch < ao_data.channels; ch++) { |
e0ef5688cce7
OpenAL audio support, actual output is mono-only (no positioning yet).
reimar
parents:
diff
changeset
|
233 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
|
234 tmpbuf[j] = d[k]; |
e0ef5688cce7
OpenAL audio support, actual output is mono-only (no positioning yet).
reimar
parents:
diff
changeset
|
235 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
|
236 CHUNK_SIZE, ao_data.samplerate); |
e0ef5688cce7
OpenAL audio support, actual output is mono-only (no positioning yet).
reimar
parents:
diff
changeset
|
237 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
|
238 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
|
239 } |
e0ef5688cce7
OpenAL audio support, actual output is mono-only (no positioning yet).
reimar
parents:
diff
changeset
|
240 d += ao_data.channels * CHUNK_SIZE / 2; |
e0ef5688cce7
OpenAL audio support, actual output is mono-only (no positioning yet).
reimar
parents:
diff
changeset
|
241 } |
e0ef5688cce7
OpenAL audio support, actual output is mono-only (no positioning yet).
reimar
parents:
diff
changeset
|
242 alGetSourcei(sources[0], AL_SOURCE_STATE, &state); |
e0ef5688cce7
OpenAL audio support, actual output is mono-only (no positioning yet).
reimar
parents:
diff
changeset
|
243 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
|
244 alSourcePlayv(ao_data.channels, sources); |
25908
7cf1b1c1c44c
Change code to also work with different outburst sizes
reimar
parents:
25907
diff
changeset
|
245 return len * ao_data.channels * CHUNK_SIZE; |
17633
e0ef5688cce7
OpenAL audio support, actual output is mono-only (no positioning yet).
reimar
parents:
diff
changeset
|
246 } |
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 static float get_delay(void) { |
e0ef5688cce7
OpenAL audio support, actual output is mono-only (no positioning yet).
reimar
parents:
diff
changeset
|
249 ALint queued; |
e0ef5688cce7
OpenAL audio support, actual output is mono-only (no positioning yet).
reimar
parents:
diff
changeset
|
250 unqueue_buffers(); |
e0ef5688cce7
OpenAL audio support, actual output is mono-only (no positioning yet).
reimar
parents:
diff
changeset
|
251 alGetSourcei(sources[0], AL_BUFFERS_QUEUED, &queued); |
e0ef5688cce7
OpenAL audio support, actual output is mono-only (no positioning yet).
reimar
parents:
diff
changeset
|
252 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
|
253 } |
e0ef5688cce7
OpenAL audio support, actual output is mono-only (no positioning yet).
reimar
parents:
diff
changeset
|
254 |