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
32 #include <pulse/pulseaudio.h>
35 #define WIN32_NO_STATUS
38 #include "mmdeviceapi.h"
40 #include "audioclient.h"
44 #include "wine/debug.h"
46 WINE_DEFAULT_DEBUG_CHANNEL(pulse
);
58 AUDCLNT_SHAREMODE share
;
60 float vol
[PA_CHANNELS_MAX
];
65 SIZE_T bufsize_frames
, alloc_size
, real_bufsize_bytes
, period_bytes
;
66 SIZE_T peek_ofs
, read_offs_bytes
, lcl_offs_bytes
, pa_offs_bytes
;
67 SIZE_T tmp_buffer_bytes
, held_bytes
, peek_len
, peek_buffer_len
, pa_held_bytes
;
68 BYTE
*local_buffer
, *tmp_buffer
, *peek_buffer
;
70 BOOL please_quit
, just_started
, just_underran
;
71 pa_usec_t last_time
, mmdev_period_usec
;
73 INT64 clock_lastpos
, clock_written
;
75 struct list packet_free_head
;
76 struct list packet_filled_head
;
79 typedef struct _ACPacket
87 static pa_context
*pulse_ctx
;
88 static pa_mainloop
*pulse_ml
;
90 /* Mixer format + period times */
91 static WAVEFORMATEXTENSIBLE pulse_fmt
[2];
92 static REFERENCE_TIME pulse_min_period
[2], pulse_def_period
[2];
94 static UINT g_phys_speakers_mask
= 0;
96 static const REFERENCE_TIME MinimumPeriod
= 30000;
97 static const REFERENCE_TIME DefaultPeriod
= 100000;
99 static pthread_mutex_t pulse_mutex
;
100 static pthread_cond_t pulse_cond
= PTHREAD_COND_INITIALIZER
;
102 UINT8
mult_alaw_sample(UINT8
, float);
103 UINT8
mult_ulaw_sample(UINT8
, float);
105 static void pulse_lock(void)
107 pthread_mutex_lock(&pulse_mutex
);
110 static void pulse_unlock(void)
112 pthread_mutex_unlock(&pulse_mutex
);
115 static int pulse_cond_wait(void)
117 return pthread_cond_wait(&pulse_cond
, &pulse_mutex
);
120 static void pulse_broadcast(void)
122 pthread_cond_broadcast(&pulse_cond
);
125 static void dump_attr(const pa_buffer_attr
*attr
)
127 TRACE("maxlength: %u\n", attr
->maxlength
);
128 TRACE("minreq: %u\n", attr
->minreq
);
129 TRACE("fragsize: %u\n", attr
->fragsize
);
130 TRACE("tlength: %u\n", attr
->tlength
);
131 TRACE("prebuf: %u\n", attr
->prebuf
);
134 /* copied from kernelbase */
135 static int muldiv(int a
, int b
, int c
)
141 /* We want to deal with a positive divisor to simplify the logic. */
148 /* If the result is positive, we "add" to round. else, we subtract to round. */
149 if ((a
< 0 && b
< 0) || (a
>= 0 && b
>= 0))
150 ret
= (((LONGLONG
)a
* b
) + (c
/ 2)) / c
;
152 ret
= (((LONGLONG
)a
* b
) - (c
/ 2)) / c
;
154 if (ret
> 2147483647 || ret
< -2147483647) return -1;
158 /* Following pulseaudio design here, mainloop has the lock taken whenever
159 * it is handling something for pulse, and the lock is required whenever
160 * doing any pa_* call that can affect the state in any way
162 * pa_cond_wait is used when waiting on results, because the mainloop needs
163 * the same lock taken to affect the state
165 * This is basically the same as the pa_threaded_mainloop implementation,
166 * but that cannot be used because it uses pthread_create directly
168 * pa_threaded_mainloop_(un)lock -> pthread_mutex_(un)lock
169 * pa_threaded_mainloop_signal -> pthread_cond_broadcast
170 * pa_threaded_mainloop_wait -> pthread_cond_wait
172 static int pulse_poll_func(struct pollfd
*ufds
, unsigned long nfds
, int timeout
, void *userdata
)
176 r
= poll(ufds
, nfds
, timeout
);
181 static NTSTATUS
pulse_main_loop(void *args
)
183 struct main_loop_params
*params
= args
;
186 pulse_ml
= pa_mainloop_new();
187 pa_mainloop_set_poll_func(pulse_ml
, pulse_poll_func
, NULL
);
188 NtSetEvent(params
->event
, NULL
);
189 pa_mainloop_run(pulse_ml
, &ret
);
190 pa_mainloop_free(pulse_ml
);
192 return STATUS_SUCCESS
;
195 static void pulse_contextcallback(pa_context
*c
, void *userdata
)
197 switch (pa_context_get_state(c
)) {
199 FIXME("Unhandled state: %i\n", pa_context_get_state(c
));
202 case PA_CONTEXT_CONNECTING
:
203 case PA_CONTEXT_UNCONNECTED
:
204 case PA_CONTEXT_AUTHORIZING
:
205 case PA_CONTEXT_SETTING_NAME
:
206 case PA_CONTEXT_TERMINATED
:
207 TRACE("State change to %i\n", pa_context_get_state(c
));
210 case PA_CONTEXT_READY
:
214 case PA_CONTEXT_FAILED
:
215 WARN("Context failed: %s\n", pa_strerror(pa_context_errno(c
)));
221 static void pulse_stream_state(pa_stream
*s
, void *user
)
223 pa_stream_state_t state
= pa_stream_get_state(s
);
224 TRACE("Stream state changed to %i\n", state
);
228 static void pulse_attr_update(pa_stream
*s
, void *user
) {
229 const pa_buffer_attr
*attr
= pa_stream_get_buffer_attr(s
);
230 TRACE("New attributes or device moved:\n");
234 static void pulse_underflow_callback(pa_stream
*s
, void *userdata
)
236 struct pulse_stream
*stream
= userdata
;
237 WARN("%p: Underflow\n", userdata
);
238 stream
->just_underran
= TRUE
;
240 stream
->pa_offs_bytes
= stream
->lcl_offs_bytes
;
241 stream
->pa_held_bytes
= stream
->held_bytes
;
244 static void pulse_started_callback(pa_stream
*s
, void *userdata
)
246 TRACE("%p: (Re)started playing\n", userdata
);
249 static void pulse_op_cb(pa_stream
*s
, int success
, void *user
)
251 TRACE("Success: %i\n", success
);
252 *(int*)user
= success
;
256 static void silence_buffer(pa_sample_format_t format
, BYTE
*buffer
, UINT32 bytes
)
258 memset(buffer
, format
== PA_SAMPLE_U8
? 0x80 : 0, bytes
);
261 static BOOL
pulse_stream_valid(struct pulse_stream
*stream
)
263 return pa_stream_get_state(stream
->stream
) == PA_STREAM_READY
;
266 static HRESULT
pulse_connect(const char *name
)
268 if (pulse_ctx
&& PA_CONTEXT_IS_GOOD(pa_context_get_state(pulse_ctx
)))
271 pa_context_unref(pulse_ctx
);
273 pulse_ctx
= pa_context_new(pa_mainloop_get_api(pulse_ml
), name
);
275 ERR("Failed to create context\n");
279 pa_context_set_state_callback(pulse_ctx
, pulse_contextcallback
, NULL
);
281 TRACE("libpulse protocol version: %u. API Version %u\n", pa_context_get_protocol_version(pulse_ctx
), PA_API_VERSION
);
282 if (pa_context_connect(pulse_ctx
, NULL
, 0, NULL
) < 0)
285 /* Wait for connection */
286 while (pulse_cond_wait()) {
287 pa_context_state_t state
= pa_context_get_state(pulse_ctx
);
289 if (state
== PA_CONTEXT_FAILED
|| state
== PA_CONTEXT_TERMINATED
)
292 if (state
== PA_CONTEXT_READY
)
296 TRACE("Connected to server %s with protocol version: %i.\n",
297 pa_context_get_server(pulse_ctx
),
298 pa_context_get_server_protocol_version(pulse_ctx
));
302 pa_context_unref(pulse_ctx
);
307 static DWORD
pulse_channel_map_to_channel_mask(const pa_channel_map
*map
)
312 for (i
= 0; i
< map
->channels
; ++i
) {
313 switch (map
->map
[i
]) {
314 default: FIXME("Unhandled channel %s\n", pa_channel_position_to_string(map
->map
[i
])); break;
315 case PA_CHANNEL_POSITION_FRONT_LEFT
: mask
|= SPEAKER_FRONT_LEFT
; break;
316 case PA_CHANNEL_POSITION_MONO
:
317 case PA_CHANNEL_POSITION_FRONT_CENTER
: mask
|= SPEAKER_FRONT_CENTER
; break;
318 case PA_CHANNEL_POSITION_FRONT_RIGHT
: mask
|= SPEAKER_FRONT_RIGHT
; break;
319 case PA_CHANNEL_POSITION_REAR_LEFT
: mask
|= SPEAKER_BACK_LEFT
; break;
320 case PA_CHANNEL_POSITION_REAR_CENTER
: mask
|= SPEAKER_BACK_CENTER
; break;
321 case PA_CHANNEL_POSITION_REAR_RIGHT
: mask
|= SPEAKER_BACK_RIGHT
; break;
322 case PA_CHANNEL_POSITION_LFE
: mask
|= SPEAKER_LOW_FREQUENCY
; break;
323 case PA_CHANNEL_POSITION_SIDE_LEFT
: mask
|= SPEAKER_SIDE_LEFT
; break;
324 case PA_CHANNEL_POSITION_SIDE_RIGHT
: mask
|= SPEAKER_SIDE_RIGHT
; break;
325 case PA_CHANNEL_POSITION_TOP_CENTER
: mask
|= SPEAKER_TOP_CENTER
; break;
326 case PA_CHANNEL_POSITION_TOP_FRONT_LEFT
: mask
|= SPEAKER_TOP_FRONT_LEFT
; break;
327 case PA_CHANNEL_POSITION_TOP_FRONT_CENTER
: mask
|= SPEAKER_TOP_FRONT_CENTER
; break;
328 case PA_CHANNEL_POSITION_TOP_FRONT_RIGHT
: mask
|= SPEAKER_TOP_FRONT_RIGHT
; break;
329 case PA_CHANNEL_POSITION_TOP_REAR_LEFT
: mask
|= SPEAKER_TOP_BACK_LEFT
; break;
330 case PA_CHANNEL_POSITION_TOP_REAR_CENTER
: mask
|= SPEAKER_TOP_BACK_CENTER
; break;
331 case PA_CHANNEL_POSITION_TOP_REAR_RIGHT
: mask
|= SPEAKER_TOP_BACK_RIGHT
; break;
332 case PA_CHANNEL_POSITION_FRONT_LEFT_OF_CENTER
: mask
|= SPEAKER_FRONT_LEFT_OF_CENTER
; break;
333 case PA_CHANNEL_POSITION_FRONT_RIGHT_OF_CENTER
: mask
|= SPEAKER_FRONT_RIGHT_OF_CENTER
; break;
340 /* For default PulseAudio render device, OR together all of the
341 * PKEY_AudioEndpoint_PhysicalSpeakers values of the sinks. */
342 static void pulse_phys_speakers_cb(pa_context
*c
, const pa_sink_info
*i
, int eol
, void *userdata
)
345 g_phys_speakers_mask
|= pulse_channel_map_to_channel_mask(&i
->channel_map
);
348 /* For most hardware on Windows, users must choose a configuration with an even
349 * number of channels (stereo, quad, 5.1, 7.1). Users can then disable
350 * channels, but those channels are still reported to applications from
351 * GetMixFormat! Some applications behave badly if given an odd number of
352 * channels (e.g. 2.1). Here, we find the nearest configuration that Windows
353 * would report for a given channel layout. */
354 static void convert_channel_map(const pa_channel_map
*pa_map
, WAVEFORMATEXTENSIBLE
*fmt
)
356 DWORD pa_mask
= pulse_channel_map_to_channel_mask(pa_map
);
358 TRACE("got mask for PA: 0x%x\n", pa_mask
);
360 if (pa_map
->channels
== 1)
362 fmt
->Format
.nChannels
= 1;
363 fmt
->dwChannelMask
= pa_mask
;
367 /* compare against known configurations and find smallest configuration
368 * which is a superset of the given speakers */
370 if (pa_map
->channels
<= 2 &&
371 (pa_mask
& ~KSAUDIO_SPEAKER_STEREO
) == 0)
373 fmt
->Format
.nChannels
= 2;
374 fmt
->dwChannelMask
= KSAUDIO_SPEAKER_STEREO
;
378 if (pa_map
->channels
<= 4 &&
379 (pa_mask
& ~KSAUDIO_SPEAKER_QUAD
) == 0)
381 fmt
->Format
.nChannels
= 4;
382 fmt
->dwChannelMask
= KSAUDIO_SPEAKER_QUAD
;
386 if (pa_map
->channels
<= 4 &&
387 (pa_mask
& ~KSAUDIO_SPEAKER_SURROUND
) == 0)
389 fmt
->Format
.nChannels
= 4;
390 fmt
->dwChannelMask
= KSAUDIO_SPEAKER_SURROUND
;
394 if (pa_map
->channels
<= 6 &&
395 (pa_mask
& ~KSAUDIO_SPEAKER_5POINT1
) == 0)
397 fmt
->Format
.nChannels
= 6;
398 fmt
->dwChannelMask
= KSAUDIO_SPEAKER_5POINT1
;
402 if (pa_map
->channels
<= 6 &&
403 (pa_mask
& ~KSAUDIO_SPEAKER_5POINT1_SURROUND
) == 0)
405 fmt
->Format
.nChannels
= 6;
406 fmt
->dwChannelMask
= KSAUDIO_SPEAKER_5POINT1_SURROUND
;
410 if (pa_map
->channels
<= 8 &&
411 (pa_mask
& ~KSAUDIO_SPEAKER_7POINT1
) == 0)
413 fmt
->Format
.nChannels
= 8;
414 fmt
->dwChannelMask
= KSAUDIO_SPEAKER_7POINT1
;
418 if (pa_map
->channels
<= 8 &&
419 (pa_mask
& ~KSAUDIO_SPEAKER_7POINT1_SURROUND
) == 0)
421 fmt
->Format
.nChannels
= 8;
422 fmt
->dwChannelMask
= KSAUDIO_SPEAKER_7POINT1_SURROUND
;
426 /* oddball format, report truthfully */
427 fmt
->Format
.nChannels
= pa_map
->channels
;
428 fmt
->dwChannelMask
= pa_mask
;
431 static void pulse_probe_settings(int render
, WAVEFORMATEXTENSIBLE
*fmt
) {
432 WAVEFORMATEX
*wfx
= &fmt
->Format
;
438 unsigned int length
= 0;
440 pa_channel_map_init_auto(&map
, 2, PA_CHANNEL_MAP_ALSA
);
442 ss
.format
= PA_SAMPLE_FLOAT32LE
;
443 ss
.channels
= map
.channels
;
447 attr
.minreq
= attr
.fragsize
= pa_frame_size(&ss
);
450 stream
= pa_stream_new(pulse_ctx
, "format test stream", &ss
, &map
);
452 pa_stream_set_state_callback(stream
, pulse_stream_state
, NULL
);
456 ret
= pa_stream_connect_playback(stream
, NULL
, &attr
,
457 PA_STREAM_START_CORKED
|PA_STREAM_FIX_RATE
|PA_STREAM_FIX_CHANNELS
|PA_STREAM_EARLY_REQUESTS
, NULL
, NULL
);
459 ret
= pa_stream_connect_record(stream
, NULL
, &attr
, PA_STREAM_START_CORKED
|PA_STREAM_FIX_RATE
|PA_STREAM_FIX_CHANNELS
|PA_STREAM_EARLY_REQUESTS
);
461 while (pa_mainloop_iterate(pulse_ml
, 1, &ret
) >= 0 &&
462 pa_stream_get_state(stream
) == PA_STREAM_CREATING
)
464 if (pa_stream_get_state(stream
) == PA_STREAM_READY
) {
465 ss
= *pa_stream_get_sample_spec(stream
);
466 map
= *pa_stream_get_channel_map(stream
);
468 length
= pa_stream_get_buffer_attr(stream
)->minreq
;
470 length
= pa_stream_get_buffer_attr(stream
)->fragsize
;
471 pa_stream_disconnect(stream
);
472 while (pa_mainloop_iterate(pulse_ml
, 1, &ret
) >= 0 &&
473 pa_stream_get_state(stream
) == PA_STREAM_READY
)
479 pa_stream_unref(stream
);
482 pulse_def_period
[!render
] = pulse_min_period
[!render
] = pa_bytes_to_usec(10 * length
, &ss
);
484 if (pulse_min_period
[!render
] < MinimumPeriod
)
485 pulse_min_period
[!render
] = MinimumPeriod
;
487 if (pulse_def_period
[!render
] < DefaultPeriod
)
488 pulse_def_period
[!render
] = DefaultPeriod
;
490 wfx
->wFormatTag
= WAVE_FORMAT_EXTENSIBLE
;
491 wfx
->cbSize
= sizeof(WAVEFORMATEXTENSIBLE
) - sizeof(WAVEFORMATEX
);
493 convert_channel_map(&map
, fmt
);
495 wfx
->wBitsPerSample
= 8 * pa_sample_size_of_format(ss
.format
);
496 wfx
->nSamplesPerSec
= ss
.rate
;
497 wfx
->nBlockAlign
= wfx
->nChannels
* wfx
->wBitsPerSample
/ 8;
498 wfx
->nAvgBytesPerSec
= wfx
->nSamplesPerSec
* wfx
->nBlockAlign
;
499 if (ss
.format
!= PA_SAMPLE_S24_32LE
)
500 fmt
->Samples
.wValidBitsPerSample
= wfx
->wBitsPerSample
;
502 fmt
->Samples
.wValidBitsPerSample
= 24;
503 if (ss
.format
== PA_SAMPLE_FLOAT32LE
)
504 fmt
->SubFormat
= KSDATAFORMAT_SUBTYPE_IEEE_FLOAT
;
506 fmt
->SubFormat
= KSDATAFORMAT_SUBTYPE_PCM
;
509 /* some poorly-behaved applications call audio functions during DllMain, so we
510 * have to do as much as possible without creating a new thread. this function
511 * sets up a synchronous connection to verify the server is running and query
513 static NTSTATUS
pulse_test_connect(void *args
)
515 struct test_connect_params
*params
= args
;
516 struct pulse_config
*config
= params
->config
;
521 pulse_ml
= pa_mainloop_new();
523 pa_mainloop_set_poll_func(pulse_ml
, pulse_poll_func
, NULL
);
525 pulse_ctx
= pa_context_new(pa_mainloop_get_api(pulse_ml
), params
->name
);
527 ERR("Failed to create context\n");
528 pa_mainloop_free(pulse_ml
);
531 params
->result
= E_FAIL
;
532 return STATUS_SUCCESS
;
535 pa_context_set_state_callback(pulse_ctx
, pulse_contextcallback
, NULL
);
537 TRACE("libpulse protocol version: %u. API Version %u\n", pa_context_get_protocol_version(pulse_ctx
), PA_API_VERSION
);
538 if (pa_context_connect(pulse_ctx
, NULL
, 0, NULL
) < 0)
541 /* Wait for connection */
542 while (pa_mainloop_iterate(pulse_ml
, 1, &ret
) >= 0) {
543 pa_context_state_t state
= pa_context_get_state(pulse_ctx
);
545 if (state
== PA_CONTEXT_FAILED
|| state
== PA_CONTEXT_TERMINATED
)
548 if (state
== PA_CONTEXT_READY
)
552 if (pa_context_get_state(pulse_ctx
) != PA_CONTEXT_READY
)
555 TRACE("Test-connected to server %s with protocol version: %i.\n",
556 pa_context_get_server(pulse_ctx
),
557 pa_context_get_server_protocol_version(pulse_ctx
));
559 pulse_probe_settings(1, &pulse_fmt
[0]);
560 pulse_probe_settings(0, &pulse_fmt
[1]);
562 g_phys_speakers_mask
= 0;
563 o
= pa_context_get_sink_info_list(pulse_ctx
, &pulse_phys_speakers_cb
, NULL
);
565 while (pa_mainloop_iterate(pulse_ml
, 1, &ret
) >= 0 &&
566 pa_operation_get_state(o
) == PA_OPERATION_RUNNING
)
568 pa_operation_unref(o
);
571 pa_context_unref(pulse_ctx
);
573 pa_mainloop_free(pulse_ml
);
576 config
->speakers_mask
= g_phys_speakers_mask
;
577 config
->modes
[0].format
= pulse_fmt
[0];
578 config
->modes
[0].def_period
= pulse_def_period
[0];
579 config
->modes
[0].min_period
= pulse_min_period
[0];
580 config
->modes
[1].format
= pulse_fmt
[1];
581 config
->modes
[1].def_period
= pulse_def_period
[1];
582 config
->modes
[1].min_period
= pulse_min_period
[1];
586 params
->result
= S_OK
;
587 return STATUS_SUCCESS
;
590 pa_context_unref(pulse_ctx
);
592 pa_mainloop_free(pulse_ml
);
595 params
->result
= E_FAIL
;
596 return STATUS_SUCCESS
;
599 static DWORD
get_channel_mask(unsigned int channels
)
605 return KSAUDIO_SPEAKER_MONO
;
607 return KSAUDIO_SPEAKER_STEREO
;
609 return KSAUDIO_SPEAKER_STEREO
| SPEAKER_LOW_FREQUENCY
;
611 return KSAUDIO_SPEAKER_QUAD
; /* not _SURROUND */
613 return KSAUDIO_SPEAKER_QUAD
| SPEAKER_LOW_FREQUENCY
;
615 return KSAUDIO_SPEAKER_5POINT1
; /* not 5POINT1_SURROUND */
617 return KSAUDIO_SPEAKER_5POINT1
| SPEAKER_BACK_CENTER
;
619 return KSAUDIO_SPEAKER_7POINT1_SURROUND
; /* Vista deprecates 7POINT1 */
621 FIXME("Unknown speaker configuration: %u\n", channels
);
625 static const enum pa_channel_position pulse_pos_from_wfx
[] = {
626 PA_CHANNEL_POSITION_FRONT_LEFT
,
627 PA_CHANNEL_POSITION_FRONT_RIGHT
,
628 PA_CHANNEL_POSITION_FRONT_CENTER
,
629 PA_CHANNEL_POSITION_LFE
,
630 PA_CHANNEL_POSITION_REAR_LEFT
,
631 PA_CHANNEL_POSITION_REAR_RIGHT
,
632 PA_CHANNEL_POSITION_FRONT_LEFT_OF_CENTER
,
633 PA_CHANNEL_POSITION_FRONT_RIGHT_OF_CENTER
,
634 PA_CHANNEL_POSITION_REAR_CENTER
,
635 PA_CHANNEL_POSITION_SIDE_LEFT
,
636 PA_CHANNEL_POSITION_SIDE_RIGHT
,
637 PA_CHANNEL_POSITION_TOP_CENTER
,
638 PA_CHANNEL_POSITION_TOP_FRONT_LEFT
,
639 PA_CHANNEL_POSITION_TOP_FRONT_CENTER
,
640 PA_CHANNEL_POSITION_TOP_FRONT_RIGHT
,
641 PA_CHANNEL_POSITION_TOP_REAR_LEFT
,
642 PA_CHANNEL_POSITION_TOP_REAR_CENTER
,
643 PA_CHANNEL_POSITION_TOP_REAR_RIGHT
646 static HRESULT
pulse_spec_from_waveformat(struct pulse_stream
*stream
, const WAVEFORMATEX
*fmt
)
648 pa_channel_map_init(&stream
->map
);
649 stream
->ss
.rate
= fmt
->nSamplesPerSec
;
650 stream
->ss
.format
= PA_SAMPLE_INVALID
;
652 switch(fmt
->wFormatTag
) {
653 case WAVE_FORMAT_IEEE_FLOAT
:
654 if (!fmt
->nChannels
|| fmt
->nChannels
> 2 || fmt
->wBitsPerSample
!= 32)
656 stream
->ss
.format
= PA_SAMPLE_FLOAT32LE
;
657 pa_channel_map_init_auto(&stream
->map
, fmt
->nChannels
, PA_CHANNEL_MAP_ALSA
);
659 case WAVE_FORMAT_PCM
:
660 if (!fmt
->nChannels
|| fmt
->nChannels
> 2)
662 if (fmt
->wBitsPerSample
== 8)
663 stream
->ss
.format
= PA_SAMPLE_U8
;
664 else if (fmt
->wBitsPerSample
== 16)
665 stream
->ss
.format
= PA_SAMPLE_S16LE
;
667 return AUDCLNT_E_UNSUPPORTED_FORMAT
;
668 pa_channel_map_init_auto(&stream
->map
, fmt
->nChannels
, PA_CHANNEL_MAP_ALSA
);
670 case WAVE_FORMAT_EXTENSIBLE
: {
671 WAVEFORMATEXTENSIBLE
*wfe
= (WAVEFORMATEXTENSIBLE
*)fmt
;
672 DWORD mask
= wfe
->dwChannelMask
;
674 if (fmt
->cbSize
!= (sizeof(*wfe
) - sizeof(*fmt
)) && fmt
->cbSize
!= sizeof(*wfe
))
676 if (IsEqualGUID(&wfe
->SubFormat
, &KSDATAFORMAT_SUBTYPE_IEEE_FLOAT
) &&
677 (!wfe
->Samples
.wValidBitsPerSample
|| wfe
->Samples
.wValidBitsPerSample
== 32) &&
678 fmt
->wBitsPerSample
== 32)
679 stream
->ss
.format
= PA_SAMPLE_FLOAT32LE
;
680 else if (IsEqualGUID(&wfe
->SubFormat
, &KSDATAFORMAT_SUBTYPE_PCM
)) {
681 DWORD valid
= wfe
->Samples
.wValidBitsPerSample
;
683 valid
= fmt
->wBitsPerSample
;
684 if (!valid
|| valid
> fmt
->wBitsPerSample
)
686 switch (fmt
->wBitsPerSample
) {
689 stream
->ss
.format
= PA_SAMPLE_U8
;
693 stream
->ss
.format
= PA_SAMPLE_S16LE
;
697 stream
->ss
.format
= PA_SAMPLE_S24LE
;
701 stream
->ss
.format
= PA_SAMPLE_S24_32LE
;
702 else if (valid
== 32)
703 stream
->ss
.format
= PA_SAMPLE_S32LE
;
706 return AUDCLNT_E_UNSUPPORTED_FORMAT
;
709 stream
->map
.channels
= fmt
->nChannels
;
710 if (!mask
|| (mask
& (SPEAKER_ALL
|SPEAKER_RESERVED
)))
711 mask
= get_channel_mask(fmt
->nChannels
);
712 for (j
= 0; j
< ARRAY_SIZE(pulse_pos_from_wfx
) && i
< fmt
->nChannels
; ++j
) {
714 stream
->map
.map
[i
++] = pulse_pos_from_wfx
[j
];
717 /* Special case for mono since pulse appears to map it differently */
718 if (mask
== SPEAKER_FRONT_CENTER
)
719 stream
->map
.map
[0] = PA_CHANNEL_POSITION_MONO
;
721 if (i
< fmt
->nChannels
|| (mask
& SPEAKER_RESERVED
)) {
722 stream
->map
.channels
= 0;
723 ERR("Invalid channel mask: %i/%i and %x(%x)\n", i
, fmt
->nChannels
, mask
, wfe
->dwChannelMask
);
728 case WAVE_FORMAT_ALAW
:
729 case WAVE_FORMAT_MULAW
:
730 if (fmt
->wBitsPerSample
!= 8) {
731 FIXME("Unsupported bpp %u for LAW\n", fmt
->wBitsPerSample
);
732 return AUDCLNT_E_UNSUPPORTED_FORMAT
;
734 if (fmt
->nChannels
!= 1 && fmt
->nChannels
!= 2) {
735 FIXME("Unsupported channels %u for LAW\n", fmt
->nChannels
);
736 return AUDCLNT_E_UNSUPPORTED_FORMAT
;
738 stream
->ss
.format
= fmt
->wFormatTag
== WAVE_FORMAT_MULAW
? PA_SAMPLE_ULAW
: PA_SAMPLE_ALAW
;
739 pa_channel_map_init_auto(&stream
->map
, fmt
->nChannels
, PA_CHANNEL_MAP_ALSA
);
742 WARN("Unhandled tag %x\n", fmt
->wFormatTag
);
743 return AUDCLNT_E_UNSUPPORTED_FORMAT
;
745 stream
->ss
.channels
= stream
->map
.channels
;
746 if (!pa_channel_map_valid(&stream
->map
) || stream
->ss
.format
== PA_SAMPLE_INVALID
) {
747 ERR("Invalid format! Channel spec valid: %i, format: %i\n",
748 pa_channel_map_valid(&stream
->map
), stream
->ss
.format
);
749 return AUDCLNT_E_UNSUPPORTED_FORMAT
;
754 static HRESULT
pulse_stream_connect(struct pulse_stream
*stream
, UINT32 period_bytes
)
761 ret
= InterlockedIncrement(&number
);
762 sprintf(buffer
, "audio stream #%i", ret
);
763 stream
->stream
= pa_stream_new(pulse_ctx
, buffer
, &stream
->ss
, &stream
->map
);
765 if (!stream
->stream
) {
766 WARN("pa_stream_new returned error %i\n", pa_context_errno(pulse_ctx
));
767 return AUDCLNT_E_ENDPOINT_CREATE_FAILED
;
770 pa_stream_set_state_callback(stream
->stream
, pulse_stream_state
, stream
);
771 pa_stream_set_buffer_attr_callback(stream
->stream
, pulse_attr_update
, stream
);
772 pa_stream_set_moved_callback(stream
->stream
, pulse_attr_update
, stream
);
774 /* PulseAudio will fill in correct values */
775 attr
.minreq
= attr
.fragsize
= period_bytes
;
776 attr
.tlength
= period_bytes
* 3;
777 attr
.maxlength
= stream
->bufsize_frames
* pa_frame_size(&stream
->ss
);
778 attr
.prebuf
= pa_frame_size(&stream
->ss
);
780 if (stream
->dataflow
== eRender
)
781 ret
= pa_stream_connect_playback(stream
->stream
, NULL
, &attr
,
782 PA_STREAM_START_CORKED
|PA_STREAM_START_UNMUTED
|PA_STREAM_ADJUST_LATENCY
, NULL
, NULL
);
784 ret
= pa_stream_connect_record(stream
->stream
, NULL
, &attr
,
785 PA_STREAM_START_CORKED
|PA_STREAM_START_UNMUTED
|PA_STREAM_ADJUST_LATENCY
);
787 WARN("Returns %i\n", ret
);
788 return AUDCLNT_E_ENDPOINT_CREATE_FAILED
;
790 while (pa_stream_get_state(stream
->stream
) == PA_STREAM_CREATING
)
792 if (pa_stream_get_state(stream
->stream
) != PA_STREAM_READY
)
793 return AUDCLNT_E_ENDPOINT_CREATE_FAILED
;
795 if (stream
->dataflow
== eRender
) {
796 pa_stream_set_underflow_callback(stream
->stream
, pulse_underflow_callback
, stream
);
797 pa_stream_set_started_callback(stream
->stream
, pulse_started_callback
, stream
);
802 static NTSTATUS
pulse_create_stream(void *args
)
804 struct create_stream_params
*params
= args
;
805 REFERENCE_TIME period
, duration
= params
->duration
;
806 struct pulse_stream
*stream
;
807 unsigned int i
, bufsize_bytes
;
812 if (FAILED(params
->result
= pulse_connect(params
->name
)))
815 return STATUS_SUCCESS
;
818 if (!(stream
= calloc(1, sizeof(*stream
))))
821 params
->result
= E_OUTOFMEMORY
;
822 return STATUS_SUCCESS
;
825 stream
->dataflow
= params
->dataflow
;
826 for (i
= 0; i
< ARRAY_SIZE(stream
->vol
); ++i
)
827 stream
->vol
[i
] = 1.f
;
829 hr
= pulse_spec_from_waveformat(stream
, params
->fmt
);
830 TRACE("Obtaining format returns %08x\n", hr
);
835 period
= pulse_def_period
[stream
->dataflow
== eCapture
];
836 if (duration
< 3 * period
)
837 duration
= 3 * period
;
839 stream
->period_bytes
= pa_frame_size(&stream
->ss
) * muldiv(period
, stream
->ss
.rate
, 10000000);
841 stream
->bufsize_frames
= ceil((duration
/ 10000000.) * params
->fmt
->nSamplesPerSec
);
842 bufsize_bytes
= stream
->bufsize_frames
* pa_frame_size(&stream
->ss
);
843 stream
->mmdev_period_usec
= period
/ 10;
845 stream
->share
= params
->mode
;
846 stream
->flags
= params
->flags
;
847 hr
= pulse_stream_connect(stream
, stream
->period_bytes
);
850 const pa_buffer_attr
*attr
= pa_stream_get_buffer_attr(stream
->stream
);
851 stream
->attr
= *attr
;
852 /* Update frames according to new size */
854 if (stream
->dataflow
== eRender
) {
855 stream
->alloc_size
= stream
->real_bufsize_bytes
=
856 stream
->bufsize_frames
* 2 * pa_frame_size(&stream
->ss
);
857 if (NtAllocateVirtualMemory(GetCurrentProcess(), (void **)&stream
->local_buffer
,
858 0, &stream
->real_bufsize_bytes
, MEM_COMMIT
, PAGE_READWRITE
))
861 UINT32 i
, capture_packets
;
863 if ((unalign
= bufsize_bytes
% stream
->period_bytes
))
864 bufsize_bytes
+= stream
->period_bytes
- unalign
;
865 stream
->bufsize_frames
= bufsize_bytes
/ pa_frame_size(&stream
->ss
);
866 stream
->real_bufsize_bytes
= bufsize_bytes
;
868 capture_packets
= stream
->real_bufsize_bytes
/ stream
->period_bytes
;
870 stream
->alloc_size
= stream
->real_bufsize_bytes
+ capture_packets
* sizeof(ACPacket
);
871 if (NtAllocateVirtualMemory(GetCurrentProcess(), (void **)&stream
->local_buffer
,
872 0, &stream
->alloc_size
, MEM_COMMIT
, PAGE_READWRITE
))
875 ACPacket
*cur_packet
= (ACPacket
*)((char*)stream
->local_buffer
+ stream
->real_bufsize_bytes
);
876 BYTE
*data
= stream
->local_buffer
;
877 silence_buffer(stream
->ss
.format
, stream
->local_buffer
, stream
->real_bufsize_bytes
);
878 list_init(&stream
->packet_free_head
);
879 list_init(&stream
->packet_filled_head
);
880 for (i
= 0; i
< capture_packets
; ++i
, ++cur_packet
) {
881 list_add_tail(&stream
->packet_free_head
, &cur_packet
->entry
);
882 cur_packet
->data
= data
;
883 data
+= stream
->period_bytes
;
889 *params
->channel_count
= stream
->ss
.channels
;
890 *params
->stream
= stream
;
893 if (FAILED(params
->result
= hr
)) {
894 free(stream
->local_buffer
);
895 if (stream
->stream
) {
896 pa_stream_disconnect(stream
->stream
);
897 pa_stream_unref(stream
->stream
);
903 return STATUS_SUCCESS
;
906 static NTSTATUS
pulse_release_stream(void *args
)
908 struct release_stream_params
*params
= args
;
909 struct pulse_stream
*stream
= params
->stream
;
912 stream
->please_quit
= TRUE
;
913 NtWaitForSingleObject(params
->timer
, FALSE
, NULL
);
914 NtClose(params
->timer
);
918 if (PA_STREAM_IS_GOOD(pa_stream_get_state(stream
->stream
))) {
919 pa_stream_disconnect(stream
->stream
);
920 while (PA_STREAM_IS_GOOD(pa_stream_get_state(stream
->stream
)))
923 pa_stream_unref(stream
->stream
);
926 if (stream
->tmp_buffer
)
927 NtFreeVirtualMemory(GetCurrentProcess(), (void **)&stream
->tmp_buffer
,
928 &stream
->tmp_buffer_bytes
, MEM_RELEASE
);
929 if (stream
->local_buffer
)
930 NtFreeVirtualMemory(GetCurrentProcess(), (void **)&stream
->local_buffer
,
931 &stream
->alloc_size
, MEM_RELEASE
);
932 free(stream
->peek_buffer
);
934 return STATUS_SUCCESS
;
937 static int write_buffer(const struct pulse_stream
*stream
, BYTE
*buffer
, UINT32 bytes
)
939 const float *vol
= stream
->vol
;
940 UINT32 i
, channels
, mute
= 0;
944 if (!bytes
) return 0;
946 /* Adjust the buffer based on the volume for each channel */
947 channels
= stream
->ss
.channels
;
948 for (i
= 0; i
< channels
; i
++)
950 adjust
|= vol
[i
] != 1.0f
;
954 if (mute
== channels
)
956 silence_buffer(stream
->ss
.format
, buffer
, bytes
);
959 if (!adjust
) goto write
;
961 end
= buffer
+ bytes
;
962 switch (stream
->ss
.format
)
964 #ifndef WORDS_BIGENDIAN
965 #define PROCESS_BUFFER(type) do \
967 type *p = (type*)buffer; \
970 for (i = 0; i < channels; i++) \
971 p[i] = p[i] * vol[i]; \
973 } while ((BYTE*)p != end); \
975 case PA_SAMPLE_S16LE
:
976 PROCESS_BUFFER(INT16
);
978 case PA_SAMPLE_S32LE
:
979 PROCESS_BUFFER(INT32
);
981 case PA_SAMPLE_FLOAT32LE
:
982 PROCESS_BUFFER(float);
984 #undef PROCESS_BUFFER
985 case PA_SAMPLE_S24_32LE
:
987 UINT32
*p
= (UINT32
*)buffer
;
990 for (i
= 0; i
< channels
; i
++)
992 p
[i
] = (INT32
)((INT32
)(p
[i
] << 8) * vol
[i
]);
996 } while ((BYTE
*)p
!= end
);
999 case PA_SAMPLE_S24LE
:
1001 /* do it 12 bytes at a time until it is no longer possible */
1002 UINT32
*q
= (UINT32
*)buffer
;
1006 while (end
- (BYTE
*)q
>= 12)
1010 v
[1] = q
[1] << 16 | (q
[0] >> 16 & ~0xff);
1011 v
[2] = q
[2] << 24 | (q
[1] >> 8 & ~0xff);
1012 v
[3] = q
[2] & ~0xff;
1013 for (k
= 0; k
< 4; k
++)
1015 v
[k
] = (INT32
)((INT32
)v
[k
] * vol
[i
]);
1016 if (++i
== channels
) i
= 0;
1018 *q
++ = v
[0] >> 8 | (v
[1] & ~0xff) << 16;
1019 *q
++ = v
[1] >> 16 | (v
[2] & ~0xff) << 8;
1020 *q
++ = v
[2] >> 24 | (v
[3] & ~0xff);
1025 UINT32 v
= (INT32
)((INT32
)(p
[0] << 8 | p
[1] << 16 | p
[2] << 24) * vol
[i
]);
1026 *p
++ = v
>> 8 & 0xff;
1027 *p
++ = v
>> 16 & 0xff;
1029 if (++i
== channels
) i
= 0;
1036 UINT8
*p
= (UINT8
*)buffer
;
1039 for (i
= 0; i
< channels
; i
++)
1040 p
[i
] = (int)((p
[i
] - 128) * vol
[i
]) + 128;
1042 } while ((BYTE
*)p
!= end
);
1045 case PA_SAMPLE_ALAW
:
1047 UINT8
*p
= (UINT8
*)buffer
;
1050 for (i
= 0; i
< channels
; i
++)
1051 p
[i
] = mult_alaw_sample(p
[i
], vol
[i
]);
1053 } while ((BYTE
*)p
!= end
);
1056 case PA_SAMPLE_ULAW
:
1058 UINT8
*p
= (UINT8
*)buffer
;
1061 for (i
= 0; i
< channels
; i
++)
1062 p
[i
] = mult_ulaw_sample(p
[i
], vol
[i
]);
1064 } while ((BYTE
*)p
!= end
);
1068 TRACE("Unhandled format %i, not adjusting volume.\n", stream
->ss
.format
);
1073 return pa_stream_write(stream
->stream
, buffer
, bytes
, NULL
, 0, PA_SEEK_RELATIVE
);
1076 static void pulse_write(struct pulse_stream
*stream
)
1078 /* write as much data to PA as we can */
1080 BYTE
*buf
= stream
->local_buffer
+ stream
->pa_offs_bytes
;
1081 UINT32 bytes
= pa_stream_writable_size(stream
->stream
);
1083 if (stream
->just_underran
)
1085 /* prebuffer with silence if needed */
1086 if(stream
->pa_held_bytes
< bytes
){
1087 to_write
= bytes
- stream
->pa_held_bytes
;
1088 TRACE("prebuffering %u frames of silence\n",
1089 (int)(to_write
/ pa_frame_size(&stream
->ss
)));
1090 buf
= calloc(1, to_write
);
1091 pa_stream_write(stream
->stream
, buf
, to_write
, NULL
, 0, PA_SEEK_RELATIVE
);
1095 stream
->just_underran
= FALSE
;
1098 buf
= stream
->local_buffer
+ stream
->pa_offs_bytes
;
1099 TRACE("held: %lu, avail: %u\n", stream
->pa_held_bytes
, bytes
);
1100 bytes
= min(stream
->pa_held_bytes
, bytes
);
1102 if (stream
->pa_offs_bytes
+ bytes
> stream
->real_bufsize_bytes
)
1104 to_write
= stream
->real_bufsize_bytes
- stream
->pa_offs_bytes
;
1105 TRACE("writing small chunk of %u bytes\n", to_write
);
1106 write_buffer(stream
, buf
, to_write
);
1107 stream
->pa_held_bytes
-= to_write
;
1108 to_write
= bytes
- to_write
;
1109 stream
->pa_offs_bytes
= 0;
1110 buf
= stream
->local_buffer
;
1115 TRACE("writing main chunk of %u bytes\n", to_write
);
1116 write_buffer(stream
, buf
, to_write
);
1117 stream
->pa_offs_bytes
+= to_write
;
1118 stream
->pa_offs_bytes
%= stream
->real_bufsize_bytes
;
1119 stream
->pa_held_bytes
-= to_write
;
1122 static void pulse_read(struct pulse_stream
*stream
)
1124 size_t bytes
= pa_stream_readable_size(stream
->stream
);
1126 TRACE("Readable total: %zu, fragsize: %u\n", bytes
, pa_stream_get_buffer_attr(stream
->stream
)->fragsize
);
1128 bytes
+= stream
->peek_len
- stream
->peek_ofs
;
1130 while (bytes
>= stream
->period_bytes
)
1132 BYTE
*dst
= NULL
, *src
;
1133 size_t src_len
, copy
, rem
= stream
->period_bytes
;
1135 if (stream
->started
)
1137 LARGE_INTEGER stamp
, freq
;
1140 if (!(p
= (ACPacket
*)list_head(&stream
->packet_free_head
)))
1142 p
= (ACPacket
*)list_head(&stream
->packet_filled_head
);
1145 next
= (ACPacket
*)p
->entry
.next
;
1148 p
= (ACPacket
*)list_tail(&stream
->packet_filled_head
);
1152 stream
->held_bytes
+= stream
->period_bytes
;
1154 NtQueryPerformanceCounter(&stamp
, &freq
);
1155 p
->qpcpos
= (stamp
.QuadPart
* (INT64
)10000000) / freq
.QuadPart
;
1157 list_remove(&p
->entry
);
1158 list_add_tail(&stream
->packet_filled_head
, &p
->entry
);
1165 if (stream
->peek_len
)
1167 copy
= min(rem
, stream
->peek_len
- stream
->peek_ofs
);
1171 memcpy(dst
, stream
->peek_buffer
+ stream
->peek_ofs
, copy
);
1176 stream
->peek_ofs
+= copy
;
1177 if(stream
->peek_len
== stream
->peek_ofs
)
1178 stream
->peek_len
= stream
->peek_ofs
= 0;
1181 else if (pa_stream_peek(stream
->stream
, (const void**)&src
, &src_len
) == 0 && src_len
)
1183 copy
= min(rem
, src_len
);
1187 memcpy(dst
, src
, copy
);
1189 silence_buffer(stream
->ss
.format
, dst
, copy
);
1198 if (src_len
> stream
->peek_buffer_len
)
1200 free(stream
->peek_buffer
);
1201 stream
->peek_buffer
= malloc(src_len
);
1202 stream
->peek_buffer_len
= src_len
;
1206 memcpy(stream
->peek_buffer
, src
+ copy
, src_len
- copy
);
1208 silence_buffer(stream
->ss
.format
, stream
->peek_buffer
, src_len
- copy
);
1210 stream
->peek_len
= src_len
- copy
;
1211 stream
->peek_ofs
= 0;
1214 pa_stream_drop(stream
->stream
);
1218 bytes
-= stream
->period_bytes
;
1222 static NTSTATUS
pulse_timer_loop(void *args
)
1224 struct timer_loop_params
*params
= args
;
1225 struct pulse_stream
*stream
= params
->stream
;
1226 LARGE_INTEGER delay
;
1232 delay
.QuadPart
= -stream
->mmdev_period_usec
* 10;
1233 pa_stream_get_time(stream
->stream
, &stream
->last_time
);
1236 while (!stream
->please_quit
)
1238 pa_usec_t now
, adv_usec
= 0;
1241 NtDelayExecution(FALSE
, &delay
);
1245 delay
.QuadPart
= -stream
->mmdev_period_usec
* 10;
1247 o
= pa_stream_update_timing_info(stream
->stream
, pulse_op_cb
, &success
);
1250 while (pa_operation_get_state(o
) == PA_OPERATION_RUNNING
)
1252 pa_operation_unref(o
);
1254 err
= pa_stream_get_time(stream
->stream
, &now
);
1257 TRACE("got now: %s, last time: %s\n", wine_dbgstr_longlong(now
), wine_dbgstr_longlong(stream
->last_time
));
1258 if (stream
->started
&& (stream
->dataflow
== eCapture
|| stream
->held_bytes
))
1260 if(stream
->just_underran
)
1262 stream
->last_time
= now
;
1263 stream
->just_started
= TRUE
;
1266 if (stream
->just_started
)
1268 /* let it play out a period to absorb some latency and get accurate timing */
1269 pa_usec_t diff
= now
- stream
->last_time
;
1271 if (diff
> stream
->mmdev_period_usec
)
1273 stream
->just_started
= FALSE
;
1274 stream
->last_time
= now
;
1279 INT32 adjust
= stream
->last_time
+ stream
->mmdev_period_usec
- now
;
1281 adv_usec
= now
- stream
->last_time
;
1283 if(adjust
> ((INT32
)(stream
->mmdev_period_usec
/ 2)))
1284 adjust
= stream
->mmdev_period_usec
/ 2;
1285 else if(adjust
< -((INT32
)(stream
->mmdev_period_usec
/ 2)))
1286 adjust
= -1 * stream
->mmdev_period_usec
/ 2;
1288 delay
.QuadPart
= -(stream
->mmdev_period_usec
+ adjust
) * 10;
1290 stream
->last_time
+= stream
->mmdev_period_usec
;
1293 if (stream
->dataflow
== eRender
)
1295 pulse_write(stream
);
1297 /* regardless of what PA does, advance one period */
1298 adv_bytes
= min(stream
->period_bytes
, stream
->held_bytes
);
1299 stream
->lcl_offs_bytes
+= adv_bytes
;
1300 stream
->lcl_offs_bytes
%= stream
->real_bufsize_bytes
;
1301 stream
->held_bytes
-= adv_bytes
;
1303 else if(stream
->dataflow
== eCapture
)
1310 stream
->last_time
= now
;
1311 delay
.QuadPart
= -stream
->mmdev_period_usec
* 10;
1316 NtSetEvent(stream
->event
, NULL
);
1318 TRACE("%p after update, adv usec: %d, held: %u, delay usec: %u\n",
1319 stream
, (int)adv_usec
,
1320 (int)(stream
->held_bytes
/ pa_frame_size(&stream
->ss
)),
1321 (unsigned int)(-delay
.QuadPart
/ 10));
1326 return STATUS_SUCCESS
;
1329 static NTSTATUS
pulse_start(void *args
)
1331 struct start_params
*params
= args
;
1332 struct pulse_stream
*stream
= params
->stream
;
1336 params
->result
= S_OK
;
1338 if (!pulse_stream_valid(stream
))
1341 params
->result
= S_OK
;
1342 return STATUS_SUCCESS
;
1345 if ((stream
->flags
& AUDCLNT_STREAMFLAGS_EVENTCALLBACK
) && !stream
->event
)
1348 params
->result
= AUDCLNT_E_EVENTHANDLE_NOT_SET
;
1349 return STATUS_SUCCESS
;
1352 if (stream
->started
)
1355 params
->result
= AUDCLNT_E_NOT_STOPPED
;
1356 return STATUS_SUCCESS
;
1359 pulse_write(stream
);
1361 if (pa_stream_is_corked(stream
->stream
))
1363 o
= pa_stream_cork(stream
->stream
, 0, pulse_op_cb
, &success
);
1366 while(pa_operation_get_state(o
) == PA_OPERATION_RUNNING
)
1368 pa_operation_unref(o
);
1373 params
->result
= E_FAIL
;
1376 if (SUCCEEDED(params
->result
))
1378 stream
->started
= TRUE
;
1379 stream
->just_started
= TRUE
;
1382 return STATUS_SUCCESS
;
1385 static NTSTATUS
pulse_stop(void *args
)
1387 struct stop_params
*params
= args
;
1388 struct pulse_stream
*stream
= params
->stream
;
1393 if (!pulse_stream_valid(stream
))
1396 params
->result
= AUDCLNT_E_DEVICE_INVALIDATED
;
1397 return STATUS_SUCCESS
;
1400 if (!stream
->started
)
1403 params
->result
= S_FALSE
;
1404 return STATUS_SUCCESS
;
1407 params
->result
= S_OK
;
1408 if (stream
->dataflow
== eRender
)
1410 o
= pa_stream_cork(stream
->stream
, 1, pulse_op_cb
, &success
);
1413 while(pa_operation_get_state(o
) == PA_OPERATION_RUNNING
)
1415 pa_operation_unref(o
);
1420 params
->result
= E_FAIL
;
1422 if (SUCCEEDED(params
->result
))
1423 stream
->started
= FALSE
;
1425 return STATUS_SUCCESS
;
1428 static NTSTATUS
pulse_reset(void *args
)
1430 struct reset_params
*params
= args
;
1431 struct pulse_stream
*stream
= params
->stream
;
1434 if (!pulse_stream_valid(stream
))
1437 params
->result
= AUDCLNT_E_DEVICE_INVALIDATED
;
1438 return STATUS_SUCCESS
;
1441 if (stream
->started
)
1444 params
->result
= AUDCLNT_E_NOT_STOPPED
;
1445 return STATUS_SUCCESS
;
1451 params
->result
= AUDCLNT_E_BUFFER_OPERATION_PENDING
;
1452 return STATUS_SUCCESS
;
1455 if (stream
->dataflow
== eRender
)
1457 /* If there is still data in the render buffer it needs to be removed from the server */
1459 if (stream
->held_bytes
)
1461 pa_operation
*o
= pa_stream_flush(stream
->stream
, pulse_op_cb
, &success
);
1464 while (pa_operation_get_state(o
) == PA_OPERATION_RUNNING
)
1466 pa_operation_unref(o
);
1469 if (success
|| !stream
->held_bytes
)
1471 stream
->clock_lastpos
= stream
->clock_written
= 0;
1472 stream
->pa_offs_bytes
= stream
->lcl_offs_bytes
= 0;
1473 stream
->held_bytes
= stream
->pa_held_bytes
= 0;
1479 stream
->clock_written
+= stream
->held_bytes
;
1480 stream
->held_bytes
= 0;
1482 if ((p
= stream
->locked_ptr
))
1484 stream
->locked_ptr
= NULL
;
1485 list_add_tail(&stream
->packet_free_head
, &p
->entry
);
1487 list_move_tail(&stream
->packet_free_head
, &stream
->packet_filled_head
);
1490 params
->result
= S_OK
;
1491 return STATUS_SUCCESS
;
1494 static BOOL
alloc_tmp_buffer(struct pulse_stream
*stream
, SIZE_T bytes
)
1496 if (stream
->tmp_buffer_bytes
>= bytes
)
1499 if (stream
->tmp_buffer
)
1501 NtFreeVirtualMemory(GetCurrentProcess(), (void **)&stream
->tmp_buffer
,
1502 &stream
->tmp_buffer_bytes
, MEM_RELEASE
);
1503 stream
->tmp_buffer
= NULL
;
1504 stream
->tmp_buffer_bytes
= 0;
1506 if (NtAllocateVirtualMemory(GetCurrentProcess(), (void **)&stream
->tmp_buffer
,
1507 0, &bytes
, MEM_COMMIT
, PAGE_READWRITE
))
1510 stream
->tmp_buffer_bytes
= bytes
;
1514 static UINT32
pulse_render_padding(struct pulse_stream
*stream
)
1516 return stream
->held_bytes
/ pa_frame_size(&stream
->ss
);
1519 static UINT32
pulse_capture_padding(struct pulse_stream
*stream
)
1521 ACPacket
*packet
= stream
->locked_ptr
;
1522 if (!packet
&& !list_empty(&stream
->packet_filled_head
))
1524 packet
= (ACPacket
*)list_head(&stream
->packet_filled_head
);
1525 stream
->locked_ptr
= packet
;
1526 list_remove(&packet
->entry
);
1528 return stream
->held_bytes
/ pa_frame_size(&stream
->ss
);
1531 static NTSTATUS
pulse_get_render_buffer(void *args
)
1533 struct get_render_buffer_params
*params
= args
;
1534 struct pulse_stream
*stream
= params
->stream
;
1536 UINT32 wri_offs_bytes
;
1539 if (!pulse_stream_valid(stream
))
1542 params
->result
= AUDCLNT_E_DEVICE_INVALIDATED
;
1543 return STATUS_SUCCESS
;
1549 params
->result
= AUDCLNT_E_OUT_OF_ORDER
;
1550 return STATUS_SUCCESS
;
1553 if (!params
->frames
)
1556 *params
->data
= NULL
;
1557 params
->result
= S_OK
;
1558 return STATUS_SUCCESS
;
1561 if (stream
->held_bytes
/ pa_frame_size(&stream
->ss
) + params
->frames
> stream
->bufsize_frames
)
1564 params
->result
= AUDCLNT_E_BUFFER_TOO_LARGE
;
1565 return STATUS_SUCCESS
;
1568 bytes
= params
->frames
* pa_frame_size(&stream
->ss
);
1569 wri_offs_bytes
= (stream
->lcl_offs_bytes
+ stream
->held_bytes
) % stream
->real_bufsize_bytes
;
1570 if (wri_offs_bytes
+ bytes
> stream
->real_bufsize_bytes
)
1572 if (!alloc_tmp_buffer(stream
, bytes
))
1575 params
->result
= E_OUTOFMEMORY
;
1576 return STATUS_SUCCESS
;
1578 *params
->data
= stream
->tmp_buffer
;
1579 stream
->locked
= -bytes
;
1583 *params
->data
= stream
->local_buffer
+ wri_offs_bytes
;
1584 stream
->locked
= bytes
;
1587 silence_buffer(stream
->ss
.format
, *params
->data
, bytes
);
1590 params
->result
= S_OK
;
1591 return STATUS_SUCCESS
;
1594 static void pulse_wrap_buffer(struct pulse_stream
*stream
, BYTE
*buffer
, UINT32 written_bytes
)
1596 UINT32 wri_offs_bytes
= (stream
->lcl_offs_bytes
+ stream
->held_bytes
) % stream
->real_bufsize_bytes
;
1597 UINT32 chunk_bytes
= stream
->real_bufsize_bytes
- wri_offs_bytes
;
1599 if (written_bytes
<= chunk_bytes
)
1601 memcpy(stream
->local_buffer
+ wri_offs_bytes
, buffer
, written_bytes
);
1605 memcpy(stream
->local_buffer
+ wri_offs_bytes
, buffer
, chunk_bytes
);
1606 memcpy(stream
->local_buffer
, buffer
+ chunk_bytes
, written_bytes
- chunk_bytes
);
1610 static NTSTATUS
pulse_release_render_buffer(void *args
)
1612 struct release_render_buffer_params
*params
= args
;
1613 struct pulse_stream
*stream
= params
->stream
;
1614 UINT32 written_bytes
;
1618 if (!stream
->locked
|| !params
->written_frames
)
1622 params
->result
= params
->written_frames
? AUDCLNT_E_OUT_OF_ORDER
: S_OK
;
1623 return STATUS_SUCCESS
;
1626 if (params
->written_frames
* pa_frame_size(&stream
->ss
) >
1627 (stream
->locked
>= 0 ? stream
->locked
: -stream
->locked
))
1630 params
->result
= AUDCLNT_E_INVALID_SIZE
;
1631 return STATUS_SUCCESS
;
1634 if (stream
->locked
>= 0)
1635 buffer
= stream
->local_buffer
+ (stream
->lcl_offs_bytes
+ stream
->held_bytes
) % stream
->real_bufsize_bytes
;
1637 buffer
= stream
->tmp_buffer
;
1639 written_bytes
= params
->written_frames
* pa_frame_size(&stream
->ss
);
1640 if (params
->flags
& AUDCLNT_BUFFERFLAGS_SILENT
)
1641 silence_buffer(stream
->ss
.format
, buffer
, written_bytes
);
1643 if (stream
->locked
< 0)
1644 pulse_wrap_buffer(stream
, buffer
, written_bytes
);
1646 stream
->held_bytes
+= written_bytes
;
1647 stream
->pa_held_bytes
+= written_bytes
;
1648 if (stream
->pa_held_bytes
> stream
->real_bufsize_bytes
)
1650 stream
->pa_offs_bytes
+= stream
->pa_held_bytes
- stream
->real_bufsize_bytes
;
1651 stream
->pa_offs_bytes
%= stream
->real_bufsize_bytes
;
1652 stream
->pa_held_bytes
= stream
->real_bufsize_bytes
;
1654 stream
->clock_written
+= written_bytes
;
1657 TRACE("Released %u, held %lu\n", params
->written_frames
, stream
->held_bytes
/ pa_frame_size(&stream
->ss
));
1660 params
->result
= S_OK
;
1661 return STATUS_SUCCESS
;
1664 static NTSTATUS
pulse_get_capture_buffer(void *args
)
1666 struct get_capture_buffer_params
*params
= args
;
1667 struct pulse_stream
*stream
= params
->stream
;
1671 if (!pulse_stream_valid(stream
))
1674 params
->result
= AUDCLNT_E_DEVICE_INVALIDATED
;
1675 return STATUS_SUCCESS
;
1680 params
->result
= AUDCLNT_E_OUT_OF_ORDER
;
1681 return STATUS_SUCCESS
;
1684 pulse_capture_padding(stream
);
1685 if ((packet
= stream
->locked_ptr
))
1687 *params
->frames
= stream
->period_bytes
/ pa_frame_size(&stream
->ss
);
1689 if (packet
->discont
)
1690 *params
->flags
|= AUDCLNT_BUFFERFLAGS_DATA_DISCONTINUITY
;
1693 if (packet
->discont
)
1694 *params
->devpos
= (stream
->clock_written
+ stream
->period_bytes
) / pa_frame_size(&stream
->ss
);
1696 *params
->devpos
= stream
->clock_written
/ pa_frame_size(&stream
->ss
);
1699 *params
->qpcpos
= packet
->qpcpos
;
1700 *params
->data
= packet
->data
;
1703 *params
->frames
= 0;
1704 stream
->locked
= *params
->frames
;
1706 params
->result
= *params
->frames
? S_OK
: AUDCLNT_S_BUFFER_EMPTY
;
1707 return STATUS_SUCCESS
;
1710 static NTSTATUS
pulse_release_capture_buffer(void *args
)
1712 struct release_capture_buffer_params
*params
= args
;
1713 struct pulse_stream
*stream
= params
->stream
;
1716 if (!stream
->locked
&& params
->done
)
1719 params
->result
= AUDCLNT_E_OUT_OF_ORDER
;
1720 return STATUS_SUCCESS
;
1722 if (params
->done
&& stream
->locked
!= params
->done
)
1725 params
->result
= AUDCLNT_E_INVALID_SIZE
;
1726 return STATUS_SUCCESS
;
1730 ACPacket
*packet
= stream
->locked_ptr
;
1731 stream
->locked_ptr
= NULL
;
1732 stream
->held_bytes
-= stream
->period_bytes
;
1733 if (packet
->discont
)
1734 stream
->clock_written
+= 2 * stream
->period_bytes
;
1736 stream
->clock_written
+= stream
->period_bytes
;
1737 list_add_tail(&stream
->packet_free_head
, &packet
->entry
);
1741 params
->result
= S_OK
;
1742 return STATUS_SUCCESS
;
1745 static NTSTATUS
pulse_get_buffer_size(void *args
)
1747 struct get_buffer_size_params
*params
= args
;
1749 params
->result
= S_OK
;
1752 if (!pulse_stream_valid(params
->stream
))
1753 params
->result
= AUDCLNT_E_DEVICE_INVALIDATED
;
1755 *params
->size
= params
->stream
->bufsize_frames
;
1758 return STATUS_SUCCESS
;
1761 static NTSTATUS
pulse_get_latency(void *args
)
1763 struct get_latency_params
*params
= args
;
1764 struct pulse_stream
*stream
= params
->stream
;
1765 const pa_buffer_attr
*attr
;
1769 if (!pulse_stream_valid(stream
)) {
1771 params
->result
= AUDCLNT_E_DEVICE_INVALIDATED
;
1772 return STATUS_SUCCESS
;
1774 attr
= pa_stream_get_buffer_attr(stream
->stream
);
1775 if (stream
->dataflow
== eRender
)
1776 lat
= attr
->minreq
/ pa_frame_size(&stream
->ss
);
1778 lat
= attr
->fragsize
/ pa_frame_size(&stream
->ss
);
1779 *params
->latency
= (lat
* 10000000) / stream
->ss
.rate
+ pulse_def_period
[0];
1781 TRACE("Latency: %u ms\n", (DWORD
)(*params
->latency
/ 10000));
1782 params
->result
= S_OK
;
1783 return STATUS_SUCCESS
;
1786 static NTSTATUS
pulse_get_current_padding(void *args
)
1788 struct get_current_padding_params
*params
= args
;
1789 struct pulse_stream
*stream
= params
->stream
;
1792 if (!pulse_stream_valid(stream
))
1795 params
->result
= AUDCLNT_E_DEVICE_INVALIDATED
;
1796 return STATUS_SUCCESS
;
1799 if (stream
->dataflow
== eRender
)
1800 *params
->padding
= pulse_render_padding(stream
);
1802 *params
->padding
= pulse_capture_padding(stream
);
1805 TRACE("%p Pad: %u ms (%u)\n", stream
, muldiv(*params
->padding
, 1000, stream
->ss
.rate
),
1807 params
->result
= S_OK
;
1808 return STATUS_SUCCESS
;
1811 static NTSTATUS
pulse_get_next_packet_size(void *args
)
1813 struct get_next_packet_size_params
*params
= args
;
1814 struct pulse_stream
*stream
= params
->stream
;
1817 pulse_capture_padding(stream
);
1818 if (stream
->locked_ptr
)
1819 *params
->frames
= stream
->period_bytes
/ pa_frame_size(&stream
->ss
);
1821 *params
->frames
= 0;
1823 params
->result
= S_OK
;
1825 return STATUS_SUCCESS
;
1828 static NTSTATUS
pulse_get_frequency(void *args
)
1830 struct get_frequency_params
*params
= args
;
1831 struct pulse_stream
*stream
= params
->stream
;
1834 if (!pulse_stream_valid(stream
))
1837 params
->result
= AUDCLNT_E_DEVICE_INVALIDATED
;
1838 return STATUS_SUCCESS
;
1841 *params
->freq
= stream
->ss
.rate
;
1842 if (stream
->share
== AUDCLNT_SHAREMODE_SHARED
)
1843 *params
->freq
*= pa_frame_size(&stream
->ss
);
1845 params
->result
= S_OK
;
1846 return STATUS_SUCCESS
;
1849 static NTSTATUS
pulse_get_position(void *args
)
1851 struct get_position_params
*params
= args
;
1852 struct pulse_stream
*stream
= params
->stream
;
1855 if (!pulse_stream_valid(stream
))
1858 params
->result
= AUDCLNT_E_DEVICE_INVALIDATED
;
1859 return STATUS_SUCCESS
;
1862 *params
->pos
= stream
->clock_written
- stream
->held_bytes
;
1864 if (stream
->share
== AUDCLNT_SHAREMODE_EXCLUSIVE
|| params
->device
)
1865 *params
->pos
/= pa_frame_size(&stream
->ss
);
1867 /* Make time never go backwards */
1868 if (*params
->pos
< stream
->clock_lastpos
)
1869 *params
->pos
= stream
->clock_lastpos
;
1871 stream
->clock_lastpos
= *params
->pos
;
1874 TRACE("%p Position: %u\n", stream
, (unsigned)*params
->pos
);
1876 if (params
->qpctime
)
1878 LARGE_INTEGER stamp
, freq
;
1879 NtQueryPerformanceCounter(&stamp
, &freq
);
1880 *params
->qpctime
= (stamp
.QuadPart
* (INT64
)10000000) / freq
.QuadPart
;
1883 params
->result
= S_OK
;
1884 return STATUS_SUCCESS
;
1887 static NTSTATUS
pulse_set_volumes(void *args
)
1889 struct set_volumes_params
*params
= args
;
1890 struct pulse_stream
*stream
= params
->stream
;
1893 for (i
= 0; i
< stream
->ss
.channels
; i
++)
1894 stream
->vol
[i
] = params
->volumes
[i
] * params
->master_volume
* params
->session_volumes
[i
];
1896 return STATUS_SUCCESS
;
1899 static NTSTATUS
pulse_set_event_handle(void *args
)
1901 struct set_event_handle_params
*params
= args
;
1902 struct pulse_stream
*stream
= params
->stream
;
1906 if (!pulse_stream_valid(stream
))
1907 hr
= AUDCLNT_E_DEVICE_INVALIDATED
;
1908 else if (!(stream
->flags
& AUDCLNT_STREAMFLAGS_EVENTCALLBACK
))
1909 hr
= AUDCLNT_E_EVENTHANDLE_NOT_EXPECTED
;
1910 else if (stream
->event
)
1911 hr
= HRESULT_FROM_WIN32(ERROR_INVALID_NAME
);
1913 stream
->event
= params
->event
;
1916 params
->result
= hr
;
1917 return STATUS_SUCCESS
;
1920 static NTSTATUS
pulse_is_started(void *args
)
1922 struct is_started_params
*params
= args
;
1923 struct pulse_stream
*stream
= params
->stream
;
1926 params
->started
= pulse_stream_valid(stream
) && stream
->started
;
1929 return STATUS_SUCCESS
;
1932 static const unixlib_entry_t unix_funcs
[] =
1935 pulse_create_stream
,
1936 pulse_release_stream
,
1941 pulse_get_render_buffer
,
1942 pulse_release_render_buffer
,
1943 pulse_get_capture_buffer
,
1944 pulse_release_capture_buffer
,
1945 pulse_get_buffer_size
,
1947 pulse_get_current_padding
,
1948 pulse_get_next_packet_size
,
1949 pulse_get_frequency
,
1952 pulse_set_event_handle
,
1957 NTSTATUS CDECL
__wine_init_unix_lib(HMODULE module
, DWORD reason
, const void *ptr_in
, void *ptr_out
)
1959 pthread_mutexattr_t attr
;
1963 case DLL_PROCESS_ATTACH
:
1964 pthread_mutexattr_init(&attr
);
1965 pthread_mutexattr_setprotocol(&attr
, PTHREAD_PRIO_INHERIT
);
1967 if (pthread_mutex_init(&pulse_mutex
, &attr
) != 0)
1968 pthread_mutex_init(&pulse_mutex
, NULL
);
1970 *(UINT64
*)ptr_out
= (UINT_PTR
)&unix_funcs
;
1972 case DLL_PROCESS_DETACH
:
1975 pa_context_disconnect(pulse_ctx
);
1976 pa_context_unref(pulse_ctx
);
1979 pa_mainloop_quit(pulse_ml
, 0);
1983 return STATUS_SUCCESS
;