Mercurial > mplayer.hg
annotate libao2/ao_openal.c @ 29946:54bacf6a38ca
Update the SuperH VEU vidix driver with code that calls fsync() after each
frame to make sure the frame is flushed in case of deferred io.
Patch by Magnus Damm, damm opensource se
author | cehoyos |
---|---|
date | Thu, 10 Dec 2009 23:16:08 +0000 |
parents | 2eff450157cd |
children | 32725ca88fed |
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 } |
e0ef5688cce7
OpenAL audio support, actual output is mono-only (no positioning yet).
reimar
parents:
diff
changeset
|
255 |