Mercurial > mplayer.hg
annotate libao2/ao_openal.c @ 28992:947ef23ba798
Test if create_vdp_decoder() might succeed by calling it from config()
with a small value for max_reference_frames.
This does not make automatic recovery by using software decoder possible,
but lets MPlayer fail more graciously on - actually existing - buggy
hardware that does not support certain H264 widths when using
hardware accelerated decoding (784, 864, 944, 1024, 1808, 1888 pixels on
NVIDIA G98) and if the user tries to hardware-decode more samples at
the same time than supported.
Might break playback of H264 Intra-Only samples on hardware with very
little video memory.
author | cehoyos |
---|---|
date | Sat, 21 Mar 2009 20:11:05 +0000 |
parents | 9a5b8c2ed6de |
children | 0f1b5b68af32 |
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 |
28823 | 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 |