Mercurial > mplayer.hg
annotate libao2/ao_win32.c @ 31671:4541f1921482
Add support for parameter changes (e.g. channel count) during playback.
This makes decoding AAC files that switch between 2 and 6 channels
work reasonably well even with -channels 6 and ffaac decoder.
author | reimar |
---|---|
date | Thu, 15 Jul 2010 17:59:46 +0000 |
parents | 02b9c1a452e1 |
children | 4e9d5dc30c00 |
rev | line source |
---|---|
26743
0f42fb42843c
Use standard license headers with standard formatting.
diego
parents:
23457
diff
changeset
|
1 /* |
0f42fb42843c
Use standard license headers with standard formatting.
diego
parents:
23457
diff
changeset
|
2 * Windows waveOut interface |
7913 | 3 * |
26743
0f42fb42843c
Use standard license headers with standard formatting.
diego
parents:
23457
diff
changeset
|
4 * Copyright (c) 2002 - 2004 Sascha Sommer <saschasommer@freenet.de> |
0f42fb42843c
Use standard license headers with standard formatting.
diego
parents:
23457
diff
changeset
|
5 * |
0f42fb42843c
Use standard license headers with standard formatting.
diego
parents:
23457
diff
changeset
|
6 * This file is part of MPlayer. |
0f42fb42843c
Use standard license headers with standard formatting.
diego
parents:
23457
diff
changeset
|
7 * |
0f42fb42843c
Use standard license headers with standard formatting.
diego
parents:
23457
diff
changeset
|
8 * MPlayer is free software; you can redistribute it and/or modify |
7913 | 9 * it under the terms of the GNU General Public License as published by |
10 * the Free Software Foundation; either version 2 of the License, or | |
11 * (at your option) any later version. | |
12 * | |
26743
0f42fb42843c
Use standard license headers with standard formatting.
diego
parents:
23457
diff
changeset
|
13 * MPlayer is distributed in the hope that it will be useful, |
7913 | 14 * but WITHOUT ANY WARRANTY; without even the implied warranty of |
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
16 * GNU General Public License for more details. | |
17 * | |
26743
0f42fb42843c
Use standard license headers with standard formatting.
diego
parents:
23457
diff
changeset
|
18 * You should have received a copy of the GNU General Public License along |
0f42fb42843c
Use standard license headers with standard formatting.
diego
parents:
23457
diff
changeset
|
19 * with MPlayer; if not, write to the Free Software Foundation, Inc., |
0f42fb42843c
Use standard license headers with standard formatting.
diego
parents:
23457
diff
changeset
|
20 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. |
0f42fb42843c
Use standard license headers with standard formatting.
diego
parents:
23457
diff
changeset
|
21 */ |
7913 | 22 |
23 #include <stdio.h> | |
24 #include <stdlib.h> | |
25 #include <windows.h> | |
26 #include <mmsystem.h> | |
27 | |
14479 | 28 #include "config.h" |
14245 | 29 #include "libaf/af_format.h" |
7913 | 30 #include "audio_out.h" |
31 #include "audio_out_internal.h" | |
14123 | 32 #include "mp_msg.h" |
33 #include "libvo/fastmemcpy.h" | |
12093
f54d02f6ddbf
let uninit wait until sound is completely played, don't restore volume at exit, fixed ringbuffer bug, patch by Nehal <nehalmistry at gmx.net>\n
faust3
parents:
11511
diff
changeset
|
34 #include "osdep/timer.h" |
7913 | 35 |
12699
02efc0619f61
10l WAVE_FORMAT_DOLBY_AC3_SPDIF needs to be defined first, patch by Gianluigi Tiesi <sherpya at netfarm.it>
faust3
parents:
12684
diff
changeset
|
36 #define WAVE_FORMAT_DOLBY_AC3_SPDIF 0x0092 |
13017 | 37 #define WAVE_FORMAT_EXTENSIBLE 0xFFFE |
38 | |
39 static const GUID KSDATAFORMAT_SUBTYPE_PCM = { | |
40 0x1,0x0000,0x0010,{0x80,0x00,0x00,0xaa,0x00,0x38,0x9b,0x71} | |
41 }; | |
42 | |
43 typedef struct { | |
44 WAVEFORMATEX Format; | |
45 union { | |
46 WORD wValidBitsPerSample; | |
47 WORD wSamplesPerBlock; | |
48 WORD wReserved; | |
49 } Samples; | |
50 DWORD dwChannelMask; | |
51 GUID SubFormat; | |
52 } WAVEFORMATEXTENSIBLE, *PWAVEFORMATEXTENSIBLE; | |
53 | |
54 #define SPEAKER_FRONT_LEFT 0x1 | |
55 #define SPEAKER_FRONT_RIGHT 0x2 | |
56 #define SPEAKER_FRONT_CENTER 0x4 | |
57 #define SPEAKER_LOW_FREQUENCY 0x8 | |
58 #define SPEAKER_BACK_LEFT 0x10 | |
59 #define SPEAKER_BACK_RIGHT 0x20 | |
60 #define SPEAKER_FRONT_LEFT_OF_CENTER 0x40 | |
61 #define SPEAKER_FRONT_RIGHT_OF_CENTER 0x80 | |
62 #define SPEAKER_BACK_CENTER 0x100 | |
63 #define SPEAKER_SIDE_LEFT 0x200 | |
64 #define SPEAKER_SIDE_RIGHT 0x400 | |
65 #define SPEAKER_TOP_CENTER 0x800 | |
66 #define SPEAKER_TOP_FRONT_LEFT 0x1000 | |
67 #define SPEAKER_TOP_FRONT_CENTER 0x2000 | |
68 #define SPEAKER_TOP_FRONT_RIGHT 0x4000 | |
69 #define SPEAKER_TOP_BACK_LEFT 0x8000 | |
70 #define SPEAKER_TOP_BACK_CENTER 0x10000 | |
71 #define SPEAKER_TOP_BACK_RIGHT 0x20000 | |
72 | |
73 static const int channel_mask[] = { | |
74 SPEAKER_FRONT_LEFT | SPEAKER_FRONT_RIGHT | SPEAKER_LOW_FREQUENCY, | |
75 SPEAKER_FRONT_LEFT | SPEAKER_FRONT_CENTER | SPEAKER_FRONT_RIGHT | SPEAKER_LOW_FREQUENCY, | |
76 SPEAKER_FRONT_LEFT | SPEAKER_FRONT_CENTER | SPEAKER_FRONT_RIGHT | SPEAKER_BACK_CENTER | SPEAKER_LOW_FREQUENCY, | |
77 SPEAKER_FRONT_LEFT | SPEAKER_FRONT_CENTER | SPEAKER_FRONT_RIGHT | SPEAKER_BACK_LEFT | SPEAKER_BACK_RIGHT | SPEAKER_LOW_FREQUENCY | |
78 }; | |
79 | |
80 | |
12699
02efc0619f61
10l WAVE_FORMAT_DOLBY_AC3_SPDIF needs to be defined first, patch by Gianluigi Tiesi <sherpya at netfarm.it>
faust3
parents:
12684
diff
changeset
|
81 |
12155
deb95ac21f14
restore original ringbuffer constants as the current values are causing heavy stutter here, especially noticable after moving the video window
faust3
parents:
12151
diff
changeset
|
82 #define SAMPLESIZE 1024 |
7913 | 83 #define BUFFER_SIZE 4096 |
12155
deb95ac21f14
restore original ringbuffer constants as the current values are causing heavy stutter here, especially noticable after moving the video window
faust3
parents:
12151
diff
changeset
|
84 #define BUFFER_COUNT 16 |
7913 | 85 |
86 | |
87 static WAVEHDR* waveBlocks; //pointer to our ringbuffer memory | |
88 static HWAVEOUT hWaveOut; //handle to the waveout device | |
89 static unsigned int buf_write=0; | |
28822
2c00a46b99c8
Use code that is actually thread-safe to calculate delay, free space etc. in ao_win32
reimar
parents:
28821
diff
changeset
|
90 static volatile int buf_read=0; |
7913 | 91 |
92 | |
28823 | 93 static const ao_info_t info = |
7913 | 94 { |
95 "Windows waveOut audio output", | |
96 "win32", | |
97 "Sascha Sommer <saschasommer@freenet.de>", | |
98 "" | |
99 }; | |
100 | |
101 LIBAO_EXTERN(win32) | |
102 | |
28821 | 103 static void CALLBACK waveOutProc(HWAVEOUT hWaveOut,UINT uMsg,DWORD dwInstance, |
7913 | 104 DWORD dwParam1,DWORD dwParam2) |
105 { | |
106 if(uMsg != WOM_DONE) | |
107 return; | |
28822
2c00a46b99c8
Use code that is actually thread-safe to calculate delay, free space etc. in ao_win32
reimar
parents:
28821
diff
changeset
|
108 buf_read = (buf_read + 1) % BUFFER_COUNT; |
7913 | 109 } |
110 | |
111 // to set/get/query special features/parameters | |
9633
12b1790038b0
64bit libao2 fix by Jens Axboe <mplayer-dev@kernel.dk>
alex
parents:
9589
diff
changeset
|
112 static int control(int cmd,void *arg) |
7913 | 113 { |
114 DWORD volume; | |
115 switch (cmd) | |
116 { | |
117 case AOCONTROL_GET_VOLUME: | |
118 { | |
119 ao_control_vol_t* vol = (ao_control_vol_t*)arg; | |
120 waveOutGetVolume(hWaveOut,&volume); | |
121 vol->left = (float)(LOWORD(volume)/655.35); | |
122 vol->right = (float)(HIWORD(volume)/655.35); | |
123 mp_msg(MSGT_AO, MSGL_DBG2,"ao_win32: volume left:%f volume right:%f\n",vol->left,vol->right); | |
124 return CONTROL_OK; | |
125 } | |
126 case AOCONTROL_SET_VOLUME: | |
127 { | |
128 ao_control_vol_t* vol = (ao_control_vol_t*)arg; | |
129 volume = MAKELONG(vol->left*655.35,vol->right*655.35); | |
130 waveOutSetVolume(hWaveOut,volume); | |
131 return CONTROL_OK; | |
132 } | |
133 } | |
134 return -1; | |
135 } | |
136 | |
137 // open & setup audio device | |
138 // return: 1=success 0=fail | |
139 static int init(int rate,int channels,int format,int flags) | |
140 { | |
28821 | 141 WAVEFORMATEXTENSIBLE wformat; |
7913 | 142 MMRESULT result; |
143 unsigned char* buffer; | |
144 int i; | |
28821 | 145 |
30241
02b9c1a452e1
Add support for distinguishing between little- and big-endian SPDIF AC3
reimar
parents:
30240
diff
changeset
|
146 if (AF_FORMAT_IS_AC3(format)) |
02b9c1a452e1
Add support for distinguishing between little- and big-endian SPDIF AC3
reimar
parents:
30240
diff
changeset
|
147 format = AF_FORMAT_AC3_NE; |
14135 | 148 switch(format){ |
30241
02b9c1a452e1
Add support for distinguishing between little- and big-endian SPDIF AC3
reimar
parents:
30240
diff
changeset
|
149 case AF_FORMAT_AC3_NE: |
14245 | 150 case AF_FORMAT_S24_LE: |
151 case AF_FORMAT_S16_LE: | |
28815
ce24a9f06ccb
The 8 bit per sample formats are unsigned on Windows, fixes playback with
reimar
parents:
28793
diff
changeset
|
152 case AF_FORMAT_U8: |
14135 | 153 break; |
154 default: | |
14264 | 155 mp_msg(MSGT_AO, MSGL_V,"ao_win32: format %s not supported defaulting to Signed 16-bit Little-Endian\n",af_fmt2str_short(format)); |
14245 | 156 format=AF_FORMAT_S16_LE; |
28821 | 157 } |
19835
807cdfafa0ce
disable multichannel mode, it never worked reliable
faust3
parents:
19614
diff
changeset
|
158 |
807cdfafa0ce
disable multichannel mode, it never worked reliable
faust3
parents:
19614
diff
changeset
|
159 // FIXME multichannel mode is buggy |
807cdfafa0ce
disable multichannel mode, it never worked reliable
faust3
parents:
19614
diff
changeset
|
160 if(channels > 2) |
807cdfafa0ce
disable multichannel mode, it never worked reliable
faust3
parents:
19614
diff
changeset
|
161 channels = 2; |
28821 | 162 |
163 //fill global ao_data | |
7913 | 164 ao_data.channels=channels; |
165 ao_data.samplerate=rate; | |
166 ao_data.format=format; | |
167 ao_data.bps=channels*rate; | |
14245 | 168 if(format != AF_FORMAT_U8 && format != AF_FORMAT_S8) |
7913 | 169 ao_data.bps*=2; |
28818
e3d54ef875a5
Always write full buffers in ao_win32, except for the last block.
reimar
parents:
28817
diff
changeset
|
170 ao_data.outburst = BUFFER_SIZE; |
7913 | 171 if(ao_data.buffersize==-1) |
172 { | |
14264 | 173 ao_data.buffersize=af_fmt2bits(format)/8; |
7913 | 174 ao_data.buffersize*= channels; |
175 ao_data.buffersize*= SAMPLESIZE; | |
176 } | |
14264 | 177 mp_msg(MSGT_AO, MSGL_V,"ao_win32: Samplerate:%iHz Channels:%i Format:%s\n",rate, channels, af_fmt2str_short(format)); |
7913 | 178 mp_msg(MSGT_AO, MSGL_V,"ao_win32: Buffersize:%d\n",ao_data.buffersize); |
28821 | 179 |
7913 | 180 //fill waveformatex |
13017 | 181 ZeroMemory( &wformat, sizeof(WAVEFORMATEXTENSIBLE)); |
13735
83c5f9888576
ringbuffer variable intialization fix for multifile playback patch by Rune Petersen <rune.mail-list at mail.tele.dk>
faust3
parents:
13017
diff
changeset
|
182 wformat.Format.cbSize = (channels>2)?sizeof(WAVEFORMATEXTENSIBLE)-sizeof(WAVEFORMATEX):0; |
28821 | 183 wformat.Format.nChannels = channels; |
184 wformat.Format.nSamplesPerSec = rate; | |
30240 | 185 if(AF_FORMAT_IS_AC3(format)) |
12684
47598beff93a
ac3 passthrough, initial patch by Gianluigi Tiesi <sherpya at netfarm.it>
faust3
parents:
12155
diff
changeset
|
186 { |
13017 | 187 wformat.Format.wFormatTag = WAVE_FORMAT_DOLBY_AC3_SPDIF; |
188 wformat.Format.wBitsPerSample = 16; | |
189 wformat.Format.nBlockAlign = 4; | |
12684
47598beff93a
ac3 passthrough, initial patch by Gianluigi Tiesi <sherpya at netfarm.it>
faust3
parents:
12155
diff
changeset
|
190 } |
28821 | 191 else |
12684
47598beff93a
ac3 passthrough, initial patch by Gianluigi Tiesi <sherpya at netfarm.it>
faust3
parents:
12155
diff
changeset
|
192 { |
13017 | 193 wformat.Format.wFormatTag = (channels>2)?WAVE_FORMAT_EXTENSIBLE:WAVE_FORMAT_PCM; |
28821 | 194 wformat.Format.wBitsPerSample = af_fmt2bits(format); |
13017 | 195 wformat.Format.nBlockAlign = wformat.Format.nChannels * (wformat.Format.wBitsPerSample >> 3); |
196 } | |
197 if(channels>2) | |
198 { | |
199 wformat.dwChannelMask = channel_mask[channels-3]; | |
200 wformat.SubFormat = KSDATAFORMAT_SUBTYPE_PCM; | |
14264 | 201 wformat.Samples.wValidBitsPerSample=af_fmt2bits(format); |
13017 | 202 } |
28821 | 203 |
13017 | 204 wformat.Format.nAvgBytesPerSec = wformat.Format.nSamplesPerSec * wformat.Format.nBlockAlign; |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
28883
diff
changeset
|
205 |
7913 | 206 //open sound device |
207 //WAVE_MAPPER always points to the default wave device on the system | |
14529
cc9c088305d9
WAVE_FORMAT_DIRECT seems to cause problems with certain os/driver combinations and seems to be useless anyway
faust3
parents:
14503
diff
changeset
|
208 result = waveOutOpen(&hWaveOut,WAVE_MAPPER,(WAVEFORMATEX*)&wformat,(DWORD_PTR)waveOutProc,0,CALLBACK_FUNCTION); |
7913 | 209 if(result == WAVERR_BADFORMAT) |
210 { | |
211 mp_msg(MSGT_AO, MSGL_ERR,"ao_win32: format not supported switching to default\n"); | |
13017 | 212 ao_data.channels = wformat.Format.nChannels = 2; |
213 ao_data.samplerate = wformat.Format.nSamplesPerSec = 44100; | |
14245 | 214 ao_data.format = AF_FORMAT_S16_LE; |
13017 | 215 ao_data.bps=ao_data.channels * ao_data.samplerate*2; |
216 wformat.Format.wBitsPerSample=16; | |
217 wformat.Format.wFormatTag=WAVE_FORMAT_PCM; | |
218 wformat.Format.nBlockAlign = wformat.Format.nChannels * (wformat.Format.wBitsPerSample >> 3); | |
219 wformat.Format.nAvgBytesPerSec = wformat.Format.nSamplesPerSec * wformat.Format.nBlockAlign; | |
220 ao_data.buffersize=(wformat.Format.wBitsPerSample>>3)*wformat.Format.nChannels*SAMPLESIZE; | |
221 result = waveOutOpen(&hWaveOut,WAVE_MAPPER,(WAVEFORMATEX*)&wformat,(DWORD_PTR)waveOutProc,0,CALLBACK_FUNCTION); | |
7913 | 222 } |
223 if(result != MMSYSERR_NOERROR) | |
224 { | |
14503 | 225 mp_msg(MSGT_AO, MSGL_ERR,"ao_win32: unable to open wave mapper device (result=%i)\n",result); |
7913 | 226 return 0; |
227 } | |
228 //allocate buffer memory as one big block | |
28817 | 229 buffer = calloc(BUFFER_COUNT, BUFFER_SIZE + sizeof(WAVEHDR)); |
28821 | 230 //and setup pointers to each buffer |
7913 | 231 waveBlocks = (WAVEHDR*)buffer; |
232 buffer += sizeof(WAVEHDR) * BUFFER_COUNT; | |
233 for(i = 0; i < BUFFER_COUNT; i++) { | |
234 waveBlocks[i].lpData = buffer; | |
235 buffer += BUFFER_SIZE; | |
236 } | |
13735
83c5f9888576
ringbuffer variable intialization fix for multifile playback patch by Rune Petersen <rune.mail-list at mail.tele.dk>
faust3
parents:
13017
diff
changeset
|
237 buf_write=0; |
28822
2c00a46b99c8
Use code that is actually thread-safe to calculate delay, free space etc. in ao_win32
reimar
parents:
28821
diff
changeset
|
238 buf_read=0; |
7913 | 239 |
240 return 1; | |
241 } | |
242 | |
243 // close audio device | |
12145 | 244 static void uninit(int immed) |
7913 | 245 { |
28793
afbd8dd23299
Sleep based on get_delay in ao_win32 uninit instead of a loop.
reimar
parents:
28776
diff
changeset
|
246 if(!immed) |
afbd8dd23299
Sleep based on get_delay in ao_win32 uninit instead of a loop.
reimar
parents:
28776
diff
changeset
|
247 usec_sleep(get_delay() * 1000 * 1000); |
28883
c3f295ceae51
Do not call waveOutReset in uninit if you should wait till playing finishes,
reimar
parents:
28823
diff
changeset
|
248 else |
7913 | 249 waveOutReset(hWaveOut); |
28883
c3f295ceae51
Do not call waveOutReset in uninit if you should wait till playing finishes,
reimar
parents:
28823
diff
changeset
|
250 while (waveOutClose(hWaveOut) == WAVERR_STILLPLAYING) usec_sleep(0); |
7913 | 251 mp_msg(MSGT_AO, MSGL_V,"waveOut device closed\n"); |
252 free(waveBlocks); | |
253 mp_msg(MSGT_AO, MSGL_V,"buffer memory freed\n"); | |
254 } | |
255 | |
256 // stop playing and empty buffers (for seeking/pause) | |
18915
99e20a22d5d0
modifies function declarations without parameters from ()
reynaldo
parents:
14529
diff
changeset
|
257 static void reset(void) |
7913 | 258 { |
259 waveOutReset(hWaveOut); | |
260 buf_write=0; | |
28822
2c00a46b99c8
Use code that is actually thread-safe to calculate delay, free space etc. in ao_win32
reimar
parents:
28821
diff
changeset
|
261 buf_read=0; |
7913 | 262 } |
263 | |
264 // stop playing, keep buffers (for pause) | |
18915
99e20a22d5d0
modifies function declarations without parameters from ()
reynaldo
parents:
14529
diff
changeset
|
265 static void audio_pause(void) |
7913 | 266 { |
267 waveOutPause(hWaveOut); | |
268 } | |
269 | |
270 // resume playing, after audio_pause() | |
18915
99e20a22d5d0
modifies function declarations without parameters from ()
reynaldo
parents:
14529
diff
changeset
|
271 static void audio_resume(void) |
7913 | 272 { |
273 waveOutRestart(hWaveOut); | |
274 } | |
275 | |
276 // return: how many bytes can be played without blocking | |
18915
99e20a22d5d0
modifies function declarations without parameters from ()
reynaldo
parents:
14529
diff
changeset
|
277 static int get_space(void) |
7913 | 278 { |
28822
2c00a46b99c8
Use code that is actually thread-safe to calculate delay, free space etc. in ao_win32
reimar
parents:
28821
diff
changeset
|
279 int free = buf_read - buf_write - 1; |
2c00a46b99c8
Use code that is actually thread-safe to calculate delay, free space etc. in ao_win32
reimar
parents:
28821
diff
changeset
|
280 if (free < 0) free += BUFFER_COUNT; |
2c00a46b99c8
Use code that is actually thread-safe to calculate delay, free space etc. in ao_win32
reimar
parents:
28821
diff
changeset
|
281 return free * BUFFER_SIZE; |
7913 | 282 } |
283 | |
284 //writes data into buffer, based on ringbuffer code in ao_sdl.c | |
285 static int write_waveOutBuffer(unsigned char* data,int len){ | |
286 WAVEHDR* current; | |
287 int len2=0; | |
288 int x; | |
28821 | 289 while(len>0){ |
28822
2c00a46b99c8
Use code that is actually thread-safe to calculate delay, free space etc. in ao_win32
reimar
parents:
28821
diff
changeset
|
290 int buf_next = (buf_write + 1) % BUFFER_COUNT; |
7913 | 291 current = &waveBlocks[buf_write]; |
28822
2c00a46b99c8
Use code that is actually thread-safe to calculate delay, free space etc. in ao_win32
reimar
parents:
28821
diff
changeset
|
292 if(buf_next == buf_read) break; |
7913 | 293 //unprepare the header if it is prepared |
28821 | 294 if(current->dwFlags & WHDR_PREPARED) |
7913 | 295 waveOutUnprepareHeader(hWaveOut, current, sizeof(WAVEHDR)); |
28821 | 296 x=BUFFER_SIZE; |
297 if(x>len) x=len; | |
298 fast_memcpy(current->lpData,data+len2,x); | |
299 len2+=x; len-=x; | |
7913 | 300 //prepare header and write data to device |
28818
e3d54ef875a5
Always write full buffers in ao_win32, except for the last block.
reimar
parents:
28817
diff
changeset
|
301 current->dwBufferLength = x; |
7913 | 302 waveOutPrepareHeader(hWaveOut, current, sizeof(WAVEHDR)); |
303 waveOutWrite(hWaveOut, current, sizeof(WAVEHDR)); | |
28821 | 304 |
28822
2c00a46b99c8
Use code that is actually thread-safe to calculate delay, free space etc. in ao_win32
reimar
parents:
28821
diff
changeset
|
305 buf_write = buf_next; |
7913 | 306 } |
307 return len2; | |
308 } | |
309 | |
310 // plays 'len' bytes of 'data' | |
311 // it should round it down to outburst*n | |
312 // return: number of bytes played | |
313 static int play(void* data,int len,int flags) | |
314 { | |
20250
7cfd3a04d537
Implement AOPLAY_FINAL_CHUNK support for dshow and win32 out.
reimar
parents:
19835
diff
changeset
|
315 if (!(flags & AOPLAY_FINAL_CHUNK)) |
12151
75fdb659f5bf
round len to outburst and increment full_buffers at the correct time, patch by Nehal <nehalmistry at gmx.net>
faust3
parents:
12146
diff
changeset
|
316 len = (len/ao_data.outburst)*ao_data.outburst; |
7913 | 317 return write_waveOutBuffer(data,len); |
318 } | |
10106 | 319 |
7913 | 320 // return: delay in seconds between first and last sample in buffer |
18915
99e20a22d5d0
modifies function declarations without parameters from ()
reynaldo
parents:
14529
diff
changeset
|
321 static float get_delay(void) |
7913 | 322 { |
28822
2c00a46b99c8
Use code that is actually thread-safe to calculate delay, free space etc. in ao_win32
reimar
parents:
28821
diff
changeset
|
323 int used = buf_write - buf_read; |
2c00a46b99c8
Use code that is actually thread-safe to calculate delay, free space etc. in ao_win32
reimar
parents:
28821
diff
changeset
|
324 if (used < 0) used += BUFFER_COUNT; |
2c00a46b99c8
Use code that is actually thread-safe to calculate delay, free space etc. in ao_win32
reimar
parents:
28821
diff
changeset
|
325 return (float)(used * BUFFER_SIZE + ao_data.buffersize)/(float)ao_data.bps; |
7913 | 326 } |