annotate libao2/ao_openal.c @ 36545:f0e92381681d

Add support for files with MLTI chunks. Fixes 06.rm and 08_lect_01.rm from FFmpeg trac #2152 Fixes also files from ftp://ftp.aduni.org/videos/ The patch has these limitations: - no multirate files with MLTI chunks - no mixed files (eg. MLTI for audio but not for video) - no MLTI for video together with non-ra audio (eg. ralf) - only DATA v0 (no v1, versions greater than 1 should not exist) Files with these feature shuld not really exist anyway. Also video MLTI files with only one stream are supported but untested
author rtogni
date Sun, 19 Jan 2014 15:12:46 +0000
parents 32725ca88fed
children
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
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
acfe034e5386 ISO8859-1 --> UTF-8
diego
parents: 21570
diff changeset
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
acfe034e5386 ISO8859-1 --> UTF-8
diego
parents: 21570
diff changeset
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
60819382adfe OpenAL: untested support for 8-channel audio.
reimar
parents: 29263
diff changeset
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
a29ae9b13a50 OpenAL volume control
reimar
parents: 21556
diff changeset
67 switch (cmd) {
a29ae9b13a50 OpenAL volume control
reimar
parents: 21556
diff changeset
68 case AOCONTROL_GET_VOLUME:
a29ae9b13a50 OpenAL volume control
reimar
parents: 21556
diff changeset
69 case AOCONTROL_SET_VOLUME: {
a29ae9b13a50 OpenAL volume control
reimar
parents: 21556
diff changeset
70 ALfloat volume;
a29ae9b13a50 OpenAL volume control
reimar
parents: 21556
diff changeset
71 ao_control_vol_t *vol = (ao_control_vol_t *)arg;
a29ae9b13a50 OpenAL volume control
reimar
parents: 21556
diff changeset
72 if (cmd == AOCONTROL_SET_VOLUME) {
a29ae9b13a50 OpenAL volume control
reimar
parents: 21556
diff changeset
73 volume = (vol->left + vol->right) / 200.0;
a29ae9b13a50 OpenAL volume control
reimar
parents: 21556
diff changeset
74 alListenerf(AL_GAIN, volume);
a29ae9b13a50 OpenAL volume control
reimar
parents: 21556
diff changeset
75 }
a29ae9b13a50 OpenAL volume control
reimar
parents: 21556
diff changeset
76 alGetListenerf(AL_GAIN, &volume);
a29ae9b13a50 OpenAL volume control
reimar
parents: 21556
diff changeset
77 vol->left = vol->right = volume * 100;
a29ae9b13a50 OpenAL volume control
reimar
parents: 21556
diff changeset
78 return CONTROL_TRUE;
a29ae9b13a50 OpenAL volume control
reimar
parents: 21556
diff changeset
79 }
a29ae9b13a50 OpenAL volume control
reimar
parents: 21556
diff changeset
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
9b228834e07b Half-properly set up OpenAL position stuff
reimar
parents: 18885
diff changeset
96 float position[3] = {0, 0, 0};
21530
b755687aa485 Improve OpenAL speaker positions a bit.
reimar
parents: 21527
diff changeset
97 float direction[6] = {0, 0, 1, 0, -1, 0};
29500
60819382adfe OpenAL: untested support for 8-channel audio.
reimar
parents: 29263
diff changeset
98 float sppos[MAX_CHANS][3] = {
21530
b755687aa485 Improve OpenAL speaker positions a bit.
reimar
parents: 21527
diff changeset
99 {-1, 0, 0.5}, {1, 0, 0.5},
b755687aa485 Improve OpenAL speaker positions a bit.
reimar
parents: 21527
diff changeset
100 {-1, 0, -1}, {1, 0, -1},
b755687aa485 Improve OpenAL speaker positions a bit.
reimar
parents: 21527
diff changeset
101 {0, 0, 1}, {0, 0, 0.1},
29500
60819382adfe OpenAL: untested support for 8-channel audio.
reimar
parents: 29263
diff changeset
102 {-1, 0, 0}, {1, 0, 0},
21527
9b228834e07b Half-properly set up OpenAL position stuff
reimar
parents: 18885
diff changeset
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
4a6d3fa76982 Set frequency and correct frequency getting
reimar
parents: 21530
diff changeset
106 ALCint freq = 0;
4a6d3fa76982 Set frequency and correct frequency getting
reimar
parents: 21530
diff changeset
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
9d9e0f1ef0e9 Fix a compiler warning
reimar
parents: 21549
diff changeset
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
9b228834e07b Half-properly set up OpenAL position stuff
reimar
parents: 18885
diff changeset
127 alListenerfv(AL_POSITION, position);
9b228834e07b Half-properly set up OpenAL position stuff
reimar
parents: 18885
diff changeset
128 alListenerfv(AL_ORIENTATION, direction);
9b228834e07b Half-properly set up OpenAL position stuff
reimar
parents: 18885
diff changeset
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
9b228834e07b Half-properly set up OpenAL position stuff
reimar
parents: 18885
diff changeset
134 alSourcefv(sources[i], AL_POSITION, sppos[i]);
9b228834e07b Half-properly set up OpenAL position stuff
reimar
parents: 18885
diff changeset
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
b755687aa485 Improve OpenAL speaker positions a bit.
reimar
parents: 21527
diff changeset
137 if (channels == 1)
b755687aa485 Improve OpenAL speaker positions a bit.
reimar
parents: 21527
diff changeset
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
4a6d3fa76982 Set frequency and correct frequency getting
reimar
parents: 21530
diff changeset
140 alcGetIntegerv(dev, ALC_FREQUENCY, 1, &freq);
4a6d3fa76982 Set frequency and correct frequency getting
reimar
parents: 21530
diff changeset
141 if (alcGetError(dev) == ALC_NO_ERROR && freq)
4a6d3fa76982 Set frequency and correct frequency getting
reimar
parents: 21530
diff changeset
142 rate = freq;
4a6d3fa76982 Set frequency and correct frequency getting
reimar
parents: 21530
diff changeset
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
5c8acc972551 rm unnecesary casts from void* - part 4
reynaldo
parents: 17644
diff changeset
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
74db93fee74f Remove unused variable.
reimar
parents: 25909
diff changeset
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
bc8452f11147 Reduce number of UnqueueBuffer calls
reimar
parents: 25906
diff changeset
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
bc8452f11147 Reduce number of UnqueueBuffer calls
reimar
parents: 25906
diff changeset
180 if (p >= till_wrap) {
bc8452f11147 Reduce number of UnqueueBuffer calls
reimar
parents: 25906
diff changeset
181 alSourceUnqueueBuffers(sources[s], till_wrap, &buffers[s][unqueue_buf[s]]);
bc8452f11147 Reduce number of UnqueueBuffer calls
reimar
parents: 25906
diff changeset
182 unqueue_buf[s] = 0;
bc8452f11147 Reduce number of UnqueueBuffer calls
reimar
parents: 25906
diff changeset
183 p -= till_wrap;
bc8452f11147 Reduce number of UnqueueBuffer calls
reimar
parents: 25906
diff changeset
184 }
bc8452f11147 Reduce number of UnqueueBuffer calls
reimar
parents: 25906
diff changeset
185 if (p) {
bc8452f11147 Reduce number of UnqueueBuffer calls
reimar
parents: 25906
diff changeset
186 alSourceUnqueueBuffers(sources[s], p, &buffers[s][unqueue_buf[s]]);
bc8452f11147 Reduce number of UnqueueBuffer calls
reimar
parents: 25906
diff changeset
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 }