winepulse: Wrap unix call parameters in structs.
[wine.git] / dlls / winepulse.drv / pulse.c
blobfe62a37465ffc643b83513e4848d9da809d0a07a
1 /*
2 * Copyright 2011-2012 Maarten Lankhorst
3 * Copyright 2010-2011 Maarten Lankhorst for CodeWeavers
4 * Copyright 2011 Andrew Eikum for CodeWeavers
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
21 #if 0
22 #pragma makedep unix
23 #endif
25 #include <stdarg.h>
26 #include <pthread.h>
27 #include <math.h>
28 #include <poll.h>
30 #include <pulse/pulseaudio.h>
32 #include "ntstatus.h"
33 #define WIN32_NO_STATUS
34 #include "winternl.h"
36 #include "mmdeviceapi.h"
37 #include "initguid.h"
38 #include "audioclient.h"
40 #include "unixlib.h"
42 #include "wine/debug.h"
44 WINE_DEFAULT_DEBUG_CHANNEL(pulse);
46 struct pulse_stream
48 EDataFlow dataflow;
50 pa_stream *stream;
51 pa_sample_spec ss;
52 pa_channel_map map;
53 pa_buffer_attr attr;
55 DWORD flags;
56 AUDCLNT_SHAREMODE share;
57 HANDLE event;
58 float vol[PA_CHANNELS_MAX];
59 BOOL mute;
61 INT32 locked;
62 BOOL started;
63 SIZE_T bufsize_frames, alloc_size, real_bufsize_bytes, period_bytes;
64 SIZE_T peek_ofs, read_offs_bytes, lcl_offs_bytes, pa_offs_bytes;
65 SIZE_T tmp_buffer_bytes, held_bytes, peek_len, peek_buffer_len, pa_held_bytes;
66 BYTE *local_buffer, *tmp_buffer, *peek_buffer;
67 void *locked_ptr;
68 BOOL please_quit, just_started, just_underran;
69 pa_usec_t last_time, mmdev_period_usec;
71 INT64 clock_lastpos, clock_written;
73 struct list packet_free_head;
74 struct list packet_filled_head;
77 typedef struct _ACPacket
79 struct list entry;
80 UINT64 qpcpos;
81 BYTE *data;
82 UINT32 discont;
83 } ACPacket;
85 static pa_context *pulse_ctx;
86 static pa_mainloop *pulse_ml;
88 /* Mixer format + period times */
89 static WAVEFORMATEXTENSIBLE pulse_fmt[2];
90 static REFERENCE_TIME pulse_min_period[2], pulse_def_period[2];
92 static UINT g_phys_speakers_mask = 0;
94 static const REFERENCE_TIME MinimumPeriod = 30000;
95 static const REFERENCE_TIME DefaultPeriod = 100000;
97 static pthread_mutex_t pulse_mutex;
98 static pthread_cond_t pulse_cond = PTHREAD_COND_INITIALIZER;
100 UINT8 mult_alaw_sample(UINT8, float);
101 UINT8 mult_ulaw_sample(UINT8, float);
103 static void pulse_lock(void)
105 pthread_mutex_lock(&pulse_mutex);
108 static void pulse_unlock(void)
110 pthread_mutex_unlock(&pulse_mutex);
113 static int pulse_cond_wait(void)
115 return pthread_cond_wait(&pulse_cond, &pulse_mutex);
118 static void pulse_broadcast(void)
120 pthread_cond_broadcast(&pulse_cond);
123 static void dump_attr(const pa_buffer_attr *attr)
125 TRACE("maxlength: %u\n", attr->maxlength);
126 TRACE("minreq: %u\n", attr->minreq);
127 TRACE("fragsize: %u\n", attr->fragsize);
128 TRACE("tlength: %u\n", attr->tlength);
129 TRACE("prebuf: %u\n", attr->prebuf);
132 /* copied from kernelbase */
133 static int muldiv(int a, int b, int c)
135 LONGLONG ret;
137 if (!c) return -1;
139 /* We want to deal with a positive divisor to simplify the logic. */
140 if (c < 0)
142 a = -a;
143 c = -c;
146 /* If the result is positive, we "add" to round. else, we subtract to round. */
147 if ((a < 0 && b < 0) || (a >= 0 && b >= 0))
148 ret = (((LONGLONG)a * b) + (c / 2)) / c;
149 else
150 ret = (((LONGLONG)a * b) - (c / 2)) / c;
152 if (ret > 2147483647 || ret < -2147483647) return -1;
153 return ret;
156 /* Following pulseaudio design here, mainloop has the lock taken whenever
157 * it is handling something for pulse, and the lock is required whenever
158 * doing any pa_* call that can affect the state in any way
160 * pa_cond_wait is used when waiting on results, because the mainloop needs
161 * the same lock taken to affect the state
163 * This is basically the same as the pa_threaded_mainloop implementation,
164 * but that cannot be used because it uses pthread_create directly
166 * pa_threaded_mainloop_(un)lock -> pthread_mutex_(un)lock
167 * pa_threaded_mainloop_signal -> pthread_cond_broadcast
168 * pa_threaded_mainloop_wait -> pthread_cond_wait
170 static int pulse_poll_func(struct pollfd *ufds, unsigned long nfds, int timeout, void *userdata)
172 int r;
173 pulse_unlock();
174 r = poll(ufds, nfds, timeout);
175 pulse_lock();
176 return r;
179 static void WINAPI pulse_main_loop(struct main_loop_params *params)
181 int ret;
182 pulse_lock();
183 pulse_ml = pa_mainloop_new();
184 pa_mainloop_set_poll_func(pulse_ml, pulse_poll_func, NULL);
185 NtSetEvent(params->event, NULL);
186 pa_mainloop_run(pulse_ml, &ret);
187 pa_mainloop_free(pulse_ml);
188 pulse_unlock();
191 static void pulse_contextcallback(pa_context *c, void *userdata)
193 switch (pa_context_get_state(c)) {
194 default:
195 FIXME("Unhandled state: %i\n", pa_context_get_state(c));
196 return;
198 case PA_CONTEXT_CONNECTING:
199 case PA_CONTEXT_UNCONNECTED:
200 case PA_CONTEXT_AUTHORIZING:
201 case PA_CONTEXT_SETTING_NAME:
202 case PA_CONTEXT_TERMINATED:
203 TRACE("State change to %i\n", pa_context_get_state(c));
204 return;
206 case PA_CONTEXT_READY:
207 TRACE("Ready\n");
208 break;
210 case PA_CONTEXT_FAILED:
211 WARN("Context failed: %s\n", pa_strerror(pa_context_errno(c)));
212 break;
214 pulse_broadcast();
217 static void pulse_stream_state(pa_stream *s, void *user)
219 pa_stream_state_t state = pa_stream_get_state(s);
220 TRACE("Stream state changed to %i\n", state);
221 pulse_broadcast();
224 static void pulse_attr_update(pa_stream *s, void *user) {
225 const pa_buffer_attr *attr = pa_stream_get_buffer_attr(s);
226 TRACE("New attributes or device moved:\n");
227 dump_attr(attr);
230 static void pulse_underflow_callback(pa_stream *s, void *userdata)
232 struct pulse_stream *stream = userdata;
233 WARN("%p: Underflow\n", userdata);
234 stream->just_underran = TRUE;
235 /* re-sync */
236 stream->pa_offs_bytes = stream->lcl_offs_bytes;
237 stream->pa_held_bytes = stream->held_bytes;
240 static void pulse_started_callback(pa_stream *s, void *userdata)
242 TRACE("%p: (Re)started playing\n", userdata);
245 static void pulse_op_cb(pa_stream *s, int success, void *user)
247 TRACE("Success: %i\n", success);
248 *(int*)user = success;
249 pulse_broadcast();
252 static void silence_buffer(pa_sample_format_t format, BYTE *buffer, UINT32 bytes)
254 memset(buffer, format == PA_SAMPLE_U8 ? 0x80 : 0, bytes);
257 static BOOL pulse_stream_valid(struct pulse_stream *stream)
259 return pa_stream_get_state(stream->stream) == PA_STREAM_READY;
262 static HRESULT pulse_connect(const char *name)
264 if (pulse_ctx && PA_CONTEXT_IS_GOOD(pa_context_get_state(pulse_ctx)))
265 return S_OK;
266 if (pulse_ctx)
267 pa_context_unref(pulse_ctx);
269 pulse_ctx = pa_context_new(pa_mainloop_get_api(pulse_ml), name);
270 if (!pulse_ctx) {
271 ERR("Failed to create context\n");
272 return E_FAIL;
275 pa_context_set_state_callback(pulse_ctx, pulse_contextcallback, NULL);
277 TRACE("libpulse protocol version: %u. API Version %u\n", pa_context_get_protocol_version(pulse_ctx), PA_API_VERSION);
278 if (pa_context_connect(pulse_ctx, NULL, 0, NULL) < 0)
279 goto fail;
281 /* Wait for connection */
282 while (pulse_cond_wait()) {
283 pa_context_state_t state = pa_context_get_state(pulse_ctx);
285 if (state == PA_CONTEXT_FAILED || state == PA_CONTEXT_TERMINATED)
286 goto fail;
288 if (state == PA_CONTEXT_READY)
289 break;
292 TRACE("Connected to server %s with protocol version: %i.\n",
293 pa_context_get_server(pulse_ctx),
294 pa_context_get_server_protocol_version(pulse_ctx));
295 return S_OK;
297 fail:
298 pa_context_unref(pulse_ctx);
299 pulse_ctx = NULL;
300 return E_FAIL;
303 static DWORD pulse_channel_map_to_channel_mask(const pa_channel_map *map)
305 int i;
306 DWORD mask = 0;
308 for (i = 0; i < map->channels; ++i) {
309 switch (map->map[i]) {
310 default: FIXME("Unhandled channel %s\n", pa_channel_position_to_string(map->map[i])); break;
311 case PA_CHANNEL_POSITION_FRONT_LEFT: mask |= SPEAKER_FRONT_LEFT; break;
312 case PA_CHANNEL_POSITION_MONO:
313 case PA_CHANNEL_POSITION_FRONT_CENTER: mask |= SPEAKER_FRONT_CENTER; break;
314 case PA_CHANNEL_POSITION_FRONT_RIGHT: mask |= SPEAKER_FRONT_RIGHT; break;
315 case PA_CHANNEL_POSITION_REAR_LEFT: mask |= SPEAKER_BACK_LEFT; break;
316 case PA_CHANNEL_POSITION_REAR_CENTER: mask |= SPEAKER_BACK_CENTER; break;
317 case PA_CHANNEL_POSITION_REAR_RIGHT: mask |= SPEAKER_BACK_RIGHT; break;
318 case PA_CHANNEL_POSITION_LFE: mask |= SPEAKER_LOW_FREQUENCY; break;
319 case PA_CHANNEL_POSITION_SIDE_LEFT: mask |= SPEAKER_SIDE_LEFT; break;
320 case PA_CHANNEL_POSITION_SIDE_RIGHT: mask |= SPEAKER_SIDE_RIGHT; break;
321 case PA_CHANNEL_POSITION_TOP_CENTER: mask |= SPEAKER_TOP_CENTER; break;
322 case PA_CHANNEL_POSITION_TOP_FRONT_LEFT: mask |= SPEAKER_TOP_FRONT_LEFT; break;
323 case PA_CHANNEL_POSITION_TOP_FRONT_CENTER: mask |= SPEAKER_TOP_FRONT_CENTER; break;
324 case PA_CHANNEL_POSITION_TOP_FRONT_RIGHT: mask |= SPEAKER_TOP_FRONT_RIGHT; break;
325 case PA_CHANNEL_POSITION_TOP_REAR_LEFT: mask |= SPEAKER_TOP_BACK_LEFT; break;
326 case PA_CHANNEL_POSITION_TOP_REAR_CENTER: mask |= SPEAKER_TOP_BACK_CENTER; break;
327 case PA_CHANNEL_POSITION_TOP_REAR_RIGHT: mask |= SPEAKER_TOP_BACK_RIGHT; break;
328 case PA_CHANNEL_POSITION_FRONT_LEFT_OF_CENTER: mask |= SPEAKER_FRONT_LEFT_OF_CENTER; break;
329 case PA_CHANNEL_POSITION_FRONT_RIGHT_OF_CENTER: mask |= SPEAKER_FRONT_RIGHT_OF_CENTER; break;
333 return mask;
336 /* For default PulseAudio render device, OR together all of the
337 * PKEY_AudioEndpoint_PhysicalSpeakers values of the sinks. */
338 static void pulse_phys_speakers_cb(pa_context *c, const pa_sink_info *i, int eol, void *userdata)
340 if (i)
341 g_phys_speakers_mask |= pulse_channel_map_to_channel_mask(&i->channel_map);
344 /* For most hardware on Windows, users must choose a configuration with an even
345 * number of channels (stereo, quad, 5.1, 7.1). Users can then disable
346 * channels, but those channels are still reported to applications from
347 * GetMixFormat! Some applications behave badly if given an odd number of
348 * channels (e.g. 2.1). Here, we find the nearest configuration that Windows
349 * would report for a given channel layout. */
350 static void convert_channel_map(const pa_channel_map *pa_map, WAVEFORMATEXTENSIBLE *fmt)
352 DWORD pa_mask = pulse_channel_map_to_channel_mask(pa_map);
354 TRACE("got mask for PA: 0x%x\n", pa_mask);
356 if (pa_map->channels == 1)
358 fmt->Format.nChannels = 1;
359 fmt->dwChannelMask = pa_mask;
360 return;
363 /* compare against known configurations and find smallest configuration
364 * which is a superset of the given speakers */
366 if (pa_map->channels <= 2 &&
367 (pa_mask & ~KSAUDIO_SPEAKER_STEREO) == 0)
369 fmt->Format.nChannels = 2;
370 fmt->dwChannelMask = KSAUDIO_SPEAKER_STEREO;
371 return;
374 if (pa_map->channels <= 4 &&
375 (pa_mask & ~KSAUDIO_SPEAKER_QUAD) == 0)
377 fmt->Format.nChannels = 4;
378 fmt->dwChannelMask = KSAUDIO_SPEAKER_QUAD;
379 return;
382 if (pa_map->channels <= 4 &&
383 (pa_mask & ~KSAUDIO_SPEAKER_SURROUND) == 0)
385 fmt->Format.nChannels = 4;
386 fmt->dwChannelMask = KSAUDIO_SPEAKER_SURROUND;
387 return;
390 if (pa_map->channels <= 6 &&
391 (pa_mask & ~KSAUDIO_SPEAKER_5POINT1) == 0)
393 fmt->Format.nChannels = 6;
394 fmt->dwChannelMask = KSAUDIO_SPEAKER_5POINT1;
395 return;
398 if (pa_map->channels <= 6 &&
399 (pa_mask & ~KSAUDIO_SPEAKER_5POINT1_SURROUND) == 0)
401 fmt->Format.nChannels = 6;
402 fmt->dwChannelMask = KSAUDIO_SPEAKER_5POINT1_SURROUND;
403 return;
406 if (pa_map->channels <= 8 &&
407 (pa_mask & ~KSAUDIO_SPEAKER_7POINT1) == 0)
409 fmt->Format.nChannels = 8;
410 fmt->dwChannelMask = KSAUDIO_SPEAKER_7POINT1;
411 return;
414 if (pa_map->channels <= 8 &&
415 (pa_mask & ~KSAUDIO_SPEAKER_7POINT1_SURROUND) == 0)
417 fmt->Format.nChannels = 8;
418 fmt->dwChannelMask = KSAUDIO_SPEAKER_7POINT1_SURROUND;
419 return;
422 /* oddball format, report truthfully */
423 fmt->Format.nChannels = pa_map->channels;
424 fmt->dwChannelMask = pa_mask;
427 static void pulse_probe_settings(int render, WAVEFORMATEXTENSIBLE *fmt) {
428 WAVEFORMATEX *wfx = &fmt->Format;
429 pa_stream *stream;
430 pa_channel_map map;
431 pa_sample_spec ss;
432 pa_buffer_attr attr;
433 int ret;
434 unsigned int length = 0;
436 pa_channel_map_init_auto(&map, 2, PA_CHANNEL_MAP_ALSA);
437 ss.rate = 48000;
438 ss.format = PA_SAMPLE_FLOAT32LE;
439 ss.channels = map.channels;
441 attr.maxlength = -1;
442 attr.tlength = -1;
443 attr.minreq = attr.fragsize = pa_frame_size(&ss);
444 attr.prebuf = 0;
446 stream = pa_stream_new(pulse_ctx, "format test stream", &ss, &map);
447 if (stream)
448 pa_stream_set_state_callback(stream, pulse_stream_state, NULL);
449 if (!stream)
450 ret = -1;
451 else if (render)
452 ret = pa_stream_connect_playback(stream, NULL, &attr,
453 PA_STREAM_START_CORKED|PA_STREAM_FIX_RATE|PA_STREAM_FIX_CHANNELS|PA_STREAM_EARLY_REQUESTS, NULL, NULL);
454 else
455 ret = pa_stream_connect_record(stream, NULL, &attr, PA_STREAM_START_CORKED|PA_STREAM_FIX_RATE|PA_STREAM_FIX_CHANNELS|PA_STREAM_EARLY_REQUESTS);
456 if (ret >= 0) {
457 while (pa_mainloop_iterate(pulse_ml, 1, &ret) >= 0 &&
458 pa_stream_get_state(stream) == PA_STREAM_CREATING)
460 if (pa_stream_get_state(stream) == PA_STREAM_READY) {
461 ss = *pa_stream_get_sample_spec(stream);
462 map = *pa_stream_get_channel_map(stream);
463 if (render)
464 length = pa_stream_get_buffer_attr(stream)->minreq;
465 else
466 length = pa_stream_get_buffer_attr(stream)->fragsize;
467 pa_stream_disconnect(stream);
468 while (pa_mainloop_iterate(pulse_ml, 1, &ret) >= 0 &&
469 pa_stream_get_state(stream) == PA_STREAM_READY)
474 if (stream)
475 pa_stream_unref(stream);
477 if (length)
478 pulse_def_period[!render] = pulse_min_period[!render] = pa_bytes_to_usec(10 * length, &ss);
480 if (pulse_min_period[!render] < MinimumPeriod)
481 pulse_min_period[!render] = MinimumPeriod;
483 if (pulse_def_period[!render] < DefaultPeriod)
484 pulse_def_period[!render] = DefaultPeriod;
486 wfx->wFormatTag = WAVE_FORMAT_EXTENSIBLE;
487 wfx->cbSize = sizeof(WAVEFORMATEXTENSIBLE) - sizeof(WAVEFORMATEX);
489 convert_channel_map(&map, fmt);
491 wfx->wBitsPerSample = 8 * pa_sample_size_of_format(ss.format);
492 wfx->nSamplesPerSec = ss.rate;
493 wfx->nBlockAlign = wfx->nChannels * wfx->wBitsPerSample / 8;
494 wfx->nAvgBytesPerSec = wfx->nSamplesPerSec * wfx->nBlockAlign;
495 if (ss.format != PA_SAMPLE_S24_32LE)
496 fmt->Samples.wValidBitsPerSample = wfx->wBitsPerSample;
497 else
498 fmt->Samples.wValidBitsPerSample = 24;
499 if (ss.format == PA_SAMPLE_FLOAT32LE)
500 fmt->SubFormat = KSDATAFORMAT_SUBTYPE_IEEE_FLOAT;
501 else
502 fmt->SubFormat = KSDATAFORMAT_SUBTYPE_PCM;
505 /* some poorly-behaved applications call audio functions during DllMain, so we
506 * have to do as much as possible without creating a new thread. this function
507 * sets up a synchronous connection to verify the server is running and query
508 * static data. */
509 static void WINAPI pulse_test_connect(struct test_connect_params *params)
511 struct pulse_config *config = params->config;
512 pa_operation *o;
513 int ret;
515 pulse_lock();
516 pulse_ml = pa_mainloop_new();
518 pa_mainloop_set_poll_func(pulse_ml, pulse_poll_func, NULL);
520 pulse_ctx = pa_context_new(pa_mainloop_get_api(pulse_ml), params->name);
521 if (!pulse_ctx) {
522 ERR("Failed to create context\n");
523 pa_mainloop_free(pulse_ml);
524 pulse_ml = NULL;
525 pulse_unlock();
526 params->result = E_FAIL;
527 return;
530 pa_context_set_state_callback(pulse_ctx, pulse_contextcallback, NULL);
532 TRACE("libpulse protocol version: %u. API Version %u\n", pa_context_get_protocol_version(pulse_ctx), PA_API_VERSION);
533 if (pa_context_connect(pulse_ctx, NULL, 0, NULL) < 0)
534 goto fail;
536 /* Wait for connection */
537 while (pa_mainloop_iterate(pulse_ml, 1, &ret) >= 0) {
538 pa_context_state_t state = pa_context_get_state(pulse_ctx);
540 if (state == PA_CONTEXT_FAILED || state == PA_CONTEXT_TERMINATED)
541 goto fail;
543 if (state == PA_CONTEXT_READY)
544 break;
547 if (pa_context_get_state(pulse_ctx) != PA_CONTEXT_READY)
548 goto fail;
550 TRACE("Test-connected to server %s with protocol version: %i.\n",
551 pa_context_get_server(pulse_ctx),
552 pa_context_get_server_protocol_version(pulse_ctx));
554 pulse_probe_settings(1, &pulse_fmt[0]);
555 pulse_probe_settings(0, &pulse_fmt[1]);
557 g_phys_speakers_mask = 0;
558 o = pa_context_get_sink_info_list(pulse_ctx, &pulse_phys_speakers_cb, NULL);
559 if (o) {
560 while (pa_mainloop_iterate(pulse_ml, 1, &ret) >= 0 &&
561 pa_operation_get_state(o) == PA_OPERATION_RUNNING)
563 pa_operation_unref(o);
566 pa_context_unref(pulse_ctx);
567 pulse_ctx = NULL;
568 pa_mainloop_free(pulse_ml);
569 pulse_ml = NULL;
571 config->speakers_mask = g_phys_speakers_mask;
572 config->modes[0].format = pulse_fmt[0];
573 config->modes[0].def_period = pulse_def_period[0];
574 config->modes[0].min_period = pulse_min_period[0];
575 config->modes[1].format = pulse_fmt[1];
576 config->modes[1].def_period = pulse_def_period[1];
577 config->modes[1].min_period = pulse_min_period[1];
579 pulse_unlock();
581 params->result = S_OK;
582 return;
584 fail:
585 pa_context_unref(pulse_ctx);
586 pulse_ctx = NULL;
587 pa_mainloop_free(pulse_ml);
588 pulse_ml = NULL;
589 pulse_unlock();
590 params->result = E_FAIL;
593 static DWORD get_channel_mask(unsigned int channels)
595 switch(channels) {
596 case 0:
597 return 0;
598 case 1:
599 return KSAUDIO_SPEAKER_MONO;
600 case 2:
601 return KSAUDIO_SPEAKER_STEREO;
602 case 3:
603 return KSAUDIO_SPEAKER_STEREO | SPEAKER_LOW_FREQUENCY;
604 case 4:
605 return KSAUDIO_SPEAKER_QUAD; /* not _SURROUND */
606 case 5:
607 return KSAUDIO_SPEAKER_QUAD | SPEAKER_LOW_FREQUENCY;
608 case 6:
609 return KSAUDIO_SPEAKER_5POINT1; /* not 5POINT1_SURROUND */
610 case 7:
611 return KSAUDIO_SPEAKER_5POINT1 | SPEAKER_BACK_CENTER;
612 case 8:
613 return KSAUDIO_SPEAKER_7POINT1_SURROUND; /* Vista deprecates 7POINT1 */
615 FIXME("Unknown speaker configuration: %u\n", channels);
616 return 0;
619 static const enum pa_channel_position pulse_pos_from_wfx[] = {
620 PA_CHANNEL_POSITION_FRONT_LEFT,
621 PA_CHANNEL_POSITION_FRONT_RIGHT,
622 PA_CHANNEL_POSITION_FRONT_CENTER,
623 PA_CHANNEL_POSITION_LFE,
624 PA_CHANNEL_POSITION_REAR_LEFT,
625 PA_CHANNEL_POSITION_REAR_RIGHT,
626 PA_CHANNEL_POSITION_FRONT_LEFT_OF_CENTER,
627 PA_CHANNEL_POSITION_FRONT_RIGHT_OF_CENTER,
628 PA_CHANNEL_POSITION_REAR_CENTER,
629 PA_CHANNEL_POSITION_SIDE_LEFT,
630 PA_CHANNEL_POSITION_SIDE_RIGHT,
631 PA_CHANNEL_POSITION_TOP_CENTER,
632 PA_CHANNEL_POSITION_TOP_FRONT_LEFT,
633 PA_CHANNEL_POSITION_TOP_FRONT_CENTER,
634 PA_CHANNEL_POSITION_TOP_FRONT_RIGHT,
635 PA_CHANNEL_POSITION_TOP_REAR_LEFT,
636 PA_CHANNEL_POSITION_TOP_REAR_CENTER,
637 PA_CHANNEL_POSITION_TOP_REAR_RIGHT
640 static HRESULT pulse_spec_from_waveformat(struct pulse_stream *stream, const WAVEFORMATEX *fmt)
642 pa_channel_map_init(&stream->map);
643 stream->ss.rate = fmt->nSamplesPerSec;
644 stream->ss.format = PA_SAMPLE_INVALID;
646 switch(fmt->wFormatTag) {
647 case WAVE_FORMAT_IEEE_FLOAT:
648 if (!fmt->nChannels || fmt->nChannels > 2 || fmt->wBitsPerSample != 32)
649 break;
650 stream->ss.format = PA_SAMPLE_FLOAT32LE;
651 pa_channel_map_init_auto(&stream->map, fmt->nChannels, PA_CHANNEL_MAP_ALSA);
652 break;
653 case WAVE_FORMAT_PCM:
654 if (!fmt->nChannels || fmt->nChannels > 2)
655 break;
656 if (fmt->wBitsPerSample == 8)
657 stream->ss.format = PA_SAMPLE_U8;
658 else if (fmt->wBitsPerSample == 16)
659 stream->ss.format = PA_SAMPLE_S16LE;
660 else
661 return AUDCLNT_E_UNSUPPORTED_FORMAT;
662 pa_channel_map_init_auto(&stream->map, fmt->nChannels, PA_CHANNEL_MAP_ALSA);
663 break;
664 case WAVE_FORMAT_EXTENSIBLE: {
665 WAVEFORMATEXTENSIBLE *wfe = (WAVEFORMATEXTENSIBLE*)fmt;
666 DWORD mask = wfe->dwChannelMask;
667 DWORD i = 0, j;
668 if (fmt->cbSize != (sizeof(*wfe) - sizeof(*fmt)) && fmt->cbSize != sizeof(*wfe))
669 break;
670 if (IsEqualGUID(&wfe->SubFormat, &KSDATAFORMAT_SUBTYPE_IEEE_FLOAT) &&
671 (!wfe->Samples.wValidBitsPerSample || wfe->Samples.wValidBitsPerSample == 32) &&
672 fmt->wBitsPerSample == 32)
673 stream->ss.format = PA_SAMPLE_FLOAT32LE;
674 else if (IsEqualGUID(&wfe->SubFormat, &KSDATAFORMAT_SUBTYPE_PCM)) {
675 DWORD valid = wfe->Samples.wValidBitsPerSample;
676 if (!valid)
677 valid = fmt->wBitsPerSample;
678 if (!valid || valid > fmt->wBitsPerSample)
679 break;
680 switch (fmt->wBitsPerSample) {
681 case 8:
682 if (valid == 8)
683 stream->ss.format = PA_SAMPLE_U8;
684 break;
685 case 16:
686 if (valid == 16)
687 stream->ss.format = PA_SAMPLE_S16LE;
688 break;
689 case 24:
690 if (valid == 24)
691 stream->ss.format = PA_SAMPLE_S24LE;
692 break;
693 case 32:
694 if (valid == 24)
695 stream->ss.format = PA_SAMPLE_S24_32LE;
696 else if (valid == 32)
697 stream->ss.format = PA_SAMPLE_S32LE;
698 break;
699 default:
700 return AUDCLNT_E_UNSUPPORTED_FORMAT;
703 stream->map.channels = fmt->nChannels;
704 if (!mask || (mask & (SPEAKER_ALL|SPEAKER_RESERVED)))
705 mask = get_channel_mask(fmt->nChannels);
706 for (j = 0; j < ARRAY_SIZE(pulse_pos_from_wfx) && i < fmt->nChannels; ++j) {
707 if (mask & (1 << j))
708 stream->map.map[i++] = pulse_pos_from_wfx[j];
711 /* Special case for mono since pulse appears to map it differently */
712 if (mask == SPEAKER_FRONT_CENTER)
713 stream->map.map[0] = PA_CHANNEL_POSITION_MONO;
715 if (i < fmt->nChannels || (mask & SPEAKER_RESERVED)) {
716 stream->map.channels = 0;
717 ERR("Invalid channel mask: %i/%i and %x(%x)\n", i, fmt->nChannels, mask, wfe->dwChannelMask);
718 break;
720 break;
722 case WAVE_FORMAT_ALAW:
723 case WAVE_FORMAT_MULAW:
724 if (fmt->wBitsPerSample != 8) {
725 FIXME("Unsupported bpp %u for LAW\n", fmt->wBitsPerSample);
726 return AUDCLNT_E_UNSUPPORTED_FORMAT;
728 if (fmt->nChannels != 1 && fmt->nChannels != 2) {
729 FIXME("Unsupported channels %u for LAW\n", fmt->nChannels);
730 return AUDCLNT_E_UNSUPPORTED_FORMAT;
732 stream->ss.format = fmt->wFormatTag == WAVE_FORMAT_MULAW ? PA_SAMPLE_ULAW : PA_SAMPLE_ALAW;
733 pa_channel_map_init_auto(&stream->map, fmt->nChannels, PA_CHANNEL_MAP_ALSA);
734 break;
735 default:
736 WARN("Unhandled tag %x\n", fmt->wFormatTag);
737 return AUDCLNT_E_UNSUPPORTED_FORMAT;
739 stream->ss.channels = stream->map.channels;
740 if (!pa_channel_map_valid(&stream->map) || stream->ss.format == PA_SAMPLE_INVALID) {
741 ERR("Invalid format! Channel spec valid: %i, format: %i\n",
742 pa_channel_map_valid(&stream->map), stream->ss.format);
743 return AUDCLNT_E_UNSUPPORTED_FORMAT;
745 return S_OK;
748 static HRESULT pulse_stream_connect(struct pulse_stream *stream, UINT32 period_bytes)
750 int ret;
751 char buffer[64];
752 static LONG number;
753 pa_buffer_attr attr;
755 ret = InterlockedIncrement(&number);
756 sprintf(buffer, "audio stream #%i", ret);
757 stream->stream = pa_stream_new(pulse_ctx, buffer, &stream->ss, &stream->map);
759 if (!stream->stream) {
760 WARN("pa_stream_new returned error %i\n", pa_context_errno(pulse_ctx));
761 return AUDCLNT_E_ENDPOINT_CREATE_FAILED;
764 pa_stream_set_state_callback(stream->stream, pulse_stream_state, stream);
765 pa_stream_set_buffer_attr_callback(stream->stream, pulse_attr_update, stream);
766 pa_stream_set_moved_callback(stream->stream, pulse_attr_update, stream);
768 /* PulseAudio will fill in correct values */
769 attr.minreq = attr.fragsize = period_bytes;
770 attr.tlength = period_bytes * 3;
771 attr.maxlength = stream->bufsize_frames * pa_frame_size(&stream->ss);
772 attr.prebuf = pa_frame_size(&stream->ss);
773 dump_attr(&attr);
774 if (stream->dataflow == eRender)
775 ret = pa_stream_connect_playback(stream->stream, NULL, &attr,
776 PA_STREAM_START_CORKED|PA_STREAM_START_UNMUTED|PA_STREAM_ADJUST_LATENCY, NULL, NULL);
777 else
778 ret = pa_stream_connect_record(stream->stream, NULL, &attr,
779 PA_STREAM_START_CORKED|PA_STREAM_START_UNMUTED|PA_STREAM_ADJUST_LATENCY);
780 if (ret < 0) {
781 WARN("Returns %i\n", ret);
782 return AUDCLNT_E_ENDPOINT_CREATE_FAILED;
784 while (pa_stream_get_state(stream->stream) == PA_STREAM_CREATING)
785 pulse_cond_wait();
786 if (pa_stream_get_state(stream->stream) != PA_STREAM_READY)
787 return AUDCLNT_E_ENDPOINT_CREATE_FAILED;
789 if (stream->dataflow == eRender) {
790 pa_stream_set_underflow_callback(stream->stream, pulse_underflow_callback, stream);
791 pa_stream_set_started_callback(stream->stream, pulse_started_callback, stream);
793 return S_OK;
796 static void WINAPI pulse_create_stream(struct create_stream_params *params)
798 REFERENCE_TIME period, duration = params->duration;
799 struct pulse_stream *stream;
800 unsigned int i, bufsize_bytes;
801 HRESULT hr;
803 pulse_lock();
805 if (FAILED(params->result = pulse_connect(params->name)))
807 pulse_unlock();
808 return;
811 if (!(stream = calloc(1, sizeof(*stream))))
813 pulse_unlock();
814 params->result = E_OUTOFMEMORY;
815 return;
818 stream->dataflow = params->dataflow;
819 for (i = 0; i < ARRAY_SIZE(stream->vol); ++i)
820 stream->vol[i] = 1.f;
822 hr = pulse_spec_from_waveformat(stream, params->fmt);
823 TRACE("Obtaining format returns %08x\n", hr);
825 if (FAILED(hr))
826 goto exit;
828 period = pulse_def_period[stream->dataflow == eCapture];
829 if (duration < 3 * period)
830 duration = 3 * period;
832 stream->period_bytes = pa_frame_size(&stream->ss) * muldiv(period, stream->ss.rate, 10000000);
834 stream->bufsize_frames = ceil((duration / 10000000.) * params->fmt->nSamplesPerSec);
835 bufsize_bytes = stream->bufsize_frames * pa_frame_size(&stream->ss);
836 stream->mmdev_period_usec = period / 10;
838 stream->share = params->mode;
839 stream->flags = params->flags;
840 hr = pulse_stream_connect(stream, stream->period_bytes);
841 if (SUCCEEDED(hr)) {
842 UINT32 unalign;
843 const pa_buffer_attr *attr = pa_stream_get_buffer_attr(stream->stream);
844 stream->attr = *attr;
845 /* Update frames according to new size */
846 dump_attr(attr);
847 if (stream->dataflow == eRender) {
848 stream->alloc_size = stream->real_bufsize_bytes =
849 stream->bufsize_frames * 2 * pa_frame_size(&stream->ss);
850 if (NtAllocateVirtualMemory(GetCurrentProcess(), (void **)&stream->local_buffer,
851 0, &stream->real_bufsize_bytes, MEM_COMMIT, PAGE_READWRITE))
852 hr = E_OUTOFMEMORY;
853 } else {
854 UINT32 i, capture_packets;
856 if ((unalign = bufsize_bytes % stream->period_bytes))
857 bufsize_bytes += stream->period_bytes - unalign;
858 stream->bufsize_frames = bufsize_bytes / pa_frame_size(&stream->ss);
859 stream->real_bufsize_bytes = bufsize_bytes;
861 capture_packets = stream->real_bufsize_bytes / stream->period_bytes;
863 stream->alloc_size = stream->real_bufsize_bytes + capture_packets * sizeof(ACPacket);
864 if (NtAllocateVirtualMemory(GetCurrentProcess(), (void **)&stream->local_buffer,
865 0, &stream->alloc_size, MEM_COMMIT, PAGE_READWRITE))
866 hr = E_OUTOFMEMORY;
867 else {
868 ACPacket *cur_packet = (ACPacket*)((char*)stream->local_buffer + stream->real_bufsize_bytes);
869 BYTE *data = stream->local_buffer;
870 silence_buffer(stream->ss.format, stream->local_buffer, stream->real_bufsize_bytes);
871 list_init(&stream->packet_free_head);
872 list_init(&stream->packet_filled_head);
873 for (i = 0; i < capture_packets; ++i, ++cur_packet) {
874 list_add_tail(&stream->packet_free_head, &cur_packet->entry);
875 cur_packet->data = data;
876 data += stream->period_bytes;
882 *params->channel_count = stream->ss.channels;
883 *params->stream = stream;
885 exit:
886 if (FAILED(params->result = hr)) {
887 free(stream->local_buffer);
888 if (stream->stream) {
889 pa_stream_disconnect(stream->stream);
890 pa_stream_unref(stream->stream);
891 free(stream);
895 pulse_unlock();
898 static void WINAPI pulse_release_stream(struct release_stream_params *params)
900 struct pulse_stream *stream = params->stream;
902 if(params->timer) {
903 stream->please_quit = TRUE;
904 NtWaitForSingleObject(params->timer, FALSE, NULL);
905 NtClose(params->timer);
908 pulse_lock();
909 if (PA_STREAM_IS_GOOD(pa_stream_get_state(stream->stream))) {
910 pa_stream_disconnect(stream->stream);
911 while (PA_STREAM_IS_GOOD(pa_stream_get_state(stream->stream)))
912 pulse_cond_wait();
914 pa_stream_unref(stream->stream);
915 pulse_unlock();
917 if (stream->tmp_buffer)
918 NtFreeVirtualMemory(GetCurrentProcess(), (void **)&stream->tmp_buffer,
919 &stream->tmp_buffer_bytes, MEM_RELEASE);
920 if (stream->local_buffer)
921 NtFreeVirtualMemory(GetCurrentProcess(), (void **)&stream->local_buffer,
922 &stream->alloc_size, MEM_RELEASE);
923 free(stream->peek_buffer);
924 free(stream);
927 static int write_buffer(const struct pulse_stream *stream, BYTE *buffer, UINT32 bytes)
929 const float *vol = stream->vol;
930 UINT32 i, channels, mute = 0;
931 BOOL adjust = FALSE;
932 BYTE *end;
934 if (!bytes) return 0;
936 /* Adjust the buffer based on the volume for each channel */
937 channels = stream->ss.channels;
938 for (i = 0; i < channels; i++)
940 adjust |= vol[i] != 1.0f;
941 if (vol[i] == 0.0f)
942 mute++;
944 if (mute == channels)
946 silence_buffer(stream->ss.format, buffer, bytes);
947 goto write;
949 if (!adjust) goto write;
951 end = buffer + bytes;
952 switch (stream->ss.format)
954 #ifndef WORDS_BIGENDIAN
955 #define PROCESS_BUFFER(type) do \
957 type *p = (type*)buffer; \
958 do \
960 for (i = 0; i < channels; i++) \
961 p[i] = p[i] * vol[i]; \
962 p += i; \
963 } while ((BYTE*)p != end); \
964 } while (0)
965 case PA_SAMPLE_S16LE:
966 PROCESS_BUFFER(INT16);
967 break;
968 case PA_SAMPLE_S32LE:
969 PROCESS_BUFFER(INT32);
970 break;
971 case PA_SAMPLE_FLOAT32LE:
972 PROCESS_BUFFER(float);
973 break;
974 #undef PROCESS_BUFFER
975 case PA_SAMPLE_S24_32LE:
977 UINT32 *p = (UINT32*)buffer;
980 for (i = 0; i < channels; i++)
982 p[i] = (INT32)((INT32)(p[i] << 8) * vol[i]);
983 p[i] >>= 8;
985 p += i;
986 } while ((BYTE*)p != end);
987 break;
989 case PA_SAMPLE_S24LE:
991 /* do it 12 bytes at a time until it is no longer possible */
992 UINT32 *q = (UINT32*)buffer;
993 BYTE *p;
995 i = 0;
996 while (end - (BYTE*)q >= 12)
998 UINT32 v[4], k;
999 v[0] = q[0] << 8;
1000 v[1] = q[1] << 16 | (q[0] >> 16 & ~0xff);
1001 v[2] = q[2] << 24 | (q[1] >> 8 & ~0xff);
1002 v[3] = q[2] & ~0xff;
1003 for (k = 0; k < 4; k++)
1005 v[k] = (INT32)((INT32)v[k] * vol[i]);
1006 if (++i == channels) i = 0;
1008 *q++ = v[0] >> 8 | (v[1] & ~0xff) << 16;
1009 *q++ = v[1] >> 16 | (v[2] & ~0xff) << 8;
1010 *q++ = v[2] >> 24 | (v[3] & ~0xff);
1012 p = (BYTE*)q;
1013 while (p != end)
1015 UINT32 v = (INT32)((INT32)(p[0] << 8 | p[1] << 16 | p[2] << 24) * vol[i]);
1016 *p++ = v >> 8 & 0xff;
1017 *p++ = v >> 16 & 0xff;
1018 *p++ = v >> 24;
1019 if (++i == channels) i = 0;
1021 break;
1023 #endif
1024 case PA_SAMPLE_U8:
1026 UINT8 *p = (UINT8*)buffer;
1029 for (i = 0; i < channels; i++)
1030 p[i] = (int)((p[i] - 128) * vol[i]) + 128;
1031 p += i;
1032 } while ((BYTE*)p != end);
1033 break;
1035 case PA_SAMPLE_ALAW:
1037 UINT8 *p = (UINT8*)buffer;
1040 for (i = 0; i < channels; i++)
1041 p[i] = mult_alaw_sample(p[i], vol[i]);
1042 p += i;
1043 } while ((BYTE*)p != end);
1044 break;
1046 case PA_SAMPLE_ULAW:
1048 UINT8 *p = (UINT8*)buffer;
1051 for (i = 0; i < channels; i++)
1052 p[i] = mult_ulaw_sample(p[i], vol[i]);
1053 p += i;
1054 } while ((BYTE*)p != end);
1055 break;
1057 default:
1058 TRACE("Unhandled format %i, not adjusting volume.\n", stream->ss.format);
1059 break;
1062 write:
1063 return pa_stream_write(stream->stream, buffer, bytes, NULL, 0, PA_SEEK_RELATIVE);
1066 static void pulse_write(struct pulse_stream *stream)
1068 /* write as much data to PA as we can */
1069 UINT32 to_write;
1070 BYTE *buf = stream->local_buffer + stream->pa_offs_bytes;
1071 UINT32 bytes = pa_stream_writable_size(stream->stream);
1073 if (stream->just_underran)
1075 /* prebuffer with silence if needed */
1076 if(stream->pa_held_bytes < bytes){
1077 to_write = bytes - stream->pa_held_bytes;
1078 TRACE("prebuffering %u frames of silence\n",
1079 (int)(to_write / pa_frame_size(&stream->ss)));
1080 buf = calloc(1, to_write);
1081 pa_stream_write(stream->stream, buf, to_write, NULL, 0, PA_SEEK_RELATIVE);
1082 free(buf);
1085 stream->just_underran = FALSE;
1088 buf = stream->local_buffer + stream->pa_offs_bytes;
1089 TRACE("held: %lu, avail: %u\n", stream->pa_held_bytes, bytes);
1090 bytes = min(stream->pa_held_bytes, bytes);
1092 if (stream->pa_offs_bytes + bytes > stream->real_bufsize_bytes)
1094 to_write = stream->real_bufsize_bytes - stream->pa_offs_bytes;
1095 TRACE("writing small chunk of %u bytes\n", to_write);
1096 write_buffer(stream, buf, to_write);
1097 stream->pa_held_bytes -= to_write;
1098 to_write = bytes - to_write;
1099 stream->pa_offs_bytes = 0;
1100 buf = stream->local_buffer;
1102 else
1103 to_write = bytes;
1105 TRACE("writing main chunk of %u bytes\n", to_write);
1106 write_buffer(stream, buf, to_write);
1107 stream->pa_offs_bytes += to_write;
1108 stream->pa_offs_bytes %= stream->real_bufsize_bytes;
1109 stream->pa_held_bytes -= to_write;
1112 static void pulse_read(struct pulse_stream *stream)
1114 size_t bytes = pa_stream_readable_size(stream->stream);
1116 TRACE("Readable total: %zu, fragsize: %u\n", bytes, pa_stream_get_buffer_attr(stream->stream)->fragsize);
1118 bytes += stream->peek_len - stream->peek_ofs;
1120 while (bytes >= stream->period_bytes)
1122 BYTE *dst = NULL, *src;
1123 size_t src_len, copy, rem = stream->period_bytes;
1125 if (stream->started)
1127 LARGE_INTEGER stamp, freq;
1128 ACPacket *p, *next;
1130 if (!(p = (ACPacket*)list_head(&stream->packet_free_head)))
1132 p = (ACPacket*)list_head(&stream->packet_filled_head);
1133 if (!p) return;
1134 if (!p->discont) {
1135 next = (ACPacket*)p->entry.next;
1136 next->discont = 1;
1137 } else
1138 p = (ACPacket*)list_tail(&stream->packet_filled_head);
1140 else
1142 stream->held_bytes += stream->period_bytes;
1144 NtQueryPerformanceCounter(&stamp, &freq);
1145 p->qpcpos = (stamp.QuadPart * (INT64)10000000) / freq.QuadPart;
1146 p->discont = 0;
1147 list_remove(&p->entry);
1148 list_add_tail(&stream->packet_filled_head, &p->entry);
1150 dst = p->data;
1153 while (rem)
1155 if (stream->peek_len)
1157 copy = min(rem, stream->peek_len - stream->peek_ofs);
1159 if (dst)
1161 memcpy(dst, stream->peek_buffer + stream->peek_ofs, copy);
1162 dst += copy;
1165 rem -= copy;
1166 stream->peek_ofs += copy;
1167 if(stream->peek_len == stream->peek_ofs)
1168 stream->peek_len = stream->peek_ofs = 0;
1171 else if (pa_stream_peek(stream->stream, (const void**)&src, &src_len) == 0 && src_len)
1173 copy = min(rem, src_len);
1175 if (dst) {
1176 if(src)
1177 memcpy(dst, src, copy);
1178 else
1179 silence_buffer(stream->ss.format, dst, copy);
1181 dst += copy;
1184 rem -= copy;
1186 if (copy < src_len)
1188 if (src_len > stream->peek_buffer_len)
1190 free(stream->peek_buffer);
1191 stream->peek_buffer = malloc(src_len);
1192 stream->peek_buffer_len = src_len;
1195 if(src)
1196 memcpy(stream->peek_buffer, src + copy, src_len - copy);
1197 else
1198 silence_buffer(stream->ss.format, stream->peek_buffer, src_len - copy);
1200 stream->peek_len = src_len - copy;
1201 stream->peek_ofs = 0;
1204 pa_stream_drop(stream->stream);
1208 bytes -= stream->period_bytes;
1212 static void WINAPI pulse_timer_loop(struct timer_loop_params *params)
1214 struct pulse_stream *stream = params->stream;
1215 LARGE_INTEGER delay;
1216 UINT32 adv_bytes;
1217 int success;
1218 pa_operation *o;
1220 pulse_lock();
1221 delay.QuadPart = -stream->mmdev_period_usec * 10;
1222 pa_stream_get_time(stream->stream, &stream->last_time);
1223 pulse_unlock();
1225 while (!stream->please_quit)
1227 pa_usec_t now, adv_usec = 0;
1228 int err;
1230 NtDelayExecution(FALSE, &delay);
1232 pulse_lock();
1234 delay.QuadPart = -stream->mmdev_period_usec * 10;
1236 o = pa_stream_update_timing_info(stream->stream, pulse_op_cb, &success);
1237 if (o)
1239 while (pa_operation_get_state(o) == PA_OPERATION_RUNNING)
1240 pulse_cond_wait();
1241 pa_operation_unref(o);
1243 err = pa_stream_get_time(stream->stream, &now);
1244 if (err == 0)
1246 TRACE("got now: %s, last time: %s\n", wine_dbgstr_longlong(now), wine_dbgstr_longlong(stream->last_time));
1247 if (stream->started && (stream->dataflow == eCapture || stream->held_bytes))
1249 if(stream->just_underran)
1251 stream->last_time = now;
1252 stream->just_started = TRUE;
1255 if (stream->just_started)
1257 /* let it play out a period to absorb some latency and get accurate timing */
1258 pa_usec_t diff = now - stream->last_time;
1260 if (diff > stream->mmdev_period_usec)
1262 stream->just_started = FALSE;
1263 stream->last_time = now;
1266 else
1268 INT32 adjust = stream->last_time + stream->mmdev_period_usec - now;
1270 adv_usec = now - stream->last_time;
1272 if(adjust > ((INT32)(stream->mmdev_period_usec / 2)))
1273 adjust = stream->mmdev_period_usec / 2;
1274 else if(adjust < -((INT32)(stream->mmdev_period_usec / 2)))
1275 adjust = -1 * stream->mmdev_period_usec / 2;
1277 delay.QuadPart = -(stream->mmdev_period_usec + adjust) * 10;
1279 stream->last_time += stream->mmdev_period_usec;
1282 if (stream->dataflow == eRender)
1284 pulse_write(stream);
1286 /* regardless of what PA does, advance one period */
1287 adv_bytes = min(stream->period_bytes, stream->held_bytes);
1288 stream->lcl_offs_bytes += adv_bytes;
1289 stream->lcl_offs_bytes %= stream->real_bufsize_bytes;
1290 stream->held_bytes -= adv_bytes;
1292 else if(stream->dataflow == eCapture)
1294 pulse_read(stream);
1297 else
1299 stream->last_time = now;
1300 delay.QuadPart = -stream->mmdev_period_usec * 10;
1304 if (stream->event)
1305 NtSetEvent(stream->event, NULL);
1307 TRACE("%p after update, adv usec: %d, held: %u, delay usec: %u\n",
1308 stream, (int)adv_usec,
1309 (int)(stream->held_bytes/ pa_frame_size(&stream->ss)),
1310 (unsigned int)(-delay.QuadPart / 10));
1312 pulse_unlock();
1316 static void WINAPI pulse_start(struct start_params *params)
1318 struct pulse_stream *stream = params->stream;
1319 int success;
1320 pa_operation *o;
1322 params->result = S_OK;
1323 pulse_lock();
1324 if (!pulse_stream_valid(stream))
1326 pulse_unlock();
1327 params->result = S_OK;
1328 return;
1331 if ((stream->flags & AUDCLNT_STREAMFLAGS_EVENTCALLBACK) && !stream->event)
1333 pulse_unlock();
1334 params->result = AUDCLNT_E_EVENTHANDLE_NOT_SET;
1335 return;
1338 if (stream->started)
1340 pulse_unlock();
1341 params->result = AUDCLNT_E_NOT_STOPPED;
1342 return;
1345 pulse_write(stream);
1347 if (pa_stream_is_corked(stream->stream))
1349 o = pa_stream_cork(stream->stream, 0, pulse_op_cb, &success);
1350 if (o)
1352 while(pa_operation_get_state(o) == PA_OPERATION_RUNNING)
1353 pulse_cond_wait();
1354 pa_operation_unref(o);
1356 else
1357 success = 0;
1358 if (!success)
1359 params->result = E_FAIL;
1362 if (SUCCEEDED(params->result))
1364 stream->started = TRUE;
1365 stream->just_started = TRUE;
1367 pulse_unlock();
1370 static void WINAPI pulse_stop(struct stop_params *params)
1372 struct pulse_stream *stream = params->stream;
1373 pa_operation *o;
1374 int success;
1376 pulse_lock();
1377 if (!pulse_stream_valid(stream))
1379 pulse_unlock();
1380 params->result = AUDCLNT_E_DEVICE_INVALIDATED;
1381 return;
1384 if (!stream->started)
1386 pulse_unlock();
1387 params->result = S_FALSE;
1388 return;
1391 params->result = S_OK;
1392 if (stream->dataflow == eRender)
1394 o = pa_stream_cork(stream->stream, 1, pulse_op_cb, &success);
1395 if (o)
1397 while(pa_operation_get_state(o) == PA_OPERATION_RUNNING)
1398 pulse_cond_wait();
1399 pa_operation_unref(o);
1401 else
1402 success = 0;
1403 if (!success)
1404 params->result = E_FAIL;
1406 if (SUCCEEDED(params->result))
1407 stream->started = FALSE;
1408 pulse_unlock();
1411 static void WINAPI pulse_reset(struct reset_params *params)
1413 struct pulse_stream *stream = params->stream;
1415 pulse_lock();
1416 if (!pulse_stream_valid(stream))
1418 pulse_unlock();
1419 params->result = AUDCLNT_E_DEVICE_INVALIDATED;
1420 return;
1423 if (stream->started)
1425 pulse_unlock();
1426 params->result = AUDCLNT_E_NOT_STOPPED;
1427 return;
1430 if (stream->locked)
1432 pulse_unlock();
1433 params->result = AUDCLNT_E_BUFFER_OPERATION_PENDING;
1434 return;
1437 if (stream->dataflow == eRender)
1439 /* If there is still data in the render buffer it needs to be removed from the server */
1440 int success = 0;
1441 if (stream->held_bytes)
1443 pa_operation *o = pa_stream_flush(stream->stream, pulse_op_cb, &success);
1444 if (o)
1446 while (pa_operation_get_state(o) == PA_OPERATION_RUNNING)
1447 pulse_cond_wait();
1448 pa_operation_unref(o);
1451 if (success || !stream->held_bytes)
1453 stream->clock_lastpos = stream->clock_written = 0;
1454 stream->pa_offs_bytes = stream->lcl_offs_bytes = 0;
1455 stream->held_bytes = stream->pa_held_bytes = 0;
1458 else
1460 ACPacket *p;
1461 stream->clock_written += stream->held_bytes;
1462 stream->held_bytes = 0;
1464 if ((p = stream->locked_ptr))
1466 stream->locked_ptr = NULL;
1467 list_add_tail(&stream->packet_free_head, &p->entry);
1469 list_move_tail(&stream->packet_free_head, &stream->packet_filled_head);
1471 pulse_unlock();
1472 params->result = S_OK;
1475 static BOOL alloc_tmp_buffer(struct pulse_stream *stream, SIZE_T bytes)
1477 if (stream->tmp_buffer_bytes >= bytes)
1478 return TRUE;
1480 if (stream->tmp_buffer)
1482 NtFreeVirtualMemory(GetCurrentProcess(), (void **)&stream->tmp_buffer,
1483 &stream->tmp_buffer_bytes, MEM_RELEASE);
1484 stream->tmp_buffer = NULL;
1485 stream->tmp_buffer_bytes = 0;
1487 if (NtAllocateVirtualMemory(GetCurrentProcess(), (void **)&stream->tmp_buffer,
1488 0, &bytes, MEM_COMMIT, PAGE_READWRITE))
1489 return FALSE;
1491 stream->tmp_buffer_bytes = bytes;
1492 return TRUE;
1495 static UINT32 pulse_render_padding(struct pulse_stream *stream)
1497 return stream->held_bytes / pa_frame_size(&stream->ss);
1500 static UINT32 pulse_capture_padding(struct pulse_stream *stream)
1502 ACPacket *packet = stream->locked_ptr;
1503 if (!packet && !list_empty(&stream->packet_filled_head))
1505 packet = (ACPacket*)list_head(&stream->packet_filled_head);
1506 stream->locked_ptr = packet;
1507 list_remove(&packet->entry);
1509 return stream->held_bytes / pa_frame_size(&stream->ss);
1512 static void WINAPI pulse_get_render_buffer(struct get_render_buffer_params *params)
1514 struct pulse_stream *stream = params->stream;
1515 size_t bytes;
1516 UINT32 wri_offs_bytes;
1518 pulse_lock();
1519 if (!pulse_stream_valid(stream))
1521 pulse_unlock();
1522 params->result = AUDCLNT_E_DEVICE_INVALIDATED;
1523 return;
1526 if (stream->locked)
1528 pulse_unlock();
1529 params->result = AUDCLNT_E_OUT_OF_ORDER;
1530 return;
1533 if (!params->frames)
1535 pulse_unlock();
1536 *params->data = NULL;
1537 params->result = S_OK;
1538 return;
1541 if (stream->held_bytes / pa_frame_size(&stream->ss) + params->frames > stream->bufsize_frames)
1543 pulse_unlock();
1544 params->result = AUDCLNT_E_BUFFER_TOO_LARGE;
1545 return;
1548 bytes = params->frames * pa_frame_size(&stream->ss);
1549 wri_offs_bytes = (stream->lcl_offs_bytes + stream->held_bytes) % stream->real_bufsize_bytes;
1550 if (wri_offs_bytes + bytes > stream->real_bufsize_bytes)
1552 if (!alloc_tmp_buffer(stream, bytes))
1554 pulse_unlock();
1555 params->result = E_OUTOFMEMORY;
1556 return;
1558 *params->data = stream->tmp_buffer;
1559 stream->locked = -bytes;
1561 else
1563 *params->data = stream->local_buffer + wri_offs_bytes;
1564 stream->locked = bytes;
1567 silence_buffer(stream->ss.format, *params->data, bytes);
1569 pulse_unlock();
1570 params->result = S_OK;
1573 static void pulse_wrap_buffer(struct pulse_stream *stream, BYTE *buffer, UINT32 written_bytes)
1575 UINT32 wri_offs_bytes = (stream->lcl_offs_bytes + stream->held_bytes) % stream->real_bufsize_bytes;
1576 UINT32 chunk_bytes = stream->real_bufsize_bytes - wri_offs_bytes;
1578 if (written_bytes <= chunk_bytes)
1580 memcpy(stream->local_buffer + wri_offs_bytes, buffer, written_bytes);
1582 else
1584 memcpy(stream->local_buffer + wri_offs_bytes, buffer, chunk_bytes);
1585 memcpy(stream->local_buffer, buffer + chunk_bytes, written_bytes - chunk_bytes);
1589 static void WINAPI pulse_release_render_buffer(struct release_render_buffer_params *params)
1591 struct pulse_stream *stream = params->stream;
1592 UINT32 written_bytes;
1593 BYTE *buffer;
1595 pulse_lock();
1596 if (!stream->locked || !params->written_frames)
1598 stream->locked = 0;
1599 pulse_unlock();
1600 params->result = params->written_frames ? AUDCLNT_E_OUT_OF_ORDER : S_OK;
1601 return;
1604 if (params->written_frames * pa_frame_size(&stream->ss) >
1605 (stream->locked >= 0 ? stream->locked : -stream->locked))
1607 pulse_unlock();
1608 params->result = AUDCLNT_E_INVALID_SIZE;
1609 return;
1612 if (stream->locked >= 0)
1613 buffer = stream->local_buffer + (stream->lcl_offs_bytes + stream->held_bytes) % stream->real_bufsize_bytes;
1614 else
1615 buffer = stream->tmp_buffer;
1617 written_bytes = params->written_frames * pa_frame_size(&stream->ss);
1618 if (params->flags & AUDCLNT_BUFFERFLAGS_SILENT)
1619 silence_buffer(stream->ss.format, buffer, written_bytes);
1621 if (stream->locked < 0)
1622 pulse_wrap_buffer(stream, buffer, written_bytes);
1624 stream->held_bytes += written_bytes;
1625 stream->pa_held_bytes += written_bytes;
1626 if (stream->pa_held_bytes > stream->real_bufsize_bytes)
1628 stream->pa_offs_bytes += stream->pa_held_bytes - stream->real_bufsize_bytes;
1629 stream->pa_offs_bytes %= stream->real_bufsize_bytes;
1630 stream->pa_held_bytes = stream->real_bufsize_bytes;
1632 stream->clock_written += written_bytes;
1633 stream->locked = 0;
1635 TRACE("Released %u, held %lu\n", params->written_frames, stream->held_bytes / pa_frame_size(&stream->ss));
1637 pulse_unlock();
1638 params->result = S_OK;
1641 static void WINAPI pulse_get_capture_buffer(struct get_capture_buffer_params *params)
1643 struct pulse_stream *stream = params->stream;
1644 ACPacket *packet;
1646 pulse_lock();
1647 if (!pulse_stream_valid(stream))
1649 pulse_unlock();
1650 params->result = AUDCLNT_E_DEVICE_INVALIDATED;
1651 return;
1653 if (stream->locked)
1655 pulse_unlock();
1656 params->result = AUDCLNT_E_OUT_OF_ORDER;
1657 return;
1660 pulse_capture_padding(stream);
1661 if ((packet = stream->locked_ptr))
1663 *params->frames = stream->period_bytes / pa_frame_size(&stream->ss);
1664 *params->flags = 0;
1665 if (packet->discont)
1666 *params->flags |= AUDCLNT_BUFFERFLAGS_DATA_DISCONTINUITY;
1667 if (params->devpos)
1669 if (packet->discont)
1670 *params->devpos = (stream->clock_written + stream->period_bytes) / pa_frame_size(&stream->ss);
1671 else
1672 *params->devpos = stream->clock_written / pa_frame_size(&stream->ss);
1674 if (params->qpcpos)
1675 *params->qpcpos = packet->qpcpos;
1676 *params->data = packet->data;
1678 else
1679 *params->frames = 0;
1680 stream->locked = *params->frames;
1681 pulse_unlock();
1682 params->result = *params->frames ? S_OK : AUDCLNT_S_BUFFER_EMPTY;
1685 static void WINAPI pulse_release_capture_buffer(struct release_capture_buffer_params *params)
1687 struct pulse_stream *stream = params->stream;
1689 pulse_lock();
1690 if (!stream->locked && params->done)
1692 pulse_unlock();
1693 params->result = AUDCLNT_E_OUT_OF_ORDER;
1694 return;
1696 if (params->done && stream->locked != params->done)
1698 pulse_unlock();
1699 params->result = AUDCLNT_E_INVALID_SIZE;
1700 return;
1702 if (params->done)
1704 ACPacket *packet = stream->locked_ptr;
1705 stream->locked_ptr = NULL;
1706 stream->held_bytes -= stream->period_bytes;
1707 if (packet->discont)
1708 stream->clock_written += 2 * stream->period_bytes;
1709 else
1710 stream->clock_written += stream->period_bytes;
1711 list_add_tail(&stream->packet_free_head, &packet->entry);
1713 stream->locked = 0;
1714 pulse_unlock();
1715 params->result = S_OK;
1718 static void WINAPI pulse_get_buffer_size(struct get_buffer_size_params *params)
1720 params->result = S_OK;
1722 pulse_lock();
1723 if (!pulse_stream_valid(params->stream))
1724 params->result = AUDCLNT_E_DEVICE_INVALIDATED;
1725 else
1726 *params->size = params->stream->bufsize_frames;
1727 pulse_unlock();
1730 static void WINAPI pulse_get_latency(struct get_latency_params *params)
1732 struct pulse_stream *stream = params->stream;
1733 const pa_buffer_attr *attr;
1734 REFERENCE_TIME lat;
1736 pulse_lock();
1737 if (!pulse_stream_valid(stream)) {
1738 pulse_unlock();
1739 params->result = AUDCLNT_E_DEVICE_INVALIDATED;
1740 return;
1742 attr = pa_stream_get_buffer_attr(stream->stream);
1743 if (stream->dataflow == eRender)
1744 lat = attr->minreq / pa_frame_size(&stream->ss);
1745 else
1746 lat = attr->fragsize / pa_frame_size(&stream->ss);
1747 *params->latency = (lat * 10000000) / stream->ss.rate + pulse_def_period[0];
1748 pulse_unlock();
1749 TRACE("Latency: %u ms\n", (DWORD)(*params->latency / 10000));
1750 params->result = S_OK;
1753 static void WINAPI pulse_get_current_padding(struct get_current_padding_params *params)
1755 struct pulse_stream *stream = params->stream;
1757 pulse_lock();
1758 if (!pulse_stream_valid(stream))
1760 pulse_unlock();
1761 params->result = AUDCLNT_E_DEVICE_INVALIDATED;
1762 return;
1765 if (stream->dataflow == eRender)
1766 *params->padding = pulse_render_padding(stream);
1767 else
1768 *params->padding = pulse_capture_padding(stream);
1769 pulse_unlock();
1771 TRACE("%p Pad: %u ms (%u)\n", stream, muldiv(*params->padding, 1000, stream->ss.rate),
1772 *params->padding);
1773 params->result = S_OK;
1776 static void WINAPI pulse_get_next_packet_size(struct get_next_packet_size_params *params)
1778 struct pulse_stream *stream = params->stream;
1780 pulse_lock();
1781 pulse_capture_padding(stream);
1782 if (stream->locked_ptr)
1783 *params->frames = stream->period_bytes / pa_frame_size(&stream->ss);
1784 else
1785 *params->frames = 0;
1786 pulse_unlock();
1787 params->result = S_OK;
1790 static void WINAPI pulse_get_frequency(struct get_frequency_params *params)
1792 struct pulse_stream *stream = params->stream;
1794 pulse_lock();
1795 if (!pulse_stream_valid(stream))
1797 pulse_unlock();
1798 params->result = AUDCLNT_E_DEVICE_INVALIDATED;
1799 return;
1802 *params->freq = stream->ss.rate;
1803 if (stream->share == AUDCLNT_SHAREMODE_SHARED)
1804 *params->freq *= pa_frame_size(&stream->ss);
1805 pulse_unlock();
1806 params->result = S_OK;
1809 static void WINAPI pulse_get_position(struct get_position_params *params)
1811 struct pulse_stream *stream = params->stream;
1813 pulse_lock();
1814 if (!pulse_stream_valid(stream))
1816 pulse_unlock();
1817 params->result = AUDCLNT_E_DEVICE_INVALIDATED;
1818 return;
1821 *params->pos = stream->clock_written - stream->held_bytes;
1823 if (stream->share == AUDCLNT_SHAREMODE_EXCLUSIVE || params->device)
1824 *params->pos /= pa_frame_size(&stream->ss);
1826 /* Make time never go backwards */
1827 if (*params->pos < stream->clock_lastpos)
1828 *params->pos = stream->clock_lastpos;
1829 else
1830 stream->clock_lastpos = *params->pos;
1831 pulse_unlock();
1833 TRACE("%p Position: %u\n", stream, (unsigned)*params->pos);
1835 if (params->qpctime)
1837 LARGE_INTEGER stamp, freq;
1838 NtQueryPerformanceCounter(&stamp, &freq);
1839 *params->qpctime = (stamp.QuadPart * (INT64)10000000) / freq.QuadPart;
1842 params->result = S_OK;
1845 static void WINAPI pulse_set_volumes(struct set_volumes_params *params)
1847 struct pulse_stream *stream = params->stream;
1848 unsigned int i;
1850 for (i = 0; i < stream->ss.channels; i++)
1851 stream->vol[i] = params->volumes[i] * params->master_volume * params->session_volumes[i];
1854 static void WINAPI pulse_set_event_handle(struct set_event_handle_params *params)
1856 struct pulse_stream *stream = params->stream;
1857 HRESULT hr = S_OK;
1859 pulse_lock();
1860 if (!pulse_stream_valid(stream))
1861 hr = AUDCLNT_E_DEVICE_INVALIDATED;
1862 else if (!(stream->flags & AUDCLNT_STREAMFLAGS_EVENTCALLBACK))
1863 hr = AUDCLNT_E_EVENTHANDLE_NOT_EXPECTED;
1864 else if (stream->event)
1865 hr = HRESULT_FROM_WIN32(ERROR_INVALID_NAME);
1866 else
1867 stream->event = params->event;
1868 pulse_unlock();
1870 params->result = hr;
1873 static void WINAPI pulse_is_started(struct is_started_params *params)
1875 struct pulse_stream *stream = params->stream;
1877 pulse_lock();
1878 params->started = pulse_stream_valid(stream) && stream->started;
1879 pulse_unlock();
1882 static const struct unix_funcs unix_funcs =
1884 pulse_main_loop,
1885 pulse_create_stream,
1886 pulse_release_stream,
1887 pulse_start,
1888 pulse_stop,
1889 pulse_reset,
1890 pulse_timer_loop,
1891 pulse_get_render_buffer,
1892 pulse_release_render_buffer,
1893 pulse_get_capture_buffer,
1894 pulse_release_capture_buffer,
1895 pulse_get_buffer_size,
1896 pulse_get_latency,
1897 pulse_get_current_padding,
1898 pulse_get_next_packet_size,
1899 pulse_get_frequency,
1900 pulse_get_position,
1901 pulse_set_volumes,
1902 pulse_set_event_handle,
1903 pulse_test_connect,
1904 pulse_is_started,
1907 NTSTATUS CDECL __wine_init_unix_lib(HMODULE module, DWORD reason, const void *ptr_in, void *ptr_out)
1909 pthread_mutexattr_t attr;
1911 switch (reason)
1913 case DLL_PROCESS_ATTACH:
1914 pthread_mutexattr_init(&attr);
1915 pthread_mutexattr_setprotocol(&attr, PTHREAD_PRIO_INHERIT);
1917 if (pthread_mutex_init(&pulse_mutex, &attr) != 0)
1918 pthread_mutex_init(&pulse_mutex, NULL);
1920 *(const struct unix_funcs **)ptr_out = &unix_funcs;
1921 break;
1922 case DLL_PROCESS_DETACH:
1923 if (pulse_ctx)
1925 pa_context_disconnect(pulse_ctx);
1926 pa_context_unref(pulse_ctx);
1928 if (pulse_ml)
1929 pa_mainloop_quit(pulse_ml, 0);
1933 return STATUS_SUCCESS;