/***
  This file is part of PulseAudio.

  Copyright 2006 Lennart Poettering
  Copyright 2006-2007 Pierre Ossman <ossman@cendio.se> for Cendio AB

  PulseAudio is free software; you can redistribute it and/or modify
  it under the terms of the GNU Lesser General Public License as published
  by the Free Software Foundation; either version 2.1 of the License,
  or (at your option) any later version.

  PulseAudio is distributed in the hope that it will be useful, but
  WITHOUT ANY WARRANTY; without even the implied warranty of
  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  General Public License for more details.

  You should have received a copy of the GNU Lesser General Public License
  along with PulseAudio; if not, see <http://www.gnu.org/licenses/>.
***/

#ifdef HAVE_CONFIG_H
#include <config.h>
#endif

#include <windows.h>
#include <mmsystem.h>
#include <mmreg.h>
#include <string.h>

#include <pulse/xmalloc.h>
#include <pulse/timeval.h>
#include <pulse/util.h>

#include <pulsecore/sink.h>
#include <pulsecore/source.h>
#include <pulsecore/module.h>
#include <pulsecore/modargs.h>
#include <pulsecore/sample-util.h>
#include <pulsecore/core-util.h>
#include <pulsecore/log.h>
#include <pulsecore/thread.h>
#include <pulsecore/thread-mq.h>

PA_MODULE_AUTHOR("Pierre Ossman");
PA_MODULE_DESCRIPTION("Windows waveOut Sink/Source");
PA_MODULE_VERSION(PACKAGE_VERSION);
PA_MODULE_USAGE(
    "sink_name=<name for the sink> "
    "source_name=<name for the source> "
    "output_device=<device number for the sink> "
    "output_device_name=<name of the output device> "
    "input_device=<device number for the source> "
    "input_device_name=<name of the input device> "
    "record=<enable source?> "
    "playback=<enable sink?> "
    "format=<sample format> "
    "rate=<sample rate> "
    "channels=<number of channels> "
    "channel_map=<channel map> "
    "fragments=<number of fragments> "
    "fragment_size=<fragment size>"
    "device=<device number - deprecated>"
    "device_name=<name of the device - deprecated>");

#define DEFAULT_SINK_NAME "wave_output"
#define DEFAULT_SOURCE_NAME "wave_input"

#define WAVEOUT_MAX_VOLUME 0xFFFF

struct userdata {
    pa_sink *sink;
    pa_source *source;
    pa_core *core;
    pa_usec_t poll_timeout;

    pa_thread *thread;
    pa_thread_mq thread_mq;
    pa_rtpoll *rtpoll;

    uint32_t fragments, fragment_size;

    uint32_t free_ofrags, free_ifrags;

    DWORD written_bytes;
    int sink_underflow;

    int cur_ohdr, cur_ihdr;
    WAVEHDR *ohdrs, *ihdrs;

    HWAVEOUT hwo;
    HWAVEIN hwi;
    pa_module *module;

    CRITICAL_SECTION crit;
};

static const char* const valid_modargs[] = {
    "sink_name",
    "source_name",
    "output_device",
    "output_device_name",
    "input_device",
    "input_device_name",
    "record",
    "playback",
    "fragments",
    "fragment_size",
    "format",
    "rate",
    "channels",
    "channel_map",
    "device",
    "device_name",
    NULL
};

static void do_write(struct userdata *u) {
    uint32_t free_frags;
    pa_memchunk memchunk;
    WAVEHDR *hdr;
    MMRESULT res;
    void *p;

    if (!u->sink)
        return;

    if (!PA_SINK_IS_LINKED(u->sink->state))
        return;

    EnterCriticalSection(&u->crit);
    free_frags = u->free_ofrags;
    LeaveCriticalSection(&u->crit);

    if (!u->sink_underflow && (free_frags == u->fragments))
        pa_log_debug("WaveOut underflow!");

    while (free_frags) {
        hdr = &u->ohdrs[u->cur_ohdr];
        if (hdr->dwFlags & WHDR_PREPARED)
            waveOutUnprepareHeader(u->hwo, hdr, sizeof(WAVEHDR));

        hdr->dwBufferLength = 0;
        while (hdr->dwBufferLength < u->fragment_size) {
            size_t len;

            len = u->fragment_size - hdr->dwBufferLength;

            pa_sink_render(u->sink, len, &memchunk);

            pa_assert(memchunk.memblock);
            pa_assert(memchunk.length);

            if (memchunk.length < len)
                len = memchunk.length;

            p = pa_memblock_acquire(memchunk.memblock);
            memcpy(hdr->lpData + hdr->dwBufferLength, (char*) p + memchunk.index, len);
            pa_memblock_release(memchunk.memblock);

            hdr->dwBufferLength += len;

            pa_memblock_unref(memchunk.memblock);
            memchunk.memblock = NULL;
        }

        /* Underflow detection */
        if (hdr->dwBufferLength == 0) {
            u->sink_underflow = 1;
            break;
        }
        u->sink_underflow = 0;

        res = waveOutPrepareHeader(u->hwo, hdr, sizeof(WAVEHDR));
        if (res != MMSYSERR_NOERROR)
            pa_log_error("Unable to prepare waveOut block: %d", res);

        res = waveOutWrite(u->hwo, hdr, sizeof(WAVEHDR));
        if (res != MMSYSERR_NOERROR)
            pa_log_error("Unable to write waveOut block: %d", res);

        u->written_bytes += hdr->dwBufferLength;

        EnterCriticalSection(&u->crit);
        u->free_ofrags--;
        LeaveCriticalSection(&u->crit);

        free_frags--;
        u->cur_ohdr++;
        u->cur_ohdr %= u->fragments;
    }
}

static void do_read(struct userdata *u) {
    uint32_t free_frags;
    pa_memchunk memchunk;
    WAVEHDR *hdr;
    MMRESULT res;
    void *p;

    if (!u->source)
        return;

    if (!PA_SOURCE_IS_LINKED(u->source->state))
        return;

    EnterCriticalSection(&u->crit);
    free_frags = u->free_ifrags;
    u->free_ifrags = 0;
    LeaveCriticalSection(&u->crit);

    if (free_frags == u->fragments)
        pa_log_debug("WaveIn overflow!");

    while (free_frags) {
        hdr = &u->ihdrs[u->cur_ihdr];
        if (hdr->dwFlags & WHDR_PREPARED)
            waveInUnprepareHeader(u->hwi, hdr, sizeof(WAVEHDR));

        if (hdr->dwBytesRecorded) {
            memchunk.memblock = pa_memblock_new(u->core->mempool, hdr->dwBytesRecorded);
            pa_assert(memchunk.memblock);

            p = pa_memblock_acquire(memchunk.memblock);
            memcpy((char*) p, hdr->lpData, hdr->dwBytesRecorded);
            pa_memblock_release(memchunk.memblock);

            memchunk.length = hdr->dwBytesRecorded;
            memchunk.index = 0;

            pa_source_post(u->source, &memchunk);
            pa_memblock_unref(memchunk.memblock);
        }

        res = waveInPrepareHeader(u->hwi, hdr, sizeof(WAVEHDR));
        if (res != MMSYSERR_NOERROR)
            pa_log_error("Unable to prepare waveIn block: %d", res);

        res = waveInAddBuffer(u->hwi, hdr, sizeof(WAVEHDR));
        if (res != MMSYSERR_NOERROR)
            pa_log_error("Unable to add waveIn block: %d", res);

        free_frags--;
        u->cur_ihdr++;
        u->cur_ihdr %= u->fragments;
    }
}

static void thread_func(void *userdata) {
    struct userdata *u = userdata;

    pa_assert(u);
    pa_assert(u->sink || u->source);

    pa_log_debug("Thread starting up");

    if (u->core->realtime_scheduling)
        pa_thread_make_realtime(u->core->realtime_priority);

    pa_thread_mq_install(&u->thread_mq);

    for (;;) {
        int ret;
        bool need_timer = false;

        if (u->sink) {
            if (PA_UNLIKELY(u->sink->thread_info.rewind_requested))
                pa_sink_process_rewind(u->sink, 0);

            if (PA_SINK_IS_OPENED(u->sink->thread_info.state)) {
                do_write(u);
                need_timer = true;
            }
        }

        if (u->source && PA_SOURCE_IS_OPENED(u->source->thread_info.state)) {
            do_read(u);
            need_timer = true;
        }

        if (need_timer)
            pa_rtpoll_set_timer_relative(u->rtpoll, u->poll_timeout);
        else
            pa_rtpoll_set_timer_disabled(u->rtpoll);

        /* Hmm, nothing to do. Let's sleep */
        if ((ret = pa_rtpoll_run(u->rtpoll)) < 0)
            goto fail;

        if (ret == 0)
            goto finish;
    }

fail:
    /* If this was no regular exit from the loop we have to continue
     * processing messages until we received PA_MESSAGE_SHUTDOWN */
    pa_asyncmsgq_post(u->thread_mq.outq, PA_MSGOBJECT(u->core), PA_CORE_MESSAGE_UNLOAD_MODULE, u->module, 0, NULL, NULL);
    pa_asyncmsgq_wait_for(u->thread_mq.inq, PA_MESSAGE_SHUTDOWN);

finish:
    pa_log_debug("Thread shutting down");
}

static void CALLBACK chunk_done_cb(HWAVEOUT hwo, UINT msg, DWORD_PTR inst, DWORD param1, DWORD param2) {
    struct userdata *u = (struct userdata*) inst;

    if (msg == WOM_OPEN)
        pa_log_debug("WaveOut subsystem opened.");
    if (msg == WOM_CLOSE)
        pa_log_debug("WaveOut subsystem closed.");
    if (msg != WOM_DONE)
        return;

    EnterCriticalSection(&u->crit);
    u->free_ofrags++;
    pa_assert(u->free_ofrags <= u->fragments);
    LeaveCriticalSection(&u->crit);
}

static void CALLBACK chunk_ready_cb(HWAVEIN hwi, UINT msg, DWORD_PTR inst, DWORD param1, DWORD param2) {
    struct userdata *u = (struct userdata*) inst;

    if (msg == WIM_OPEN)
        pa_log_debug("WaveIn subsystem opened.");
    if (msg == WIM_CLOSE)
        pa_log_debug("WaveIn subsystem closed.");
    if (msg != WIM_DATA)
        return;

    EnterCriticalSection(&u->crit);
    u->free_ifrags++;
    pa_assert(u->free_ifrags <= u->fragments);
    LeaveCriticalSection(&u->crit);
}

static pa_usec_t sink_get_latency(struct userdata *u) {
    uint32_t free_frags;
    MMTIME mmt;
    pa_assert(u);
    pa_assert(u->sink);

    memset(&mmt, 0, sizeof(mmt));
    mmt.wType = TIME_BYTES;
    if (waveOutGetPosition(u->hwo, &mmt, sizeof(mmt)) == MMSYSERR_NOERROR)
        return pa_bytes_to_usec(u->written_bytes - mmt.u.cb, &u->sink->sample_spec);
    else {
        EnterCriticalSection(&u->crit);
        free_frags = u->free_ofrags;
        LeaveCriticalSection(&u->crit);

        return pa_bytes_to_usec((u->fragments - free_frags) * u->fragment_size, &u->sink->sample_spec);
    }
}

static pa_usec_t source_get_latency(struct userdata *u) {
    pa_usec_t r = 0;
    uint32_t free_frags;
    pa_assert(u);
    pa_assert(u->source);

    EnterCriticalSection(&u->crit);
    free_frags = u->free_ifrags;
    LeaveCriticalSection(&u->crit);

    r += pa_bytes_to_usec((free_frags + 1) * u->fragment_size, &u->source->sample_spec);

    return r;
}

static int process_msg(pa_msgobject *o, int code, void *data, int64_t offset, pa_memchunk *chunk) {
    struct userdata *u;

    if (pa_sink_isinstance(o)) {
        u = PA_SINK(o)->userdata;

        switch (code) {

            case PA_SINK_MESSAGE_GET_LATENCY: {
                pa_usec_t r = 0;
                if (u->hwo)
                    r = sink_get_latency(u);
                *((int64_t*) data) = (int64_t)r;
                return 0;
            }

        }

        return pa_sink_process_msg(o, code, data, offset, chunk);
    }

    if (pa_source_isinstance(o)) {
        u = PA_SOURCE(o)->userdata;

        switch (code) {

            case PA_SOURCE_MESSAGE_GET_LATENCY: {
                pa_usec_t r = 0;
                if (u->hwi)
                    r = source_get_latency(u);
                *((int64_t*) data) = (int64_t)r;
                return 0;
            }

        }

        return pa_source_process_msg(o, code, data, offset, chunk);
    }

    return -1;
}

static void sink_get_volume_cb(pa_sink *s) {
    struct userdata *u = s->userdata;
    WAVEOUTCAPS caps;
    DWORD vol;
    pa_volume_t left, right;

    if (waveOutGetDevCaps((UINT_PTR) u->hwo, &caps, sizeof(caps)) != MMSYSERR_NOERROR)
        return;
    if (!(caps.dwSupport & WAVECAPS_VOLUME))
        return;

    if (waveOutGetVolume(u->hwo, &vol) != MMSYSERR_NOERROR)
        return;

    left = PA_CLAMP_VOLUME((vol & 0xFFFF) * PA_VOLUME_NORM / WAVEOUT_MAX_VOLUME);
    if (caps.dwSupport & WAVECAPS_LRVOLUME)
        right = PA_CLAMP_VOLUME(((vol >> 16) & 0xFFFF) * PA_VOLUME_NORM / WAVEOUT_MAX_VOLUME);
    else
        right = left;

    /* Windows supports > 2 channels, except for volume control */
    if (s->real_volume.channels > 2)
        pa_cvolume_set(&s->real_volume, s->real_volume.channels, (left + right)/2);

    s->real_volume.values[0] = left;
    if (s->real_volume.channels > 1)
        s->real_volume.values[1] = right;
}

static void sink_set_volume_cb(pa_sink *s) {
    struct userdata *u = s->userdata;
    WAVEOUTCAPS caps;
    DWORD vol;

    if (waveOutGetDevCaps((UINT_PTR) u->hwo, &caps, sizeof(caps)) != MMSYSERR_NOERROR)
        return;
    if (!(caps.dwSupport & WAVECAPS_VOLUME))
        return;

    if (s->real_volume.channels == 2 && caps.dwSupport & WAVECAPS_LRVOLUME) {
        vol = (s->real_volume.values[0] * WAVEOUT_MAX_VOLUME / PA_VOLUME_NORM)
            | (s->real_volume.values[1] * WAVEOUT_MAX_VOLUME / PA_VOLUME_NORM) << 16;
    } else {
        vol = (pa_cvolume_avg(&(s->real_volume)) * WAVEOUT_MAX_VOLUME / PA_VOLUME_NORM)
            | (pa_cvolume_avg(&(s->real_volume)) * WAVEOUT_MAX_VOLUME / PA_VOLUME_NORM) << 16;
    }

    if (waveOutSetVolume(u->hwo, vol) != MMSYSERR_NOERROR)
        return;
}

static DWORD channel_position_to_wavefmt(pa_channel_position_t channel) {
    switch(channel) {
        case PA_CHANNEL_POSITION_MONO:
        case PA_CHANNEL_POSITION_FRONT_LEFT:
            return SPEAKER_FRONT_LEFT;
        case PA_CHANNEL_POSITION_FRONT_RIGHT:
            return SPEAKER_FRONT_RIGHT;
        case PA_CHANNEL_POSITION_FRONT_CENTER:
            return SPEAKER_FRONT_CENTER;

        case PA_CHANNEL_POSITION_REAR_LEFT:
            return SPEAKER_BACK_LEFT;
        case PA_CHANNEL_POSITION_REAR_RIGHT:
            return SPEAKER_BACK_RIGHT;
        case PA_CHANNEL_POSITION_REAR_CENTER:
            return SPEAKER_BACK_CENTER;

        case PA_CHANNEL_POSITION_LFE:
            return SPEAKER_LOW_FREQUENCY;

        case PA_CHANNEL_POSITION_FRONT_LEFT_OF_CENTER:
            return SPEAKER_FRONT_LEFT_OF_CENTER;
        case PA_CHANNEL_POSITION_FRONT_RIGHT_OF_CENTER:
            return SPEAKER_FRONT_RIGHT_OF_CENTER;

        case PA_CHANNEL_POSITION_SIDE_LEFT:
            return SPEAKER_SIDE_LEFT;
        case PA_CHANNEL_POSITION_SIDE_RIGHT:
            return SPEAKER_SIDE_RIGHT;

        case PA_CHANNEL_POSITION_TOP_CENTER:
            return SPEAKER_TOP_CENTER;

        case PA_CHANNEL_POSITION_TOP_FRONT_LEFT:
            return SPEAKER_TOP_FRONT_LEFT;
        case PA_CHANNEL_POSITION_TOP_FRONT_RIGHT:
            return SPEAKER_TOP_FRONT_RIGHT;
        case PA_CHANNEL_POSITION_TOP_FRONT_CENTER:
            return SPEAKER_TOP_FRONT_CENTER;

        case PA_CHANNEL_POSITION_TOP_REAR_LEFT:
            return SPEAKER_TOP_BACK_LEFT;
        case PA_CHANNEL_POSITION_TOP_REAR_RIGHT:
            return SPEAKER_TOP_BACK_RIGHT;
        case PA_CHANNEL_POSITION_TOP_REAR_CENTER:
            return SPEAKER_TOP_BACK_CENTER;

        default:
            return 0;
    }
}

static int ss_to_waveformat(pa_sample_spec *ss, pa_channel_map *map, PWAVEFORMATEXTENSIBLE wf) {
    wf->Format.wFormatTag = WAVE_FORMAT_EXTENSIBLE;
    wf->SubFormat = KSDATAFORMAT_SUBTYPE_PCM;

    wf->Format.nChannels = ss->channels;
    wf->Format.nSamplesPerSec = ss->rate;

    wf->dwChannelMask = 0;
    for (int i = 0; i < map->channels; i++) {
        DWORD thisSpeaker = channel_position_to_wavefmt(map->map[i]);
        if (thisSpeaker == 0 || (wf->dwChannelMask & thisSpeaker)) {
            pa_log_error("Invalid channel map: unknown or duplicated channel %d.", map->map[i]);
            return -1;
        }
        wf->dwChannelMask |= thisSpeaker;
    }

    if (ss->format == PA_SAMPLE_U8) {
        wf->Format.wBitsPerSample = 8;
        wf->Samples.wValidBitsPerSample = 8;
    } else if (ss->format == PA_SAMPLE_S16LE) {
        wf->Format.wBitsPerSample = 16;
        wf->Samples.wValidBitsPerSample = 16;
    } else if (ss->format == PA_SAMPLE_S24LE) {
        wf->Format.wBitsPerSample = 24;
        wf->Samples.wValidBitsPerSample = 24;
    } else if (ss->format == PA_SAMPLE_S32LE) {
        wf->Format.wBitsPerSample = 32;
        wf->Samples.wValidBitsPerSample = 32;
    } else {
        pa_log_error("Unsupported sample format, only u8, s16le, s24le, and s32le are supported.");
        return -1;
    }

    wf->Format.nBlockAlign = wf->Format.nChannels * wf->Format.wBitsPerSample/8;
    wf->Format.nAvgBytesPerSec = wf->Format.nSamplesPerSec * wf->Format.nBlockAlign;

    wf->Format.cbSize = 22;

    return 0;
}

int pa__get_n_used(pa_module *m) {
    struct userdata *u;
    pa_assert(m);
    pa_assert(m->userdata);
    u = (struct userdata*) m->userdata;

    return (u->sink ? pa_sink_used_by(u->sink) : 0) +
           (u->source ? pa_source_used_by(u->source) : 0);
}

int pa__init(pa_module *m) {
    struct userdata *u = NULL;
    HWAVEOUT hwo = INVALID_HANDLE_VALUE;
    HWAVEIN hwi = INVALID_HANDLE_VALUE;
    WAVEFORMATEXTENSIBLE wf;
    WAVEOUTCAPS pwoc;
    WAVEINCAPS pwic;
    MMRESULT result;
    int nfrags, frag_size;
    bool record = true, playback = true;
    unsigned int input_device;
    unsigned int output_device;
    pa_sample_spec ss;
    pa_channel_map map;
    pa_modargs *ma = NULL;
    const char *input_device_name = NULL;
    const char *output_device_name = NULL;
    unsigned int i;

    pa_assert(m);
    pa_assert(m->core);

    if (!(ma = pa_modargs_new(m->argument, valid_modargs))) {
        pa_log("failed to parse module arguments.");
        goto fail;
    }

    /* Check whether deprecated arguments have been used. */
    if (pa_modargs_get_value(ma, "device", NULL) != NULL || pa_modargs_get_value(ma, "device_name", NULL) != NULL) {
        pa_log("device and device_name are no longer supported. Please use input_device, input_device_name, output_device and output_device_name.");
        goto fail;
    }

    if (pa_modargs_get_value_boolean(ma, "record", &record) < 0 || pa_modargs_get_value_boolean(ma, "playback", &playback) < 0) {
        pa_log("record= and playback= expect boolean argument.");
        goto fail;
    }

    if (!playback && !record) {
        pa_log("neither playback nor record enabled for device.");
        goto fail;
    }

    /* Set the output_device to be opened. If set output_device_name is used,
     * else output_device if set and lastly WAVE_MAPPER is the default */
    output_device = WAVE_MAPPER;
    if (pa_modargs_get_value_u32(ma, "output_device", &output_device) < 0) {
        pa_log("failed to parse output_device argument");
        goto fail;
    }
    if ((output_device_name = pa_modargs_get_value(ma, "output_device_name", NULL)) != NULL) {
        unsigned int num_output_devices = waveOutGetNumDevs();
        for (i = 0; i < num_output_devices; i++) {
            if (waveOutGetDevCaps(i, &pwoc, sizeof(pwoc)) == MMSYSERR_NOERROR)
                if (strcmp(output_device_name, pwoc.szPname) == 0)
                    break;
        }
        if (i < num_output_devices)
            output_device = i;
        else {
            pa_log("output_device not found: %s", output_device_name);
            goto fail;
        }
    }
    if (waveOutGetDevCaps(output_device, &pwoc, sizeof(pwoc)) == MMSYSERR_NOERROR)
        output_device_name = pwoc.szPname;
    else
        output_device_name = "unknown";

    /* Set the input_device to be opened. If set input_device_name is used,
     * else input_device if set and lastly WAVE_MAPPER is the default */
    input_device = WAVE_MAPPER;
    if (pa_modargs_get_value_u32(ma, "input_device", &input_device) < 0) {
        pa_log("failed to parse input_device argument");
        goto fail;
    }
    if ((input_device_name = pa_modargs_get_value(ma, "input_device_name", NULL)) != NULL) {
        unsigned int num_input_devices = waveInGetNumDevs();
        for (i = 0; i < num_input_devices; i++) {
            if (waveInGetDevCaps(i, &pwic, sizeof(pwic)) == MMSYSERR_NOERROR)
                if (strcmp(input_device_name, pwic.szPname) == 0)
                    break;
        }
        if (i < num_input_devices)
            input_device = i;
        else {
            pa_log("input_device not found: %s", input_device_name);
            goto fail;
        }
    }
    if (waveInGetDevCaps(input_device, &pwic, sizeof(pwic)) == MMSYSERR_NOERROR)
        input_device_name = pwic.szPname;
    else
        input_device_name = "unknown";


    nfrags = 5;
    frag_size = 8192;
    if (pa_modargs_get_value_s32(ma, "fragments", &nfrags) < 0 || pa_modargs_get_value_s32(ma, "fragment_size", &frag_size) < 0) {
        pa_log("failed to parse fragments arguments");
        goto fail;
    }

    ss = m->core->default_sample_spec;
    if (pa_modargs_get_sample_spec_and_channel_map(ma, &ss, &map, PA_CHANNEL_MAP_WAVEEX) < 0) {
        pa_log("failed to parse sample specification");
        goto fail;
    }

    if (ss_to_waveformat(&ss, &map, &wf) < 0)
        goto fail;

    u = pa_xmalloc(sizeof(struct userdata));

    if (record) {
        result = waveInOpen(&hwi, input_device, &wf, 0, 0, WAVE_FORMAT_DIRECT | WAVE_FORMAT_QUERY);
        if (result != MMSYSERR_NOERROR) {
            pa_log_warn("Sample spec not supported by WaveIn, falling back to default sample rate.");
            ss.rate = wf.Format.nSamplesPerSec = m->core->default_sample_spec.rate;
        }
        result = waveInOpen(&hwi, input_device, &wf, (DWORD_PTR) chunk_ready_cb, (DWORD_PTR) u, CALLBACK_FUNCTION);
        if (result != MMSYSERR_NOERROR) {
            char errortext[MAXERRORLENGTH];
            pa_log("Failed to open WaveIn.");
            if (waveInGetErrorText(result, errortext, sizeof(errortext)) == MMSYSERR_NOERROR)
                pa_log("Error: %s", errortext);
            goto fail;
        }
        if (waveInStart(hwi) != MMSYSERR_NOERROR) {
            pa_log("failed to start waveIn");
            goto fail;
        }
    }

    if (playback) {
        result = waveOutOpen(&hwo, output_device, &wf, 0, 0, WAVE_FORMAT_DIRECT | WAVE_FORMAT_QUERY);
        if (result != MMSYSERR_NOERROR) {
            pa_log_warn("Sample spec not supported by WaveOut, falling back to default sample rate.");
            ss.rate = wf.Format.nSamplesPerSec = m->core->default_sample_spec.rate;
        }
        result = waveOutOpen(&hwo, output_device, &wf, (DWORD_PTR) chunk_done_cb, (DWORD_PTR) u, CALLBACK_FUNCTION);
        if (result != MMSYSERR_NOERROR) {
            char errortext[MAXERRORLENGTH];
            pa_log("Failed to open WaveOut.");
            if (waveOutGetErrorText(result, errortext, sizeof(errortext)) == MMSYSERR_NOERROR)
                pa_log("Error: %s", errortext);
            goto fail;
        }
    }

    InitializeCriticalSection(&u->crit);

    if (hwi != INVALID_HANDLE_VALUE) {
        pa_source_new_data data;
        pa_source_new_data_init(&data);
        data.driver = __FILE__;
        data.module = m;
        pa_source_new_data_set_sample_spec(&data, &ss);
        pa_source_new_data_set_channel_map(&data, &map);
        pa_source_new_data_set_name(&data, pa_modargs_get_value(ma, "source_name", DEFAULT_SOURCE_NAME));
        pa_proplist_setf(data.proplist, PA_PROP_DEVICE_DESCRIPTION, "WaveIn on %s", input_device_name);
        u->source = pa_source_new(m->core, &data, PA_SOURCE_HARDWARE|PA_SOURCE_LATENCY);
        pa_source_new_data_done(&data);

        pa_assert(u->source);
        u->source->userdata = u;
        u->source->parent.process_msg = process_msg;
    } else
        u->source = NULL;

    if (hwo != INVALID_HANDLE_VALUE) {
        pa_sink_new_data data;
        pa_sink_new_data_init(&data);
        data.driver = __FILE__;
        data.module = m;
        pa_sink_new_data_set_sample_spec(&data, &ss);
        pa_sink_new_data_set_channel_map(&data, &map);
        pa_sink_new_data_set_name(&data, pa_modargs_get_value(ma, "sink_name", DEFAULT_SINK_NAME));
        pa_proplist_setf(data.proplist, PA_PROP_DEVICE_DESCRIPTION, "WaveOut on %s", output_device_name);
        u->sink = pa_sink_new(m->core, &data, PA_SINK_HARDWARE|PA_SINK_LATENCY);
        pa_sink_new_data_done(&data);

        pa_assert(u->sink);
        pa_sink_set_get_volume_callback(u->sink, sink_get_volume_cb);
        pa_sink_set_set_volume_callback(u->sink, sink_set_volume_cb);
        u->sink->userdata = u;
        u->sink->parent.process_msg = process_msg;
    } else
        u->sink = NULL;

    pa_assert(u->source || u->sink);
    pa_modargs_free(ma);

    u->core = m->core;
    u->hwi = hwi;
    u->hwo = hwo;

    u->fragments = nfrags;
    u->free_ifrags = u->fragments;
    u->free_ofrags = u->fragments;
    u->fragment_size = frag_size - (frag_size % pa_frame_size(&ss));

    u->written_bytes = 0;
    u->sink_underflow = 1;

    u->poll_timeout = pa_bytes_to_usec(u->fragments * u->fragment_size / 10, &ss);
    pa_log_debug("Poll timeout = %.1f ms", (double) u->poll_timeout / PA_USEC_PER_MSEC);

    u->cur_ihdr = 0;
    u->cur_ohdr = 0;
    u->ihdrs = pa_xmalloc0(sizeof(WAVEHDR) * u->fragments);
    pa_assert(u->ihdrs);
    u->ohdrs = pa_xmalloc0(sizeof(WAVEHDR) * u->fragments);
    pa_assert(u->ohdrs);
    for (i = 0; i < u->fragments; i++) {
        u->ihdrs[i].dwBufferLength = u->fragment_size;
        u->ohdrs[i].dwBufferLength = u->fragment_size;
        u->ihdrs[i].lpData = pa_xmalloc(u->fragment_size);
        pa_assert(u->ihdrs);
        u->ohdrs[i].lpData = pa_xmalloc(u->fragment_size);
        pa_assert(u->ohdrs);
    }

    u->module = m;
    m->userdata = u;

    /* Read mixer settings */
    if (u->sink)
        sink_get_volume_cb(u->sink);

    u->rtpoll = pa_rtpoll_new();

    if (pa_thread_mq_init(&u->thread_mq, m->core->mainloop, u->rtpoll) < 0) {
        pa_log("pa_thread_mq_init() failed.");
        goto fail;
    }

    if (u->sink) {
        pa_sink_set_asyncmsgq(u->sink, u->thread_mq.inq);
        pa_sink_set_rtpoll(u->sink, u->rtpoll);
    }
    if (u->source) {
        pa_source_set_asyncmsgq(u->source, u->thread_mq.inq);
        pa_source_set_rtpoll(u->source, u->rtpoll);
    }

    if (!(u->thread = pa_thread_new("waveout", thread_func, u))) {
        pa_log("Failed to create thread.");
        goto fail;
    }

    if (u->sink)
        pa_sink_put(u->sink);
    if (u->source)
        pa_source_put(u->source);

    return 0;

fail:
    if (ma)
        pa_modargs_free(ma);

    pa__done(m);

    return -1;
}

void pa__done(pa_module *m) {
    struct userdata *u;
    unsigned int i;

    pa_assert(m);
    pa_assert(m->core);

    if (!(u = m->userdata))
        return;

    if (u->sink)
        pa_sink_unlink(u->sink);
    if (u->source)
        pa_source_unlink(u->source);

    pa_asyncmsgq_send(u->thread_mq.inq, NULL, PA_MESSAGE_SHUTDOWN, NULL, 0, NULL);
    if (u->thread)
        pa_thread_free(u->thread);
    pa_thread_mq_done(&u->thread_mq);

    if (u->sink)
        pa_sink_unref(u->sink);
    if (u->source)
        pa_source_unref(u->source);

    if (u->rtpoll)
        pa_rtpoll_free(u->rtpoll);

    if (u->hwi != INVALID_HANDLE_VALUE) {
        waveInReset(u->hwi);
        waveInClose(u->hwi);
    }

    if (u->hwo != INVALID_HANDLE_VALUE) {
        waveOutReset(u->hwo);
        waveOutClose(u->hwo);
    }

    for (i = 0; i < u->fragments; i++) {
        pa_xfree(u->ihdrs[i].lpData);
        pa_xfree(u->ohdrs[i].lpData);
    }

    pa_xfree(u->ihdrs);
    pa_xfree(u->ohdrs);

    DeleteCriticalSection(&u->crit);

    pa_xfree(u);
}
