Mercurial > mplayer.hg
annotate libao2/ao_openal.c @ 21836:7c5e893dff54
Make sure we do not crash when eof is reset, e.g. due to an attempt to seek.
author | reimar |
---|---|
date | Sun, 07 Jan 2007 19:23:59 +0000 |
parents | a29ae9b13a50 |
children | acfe034e5386 |
rev | line source |
---|---|
17633
e0ef5688cce7
OpenAL audio support, actual output is mono-only (no positioning yet).
reimar
parents:
diff
changeset
|
1 /* |
e0ef5688cce7
OpenAL audio support, actual output is mono-only (no positioning yet).
reimar
parents:
diff
changeset
|
2 * ao_openal.c - OpenAL audio output driver for MPlayer |
e0ef5688cce7
OpenAL audio support, actual output is mono-only (no positioning yet).
reimar
parents:
diff
changeset
|
3 * |
e0ef5688cce7
OpenAL audio support, actual output is mono-only (no positioning yet).
reimar
parents:
diff
changeset
|
4 * This driver is under the same license as MPlayer. |
e0ef5688cce7
OpenAL audio support, actual output is mono-only (no positioning yet).
reimar
parents:
diff
changeset
|
5 * (http://www.mplayerhq.hu) |
e0ef5688cce7
OpenAL audio support, actual output is mono-only (no positioning yet).
reimar
parents:
diff
changeset
|
6 * |
e0ef5688cce7
OpenAL audio support, actual output is mono-only (no positioning yet).
reimar
parents:
diff
changeset
|
7 * Copyleft 2006 by Reimar Döffinger (Reimar.Doeffinger@stud.uni-karlsruhe.de) |
e0ef5688cce7
OpenAL audio support, actual output is mono-only (no positioning yet).
reimar
parents:
diff
changeset
|
8 */ |
e0ef5688cce7
OpenAL audio support, actual output is mono-only (no positioning yet).
reimar
parents:
diff
changeset
|
9 |
21556
283bff578e1c
Support OpenAL headers in OpenAL/ instead of AL/ and OpenAL on MacOSX in general.
reimar
parents:
21550
diff
changeset
|
10 #include "config.h" |
283bff578e1c
Support OpenAL headers in OpenAL/ instead of AL/ and OpenAL on MacOSX in general.
reimar
parents:
21550
diff
changeset
|
11 |
17644
87c049a38c36
include stdlib.h and stdio.h, they tend to be useful :-)
reimar
parents:
17633
diff
changeset
|
12 #include <stdlib.h> |
87c049a38c36
include stdlib.h and stdio.h, they tend to be useful :-)
reimar
parents:
17633
diff
changeset
|
13 #include <stdio.h> |
17633
e0ef5688cce7
OpenAL audio support, actual output is mono-only (no positioning yet).
reimar
parents:
diff
changeset
|
14 #include <inttypes.h> |
21556
283bff578e1c
Support OpenAL headers in OpenAL/ instead of AL/ and OpenAL on MacOSX in general.
reimar
parents:
21550
diff
changeset
|
15 #ifdef OPENAL_AL_H |
283bff578e1c
Support OpenAL headers in OpenAL/ instead of AL/ and OpenAL on MacOSX in general.
reimar
parents:
21550
diff
changeset
|
16 #include <OpenAL/alc.h> |
283bff578e1c
Support OpenAL headers in OpenAL/ instead of AL/ and OpenAL on MacOSX in general.
reimar
parents:
21550
diff
changeset
|
17 #include <OpenAL/al.h> |
283bff578e1c
Support OpenAL headers in OpenAL/ instead of AL/ and OpenAL on MacOSX in general.
reimar
parents:
21550
diff
changeset
|
18 #else |
17633
e0ef5688cce7
OpenAL audio support, actual output is mono-only (no positioning yet).
reimar
parents:
diff
changeset
|
19 #include <AL/alc.h> |
e0ef5688cce7
OpenAL audio support, actual output is mono-only (no positioning yet).
reimar
parents:
diff
changeset
|
20 #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
|
21 #endif |
17633
e0ef5688cce7
OpenAL audio support, actual output is mono-only (no positioning yet).
reimar
parents:
diff
changeset
|
22 |
e0ef5688cce7
OpenAL audio support, actual output is mono-only (no positioning yet).
reimar
parents:
diff
changeset
|
23 #include "mp_msg.h" |
e0ef5688cce7
OpenAL audio support, actual output is mono-only (no positioning yet).
reimar
parents:
diff
changeset
|
24 #include "help_mp.h" |
e0ef5688cce7
OpenAL audio support, actual output is mono-only (no positioning yet).
reimar
parents:
diff
changeset
|
25 |
e0ef5688cce7
OpenAL audio support, actual output is mono-only (no positioning yet).
reimar
parents:
diff
changeset
|
26 #include "audio_out.h" |
e0ef5688cce7
OpenAL audio support, actual output is mono-only (no positioning yet).
reimar
parents:
diff
changeset
|
27 #include "audio_out_internal.h" |
e0ef5688cce7
OpenAL audio support, actual output is mono-only (no positioning yet).
reimar
parents:
diff
changeset
|
28 #include "libaf/af_format.h" |
e0ef5688cce7
OpenAL audio support, actual output is mono-only (no positioning yet).
reimar
parents:
diff
changeset
|
29 #include "osdep/timer.h" |
e0ef5688cce7
OpenAL audio support, actual output is mono-only (no positioning yet).
reimar
parents:
diff
changeset
|
30 #include "subopt-helper.h" |
e0ef5688cce7
OpenAL audio support, actual output is mono-only (no positioning yet).
reimar
parents:
diff
changeset
|
31 |
e0ef5688cce7
OpenAL audio support, actual output is mono-only (no positioning yet).
reimar
parents:
diff
changeset
|
32 static ao_info_t info = |
e0ef5688cce7
OpenAL audio support, actual output is mono-only (no positioning yet).
reimar
parents:
diff
changeset
|
33 { |
e0ef5688cce7
OpenAL audio support, actual output is mono-only (no positioning yet).
reimar
parents:
diff
changeset
|
34 "OpenAL audio output", |
e0ef5688cce7
OpenAL audio support, actual output is mono-only (no positioning yet).
reimar
parents:
diff
changeset
|
35 "openal", |
e0ef5688cce7
OpenAL audio support, actual output is mono-only (no positioning yet).
reimar
parents:
diff
changeset
|
36 "Reimar Döffinger <Reimar.Doeffinger@stud.uni-karlsruhe.de>", |
e0ef5688cce7
OpenAL audio support, actual output is mono-only (no positioning yet).
reimar
parents:
diff
changeset
|
37 "" |
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 |
e0ef5688cce7
OpenAL audio support, actual output is mono-only (no positioning yet).
reimar
parents:
diff
changeset
|
40 LIBAO_EXTERN(openal) |
e0ef5688cce7
OpenAL audio support, actual output is mono-only (no positioning yet).
reimar
parents:
diff
changeset
|
41 |
e0ef5688cce7
OpenAL audio support, actual output is mono-only (no positioning yet).
reimar
parents:
diff
changeset
|
42 #define MAX_CHANS 6 |
e0ef5688cce7
OpenAL audio support, actual output is mono-only (no positioning yet).
reimar
parents:
diff
changeset
|
43 #define NUM_BUF 128 |
e0ef5688cce7
OpenAL audio support, actual output is mono-only (no positioning yet).
reimar
parents:
diff
changeset
|
44 #define CHUNK_SIZE 512 |
e0ef5688cce7
OpenAL audio support, actual output is mono-only (no positioning yet).
reimar
parents:
diff
changeset
|
45 static ALuint buffers[MAX_CHANS][NUM_BUF]; |
e0ef5688cce7
OpenAL audio support, actual output is mono-only (no positioning yet).
reimar
parents:
diff
changeset
|
46 static ALuint sources[MAX_CHANS]; |
e0ef5688cce7
OpenAL audio support, actual output is mono-only (no positioning yet).
reimar
parents:
diff
changeset
|
47 |
e0ef5688cce7
OpenAL audio support, actual output is mono-only (no positioning yet).
reimar
parents:
diff
changeset
|
48 static int cur_buf[MAX_CHANS]; |
e0ef5688cce7
OpenAL audio support, actual output is mono-only (no positioning yet).
reimar
parents:
diff
changeset
|
49 static int unqueue_buf[MAX_CHANS]; |
e0ef5688cce7
OpenAL audio support, actual output is mono-only (no positioning yet).
reimar
parents:
diff
changeset
|
50 static int16_t *tmpbuf; |
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 static int control(int cmd, void *arg) { |
21570 | 54 switch (cmd) { |
55 case AOCONTROL_GET_VOLUME: | |
56 case AOCONTROL_SET_VOLUME: { | |
57 ALfloat volume; | |
58 ao_control_vol_t *vol = (ao_control_vol_t *)arg; | |
59 if (cmd == AOCONTROL_SET_VOLUME) { | |
60 volume = (vol->left + vol->right) / 200.0; | |
61 alListenerf(AL_GAIN, volume); | |
62 } | |
63 alGetListenerf(AL_GAIN, &volume); | |
64 vol->left = vol->right = volume * 100; | |
65 return CONTROL_TRUE; | |
66 } | |
67 } | |
17633
e0ef5688cce7
OpenAL audio support, actual output is mono-only (no positioning yet).
reimar
parents:
diff
changeset
|
68 return CONTROL_UNKNOWN; |
e0ef5688cce7
OpenAL audio support, actual output is mono-only (no positioning yet).
reimar
parents:
diff
changeset
|
69 } |
e0ef5688cce7
OpenAL audio support, actual output is mono-only (no positioning yet).
reimar
parents:
diff
changeset
|
70 |
e0ef5688cce7
OpenAL audio support, actual output is mono-only (no positioning yet).
reimar
parents:
diff
changeset
|
71 /** |
e0ef5688cce7
OpenAL audio support, actual output is mono-only (no positioning yet).
reimar
parents:
diff
changeset
|
72 * \brief print suboption usage help |
e0ef5688cce7
OpenAL audio support, actual output is mono-only (no positioning yet).
reimar
parents:
diff
changeset
|
73 */ |
e0ef5688cce7
OpenAL audio support, actual output is mono-only (no positioning yet).
reimar
parents:
diff
changeset
|
74 static void print_help(void) { |
e0ef5688cce7
OpenAL audio support, actual output is mono-only (no positioning yet).
reimar
parents:
diff
changeset
|
75 mp_msg(MSGT_AO, MSGL_FATAL, |
e0ef5688cce7
OpenAL audio support, actual output is mono-only (no positioning yet).
reimar
parents:
diff
changeset
|
76 "\n-ao openal commandline help:\n" |
e0ef5688cce7
OpenAL audio support, actual output is mono-only (no positioning yet).
reimar
parents:
diff
changeset
|
77 "Example: mplayer -ao openal\n" |
e0ef5688cce7
OpenAL audio support, actual output is mono-only (no positioning yet).
reimar
parents:
diff
changeset
|
78 "\nOptions:\n" |
e0ef5688cce7
OpenAL audio support, actual output is mono-only (no positioning yet).
reimar
parents:
diff
changeset
|
79 ); |
e0ef5688cce7
OpenAL audio support, actual output is mono-only (no positioning yet).
reimar
parents:
diff
changeset
|
80 } |
e0ef5688cce7
OpenAL audio support, actual output is mono-only (no positioning yet).
reimar
parents:
diff
changeset
|
81 |
e0ef5688cce7
OpenAL audio support, actual output is mono-only (no positioning yet).
reimar
parents:
diff
changeset
|
82 static int init(int rate, int channels, int format, int flags) { |
21527 | 83 float position[3] = {0, 0, 0}; |
21530 | 84 float direction[6] = {0, 0, 1, 0, -1, 0}; |
21527 | 85 float sppos[6][3] = { |
21530 | 86 {-1, 0, 0.5}, {1, 0, 0.5}, |
87 {-1, 0, -1}, {1, 0, -1}, | |
88 {0, 0, 1}, {0, 0, 0.1}, | |
21527 | 89 }; |
17633
e0ef5688cce7
OpenAL audio support, actual output is mono-only (no positioning yet).
reimar
parents:
diff
changeset
|
90 ALCdevice *dev = NULL; |
e0ef5688cce7
OpenAL audio support, actual output is mono-only (no positioning yet).
reimar
parents:
diff
changeset
|
91 ALCcontext *ctx = NULL; |
21549 | 92 ALCint freq = 0; |
93 ALCint attribs[] = {ALC_FREQUENCY, rate, 0, 0}; | |
17633
e0ef5688cce7
OpenAL audio support, actual output is mono-only (no positioning yet).
reimar
parents:
diff
changeset
|
94 int i; |
e0ef5688cce7
OpenAL audio support, actual output is mono-only (no positioning yet).
reimar
parents:
diff
changeset
|
95 opt_t subopts[] = { |
e0ef5688cce7
OpenAL audio support, actual output is mono-only (no positioning yet).
reimar
parents:
diff
changeset
|
96 {NULL} |
e0ef5688cce7
OpenAL audio support, actual output is mono-only (no positioning yet).
reimar
parents:
diff
changeset
|
97 }; |
e0ef5688cce7
OpenAL audio support, actual output is mono-only (no positioning yet).
reimar
parents:
diff
changeset
|
98 if (subopt_parse(ao_subdevice, subopts) != 0) { |
e0ef5688cce7
OpenAL audio support, actual output is mono-only (no positioning yet).
reimar
parents:
diff
changeset
|
99 print_help(); |
e0ef5688cce7
OpenAL audio support, actual output is mono-only (no positioning yet).
reimar
parents:
diff
changeset
|
100 return 0; |
e0ef5688cce7
OpenAL audio support, actual output is mono-only (no positioning yet).
reimar
parents:
diff
changeset
|
101 } |
e0ef5688cce7
OpenAL audio support, actual output is mono-only (no positioning yet).
reimar
parents:
diff
changeset
|
102 if (channels > MAX_CHANS) { |
e0ef5688cce7
OpenAL audio support, actual output is mono-only (no positioning yet).
reimar
parents:
diff
changeset
|
103 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
|
104 goto err_out; |
e0ef5688cce7
OpenAL audio support, actual output is mono-only (no positioning yet).
reimar
parents:
diff
changeset
|
105 } |
e0ef5688cce7
OpenAL audio support, actual output is mono-only (no positioning yet).
reimar
parents:
diff
changeset
|
106 dev = alcOpenDevice(NULL); |
e0ef5688cce7
OpenAL audio support, actual output is mono-only (no positioning yet).
reimar
parents:
diff
changeset
|
107 if (!dev) { |
e0ef5688cce7
OpenAL audio support, actual output is mono-only (no positioning yet).
reimar
parents:
diff
changeset
|
108 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
|
109 goto err_out; |
e0ef5688cce7
OpenAL audio support, actual output is mono-only (no positioning yet).
reimar
parents:
diff
changeset
|
110 } |
21550 | 111 ctx = alcCreateContext(dev, attribs); |
17633
e0ef5688cce7
OpenAL audio support, actual output is mono-only (no positioning yet).
reimar
parents:
diff
changeset
|
112 alcMakeContextCurrent(ctx); |
21527 | 113 alListenerfv(AL_POSITION, position); |
114 alListenerfv(AL_ORIENTATION, direction); | |
115 alGenSources(channels, sources); | |
17633
e0ef5688cce7
OpenAL audio support, actual output is mono-only (no positioning yet).
reimar
parents:
diff
changeset
|
116 for (i = 0; i < channels; i++) { |
e0ef5688cce7
OpenAL audio support, actual output is mono-only (no positioning yet).
reimar
parents:
diff
changeset
|
117 cur_buf[i] = 0; |
e0ef5688cce7
OpenAL audio support, actual output is mono-only (no positioning yet).
reimar
parents:
diff
changeset
|
118 unqueue_buf[i] = 0; |
e0ef5688cce7
OpenAL audio support, actual output is mono-only (no positioning yet).
reimar
parents:
diff
changeset
|
119 alGenBuffers(NUM_BUF, buffers[i]); |
21527 | 120 alSourcefv(sources[i], AL_POSITION, sppos[i]); |
121 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
|
122 } |
21530 | 123 if (channels == 1) |
124 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
|
125 ao_data.channels = channels; |
21549 | 126 alcGetIntegerv(dev, ALC_FREQUENCY, 1, &freq); |
127 if (alcGetError(dev) == ALC_NO_ERROR && freq) | |
128 rate = freq; | |
129 ao_data.samplerate = rate; | |
17633
e0ef5688cce7
OpenAL audio support, actual output is mono-only (no positioning yet).
reimar
parents:
diff
changeset
|
130 ao_data.format = AF_FORMAT_S16_NE; |
e0ef5688cce7
OpenAL audio support, actual output is mono-only (no positioning yet).
reimar
parents:
diff
changeset
|
131 ao_data.bps = channels * rate * 2; |
e0ef5688cce7
OpenAL audio support, actual output is mono-only (no positioning yet).
reimar
parents:
diff
changeset
|
132 ao_data.buffersize = CHUNK_SIZE * NUM_BUF; |
e0ef5688cce7
OpenAL audio support, actual output is mono-only (no positioning yet).
reimar
parents:
diff
changeset
|
133 ao_data.outburst = channels * CHUNK_SIZE; |
18885 | 134 tmpbuf = malloc(CHUNK_SIZE); |
17633
e0ef5688cce7
OpenAL audio support, actual output is mono-only (no positioning yet).
reimar
parents:
diff
changeset
|
135 return 1; |
e0ef5688cce7
OpenAL audio support, actual output is mono-only (no positioning yet).
reimar
parents:
diff
changeset
|
136 |
e0ef5688cce7
OpenAL audio support, actual output is mono-only (no positioning yet).
reimar
parents:
diff
changeset
|
137 err_out: |
e0ef5688cce7
OpenAL audio support, actual output is mono-only (no positioning yet).
reimar
parents:
diff
changeset
|
138 return 0; |
e0ef5688cce7
OpenAL audio support, actual output is mono-only (no positioning yet).
reimar
parents:
diff
changeset
|
139 } |
e0ef5688cce7
OpenAL audio support, actual output is mono-only (no positioning yet).
reimar
parents:
diff
changeset
|
140 |
e0ef5688cce7
OpenAL audio support, actual output is mono-only (no positioning yet).
reimar
parents:
diff
changeset
|
141 // close audio device |
e0ef5688cce7
OpenAL audio support, actual output is mono-only (no positioning yet).
reimar
parents:
diff
changeset
|
142 static void uninit(int immed) { |
e0ef5688cce7
OpenAL audio support, actual output is mono-only (no positioning yet).
reimar
parents:
diff
changeset
|
143 ALCcontext *ctx = alcGetCurrentContext(); |
e0ef5688cce7
OpenAL audio support, actual output is mono-only (no positioning yet).
reimar
parents:
diff
changeset
|
144 ALCdevice *dev = alcGetContextsDevice(ctx); |
e0ef5688cce7
OpenAL audio support, actual output is mono-only (no positioning yet).
reimar
parents:
diff
changeset
|
145 free(tmpbuf); |
e0ef5688cce7
OpenAL audio support, actual output is mono-only (no positioning yet).
reimar
parents:
diff
changeset
|
146 if (!immed) { |
e0ef5688cce7
OpenAL audio support, actual output is mono-only (no positioning yet).
reimar
parents:
diff
changeset
|
147 ALint state; |
e0ef5688cce7
OpenAL audio support, actual output is mono-only (no positioning yet).
reimar
parents:
diff
changeset
|
148 alGetSourcei(sources[0], AL_SOURCE_STATE, &state); |
e0ef5688cce7
OpenAL audio support, actual output is mono-only (no positioning yet).
reimar
parents:
diff
changeset
|
149 while (state == AL_PLAYING) { |
e0ef5688cce7
OpenAL audio support, actual output is mono-only (no positioning yet).
reimar
parents:
diff
changeset
|
150 usec_sleep(10000); |
e0ef5688cce7
OpenAL audio support, actual output is mono-only (no positioning yet).
reimar
parents:
diff
changeset
|
151 alGetSourcei(sources[0], AL_SOURCE_STATE, &state); |
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 reset(); |
e0ef5688cce7
OpenAL audio support, actual output is mono-only (no positioning yet).
reimar
parents:
diff
changeset
|
155 alcMakeContextCurrent(NULL); |
e0ef5688cce7
OpenAL audio support, actual output is mono-only (no positioning yet).
reimar
parents:
diff
changeset
|
156 alcDestroyContext(ctx); |
e0ef5688cce7
OpenAL audio support, actual output is mono-only (no positioning yet).
reimar
parents:
diff
changeset
|
157 alcCloseDevice(dev); |
e0ef5688cce7
OpenAL audio support, actual output is mono-only (no positioning yet).
reimar
parents:
diff
changeset
|
158 } |
e0ef5688cce7
OpenAL audio support, actual output is mono-only (no positioning yet).
reimar
parents:
diff
changeset
|
159 |
e0ef5688cce7
OpenAL audio support, actual output is mono-only (no positioning yet).
reimar
parents:
diff
changeset
|
160 static void unqueue_buffers(void) { |
e0ef5688cce7
OpenAL audio support, actual output is mono-only (no positioning yet).
reimar
parents:
diff
changeset
|
161 ALint p; |
e0ef5688cce7
OpenAL audio support, actual output is mono-only (no positioning yet).
reimar
parents:
diff
changeset
|
162 int s, i; |
e0ef5688cce7
OpenAL audio support, actual output is mono-only (no positioning yet).
reimar
parents:
diff
changeset
|
163 for (s = 0; s < ao_data.channels; s++) { |
e0ef5688cce7
OpenAL audio support, actual output is mono-only (no positioning yet).
reimar
parents:
diff
changeset
|
164 alGetSourcei(sources[s], AL_BUFFERS_PROCESSED, &p); |
e0ef5688cce7
OpenAL audio support, actual output is mono-only (no positioning yet).
reimar
parents:
diff
changeset
|
165 for (i = 0; i < p; i++) { |
e0ef5688cce7
OpenAL audio support, actual output is mono-only (no positioning yet).
reimar
parents:
diff
changeset
|
166 alSourceUnqueueBuffers(sources[s], 1, &buffers[s][unqueue_buf[s]]); |
e0ef5688cce7
OpenAL audio support, actual output is mono-only (no positioning yet).
reimar
parents:
diff
changeset
|
167 unqueue_buf[s] = (unqueue_buf[s] + 1) % NUM_BUF; |
e0ef5688cce7
OpenAL audio support, actual output is mono-only (no positioning yet).
reimar
parents:
diff
changeset
|
168 } |
e0ef5688cce7
OpenAL audio support, actual output is mono-only (no positioning yet).
reimar
parents:
diff
changeset
|
169 } |
e0ef5688cce7
OpenAL audio support, actual output is mono-only (no positioning yet).
reimar
parents:
diff
changeset
|
170 } |
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 * \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
|
174 */ |
e0ef5688cce7
OpenAL audio support, actual output is mono-only (no positioning yet).
reimar
parents:
diff
changeset
|
175 static void reset(void) { |
e0ef5688cce7
OpenAL audio support, actual output is mono-only (no positioning yet).
reimar
parents:
diff
changeset
|
176 alSourceRewindv(ao_data.channels, sources); |
e0ef5688cce7
OpenAL audio support, actual output is mono-only (no positioning yet).
reimar
parents:
diff
changeset
|
177 unqueue_buffers(); |
e0ef5688cce7
OpenAL audio support, actual output is mono-only (no positioning yet).
reimar
parents:
diff
changeset
|
178 } |
e0ef5688cce7
OpenAL audio support, actual output is mono-only (no positioning yet).
reimar
parents:
diff
changeset
|
179 |
e0ef5688cce7
OpenAL audio support, actual output is mono-only (no positioning yet).
reimar
parents:
diff
changeset
|
180 /** |
e0ef5688cce7
OpenAL audio support, actual output is mono-only (no positioning yet).
reimar
parents:
diff
changeset
|
181 * \brief stop playing, keep buffers (for pause) |
e0ef5688cce7
OpenAL audio support, actual output is mono-only (no positioning yet).
reimar
parents:
diff
changeset
|
182 */ |
e0ef5688cce7
OpenAL audio support, actual output is mono-only (no positioning yet).
reimar
parents:
diff
changeset
|
183 static void audio_pause(void) { |
e0ef5688cce7
OpenAL audio support, actual output is mono-only (no positioning yet).
reimar
parents:
diff
changeset
|
184 alSourcePausev(ao_data.channels, sources); |
e0ef5688cce7
OpenAL audio support, actual output is mono-only (no positioning yet).
reimar
parents:
diff
changeset
|
185 } |
e0ef5688cce7
OpenAL audio support, actual output is mono-only (no positioning yet).
reimar
parents:
diff
changeset
|
186 |
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 * \brief resume playing, after audio_pause() |
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 static void audio_resume(void) { |
e0ef5688cce7
OpenAL audio support, actual output is mono-only (no positioning yet).
reimar
parents:
diff
changeset
|
191 alSourcePlayv(ao_data.channels, sources); |
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 |
e0ef5688cce7
OpenAL audio support, actual output is mono-only (no positioning yet).
reimar
parents:
diff
changeset
|
194 static int get_space(void) { |
e0ef5688cce7
OpenAL audio support, actual output is mono-only (no positioning yet).
reimar
parents:
diff
changeset
|
195 ALint queued; |
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 alGetSourcei(sources[0], AL_BUFFERS_QUEUED, &queued); |
e0ef5688cce7
OpenAL audio support, actual output is mono-only (no positioning yet).
reimar
parents:
diff
changeset
|
198 return (NUM_BUF - queued) * CHUNK_SIZE * ao_data.channels; |
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 /** |
e0ef5688cce7
OpenAL audio support, actual output is mono-only (no positioning yet).
reimar
parents:
diff
changeset
|
202 * \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
|
203 */ |
e0ef5688cce7
OpenAL audio support, actual output is mono-only (no positioning yet).
reimar
parents:
diff
changeset
|
204 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
|
205 ALint state; |
e0ef5688cce7
OpenAL audio support, actual output is mono-only (no positioning yet).
reimar
parents:
diff
changeset
|
206 int i, j, k; |
e0ef5688cce7
OpenAL audio support, actual output is mono-only (no positioning yet).
reimar
parents:
diff
changeset
|
207 int ch; |
e0ef5688cce7
OpenAL audio support, actual output is mono-only (no positioning yet).
reimar
parents:
diff
changeset
|
208 int16_t *d = data; |
e0ef5688cce7
OpenAL audio support, actual output is mono-only (no positioning yet).
reimar
parents:
diff
changeset
|
209 len /= ao_data.outburst; |
e0ef5688cce7
OpenAL audio support, actual output is mono-only (no positioning yet).
reimar
parents:
diff
changeset
|
210 for (i = 0; i < len; i++) { |
e0ef5688cce7
OpenAL audio support, actual output is mono-only (no positioning yet).
reimar
parents:
diff
changeset
|
211 for (ch = 0; ch < ao_data.channels; ch++) { |
e0ef5688cce7
OpenAL audio support, actual output is mono-only (no positioning yet).
reimar
parents:
diff
changeset
|
212 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
|
213 tmpbuf[j] = d[k]; |
e0ef5688cce7
OpenAL audio support, actual output is mono-only (no positioning yet).
reimar
parents:
diff
changeset
|
214 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
|
215 CHUNK_SIZE, ao_data.samplerate); |
e0ef5688cce7
OpenAL audio support, actual output is mono-only (no positioning yet).
reimar
parents:
diff
changeset
|
216 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
|
217 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
|
218 } |
e0ef5688cce7
OpenAL audio support, actual output is mono-only (no positioning yet).
reimar
parents:
diff
changeset
|
219 d += ao_data.channels * CHUNK_SIZE / 2; |
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 alGetSourcei(sources[0], AL_SOURCE_STATE, &state); |
e0ef5688cce7
OpenAL audio support, actual output is mono-only (no positioning yet).
reimar
parents:
diff
changeset
|
222 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
|
223 alSourcePlayv(ao_data.channels, sources); |
e0ef5688cce7
OpenAL audio support, actual output is mono-only (no positioning yet).
reimar
parents:
diff
changeset
|
224 return len * ao_data.outburst; |
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 |
e0ef5688cce7
OpenAL audio support, actual output is mono-only (no positioning yet).
reimar
parents:
diff
changeset
|
227 static float get_delay(void) { |
e0ef5688cce7
OpenAL audio support, actual output is mono-only (no positioning yet).
reimar
parents:
diff
changeset
|
228 ALint queued; |
e0ef5688cce7
OpenAL audio support, actual output is mono-only (no positioning yet).
reimar
parents:
diff
changeset
|
229 unqueue_buffers(); |
e0ef5688cce7
OpenAL audio support, actual output is mono-only (no positioning yet).
reimar
parents:
diff
changeset
|
230 alGetSourcei(sources[0], AL_BUFFERS_QUEUED, &queued); |
e0ef5688cce7
OpenAL audio support, actual output is mono-only (no positioning yet).
reimar
parents:
diff
changeset
|
231 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
|
232 } |
e0ef5688cce7
OpenAL audio support, actual output is mono-only (no positioning yet).
reimar
parents:
diff
changeset
|
233 |