/*  			DirectSound
 *
 * Copyright 1998 Marcus Meissner
 * Copyright 1998 Rob Riggs
 * Copyright 2000-2002 TransGaming Technologies, Inc.
 *
 * This library 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.
 *
 * This library 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
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
 *
 * TODO:
 *      When PrimarySetFormat (via ReopenDevice or PrimaryOpen) fails,
 *       it leaves dsound in unusable (not really open) state.
 */

#include <stdarg.h>

#define NONAMELESSSTRUCT
#define NONAMELESSUNION
#include "windef.h"
#include "winbase.h"
#include "winuser.h"
#include "mmsystem.h"
#include "winternl.h"
#include "mmddk.h"
#include "wine/debug.h"
#include "dsound.h"
#include "dsdriver.h"
#include "dsound_private.h"

WINE_DEFAULT_DEBUG_CHANNEL(dsound);

/** Calculate how long a fragment length of about 10 ms should be in frames
 *
 * nSamplesPerSec: Frequency rate in samples per second
 * nBlockAlign: Size of a single blockalign
 *
 * Returns:
 * Size in bytes of a single fragment
 */
DWORD DSOUND_fraglen(DWORD nSamplesPerSec, DWORD nBlockAlign)
{
    /* Given a timer delay of 10ms, the fragment size is approximately:
     *     fraglen = (nSamplesPerSec * 10 / 1000) * nBlockAlign
     * ==> fraglen = (nSamplesPerSec / 100) * nBlockSize
     *
     * ALSA uses buffers that are powers of 2. Because of this, fraglen
     * is rounded up to the nearest power of 2:
     */

    if (nSamplesPerSec <= 12800)
        return 128 * nBlockAlign;

    if (nSamplesPerSec <= 25600)
        return 256 * nBlockAlign;

    if (nSamplesPerSec <= 51200)
        return 512 * nBlockAlign;

    return 1024 * nBlockAlign;
}

static void DSOUND_RecalcPrimary(DirectSoundDevice *device)
{
    TRACE("(%p)\n", device);

    device->fraglen = DSOUND_fraglen(device->pwfx->nSamplesPerSec, device->pwfx->nBlockAlign);
    device->helfrags = device->buflen / device->fraglen;
    TRACE("fraglen=%d helfrags=%d\n", device->fraglen, device->helfrags);

    if (device->hwbuf && device->drvdesc.dwFlags & DSDDESC_DONTNEEDWRITELEAD)
        device->writelead = 0;
    else
        /* calculate the 10ms write lead */
        device->writelead = (device->pwfx->nSamplesPerSec / 100) * device->pwfx->nBlockAlign;
}

HRESULT DSOUND_ReopenDevice(DirectSoundDevice *device, BOOL forcewave)
{
	HRESULT hres = DS_OK;
	TRACE("(%p, %d)\n", device, forcewave);

	if (device->driver)
	{
		IDsDriver_Close(device->driver);
		if (device->drvdesc.dwFlags & DSDDESC_DOMMSYSTEMOPEN)
			waveOutClose(device->hwo);
		IDsDriver_Release(device->driver);
		device->driver = NULL;
		device->buffer = NULL;
		device->hwo = 0;
	}
	else if (device->drvdesc.dwFlags & DSDDESC_DOMMSYSTEMOPEN)
		waveOutClose(device->hwo);

	/* DRV_QUERYDSOUNDIFACE is a "Wine extension" to get the DSound interface */
	if (ds_hw_accel != DS_HW_ACCEL_EMULATION && !forcewave)
		waveOutMessage((HWAVEOUT)device->drvdesc.dnDevNode, DRV_QUERYDSOUNDIFACE, (DWORD_PTR)&device->driver, 0);

	/* Get driver description */
	if (device->driver) {
		DWORD wod = device->drvdesc.dnDevNode;
		hres = IDsDriver_GetDriverDesc(device->driver,&(device->drvdesc));
		device->drvdesc.dnDevNode = wod;
		if (FAILED(hres)) {
			WARN("IDsDriver_GetDriverDesc failed: %08x\n", hres);
			IDsDriver_Release(device->driver);
			device->driver = NULL;
		}
        }

        /* if no DirectSound interface available, use WINMM API instead */
	if (!device->driver)
		device->drvdesc.dwFlags = DSDDESC_DOMMSYSTEMOPEN | DSDDESC_DOMMSYSTEMSETFORMAT;

	if (device->drvdesc.dwFlags & DSDDESC_DOMMSYSTEMOPEN)
	{
		DWORD flags = CALLBACK_FUNCTION;

		if (device->driver)
			flags |= WAVE_DIRECTSOUND;

		hres = mmErr(waveOutOpen(&(device->hwo), device->drvdesc.dnDevNode, device->pwfx, (DWORD_PTR)DSOUND_callback, (DWORD_PTR)device, flags));
		if (FAILED(hres)) {
			WARN("waveOutOpen failed\n");
			if (device->driver)
			{
				IDsDriver_Release(device->driver);
				device->driver = NULL;
			}
			return hres;
		}
	}

	if (device->driver)
		hres = IDsDriver_Open(device->driver);

	return hres;
}

static HRESULT DSOUND_PrimaryOpen(DirectSoundDevice *device)
{
	DWORD buflen;
	HRESULT err = DS_OK;
	TRACE("(%p)\n", device);

	/* on original windows, the buffer it set to a fixed size, no matter what the settings are.
	   on windows this size is always fixed (tested on win-xp) */
	if (!device->buflen)
		device->buflen = ds_hel_buflen;
	buflen = device->buflen;
	buflen -= buflen % device->pwfx->nBlockAlign;
	device->buflen = buflen;

	if (device->driver)
	{
		err = IDsDriver_CreateSoundBuffer(device->driver,device->pwfx,
						  DSBCAPS_PRIMARYBUFFER,0,
						  &(device->buflen),&(device->buffer),
						  (LPVOID*)&(device->hwbuf));

		if (err != DS_OK) {
			WARN("IDsDriver_CreateSoundBuffer failed (%08x), falling back to waveout\n", err);
			err = DSOUND_ReopenDevice(device, TRUE);
			if (FAILED(err))
			{
				WARN("Falling back to waveout failed too! Giving up\n");
				return err;
			}
		}
                if (device->hwbuf)
                    IDsDriverBuffer_SetVolumePan(device->hwbuf, &device->volpan);

                DSOUND_RecalcPrimary(device);
		device->prebuf = ds_snd_queue_max;
		if (device->helfrags < ds_snd_queue_min)
		{
			WARN("Too little sound buffer to be effective (%d/%d) falling back to waveout\n", device->buflen, ds_snd_queue_min * device->fraglen);
			device->buflen = buflen;
			IDsDriverBuffer_Release(device->hwbuf);
			device->hwbuf = NULL;
			err = DSOUND_ReopenDevice(device, TRUE);
			if (FAILED(err))
			{
				WARN("Falling back to waveout failed too! Giving up\n");
				return err;
			}
		}
		else if (device->helfrags < ds_snd_queue_max)
			device->prebuf = device->helfrags;
	}

	device->mix_buffer_len = DSOUND_bufpos_to_mixpos(device, device->buflen);
	device->mix_buffer = HeapAlloc(GetProcessHeap(), 0, device->mix_buffer_len);
	if (!device->mix_buffer)
	{
		if (device->hwbuf)
			IDsDriverBuffer_Release(device->hwbuf);
		device->hwbuf = NULL;
		return DSERR_OUTOFMEMORY;
	}

	if (device->state == STATE_PLAYING) device->state = STATE_STARTING;
	else if (device->state == STATE_STOPPING) device->state = STATE_STOPPED;

	/* are we using waveOut stuff? */
	if (!device->driver) {
		LPBYTE newbuf;
		LPWAVEHDR headers = NULL;
		DWORD overshot;
		unsigned int c;

		/* Start in pause mode, to allow buffers to get filled */
		waveOutPause(device->hwo);

		TRACE("desired buflen=%d, old buffer=%p\n", buflen, device->buffer);

		/* reallocate emulated primary buffer */
		if (device->buffer)
			newbuf = HeapReAlloc(GetProcessHeap(),0,device->buffer, buflen);
		else
			newbuf = HeapAlloc(GetProcessHeap(),0, buflen);

		if (!newbuf) {
			ERR("failed to allocate primary buffer\n");
			return DSERR_OUTOFMEMORY;
			/* but the old buffer might still exist and must be re-prepared */
		}

		DSOUND_RecalcPrimary(device);
		if (device->pwave)
			headers = HeapReAlloc(GetProcessHeap(),0,device->pwave, device->helfrags * sizeof(WAVEHDR));
		else
			headers = HeapAlloc(GetProcessHeap(),0,device->helfrags * sizeof(WAVEHDR));

		if (!headers) {
			ERR("failed to allocate wave headers\n");
			HeapFree(GetProcessHeap(), 0, newbuf);
			DSOUND_RecalcPrimary(device);
			return DSERR_OUTOFMEMORY;
		}

		device->buffer = newbuf;
		device->pwave = headers;

		/* prepare fragment headers */
		for (c=0; c<device->helfrags; c++) {
			device->pwave[c].lpData = (char*)device->buffer + c*device->fraglen;
			device->pwave[c].dwBufferLength = device->fraglen;
			device->pwave[c].dwUser = (DWORD_PTR)device;
			device->pwave[c].dwFlags = 0;
			device->pwave[c].dwLoops = 0;
			err = mmErr(waveOutPrepareHeader(device->hwo,&device->pwave[c],sizeof(WAVEHDR)));
			if (err != DS_OK) {
				while (c--)
					waveOutUnprepareHeader(device->hwo,&device->pwave[c],sizeof(WAVEHDR));
				break;
			}
		}

		overshot = device->buflen % device->fraglen;
		/* sanity */
		if(overshot)
		{
			overshot -= overshot % device->pwfx->nBlockAlign;
			device->pwave[device->helfrags - 1].dwBufferLength += overshot;
		}

		TRACE("fraglen=%d, overshot=%d\n", device->fraglen, overshot);
	}
	device->mixfunction = mixfunctions[device->pwfx->wBitsPerSample/8 - 1];
	device->normfunction = normfunctions[device->pwfx->wBitsPerSample/8 - 1];
	FillMemory(device->buffer, device->buflen, (device->pwfx->wBitsPerSample == 8) ? 128 : 0);
	FillMemory(device->mix_buffer, device->mix_buffer_len, 0);
	device->pwplay = device->pwqueue = device->playpos = device->mixpos = 0;
	return err;
}


static void DSOUND_PrimaryClose(DirectSoundDevice *device)
{
	TRACE("(%p)\n", device);

	/* are we using waveOut stuff? */
	if (!device->hwbuf) {
		unsigned c;

		/* get out of CS when calling the wave system */
		LeaveCriticalSection(&(device->mixlock));
		/* **** */
		device->pwqueue = (DWORD)-1; /* resetting queues */
		waveOutReset(device->hwo);
		for (c=0; c<device->helfrags; c++)
			waveOutUnprepareHeader(device->hwo, &device->pwave[c], sizeof(WAVEHDR));
		/* **** */
		EnterCriticalSection(&(device->mixlock));

		/* clear the queue */
		device->pwqueue = 0;
	} else {
		ULONG ref = IDsDriverBuffer_Release(device->hwbuf);
		if (!ref)
			device->hwbuf = 0;
		else
			ERR("Still %d references on primary buffer, refcount leak?\n", ref);
	}
}

HRESULT DSOUND_PrimaryCreate(DirectSoundDevice *device)
{
	HRESULT err = DS_OK;
	TRACE("(%p)\n", device);

	device->buflen = ds_hel_buflen;
	err = DSOUND_PrimaryOpen(device);

	if (err != DS_OK) {
		WARN("DSOUND_PrimaryOpen failed\n");
		return err;
	}

	device->state = STATE_STOPPED;
	return DS_OK;
}

HRESULT DSOUND_PrimaryDestroy(DirectSoundDevice *device)
{
	TRACE("(%p)\n", device);

	/* **** */
	EnterCriticalSection(&(device->mixlock));

	DSOUND_PrimaryClose(device);
	if (device->driver) {
		if (device->hwbuf) {
			if (IDsDriverBuffer_Release(device->hwbuf) == 0)
				device->hwbuf = 0;
		}
	} else
                HeapFree(GetProcessHeap(),0,device->pwave);
        HeapFree(GetProcessHeap(),0,device->pwfx);
        device->pwfx=NULL;

	LeaveCriticalSection(&(device->mixlock));
	/* **** */

	return DS_OK;
}

HRESULT DSOUND_PrimaryPlay(DirectSoundDevice *device)
{
	HRESULT err = DS_OK;
	TRACE("(%p)\n", device);

	if (device->hwbuf) {
		err = IDsDriverBuffer_Play(device->hwbuf, 0, 0, DSBPLAY_LOOPING);
		if (err != DS_OK)
			WARN("IDsDriverBuffer_Play failed\n");
	} else {
		err = mmErr(waveOutRestart(device->hwo));
		if (err != DS_OK)
			WARN("waveOutRestart failed\n");
	}

	return err;
}

HRESULT DSOUND_PrimaryStop(DirectSoundDevice *device)
{
	HRESULT err = DS_OK;
	TRACE("(%p)\n", device);

	if (device->hwbuf) {
		err = IDsDriverBuffer_Stop(device->hwbuf);
		if (err == DSERR_BUFFERLOST) {
			DSOUND_PrimaryClose(device);
			err = DSOUND_ReopenDevice(device, FALSE);
			if (FAILED(err))
				ERR("DSOUND_ReopenDevice failed\n");
			else
			{
				err = DSOUND_PrimaryOpen(device);
				if (FAILED(err))
					WARN("DSOUND_PrimaryOpen failed\n");
			}
		} else if (err != DS_OK) {
			WARN("IDsDriverBuffer_Stop failed\n");
		}
	} else {

		/* don't call the wave system with the lock set */
		LeaveCriticalSection(&(device->mixlock));
		/* **** */

		err = mmErr(waveOutPause(device->hwo));

		/* **** */
		EnterCriticalSection(&(device->mixlock));

		if (err != DS_OK)
			WARN("waveOutPause failed\n");
	}

	return err;
}

HRESULT DSOUND_PrimaryGetPosition(DirectSoundDevice *device, LPDWORD playpos, LPDWORD writepos)
{
	TRACE("(%p,%p,%p)\n", device, playpos, writepos);

	if (device->hwbuf) {
		HRESULT err=IDsDriverBuffer_GetPosition(device->hwbuf,playpos,writepos);
		if (err != S_OK) {
			WARN("IDsDriverBuffer_GetPosition failed\n");
			return err;
		}
	} else {
		TRACE("pwplay=%i, pwqueue=%i\n", device->pwplay, device->pwqueue);

		/* check if playpos was requested */
		if (playpos)
			/* use the cached play position */
			*playpos = device->pwplay * device->fraglen;

		/* check if writepos was requested */
		if (writepos)
			/* the writepos is the first non-queued position */
			*writepos = ((device->pwplay + device->pwqueue) % device->helfrags) * device->fraglen;
	}
	TRACE("playpos = %d, writepos = %d (%p, time=%d)\n", playpos?*playpos:-1, writepos?*writepos:-1, device, GetTickCount());
	return DS_OK;
}

LPWAVEFORMATEX DSOUND_CopyFormat(LPCWAVEFORMATEX wfex)
{
	DWORD size = wfex->wFormatTag == WAVE_FORMAT_PCM ?
		sizeof(WAVEFORMATEX) : sizeof(WAVEFORMATEX) + wfex->cbSize;
	LPWAVEFORMATEX pwfx = HeapAlloc(GetProcessHeap(),0,size);
	if (pwfx == NULL) {
		WARN("out of memory\n");
	} else if (wfex->wFormatTag != WAVE_FORMAT_PCM) {
		CopyMemory(pwfx, wfex, size);
	} else {
		CopyMemory(pwfx, wfex, sizeof(PCMWAVEFORMAT));
		pwfx->cbSize=0;
		if (pwfx->nBlockAlign != pwfx->nChannels * pwfx->wBitsPerSample/8) {
			WARN("Fixing bad nBlockAlign (%u)\n", pwfx->nBlockAlign);
			pwfx->nBlockAlign  = pwfx->nChannels * pwfx->wBitsPerSample/8;
		}
		if (pwfx->nAvgBytesPerSec != pwfx->nSamplesPerSec * pwfx->nBlockAlign) {
			WARN("Fixing bad nAvgBytesPerSec (%u)\n", pwfx->nAvgBytesPerSec);
			pwfx->nAvgBytesPerSec  = pwfx->nSamplesPerSec * pwfx->nBlockAlign;
		}
	}
	return pwfx;
}

static HRESULT DSOUND_PrimarySetFormat(DirectSoundDevice *device, LPCWAVEFORMATEX wfex, BOOL forced)
{
	HRESULT err = DSERR_BUFFERLOST;
	int i;
	DWORD nSamplesPerSec, bpp, chans;
	LPWAVEFORMATEX oldpwfx;
	TRACE("(%p,%p)\n", device, wfex);

	if (device->priolevel == DSSCL_NORMAL) {
		WARN("failed priority check!\n");
		return DSERR_PRIOLEVELNEEDED;
	}

	/* Let's be pedantic! */
	if (wfex == NULL) {
		WARN("invalid parameter: wfex==NULL!\n");
		return DSERR_INVALIDPARAM;
	}
	TRACE("(formattag=0x%04x,chans=%d,samplerate=%d,"
              "bytespersec=%d,blockalign=%d,bitspersamp=%d,cbSize=%d)\n",
	      wfex->wFormatTag, wfex->nChannels, wfex->nSamplesPerSec,
	      wfex->nAvgBytesPerSec, wfex->nBlockAlign,
	      wfex->wBitsPerSample, wfex->cbSize);

	/* **** */
	RtlAcquireResourceExclusive(&(device->buffer_list_lock), TRUE);
	EnterCriticalSection(&(device->mixlock));

	nSamplesPerSec = device->pwfx->nSamplesPerSec;
	bpp = device->pwfx->wBitsPerSample;
	chans = device->pwfx->nChannels;

	oldpwfx = device->pwfx;
	device->pwfx = DSOUND_CopyFormat(wfex);
	if (device->pwfx == NULL) {
		device->pwfx = oldpwfx;
		err = DSERR_OUTOFMEMORY;
		goto done;
	}
	/* TODO: on failure below (bad format?), reinstall oldpwfx */
	HeapFree(GetProcessHeap(), 0, oldpwfx);

	if (!(device->drvdesc.dwFlags & DSDDESC_DOMMSYSTEMSETFORMAT) && device->hwbuf) {
		err = IDsDriverBuffer_SetFormat(device->hwbuf, device->pwfx);

		/* On bad format, try to re-create, big chance it will work then, only do this if we <HAVE> to */
		if (forced && (device->pwfx->nSamplesPerSec/100 != wfex->nSamplesPerSec/100 || err == DSERR_BADFORMAT))
		{
			DWORD cp_size = wfex->wFormatTag == WAVE_FORMAT_PCM ?
				sizeof(PCMWAVEFORMAT) : sizeof(WAVEFORMATEX) + wfex->cbSize;
			err = DSERR_BUFFERLOST;
			CopyMemory(device->pwfx, wfex, cp_size);
		}

		if (err != DSERR_BUFFERLOST && FAILED(err)) {
			WARN("IDsDriverBuffer_SetFormat failed\n");
			if (!forced)
				err = DS_OK;
			goto done;
		}

		if (err == S_FALSE)
		{
			/* ALSA specific: S_FALSE tells that recreation was successful,
			 * but size and location may be changed, and buffer has to be restarted
			 * I put it here, so if frequency doesn't match the error will be changed to DSERR_BUFFERLOST
			 * and the entire re-initialization will occur anyway
			 */
			IDsDriverBuffer_Lock(device->hwbuf, (LPVOID *)&device->buffer, &device->buflen, NULL, NULL, 0, 0, DSBLOCK_ENTIREBUFFER);
			IDsDriverBuffer_Unlock(device->hwbuf, device->buffer, 0, NULL, 0);

			if (device->state == STATE_PLAYING) device->state = STATE_STARTING;
			else if (device->state == STATE_STOPPING) device->state = STATE_STOPPED;
			device->pwplay = device->pwqueue = device->playpos = device->mixpos = 0;
			err = DS_OK;
		}
		DSOUND_RecalcPrimary(device);
	}

	if (err == DSERR_BUFFERLOST)
	{
		DSOUND_PrimaryClose(device);

		err = DSOUND_ReopenDevice(device, FALSE);
		if (FAILED(err))
		{
			WARN("DSOUND_ReopenDevice failed: %08x\n", err);
			goto done;
		}
		err = DSOUND_PrimaryOpen(device);
		if (err != DS_OK) {
			WARN("DSOUND_PrimaryOpen failed\n");
			goto done;
		}

		if (wfex->nSamplesPerSec/100 != device->pwfx->nSamplesPerSec/100 && forced && device->buffer)
		{
			DSOUND_PrimaryClose(device);
			device->pwfx->nSamplesPerSec = wfex->nSamplesPerSec;
			err = DSOUND_ReopenDevice(device, TRUE);
			if (FAILED(err))
				WARN("DSOUND_ReopenDevice(2) failed: %08x\n", err);
			else if (FAILED((err = DSOUND_PrimaryOpen(device))))
				WARN("DSOUND_PrimaryOpen(2) failed: %08x\n", err);
		}
	}

	device->mix_buffer_len = DSOUND_bufpos_to_mixpos(device, device->buflen);
	device->mix_buffer = HeapReAlloc(GetProcessHeap(), 0, device->mix_buffer, device->mix_buffer_len);
	FillMemory(device->mix_buffer, device->mix_buffer_len, 0);
	device->mixfunction = mixfunctions[device->pwfx->wBitsPerSample/8 - 1];
	device->normfunction = normfunctions[device->pwfx->wBitsPerSample/8 - 1];

	if (nSamplesPerSec != device->pwfx->nSamplesPerSec || bpp != device->pwfx->wBitsPerSample || chans != device->pwfx->nChannels) {
		IDirectSoundBufferImpl** dsb = device->buffers;
		for (i = 0; i < device->nrofbuffers; i++, dsb++) {
			/* **** */
			RtlAcquireResourceExclusive(&(*dsb)->lock, TRUE);

			(*dsb)->freqAdjust = ((DWORD64)(*dsb)->freq << DSOUND_FREQSHIFT) / device->pwfx->nSamplesPerSec;
			DSOUND_RecalcFormat((*dsb));
			DSOUND_MixToTemporary((*dsb), 0, (*dsb)->buflen, FALSE);
			(*dsb)->primary_mixpos = 0;

			RtlReleaseResource(&(*dsb)->lock);
			/* **** */
		}
	}

done:
	LeaveCriticalSection(&(device->mixlock));
	RtlReleaseResource(&(device->buffer_list_lock));
	/* **** */

	return err;
}

/*******************************************************************************
 *		PrimaryBuffer
 */
/* This sets this format for the <em>Primary Buffer Only</em> */
/* See file:///cdrom/sdk52/docs/worddoc/dsound.doc page 120 */
static HRESULT WINAPI PrimaryBufferImpl_SetFormat(
    LPDIRECTSOUNDBUFFER iface,
    LPCWAVEFORMATEX wfex)
{
    DirectSoundDevice *device = ((PrimaryBufferImpl *)iface)->device;
    TRACE("(%p,%p)\n", iface, wfex);
    return DSOUND_PrimarySetFormat(device, wfex, device->priolevel == DSSCL_WRITEPRIMARY);
}

static HRESULT WINAPI PrimaryBufferImpl_SetVolume(
	LPDIRECTSOUNDBUFFER iface,LONG vol
) {
	DirectSoundDevice *device = ((PrimaryBufferImpl *)iface)->device;
	DWORD ampfactors;
        HRESULT hres = DS_OK;
	TRACE("(%p,%d)\n", iface, vol);

	if (!(device->dsbd.dwFlags & DSBCAPS_CTRLVOLUME)) {
		WARN("control unavailable\n");
		return DSERR_CONTROLUNAVAIL;
	}

	if ((vol > DSBVOLUME_MAX) || (vol < DSBVOLUME_MIN)) {
		WARN("invalid parameter: vol = %d\n", vol);
		return DSERR_INVALIDPARAM;
	}

	/* **** */
	EnterCriticalSection(&(device->mixlock));

        waveOutGetVolume(device->hwo, &ampfactors);
        device->volpan.dwTotalLeftAmpFactor=ampfactors & 0xffff;
        device->volpan.dwTotalRightAmpFactor=ampfactors >> 16;
        DSOUND_AmpFactorToVolPan(&device->volpan);
        if (vol != device->volpan.lVolume) {
            device->volpan.lVolume=vol;
            DSOUND_RecalcVolPan(&device->volpan);
            if (device->hwbuf) {
                hres = IDsDriverBuffer_SetVolumePan(device->hwbuf, &device->volpan);
                if (hres != DS_OK)
                    WARN("IDsDriverBuffer_SetVolumePan failed\n");
            } else {
                ampfactors = (device->volpan.dwTotalLeftAmpFactor & 0xffff) | (device->volpan.dwTotalRightAmpFactor << 16);
                waveOutSetVolume(device->hwo, ampfactors);
            }
        }

	LeaveCriticalSection(&(device->mixlock));
	/* **** */

	return hres;
}

static HRESULT WINAPI PrimaryBufferImpl_GetVolume(
	LPDIRECTSOUNDBUFFER iface,LPLONG vol
) {
	DirectSoundDevice *device = ((PrimaryBufferImpl *)iface)->device;
	DWORD ampfactors;
	TRACE("(%p,%p)\n", iface, vol);

	if (!(device->dsbd.dwFlags & DSBCAPS_CTRLVOLUME)) {
		WARN("control unavailable\n");
		return DSERR_CONTROLUNAVAIL;
	}

	if (vol == NULL) {
		WARN("invalid parameter: vol = NULL\n");
		return DSERR_INVALIDPARAM;
	}

        if (!device->hwbuf)
        {
	    waveOutGetVolume(device->hwo, &ampfactors);
	    device->volpan.dwTotalLeftAmpFactor=ampfactors & 0xffff;
	    device->volpan.dwTotalRightAmpFactor=ampfactors >> 16;
	    DSOUND_AmpFactorToVolPan(&device->volpan);
        }
        *vol = device->volpan.lVolume;
	return DS_OK;
}

static HRESULT WINAPI PrimaryBufferImpl_SetFrequency(
	LPDIRECTSOUNDBUFFER iface,DWORD freq
) {
	PrimaryBufferImpl *This = (PrimaryBufferImpl *)iface;
	TRACE("(%p,%d)\n",This,freq);

	/* You cannot set the frequency of the primary buffer */
	WARN("control unavailable\n");
	return DSERR_CONTROLUNAVAIL;
}

static HRESULT WINAPI PrimaryBufferImpl_Play(
	LPDIRECTSOUNDBUFFER iface,DWORD reserved1,DWORD reserved2,DWORD flags
) {
	DirectSoundDevice *device = ((PrimaryBufferImpl *)iface)->device;
	TRACE("(%p,%08x,%08x,%08x)\n", iface, reserved1, reserved2, flags);

	if (!(flags & DSBPLAY_LOOPING)) {
		WARN("invalid parameter: flags = %08x\n", flags);
		return DSERR_INVALIDPARAM;
	}

	/* **** */
	EnterCriticalSection(&(device->mixlock));

	if (device->state == STATE_STOPPED)
		device->state = STATE_STARTING;
	else if (device->state == STATE_STOPPING)
		device->state = STATE_PLAYING;

	LeaveCriticalSection(&(device->mixlock));
	/* **** */

	return DS_OK;
}

static HRESULT WINAPI PrimaryBufferImpl_Stop(LPDIRECTSOUNDBUFFER iface)
{
	DirectSoundDevice *device = ((PrimaryBufferImpl *)iface)->device;
	TRACE("(%p)\n", iface);

	/* **** */
	EnterCriticalSection(&(device->mixlock));

	if (device->state == STATE_PLAYING)
		device->state = STATE_STOPPING;
	else if (device->state == STATE_STARTING)
		device->state = STATE_STOPPED;

	LeaveCriticalSection(&(device->mixlock));
	/* **** */

	return DS_OK;
}

static ULONG WINAPI PrimaryBufferImpl_AddRef(LPDIRECTSOUNDBUFFER iface)
{
    PrimaryBufferImpl *This = (PrimaryBufferImpl *)iface;
    ULONG ref = InterlockedIncrement(&(This->ref));
    TRACE("(%p) ref was %d\n", This, ref - 1);
    return ref;
}

static ULONG WINAPI PrimaryBufferImpl_Release(LPDIRECTSOUNDBUFFER iface)
{
    PrimaryBufferImpl *This = (PrimaryBufferImpl *)iface;
    DWORD ref = InterlockedDecrement(&(This->ref));
    TRACE("(%p) ref was %d\n", This, ref + 1);

    if (!ref) {
        This->device->primary = NULL;
        HeapFree(GetProcessHeap(), 0, This);
        TRACE("(%p) released\n", This);
    }
    return ref;
}

static HRESULT WINAPI PrimaryBufferImpl_GetCurrentPosition(
	LPDIRECTSOUNDBUFFER iface,LPDWORD playpos,LPDWORD writepos
) {
	HRESULT	hres;
        DirectSoundDevice *device = ((PrimaryBufferImpl *)iface)->device;
	TRACE("(%p,%p,%p)\n", iface, playpos, writepos);

	/* **** */
	EnterCriticalSection(&(device->mixlock));

	hres = DSOUND_PrimaryGetPosition(device, playpos, writepos);
	if (hres != DS_OK) {
		WARN("DSOUND_PrimaryGetPosition failed\n");
		LeaveCriticalSection(&(device->mixlock));
		return hres;
	}
	if (writepos) {
		if (device->state != STATE_STOPPED)
			/* apply the documented 10ms lead to writepos */
			*writepos += device->writelead;
		while (*writepos >= device->buflen) *writepos -= device->buflen;
	}

	LeaveCriticalSection(&(device->mixlock));
	/* **** */

	TRACE("playpos = %d, writepos = %d (%p, time=%d)\n", playpos?*playpos:0, writepos?*writepos:0, device, GetTickCount());
	return DS_OK;
}

static HRESULT WINAPI PrimaryBufferImpl_GetStatus(
	LPDIRECTSOUNDBUFFER iface,LPDWORD status
) {
        DirectSoundDevice *device = ((PrimaryBufferImpl *)iface)->device;
	TRACE("(%p,%p)\n", iface, status);

	if (status == NULL) {
		WARN("invalid parameter: status == NULL\n");
		return DSERR_INVALIDPARAM;
	}

	*status = 0;
	if ((device->state == STATE_STARTING) ||
	    (device->state == STATE_PLAYING))
		*status |= DSBSTATUS_PLAYING | DSBSTATUS_LOOPING;

	TRACE("status=%x\n", *status);
	return DS_OK;
}


static HRESULT WINAPI PrimaryBufferImpl_GetFormat(
    LPDIRECTSOUNDBUFFER iface,
    LPWAVEFORMATEX lpwf,
    DWORD wfsize,
    LPDWORD wfwritten)
{
    DWORD size;
    DirectSoundDevice *device = ((PrimaryBufferImpl *)iface)->device;
    TRACE("(%p,%p,%d,%p)\n", iface, lpwf, wfsize, wfwritten);

    size = sizeof(WAVEFORMATEX) + device->pwfx->cbSize;

    if (lpwf) {	/* NULL is valid */
        if (wfsize >= size) {
            CopyMemory(lpwf,device->pwfx,size);
            if (wfwritten)
                *wfwritten = size;
        } else {
            WARN("invalid parameter: wfsize too small\n");
            if (wfwritten)
                *wfwritten = 0;
            return DSERR_INVALIDPARAM;
        }
    } else {
        if (wfwritten)
            *wfwritten = sizeof(WAVEFORMATEX) + device->pwfx->cbSize;
        else {
            WARN("invalid parameter: wfwritten == NULL\n");
            return DSERR_INVALIDPARAM;
        }
    }

    return DS_OK;
}

static HRESULT WINAPI PrimaryBufferImpl_Lock(
	LPDIRECTSOUNDBUFFER iface,DWORD writecursor,DWORD writebytes,LPVOID *lplpaudioptr1,LPDWORD audiobytes1,LPVOID *lplpaudioptr2,LPDWORD audiobytes2,DWORD flags
) {
	HRESULT hres;
        DirectSoundDevice *device = ((PrimaryBufferImpl *)iface)->device;
	TRACE("(%p,%d,%d,%p,%p,%p,%p,0x%08x) at %d\n",
		iface,
		writecursor,
		writebytes,
		lplpaudioptr1,
		audiobytes1,
		lplpaudioptr2,
		audiobytes2,
		flags,
		GetTickCount()
	);

        if (!audiobytes1)
            return DSERR_INVALIDPARAM;

	if (device->priolevel != DSSCL_WRITEPRIMARY) {
		WARN("failed priority check!\n");
		return DSERR_PRIOLEVELNEEDED;
	}

        /* when this flag is set, writecursor is meaningless and must be calculated */
	if (flags & DSBLOCK_FROMWRITECURSOR) {
		/* GetCurrentPosition does too much magic to duplicate here */
		hres = IDirectSoundBuffer_GetCurrentPosition(iface, NULL, &writecursor);
		if (hres != DS_OK) {
			WARN("IDirectSoundBuffer_GetCurrentPosition failed\n");
			return hres;
		}
	}

        /* when this flag is set, writebytes is meaningless and must be set */
	if (flags & DSBLOCK_ENTIREBUFFER)
		writebytes = device->buflen;

        if (writecursor >= device->buflen) {
                WARN("Invalid parameter, writecursor: %u >= buflen: %u\n",
		     writecursor, device->buflen);
                return DSERR_INVALIDPARAM;
        }

        if (writebytes > device->buflen) {
                WARN("Invalid parameter, writebytes: %u > buflen: %u\n",
		     writebytes, device->buflen);
                return DSERR_INVALIDPARAM;
        }

	if (!(device->drvdesc.dwFlags & DSDDESC_DONTNEEDPRIMARYLOCK) && device->hwbuf) {
		hres = IDsDriverBuffer_Lock(device->hwbuf,
					    lplpaudioptr1, audiobytes1,
					    lplpaudioptr2, audiobytes2,
					    writecursor, writebytes,
					    0);
		if (hres != DS_OK) {
			WARN("IDsDriverBuffer_Lock failed\n");
			return hres;
		}
	} else {
		if (writecursor+writebytes <= device->buflen) {
			*(LPBYTE*)lplpaudioptr1 = device->buffer+writecursor;
			*audiobytes1 = writebytes;
			if (lplpaudioptr2)
				*(LPBYTE*)lplpaudioptr2 = NULL;
			if (audiobytes2)
				*audiobytes2 = 0;
			TRACE("->%d.0\n",writebytes);
		} else {
			*(LPBYTE*)lplpaudioptr1 = device->buffer+writecursor;
			*audiobytes1 = device->buflen-writecursor;
			if (lplpaudioptr2)
				*(LPBYTE*)lplpaudioptr2 = device->buffer;
			if (audiobytes2)
				*audiobytes2 = writebytes-(device->buflen-writecursor);
			TRACE("->%d.%d\n",*audiobytes1,audiobytes2?*audiobytes2:0);
		}
	}
	return DS_OK;
}

static HRESULT WINAPI PrimaryBufferImpl_SetCurrentPosition(
	LPDIRECTSOUNDBUFFER iface,DWORD newpos
) {
	PrimaryBufferImpl *This = (PrimaryBufferImpl *)iface;
	TRACE("(%p,%d)\n",This,newpos);

	/* You cannot set the position of the primary buffer */
	WARN("invalid call\n");
	return DSERR_INVALIDCALL;
}

static HRESULT WINAPI PrimaryBufferImpl_SetPan(
	LPDIRECTSOUNDBUFFER iface,LONG pan
) {
        DirectSoundDevice *device = ((PrimaryBufferImpl *)iface)->device;
	DWORD ampfactors;
        HRESULT hres = DS_OK;
	TRACE("(%p,%d)\n", iface, pan);

	if (!(device->dsbd.dwFlags & DSBCAPS_CTRLPAN)) {
		WARN("control unavailable\n");
		return DSERR_CONTROLUNAVAIL;
	}

	if ((pan > DSBPAN_RIGHT) || (pan < DSBPAN_LEFT)) {
		WARN("invalid parameter: pan = %d\n", pan);
		return DSERR_INVALIDPARAM;
	}

	/* **** */
	EnterCriticalSection(&(device->mixlock));

        if (!device->hwbuf)
        {
            waveOutGetVolume(device->hwo, &ampfactors);
            device->volpan.dwTotalLeftAmpFactor=ampfactors & 0xffff;
            device->volpan.dwTotalRightAmpFactor=ampfactors >> 16;
            DSOUND_AmpFactorToVolPan(&device->volpan);
        }
        if (pan != device->volpan.lPan) {
            device->volpan.lPan=pan;
            DSOUND_RecalcVolPan(&device->volpan);
            if (device->hwbuf) {
                hres = IDsDriverBuffer_SetVolumePan(device->hwbuf, &device->volpan);
                if (hres != DS_OK)
                    WARN("IDsDriverBuffer_SetVolumePan failed\n");
            } else {
                ampfactors = (device->volpan.dwTotalLeftAmpFactor & 0xffff) | (device->volpan.dwTotalRightAmpFactor << 16);
                waveOutSetVolume(device->hwo, ampfactors);
            }
        }

	LeaveCriticalSection(&(device->mixlock));
	/* **** */

	return hres;
}

static HRESULT WINAPI PrimaryBufferImpl_GetPan(
	LPDIRECTSOUNDBUFFER iface,LPLONG pan
) {
        DirectSoundDevice *device = ((PrimaryBufferImpl *)iface)->device;
	DWORD ampfactors;
	TRACE("(%p,%p)\n", iface, pan);

	if (!(device->dsbd.dwFlags & DSBCAPS_CTRLPAN)) {
		WARN("control unavailable\n");
		return DSERR_CONTROLUNAVAIL;
	}

	if (pan == NULL) {
		WARN("invalid parameter: pan == NULL\n");
		return DSERR_INVALIDPARAM;
	}

        if (!device->hwbuf)
        {
	    waveOutGetVolume(device->hwo, &ampfactors);
	    device->volpan.dwTotalLeftAmpFactor=ampfactors & 0xffff;
	    device->volpan.dwTotalRightAmpFactor=ampfactors >> 16;
	    DSOUND_AmpFactorToVolPan(&device->volpan);
        }
	*pan = device->volpan.lPan;
	return DS_OK;
}

static HRESULT WINAPI PrimaryBufferImpl_Unlock(
	LPDIRECTSOUNDBUFFER iface,LPVOID p1,DWORD x1,LPVOID p2,DWORD x2
) {
        DirectSoundDevice *device = ((PrimaryBufferImpl *)iface)->device;
	TRACE("(%p,%p,%d,%p,%d)\n", iface, p1, x1, p2, x2);

	if (device->priolevel != DSSCL_WRITEPRIMARY) {
		WARN("failed priority check!\n");
		return DSERR_PRIOLEVELNEEDED;
	}

	if (!(device->drvdesc.dwFlags & DSDDESC_DONTNEEDPRIMARYLOCK) && device->hwbuf) {
		HRESULT	hres;

		if ((char *)p1 - (char *)device->buffer + x1 > device->buflen)
		    hres = DSERR_INVALIDPARAM;
		else
		    hres = IDsDriverBuffer_Unlock(device->hwbuf, p1, x1, p2, x2);

		if (hres != DS_OK) {
			WARN("IDsDriverBuffer_Unlock failed\n");
			return hres;
		}
	}

	return DS_OK;
}

static HRESULT WINAPI PrimaryBufferImpl_Restore(
	LPDIRECTSOUNDBUFFER iface
) {
	PrimaryBufferImpl *This = (PrimaryBufferImpl *)iface;
	FIXME("(%p):stub\n",This);
	return DS_OK;
}

static HRESULT WINAPI PrimaryBufferImpl_GetFrequency(
	LPDIRECTSOUNDBUFFER iface,LPDWORD freq
) {
        DirectSoundDevice *device = ((PrimaryBufferImpl *)iface)->device;
	TRACE("(%p,%p)\n", iface, freq);

	if (freq == NULL) {
		WARN("invalid parameter: freq == NULL\n");
		return DSERR_INVALIDPARAM;
	}

	if (!(device->dsbd.dwFlags & DSBCAPS_CTRLFREQUENCY)) {
		WARN("control unavailable\n");
		return DSERR_CONTROLUNAVAIL;
	}

	*freq = device->pwfx->nSamplesPerSec;
	TRACE("-> %d\n", *freq);

	return DS_OK;
}

static HRESULT WINAPI PrimaryBufferImpl_Initialize(
	LPDIRECTSOUNDBUFFER iface,LPDIRECTSOUND dsound,LPCDSBUFFERDESC dbsd
) {
	PrimaryBufferImpl *This = (PrimaryBufferImpl *)iface;
	WARN("(%p) already initialized\n", This);
	return DSERR_ALREADYINITIALIZED;
}

static HRESULT WINAPI PrimaryBufferImpl_GetCaps(
	LPDIRECTSOUNDBUFFER iface,LPDSBCAPS caps
) {
        DirectSoundDevice *device = ((PrimaryBufferImpl *)iface)->device;
  	TRACE("(%p,%p)\n", iface, caps);

	if (caps == NULL) {
		WARN("invalid parameter: caps == NULL\n");
		return DSERR_INVALIDPARAM;
	}

	if (caps->dwSize < sizeof(*caps)) {
		WARN("invalid parameter: caps->dwSize = %d\n", caps->dwSize);
		return DSERR_INVALIDPARAM;
	}

	caps->dwFlags = device->dsbd.dwFlags;
	caps->dwBufferBytes = device->buflen;

	/* Windows reports these as zero */
	caps->dwUnlockTransferRate = 0;
	caps->dwPlayCpuOverhead = 0;

	return DS_OK;
}

static HRESULT WINAPI PrimaryBufferImpl_QueryInterface(
	LPDIRECTSOUNDBUFFER iface,REFIID riid,LPVOID *ppobj
) {
        PrimaryBufferImpl *This = (PrimaryBufferImpl *)iface;
        DirectSoundDevice *device = This->device;
	TRACE("(%p,%s,%p)\n", iface, debugstr_guid(riid), ppobj);

	if (ppobj == NULL) {
		WARN("invalid parameter\n");
		return E_INVALIDARG;
	}

	*ppobj = NULL;	/* assume failure */

	if ( IsEqualGUID(riid, &IID_IUnknown) ||
	     IsEqualGUID(riid, &IID_IDirectSoundBuffer) ) {
		IDirectSoundBuffer_AddRef((LPDIRECTSOUNDBUFFER)This);
		*ppobj = This;
		return S_OK;
	}

	/* DirectSoundBuffer and DirectSoundBuffer8 are different and */
	/* a primary buffer can't have a DirectSoundBuffer8 interface */
	if ( IsEqualGUID( &IID_IDirectSoundBuffer8, riid ) ) {
		WARN("app requested DirectSoundBuffer8 on primary buffer\n");
		return E_NOINTERFACE;
	}

	if ( IsEqualGUID( &IID_IDirectSoundNotify, riid ) ) {
		ERR("app requested IDirectSoundNotify on primary buffer\n");
		/* FIXME: should we support this? */
		return E_NOINTERFACE;
	}

	if ( IsEqualGUID( &IID_IDirectSound3DBuffer, riid ) ) {
		ERR("app requested IDirectSound3DBuffer on primary buffer\n");
		return E_NOINTERFACE;
	}

        if ( IsEqualGUID( &IID_IDirectSound3DListener, riid ) ) {
		if (!device->listener)
			IDirectSound3DListenerImpl_Create(device, &device->listener);
		if (device->listener) {
			*ppobj = device->listener;
			IDirectSound3DListener_AddRef((LPDIRECTSOUND3DLISTENER)*ppobj);
			return S_OK;
		}

		WARN("IID_IDirectSound3DListener failed\n");
		return E_NOINTERFACE;
	}

	if ( IsEqualGUID( &IID_IKsPropertySet, riid ) ) {
		FIXME("app requested IKsPropertySet on primary buffer\n");
		return E_NOINTERFACE;
	}

	FIXME( "Unknown IID %s\n", debugstr_guid( riid ) );
	return E_NOINTERFACE;
}

static const IDirectSoundBufferVtbl dspbvt =
{
	PrimaryBufferImpl_QueryInterface,
	PrimaryBufferImpl_AddRef,
	PrimaryBufferImpl_Release,
	PrimaryBufferImpl_GetCaps,
	PrimaryBufferImpl_GetCurrentPosition,
	PrimaryBufferImpl_GetFormat,
	PrimaryBufferImpl_GetVolume,
	PrimaryBufferImpl_GetPan,
        PrimaryBufferImpl_GetFrequency,
	PrimaryBufferImpl_GetStatus,
	PrimaryBufferImpl_Initialize,
	PrimaryBufferImpl_Lock,
	PrimaryBufferImpl_Play,
	PrimaryBufferImpl_SetCurrentPosition,
	PrimaryBufferImpl_SetFormat,
	PrimaryBufferImpl_SetVolume,
	PrimaryBufferImpl_SetPan,
	PrimaryBufferImpl_SetFrequency,
	PrimaryBufferImpl_Stop,
	PrimaryBufferImpl_Unlock,
	PrimaryBufferImpl_Restore
};

HRESULT PrimaryBufferImpl_Create(
	DirectSoundDevice * device,
	PrimaryBufferImpl ** ppdsb,
	LPCDSBUFFERDESC dsbd)
{
	PrimaryBufferImpl *dsb;
	TRACE("%p,%p,%p)\n",device,ppdsb,dsbd);

	if (dsbd->lpwfxFormat) {
		WARN("invalid parameter: dsbd->lpwfxFormat != NULL\n");
		*ppdsb = NULL;
		return DSERR_INVALIDPARAM;
	}

	dsb = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(*dsb));

	if (dsb == NULL) {
		WARN("out of memory\n");
		*ppdsb = NULL;
		return DSERR_OUTOFMEMORY;
	}

	dsb->ref = 0;
	dsb->device = device;
	dsb->lpVtbl = &dspbvt;

	device->dsbd = *dsbd;

	TRACE("Created primary buffer at %p\n", dsb);
	TRACE("(formattag=0x%04x,chans=%d,samplerate=%d,"
		"bytespersec=%d,blockalign=%d,bitspersamp=%d,cbSize=%d)\n",
		device->pwfx->wFormatTag, device->pwfx->nChannels,
                device->pwfx->nSamplesPerSec, device->pwfx->nAvgBytesPerSec,
                device->pwfx->nBlockAlign, device->pwfx->wBitsPerSample,
                device->pwfx->cbSize);

	*ppdsb = dsb;
	return S_OK;
}
