bluetooth: Support port availability flag
[profile/ivi/pulseaudio.git] / src / modules / module-waveout.c
1 /***
2   This file is part of PulseAudio.
3
4   Copyright 2006 Lennart Poettering
5   Copyright 2006-2007 Pierre Ossman <ossman@cendio.se> for Cendio AB
6
7   PulseAudio is free software; you can redistribute it and/or modify
8   it under the terms of the GNU Lesser General Public License as published
9   by the Free Software Foundation; either version 2.1 of the License,
10   or (at your option) any later version.
11
12   PulseAudio is distributed in the hope that it will be useful, but
13   WITHOUT ANY WARRANTY; without even the implied warranty of
14   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15   General Public License for more details.
16
17   You should have received a copy of the GNU Lesser General Public License
18   along with PulseAudio; if not, write to the Free Software
19   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
20   USA.
21 ***/
22
23 #ifdef HAVE_CONFIG_H
24 #include <config.h>
25 #endif
26
27 #include <windows.h>
28 #include <mmsystem.h>
29
30 #include <pulse/xmalloc.h>
31 #include <pulse/timeval.h>
32
33 #include <pulsecore/sink.h>
34 #include <pulsecore/source.h>
35 #include <pulsecore/module.h>
36 #include <pulsecore/modargs.h>
37 #include <pulsecore/sample-util.h>
38 #include <pulsecore/core-util.h>
39 #include <pulsecore/log.h>
40 #include <pulsecore/thread.h>
41 #include <pulsecore/thread-mq.h>
42
43 #include "module-waveout-symdef.h"
44
45 PA_MODULE_AUTHOR("Pierre Ossman");
46 PA_MODULE_DESCRIPTION("Windows waveOut Sink/Source");
47 PA_MODULE_VERSION(PACKAGE_VERSION);
48 PA_MODULE_USAGE(
49     "sink_name=<name for the sink> "
50     "source_name=<name for the source> "
51     "device=<device number> "
52     "device_name=<name of the device> "
53     "record=<enable source?> "
54     "playback=<enable sink?> "
55     "format=<sample format> "
56     "rate=<sample rate> "
57     "channels=<number of channels> "
58     "channel_map=<channel map> "
59     "fragments=<number of fragments> "
60     "fragment_size=<fragment size>");
61
62 #define DEFAULT_SINK_NAME "wave_output"
63 #define DEFAULT_SOURCE_NAME "wave_input"
64
65 #define WAVEOUT_MAX_VOLUME 0xFFFF
66
67 struct userdata {
68     pa_sink *sink;
69     pa_source *source;
70     pa_core *core;
71     pa_usec_t poll_timeout;
72
73     pa_thread *thread;
74     pa_thread_mq thread_mq;
75     pa_rtpoll *rtpoll;
76
77     uint32_t fragments, fragment_size;
78
79     uint32_t free_ofrags, free_ifrags;
80
81     DWORD written_bytes;
82     int sink_underflow;
83
84     int cur_ohdr, cur_ihdr;
85     WAVEHDR *ohdrs, *ihdrs;
86
87     HWAVEOUT hwo;
88     HWAVEIN hwi;
89     pa_module *module;
90
91     CRITICAL_SECTION crit;
92 };
93
94 static const char* const valid_modargs[] = {
95     "sink_name",
96     "source_name",
97     "device",
98     "device_name",
99     "record",
100     "playback",
101     "fragments",
102     "fragment_size",
103     "format",
104     "rate",
105     "channels",
106     "channel_map",
107     NULL
108 };
109
110 static void do_write(struct userdata *u) {
111     uint32_t free_frags;
112     pa_memchunk memchunk;
113     WAVEHDR *hdr;
114     MMRESULT res;
115     void *p;
116
117     if (!u->sink)
118         return;
119
120     if (!PA_SINK_IS_LINKED(u->sink->state))
121         return;
122
123     EnterCriticalSection(&u->crit);
124     free_frags = u->free_ofrags;
125     LeaveCriticalSection(&u->crit);
126
127     if (!u->sink_underflow && (free_frags == u->fragments))
128         pa_log_debug("WaveOut underflow!");
129
130     while (free_frags) {
131         hdr = &u->ohdrs[u->cur_ohdr];
132         if (hdr->dwFlags & WHDR_PREPARED)
133             waveOutUnprepareHeader(u->hwo, hdr, sizeof(WAVEHDR));
134
135         hdr->dwBufferLength = 0;
136         while (hdr->dwBufferLength < u->fragment_size) {
137             size_t len;
138
139             len = u->fragment_size - hdr->dwBufferLength;
140
141             pa_sink_render(u->sink, len, &memchunk);
142
143             pa_assert(memchunk.memblock);
144             pa_assert(memchunk.length);
145
146             if (memchunk.length < len)
147                 len = memchunk.length;
148
149             p = pa_memblock_acquire(memchunk.memblock);
150             memcpy(hdr->lpData + hdr->dwBufferLength, (char*) p + memchunk.index, len);
151             pa_memblock_release(memchunk.memblock);
152
153             hdr->dwBufferLength += len;
154
155             pa_memblock_unref(memchunk.memblock);
156             memchunk.memblock = NULL;
157         }
158
159         /* Underflow detection */
160         if (hdr->dwBufferLength == 0) {
161             u->sink_underflow = 1;
162             break;
163         }
164         u->sink_underflow = 0;
165
166         res = waveOutPrepareHeader(u->hwo, hdr, sizeof(WAVEHDR));
167         if (res != MMSYSERR_NOERROR)
168             pa_log_error("Unable to prepare waveOut block: %d", res);
169
170         res = waveOutWrite(u->hwo, hdr, sizeof(WAVEHDR));
171         if (res != MMSYSERR_NOERROR)
172             pa_log_error("Unable to write waveOut block: %d", res);
173
174         u->written_bytes += hdr->dwBufferLength;
175
176         EnterCriticalSection(&u->crit);
177         u->free_ofrags--;
178         LeaveCriticalSection(&u->crit);
179
180         free_frags--;
181         u->cur_ohdr++;
182         u->cur_ohdr %= u->fragments;
183     }
184 }
185
186 static void do_read(struct userdata *u) {
187     uint32_t free_frags;
188     pa_memchunk memchunk;
189     WAVEHDR *hdr;
190     MMRESULT res;
191     void *p;
192
193     if (!u->source)
194         return;
195
196     if (!PA_SOURCE_IS_LINKED(u->source->state))
197         return;
198
199     EnterCriticalSection(&u->crit);
200     free_frags = u->free_ifrags;
201     u->free_ifrags = 0;
202     LeaveCriticalSection(&u->crit);
203
204     if (free_frags == u->fragments)
205         pa_log_debug("WaveIn overflow!");
206
207     while (free_frags) {
208         hdr = &u->ihdrs[u->cur_ihdr];
209         if (hdr->dwFlags & WHDR_PREPARED)
210             waveInUnprepareHeader(u->hwi, hdr, sizeof(WAVEHDR));
211
212         if (hdr->dwBytesRecorded) {
213             memchunk.memblock = pa_memblock_new(u->core->mempool, hdr->dwBytesRecorded);
214             pa_assert(memchunk.memblock);
215
216             p = pa_memblock_acquire(memchunk.memblock);
217             memcpy((char*) p, hdr->lpData, hdr->dwBytesRecorded);
218             pa_memblock_release(memchunk.memblock);
219
220             memchunk.length = hdr->dwBytesRecorded;
221             memchunk.index = 0;
222
223             pa_source_post(u->source, &memchunk);
224             pa_memblock_unref(memchunk.memblock);
225         }
226
227         res = waveInPrepareHeader(u->hwi, hdr, sizeof(WAVEHDR));
228         if (res != MMSYSERR_NOERROR)
229             pa_log_error("Unable to prepare waveIn block: %d", res);
230
231         res = waveInAddBuffer(u->hwi, hdr, sizeof(WAVEHDR));
232         if (res != MMSYSERR_NOERROR)
233             pa_log_error("Unable to add waveIn block: %d", res);
234
235         free_frags--;
236         u->cur_ihdr++;
237         u->cur_ihdr %= u->fragments;
238     }
239 }
240
241 static void thread_func(void *userdata) {
242     struct userdata *u = userdata;
243
244     pa_assert(u);
245     pa_assert(u->sink || u->source);
246
247     pa_log_debug("Thread starting up");
248
249     if (u->core->realtime_scheduling)
250         pa_make_realtime(u->core->realtime_priority);
251
252     pa_thread_mq_install(&u->thread_mq);
253
254     for (;;) {
255         int ret;
256         pa_bool_t need_timer = FALSE;
257
258         if (u->sink && PA_SINK_IS_OPENED(u->sink->thread_info.state)) {
259             if (u->sink->thread_info.rewind_requested)
260                 pa_sink_process_rewind(u->sink, 0);
261
262             do_write(u);
263             need_timer = TRUE;
264         }
265         if (u->source && PA_SOURCE_IS_OPENED(u->source->thread_info.state)) {
266             do_read(u);
267             need_timer = TRUE;
268         }
269
270         if (need_timer)
271             pa_rtpoll_set_timer_relative(u->rtpoll, u->poll_timeout);
272         else
273             pa_rtpoll_set_timer_disabled(u->rtpoll);
274
275         /* Hmm, nothing to do. Let's sleep */
276         if ((ret = pa_rtpoll_run(u->rtpoll, TRUE)) < 0)
277             goto fail;
278
279         if (ret == 0)
280             goto finish;
281     }
282
283 fail:
284     /* If this was no regular exit from the loop we have to continue
285      * processing messages until we received PA_MESSAGE_SHUTDOWN */
286     pa_asyncmsgq_post(u->thread_mq.outq, PA_MSGOBJECT(u->core), PA_CORE_MESSAGE_UNLOAD_MODULE, u->module, 0, NULL, NULL);
287     pa_asyncmsgq_wait_for(u->thread_mq.inq, PA_MESSAGE_SHUTDOWN);
288
289 finish:
290     pa_log_debug("Thread shutting down");
291 }
292
293 static void CALLBACK chunk_done_cb(HWAVEOUT hwo, UINT msg, DWORD_PTR inst, DWORD param1, DWORD param2) {
294     struct userdata *u = (struct userdata*) inst;
295
296     if (msg == WOM_OPEN)
297         pa_log_debug("WaveOut subsystem opened.");
298     if (msg == WOM_CLOSE)
299         pa_log_debug("WaveOut subsystem closed.");
300     if (msg != WOM_DONE)
301         return;
302
303     EnterCriticalSection(&u->crit);
304     u->free_ofrags++;
305     pa_assert(u->free_ofrags <= u->fragments);
306     LeaveCriticalSection(&u->crit);
307 }
308
309 static void CALLBACK chunk_ready_cb(HWAVEIN hwi, UINT msg, DWORD_PTR inst, DWORD param1, DWORD param2) {
310     struct userdata *u = (struct userdata*) inst;
311
312     if (msg == WIM_OPEN)
313         pa_log_debug("WaveIn subsystem opened.");
314     if (msg == WIM_CLOSE)
315         pa_log_debug("WaveIn subsystem closed.");
316     if (msg != WIM_DATA)
317         return;
318
319     EnterCriticalSection(&u->crit);
320     u->free_ifrags++;
321     pa_assert(u->free_ifrags <= u->fragments);
322     LeaveCriticalSection(&u->crit);
323 }
324
325 static pa_usec_t sink_get_latency(struct userdata *u) {
326     uint32_t free_frags;
327     MMTIME mmt;
328     pa_assert(u);
329     pa_assert(u->sink);
330
331     memset(&mmt, 0, sizeof(mmt));
332     mmt.wType = TIME_BYTES;
333     if (waveOutGetPosition(u->hwo, &mmt, sizeof(mmt)) == MMSYSERR_NOERROR)
334         return pa_bytes_to_usec(u->written_bytes - mmt.u.cb, &u->sink->sample_spec);
335     else {
336         EnterCriticalSection(&u->crit);
337         free_frags = u->free_ofrags;
338         LeaveCriticalSection(&u->crit);
339
340         return pa_bytes_to_usec((u->fragments - free_frags) * u->fragment_size, &u->sink->sample_spec);
341     }
342 }
343
344 static pa_usec_t source_get_latency(struct userdata *u) {
345     pa_usec_t r = 0;
346     uint32_t free_frags;
347     pa_assert(u);
348     pa_assert(u->source);
349
350     EnterCriticalSection(&u->crit);
351     free_frags = u->free_ifrags;
352     LeaveCriticalSection(&u->crit);
353
354     r += pa_bytes_to_usec((free_frags + 1) * u->fragment_size, &u->source->sample_spec);
355
356     return r;
357 }
358
359 static int process_msg(pa_msgobject *o, int code, void *data, int64_t offset, pa_memchunk *chunk) {
360     struct userdata *u;
361
362     if (pa_sink_isinstance(o)) {
363         u = PA_SINK(o)->userdata;
364
365         switch (code) {
366
367             case PA_SINK_MESSAGE_GET_LATENCY: {
368                 pa_usec_t r = 0;
369                 if (u->hwo)
370                     r = sink_get_latency(u);
371                 *((pa_usec_t*) data) = r;
372                 return 0;
373             }
374
375         }
376
377         return pa_sink_process_msg(o, code, data, offset, chunk);
378     }
379
380     if (pa_source_isinstance(o)) {
381         u = PA_SOURCE(o)->userdata;
382
383         switch (code) {
384
385             case PA_SOURCE_MESSAGE_GET_LATENCY: {
386                 pa_usec_t r = 0;
387                 if (u->hwi)
388                     r = source_get_latency(u);
389                 *((pa_usec_t*) data) = r;
390                 return 0;
391             }
392
393         }
394
395         return pa_source_process_msg(o, code, data, offset, chunk);
396     }
397
398     return -1;
399 }
400
401 static void sink_get_volume_cb(pa_sink *s) {
402     struct userdata *u = s->userdata;
403     WAVEOUTCAPS caps;
404     DWORD vol;
405     pa_volume_t left, right;
406
407     if (waveOutGetDevCaps(u->hwo, &caps, sizeof(caps)) != MMSYSERR_NOERROR)
408         return;
409     if (!(caps.dwSupport & WAVECAPS_VOLUME))
410         return;
411
412     if (waveOutGetVolume(u->hwo, &vol) != MMSYSERR_NOERROR)
413         return;
414
415     left = PA_CLAMP_VOLUME((vol & 0xFFFF) * PA_VOLUME_NORM / WAVEOUT_MAX_VOLUME);
416     if (caps.dwSupport & WAVECAPS_LRVOLUME)
417         right = PA_CLAMP_VOLUME(((vol >> 16) & 0xFFFF) * PA_VOLUME_NORM / WAVEOUT_MAX_VOLUME);
418     else
419         right = left;
420
421     /* Windows supports > 2 channels, except for volume control */
422     if (s->real_volume.channels > 2)
423         pa_cvolume_set(&s->real_volume, s->real_volume.channels, (left + right)/2);
424
425     s->real_volume.values[0] = left;
426     if (s->real_volume.channels > 1)
427         s->real_volume.values[1] = right;
428 }
429
430 static void sink_set_volume_cb(pa_sink *s) {
431     struct userdata *u = s->userdata;
432     WAVEOUTCAPS caps;
433     DWORD vol;
434
435     if (waveOutGetDevCaps(u->hwo, &caps, sizeof(caps)) != MMSYSERR_NOERROR)
436         return;
437     if (!(caps.dwSupport & WAVECAPS_VOLUME))
438         return;
439
440     if (s->real_volume.channels == 2 && caps.dwSupport & WAVECAPS_LRVOLUME) {
441         vol = (s->real_volume.values[0] * WAVEOUT_MAX_VOLUME / PA_VOLUME_NORM)
442             | (s->real_volume.values[1] * WAVEOUT_MAX_VOLUME / PA_VOLUME_NORM) << 16;
443     } else {
444         vol = (pa_cvolume_avg(&(s->real_volume)) * WAVEOUT_MAX_VOLUME / PA_VOLUME_NORM)
445             | (pa_cvolume_avg(&(s->real_volume)) * WAVEOUT_MAX_VOLUME / PA_VOLUME_NORM) << 16;
446     }
447
448     if (waveOutSetVolume(u->hwo, vol) != MMSYSERR_NOERROR)
449         return;
450 }
451
452 static int ss_to_waveformat(pa_sample_spec *ss, LPWAVEFORMATEX wf) {
453     wf->wFormatTag = WAVE_FORMAT_PCM;
454
455     if (ss->channels > 2) {
456         pa_log_error("More than two channels not supported.");
457         return -1;
458     }
459
460     wf->nChannels = ss->channels;
461
462     wf->nSamplesPerSec = ss->rate;
463
464     if (ss->format == PA_SAMPLE_U8)
465         wf->wBitsPerSample = 8;
466     else if (ss->format == PA_SAMPLE_S16NE)
467         wf->wBitsPerSample = 16;
468     else {
469         pa_log_error("Unsupported sample format, only u8 and s16 are supported.");
470         return -1;
471     }
472
473     wf->nBlockAlign = wf->nChannels * wf->wBitsPerSample/8;
474     wf->nAvgBytesPerSec = wf->nSamplesPerSec * wf->nBlockAlign;
475
476     wf->cbSize = 0;
477
478     return 0;
479 }
480
481 int pa__get_n_used(pa_module *m) {
482     struct userdata *u;
483     pa_assert(m);
484     pa_assert(m->userdata);
485     u = (struct userdata*) m->userdata;
486
487     return (u->sink ? pa_sink_used_by(u->sink) : 0) +
488            (u->source ? pa_source_used_by(u->source) : 0);
489 }
490
491 int pa__init(pa_module *m) {
492     struct userdata *u = NULL;
493     HWAVEOUT hwo = INVALID_HANDLE_VALUE;
494     HWAVEIN hwi = INVALID_HANDLE_VALUE;
495     WAVEFORMATEX wf;
496     WAVEOUTCAPS pwoc;
497     MMRESULT result;
498     int nfrags, frag_size;
499     pa_bool_t record = TRUE, playback = TRUE;
500     unsigned int device;
501     pa_sample_spec ss;
502     pa_channel_map map;
503     pa_modargs *ma = NULL;
504     const char *device_name = NULL;
505     unsigned int i;
506
507     pa_assert(m);
508     pa_assert(m->core);
509
510     if (!(ma = pa_modargs_new(m->argument, valid_modargs))) {
511         pa_log("failed to parse module arguments.");
512         goto fail;
513     }
514
515     if (pa_modargs_get_value_boolean(ma, "record", &record) < 0 || pa_modargs_get_value_boolean(ma, "playback", &playback) < 0) {
516         pa_log("record= and playback= expect boolean argument.");
517         goto fail;
518     }
519
520     if (!playback && !record) {
521         pa_log("neither playback nor record enabled for device.");
522         goto fail;
523     }
524
525     /* Set the device to be opened.  If set device_name is used,
526      * else device if set and lastly WAVE_MAPPER is the default */
527     device = WAVE_MAPPER;
528     if (pa_modargs_get_value_u32(ma, "device", &device) < 0) {
529         pa_log("failed to parse device argument");
530         goto fail;
531     }
532     if ((device_name = pa_modargs_get_value(ma, "device_name", NULL)) != NULL) {
533         unsigned int num_devices = waveOutGetNumDevs();
534         for (i = 0; i < num_devices; i++) {
535             if (waveOutGetDevCaps(i, &pwoc, sizeof(pwoc)) == MMSYSERR_NOERROR)
536                 if (_stricmp(device_name, pwoc.szPname) == 0)
537                     break;
538         }
539         if (i < num_devices)
540             device = i;
541         else {
542             pa_log("device not found: %s", device_name);
543             goto fail;
544         }
545     }
546     if (waveOutGetDevCaps(device, &pwoc, sizeof(pwoc)) == MMSYSERR_NOERROR)
547         device_name = pwoc.szPname;
548     else
549         device_name = "unknown";
550
551     nfrags = 5;
552     frag_size = 8192;
553     if (pa_modargs_get_value_s32(ma, "fragments", &nfrags) < 0 || pa_modargs_get_value_s32(ma, "fragment_size", &frag_size) < 0) {
554         pa_log("failed to parse fragments arguments");
555         goto fail;
556     }
557
558     ss = m->core->default_sample_spec;
559     if (pa_modargs_get_sample_spec_and_channel_map(ma, &ss, &map, PA_CHANNEL_MAP_WAVEEX) < 0) {
560         pa_log("failed to parse sample specification");
561         goto fail;
562     }
563
564     if (ss_to_waveformat(&ss, &wf) < 0)
565         goto fail;
566
567     u = pa_xmalloc(sizeof(struct userdata));
568
569     if (record) {
570         result = waveInOpen(&hwi, device, &wf, 0, 0, WAVE_FORMAT_DIRECT | WAVE_FORMAT_QUERY);
571         if (result != MMSYSERR_NOERROR) {
572             pa_log_warn("Sample spec not supported by WaveIn, falling back to default sample rate.");
573             ss.rate = wf.nSamplesPerSec = m->core->default_sample_spec.rate;
574         }
575         result = waveInOpen(&hwi, device, &wf, (DWORD_PTR) chunk_ready_cb, (DWORD_PTR) u, CALLBACK_FUNCTION);
576         if (result != MMSYSERR_NOERROR) {
577             char errortext[MAXERRORLENGTH];
578             pa_log("Failed to open WaveIn.");
579             if (waveInGetErrorText(result, errortext, sizeof(errortext)) == MMSYSERR_NOERROR)
580                 pa_log("Error: %s", errortext);
581             goto fail;
582         }
583         if (waveInStart(hwi) != MMSYSERR_NOERROR) {
584             pa_log("failed to start waveIn");
585             goto fail;
586         }
587     }
588
589     if (playback) {
590         result = waveOutOpen(&hwo, device, &wf, 0, 0, WAVE_FORMAT_DIRECT | WAVE_FORMAT_QUERY);
591         if (result != MMSYSERR_NOERROR) {
592             pa_log_warn("Sample spec not supported by WaveOut, falling back to default sample rate.");
593             ss.rate = wf.nSamplesPerSec = m->core->default_sample_spec.rate;
594         }
595         result = waveOutOpen(&hwo, device, &wf, (DWORD_PTR) chunk_done_cb, (DWORD_PTR) u, CALLBACK_FUNCTION);
596         if (result != MMSYSERR_NOERROR) {
597             char errortext[MAXERRORLENGTH];
598             pa_log("Failed to open WaveOut.");
599             if (waveOutGetErrorText(result, errortext, sizeof(errortext)) == MMSYSERR_NOERROR)
600                 pa_log("Error: %s", errortext);
601             goto fail;
602         }
603     }
604
605     InitializeCriticalSection(&u->crit);
606
607     if (hwi != INVALID_HANDLE_VALUE) {
608         char *description = pa_sprintf_malloc("WaveIn on %s", device_name);
609         pa_source_new_data data;
610         pa_source_new_data_init(&data);
611         data.driver = __FILE__;
612         data.module = m;
613         pa_source_new_data_set_sample_spec(&data, &ss);
614         pa_source_new_data_set_channel_map(&data, &map);
615         pa_source_new_data_set_name(&data, pa_modargs_get_value(ma, "source_name", DEFAULT_SOURCE_NAME));
616         u->source = pa_source_new(m->core, &data, PA_SOURCE_HARDWARE|PA_SOURCE_LATENCY);
617         pa_source_new_data_done(&data);
618
619         pa_assert(u->source);
620         u->source->userdata = u;
621         pa_source_set_description(u->source, description);
622         u->source->parent.process_msg = process_msg;
623         pa_xfree(description);
624     } else
625         u->source = NULL;
626
627     if (hwo != INVALID_HANDLE_VALUE) {
628         char *description = pa_sprintf_malloc("WaveOut on %s", device_name);
629         pa_sink_new_data data;
630         pa_sink_new_data_init(&data);
631         data.driver = __FILE__;
632         data.module = m;
633         pa_sink_new_data_set_sample_spec(&data, &ss);
634         pa_sink_new_data_set_channel_map(&data, &map);
635         pa_sink_new_data_set_name(&data, pa_modargs_get_value(ma, "sink_name", DEFAULT_SINK_NAME));
636         u->sink = pa_sink_new(m->core, &data, PA_SINK_HARDWARE|PA_SINK_LATENCY);
637         pa_sink_new_data_done(&data);
638
639         pa_assert(u->sink);
640         pa_sink_set_get_volume_callback(u->sink, sink_get_volume_cb);
641         pa_sink_set_set_volume_callback(u->sink, sink_set_volume_cb);
642         u->sink->userdata = u;
643         pa_sink_set_description(u->sink, description);
644         u->sink->parent.process_msg = process_msg;
645         pa_xfree(description);
646     } else
647         u->sink = NULL;
648
649     pa_assert(u->source || u->sink);
650     pa_modargs_free(ma);
651
652     u->core = m->core;
653     u->hwi = hwi;
654     u->hwo = hwo;
655
656     u->fragments = nfrags;
657     u->free_ifrags = u->fragments;
658     u->free_ofrags = u->fragments;
659     u->fragment_size = frag_size - (frag_size % pa_frame_size(&ss));
660
661     u->written_bytes = 0;
662     u->sink_underflow = 1;
663
664     u->poll_timeout = pa_bytes_to_usec(u->fragments * u->fragment_size / 10, &ss);
665     pa_log_debug("Poll timeout = %.1f ms", (double) u->poll_timeout / PA_USEC_PER_MSEC);
666
667     u->cur_ihdr = 0;
668     u->cur_ohdr = 0;
669     u->ihdrs = pa_xmalloc0(sizeof(WAVEHDR) * u->fragments);
670     pa_assert(u->ihdrs);
671     u->ohdrs = pa_xmalloc0(sizeof(WAVEHDR) * u->fragments);
672     pa_assert(u->ohdrs);
673     for (i = 0; i < u->fragments; i++) {
674         u->ihdrs[i].dwBufferLength = u->fragment_size;
675         u->ohdrs[i].dwBufferLength = u->fragment_size;
676         u->ihdrs[i].lpData = pa_xmalloc(u->fragment_size);
677         pa_assert(u->ihdrs);
678         u->ohdrs[i].lpData = pa_xmalloc(u->fragment_size);
679         pa_assert(u->ohdrs);
680     }
681
682     u->module = m;
683     m->userdata = u;
684
685     /* Read mixer settings */
686     if (u->sink)
687         sink_get_volume_cb(u->sink);
688
689     u->rtpoll = pa_rtpoll_new();
690     pa_thread_mq_init(&u->thread_mq, m->core->mainloop, u->rtpoll);
691
692     if (u->sink) {
693         pa_sink_set_asyncmsgq(u->sink, u->thread_mq.inq);
694         pa_sink_set_rtpoll(u->sink, u->rtpoll);
695     }
696     if (u->source) {
697         pa_source_set_asyncmsgq(u->source, u->thread_mq.inq);
698         pa_source_set_rtpoll(u->source, u->rtpoll);
699     }
700
701     if (!(u->thread = pa_thread_new("waveout", thread_func, u))) {
702         pa_log("Failed to create thread.");
703         goto fail;
704     }
705
706     if (u->sink)
707         pa_sink_put(u->sink);
708     if (u->source)
709         pa_source_put(u->source);
710
711     return 0;
712
713 fail:
714     if (ma)
715         pa_modargs_free(ma);
716
717     pa__done(m);
718
719     return -1;
720 }
721
722 void pa__done(pa_module *m) {
723     struct userdata *u;
724     unsigned int i;
725
726     pa_assert(m);
727     pa_assert(m->core);
728
729     if (!(u = m->userdata))
730         return;
731
732     if (u->sink)
733         pa_sink_unlink(u->sink);
734     if (u->source)
735         pa_source_unlink(u->source);
736
737     pa_asyncmsgq_send(u->thread_mq.inq, NULL, PA_MESSAGE_SHUTDOWN, NULL, 0, NULL);
738     if (u->thread)
739         pa_thread_free(u->thread);
740     pa_thread_mq_done(&u->thread_mq);
741
742     if (u->sink)
743         pa_sink_unref(u->sink);
744     if (u->source)
745         pa_source_unref(u->source);
746
747     if (u->rtpoll)
748         pa_rtpoll_free(u->rtpoll);
749
750     if (u->hwi != INVALID_HANDLE_VALUE) {
751         waveInReset(u->hwi);
752         waveInClose(u->hwi);
753     }
754
755     if (u->hwo != INVALID_HANDLE_VALUE) {
756         waveOutReset(u->hwo);
757         waveOutClose(u->hwo);
758     }
759
760     for (i = 0; i < u->fragments; i++) {
761         pa_xfree(u->ihdrs[i].lpData);
762         pa_xfree(u->ohdrs[i].lpData);
763     }
764
765     pa_xfree(u->ihdrs);
766     pa_xfree(u->ohdrs);
767
768     DeleteCriticalSection(&u->crit);
769
770     pa_xfree(u);
771 }