1 /* Definitions for PulseAudio Wine Driver
3 * Copyright 2008 Arthur Taylor
5 * This library is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU Lesser General Public
7 * License as published by the Free Software Foundation; either
8 * version 2.1 of the License, or (at your option) any later version.
10 * This library is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * Lesser General Public License for more details.
15 * You should have received a copy of the GNU Lesser General Public
16 * License along with this library; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
20 #ifndef __WINE_CONFIG_H
21 # error You must include config.h to use this header
24 #if defined(HAVE_PULSEAUDIO) && !defined(__WINEPULSE_H)
35 #include <pulse/pulseaudio.h>
37 /* state diagram for waveOut writing:
39 * +---------+-------------+---------------+---------------------------------+
40 * | state | function | event | new state |
41 * +---------+-------------+---------------+---------------------------------+
42 * | | open() | | STOPPED |
43 * | PAUSED | write() | | PAUSED |
44 * | STOPPED | write() | <thrd create> | PLAYING |
45 * | PLAYING | write() | HEADER | PLAYING |
46 * | (other) | write() | <error> | |
47 * | (any) | pause() | PAUSING | PAUSED |
48 * | PAUSED | restart() | RESTARTING | PLAYING (if no thrd => STOPPED) |
49 * | (any) | reset() | RESETTING | STOPPED |
50 * | (any) | close() | CLOSING | CLOSED |
51 * +---------+-------------+---------------+---------------------------------+
56 /* states of the playing device */
57 #define WINE_WS_PLAYING 1
58 #define WINE_WS_PAUSED 2
59 #define WINE_WS_STOPPED 3
60 #define WINE_WS_CLOSED 4
61 #define WINE_WS_FAILED 5
63 #define PULSE_MAX_STREAM_INSTANCES 16 /* Sixteen streams per device should be good enough? */
65 /* events to be sent to device */
67 WINE_WM_PAUSING
= WM_USER
+ 1, WINE_WM_RESTARTING
, WINE_WM_RESETTING
, WINE_WM_HEADER
,
68 WINE_WM_BREAKLOOP
, WINE_WM_CLOSING
, WINE_WM_STARTING
, WINE_WM_STOPPING
, WINE_WM_XRUN
, WINE_WM_FEED
72 enum win_wm_message msg
; /* message identifier */
73 DWORD param
; /* parameter for this message */
74 HANDLE hEvent
; /* if message is synchronous, handle of event for synchro */
77 /* implement an in-process message ring for better performance
78 * (compared to passing thru the server)
79 * this ring will be used by the input (resp output) record (resp playback) routine
86 /* Either pipe or event is used, but that is defined in pulse.c,
87 * since this is a global header we define both here */
90 CRITICAL_SECTION msg_crst
;
93 /* Per-playback/record instance */
95 int instance_ref
; /* The array index of WINE_WAVEDEV->instance[] that this is */
96 volatile int state
; /* one of the WINE_WS_ manifest constants */
97 WAVEOPENDESC waveDesc
;
99 pa_stream
*stream
; /* The PulseAudio stream */
100 const pa_timing_info
*timing_info
;
101 pa_buffer_attr
*buffer_attr
;
102 pa_sample_spec sample_spec
; /* Sample spec of this stream / device */
105 /* WavaHdr information */
106 LPWAVEHDR lpQueuePtr
; /* start of queued WAVEHDRs (waiting to be notified) */
107 LPWAVEHDR lpPlayPtr
; /* start of not yet fully written buffers */
108 DWORD dwPartialOffset
; /* Offset of not yet written bytes in lpPlayPtr */
109 LPWAVEHDR lpLoopPtr
; /* pointer of first buffer in loop, if any */
110 DWORD dwLoops
; /* private copy of loop counter */
112 /* Virtual stream positioning information */
113 DWORD last_reset
; /* When the last reset occured, as pa stream time doesn't reset */
114 BOOL is_buffering
; /* !is_playing */
115 struct timeval last_header
; /* When the last wavehdr was received, only updated when is_buffering is true */
116 BOOL is_releasing
; /* Whether we are releasing wavehdrs, may not always be the inverse of is_buffering */
117 struct timeval started_releasing
; /* When wavehdr releasing started, for comparison to queued written wavehdrs */
118 DWORD releasing_offset
; /* How much audio has been released prior when releasing started in this instance */
120 /* Thread communication and synchronization stuff */
121 HANDLE hStartUpEvent
;
124 PULSE_MSG_RING msgRing
;
127 /* Per-playback/record device */
129 char *device_name
; /* Name of the device used as an identifer on the server */
130 char interface_name
[MAXPNAMELEN
* 2];
132 pa_volume_t left_vol
; /* Volume is per device and always stereo */
133 pa_volume_t right_vol
;
140 WINE_WAVEINST
*instance
[PULSE_MAX_STREAM_INSTANCES
];
143 /* We establish one context per instance, so make it global to the lib */
144 pa_context
*PULSE_context
; /* Connection Context */
145 pa_threaded_mainloop
*PULSE_ml
; /* PA Runtime information */
147 /* WaveIn / WaveOut devices */
148 WINE_WAVEDEV
*WOutDev
;
149 WINE_WAVEDEV
*WInDev
;
150 DWORD PULSE_WodNumDevs
;
151 DWORD PULSE_WidNumDevs
;
154 void PULSE_wait_for_operation(pa_operation
*o
, WINE_WAVEINST
*ww
);
155 void PULSE_stream_success_callback(pa_stream
*s
, int success
, void *userdata
);
156 void PULSE_stream_state_callback(pa_stream
*s
, void *userdata
);
157 void PULSE_context_success_callback(pa_context
*c
, int success
, void *userdata
);
158 void PULSE_stream_request_callback(pa_stream
*s
, size_t n
, void *userdata
);
159 BOOL
PULSE_setupFormat(LPWAVEFORMATEX wf
, pa_sample_spec
*ss
);
160 int PULSE_InitRingMessage(PULSE_MSG_RING
* omr
);
161 int PULSE_DestroyRingMessage(PULSE_MSG_RING
* omr
);
162 void PULSE_ResetRingMessage(PULSE_MSG_RING
* omr
);
163 void PULSE_WaitRingMessage(PULSE_MSG_RING
* omr
, DWORD sleep
);
164 int PULSE_AddRingMessage(PULSE_MSG_RING
* omr
, enum win_wm_message msg
, DWORD param
, BOOL wait
);
165 int PULSE_RetrieveRingMessage(PULSE_MSG_RING
* omr
, enum win_wm_message
*msg
, DWORD
*param
, HANDLE
*hEvent
);
166 const char * PULSE_getCmdString(enum win_wm_message msg
);