push 9eb9af089d68d39110a91889d3a673043db63c4b
[wine/hacks.git] / dlls / winepulse.drv / winepulse.h
blob64778ca9dda8b6da7183e042b18ffb5cbb23daad
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
22 #endif
24 #if defined(HAVE_PULSEAUDIO) && !defined(__WINEPULSE_H)
25 #define __WINEPULSE_H
27 #include "mmreg.h"
28 #include "dsound.h"
29 #include "dsdriver.h"
31 #include "ks.h"
32 #include "ksmedia.h"
33 #include "ksguid.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 * +---------+-------------+---------------+---------------------------------+
54 #undef PULSE_VERBOSE
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 */
66 enum win_wm_message {
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
71 typedef struct {
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 */
75 } PULSE_MSG;
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
81 typedef struct {
82 PULSE_MSG * messages;
83 int ring_buffer_size;
84 int msg_tosave;
85 int msg_toget;
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 */
88 int msg_pipe[2];
89 HANDLE msg_event;
90 CRITICAL_SECTION msg_crst;
91 } PULSE_MSG_RING;
93 /* Per-playback/record instance */
94 typedef struct {
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;
98 WORD wFlags;
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 */
103 pa_cvolume volume;
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;
122 HANDLE hThread;
123 DWORD dwThreadID;
124 PULSE_MSG_RING msgRing;
125 } WINE_WAVEINST;
127 /* Per-playback/record device */
128 typedef struct {
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;
135 union {
136 WAVEOUTCAPSW out;
137 WAVEINCAPSW in;
138 } caps;
140 WINE_WAVEINST *instance[PULSE_MAX_STREAM_INSTANCES];
141 } WINE_WAVEDEV;
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;
153 /* pulse.c */
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);
167 #endif