/*  			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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 */

#include <stdarg.h>

#define NONAMELESSSTRUCT
#define NONAMELESSUNION
#include "windef.h"
#include "winbase.h"
#include "mmsystem.h"
#include "winreg.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);

void DSOUND_RecalcPrimary(IDirectSoundImpl *This)
{
	DWORD sw;
	TRACE("(%p)\n",This);

	sw = This->pwfx->nChannels * (This->pwfx->wBitsPerSample / 8);
	if (This->hwbuf) {
		DWORD fraglen;
		/* let fragment size approximate the timer delay */
		fraglen = (This->pwfx->nSamplesPerSec * DS_TIME_DEL / 1000) * sw;
		/* reduce fragment size until an integer number of them fits in the buffer */
		/* (FIXME: this may or may not be a good idea) */
		while (This->buflen % fraglen) fraglen -= sw;
		This->fraglen = fraglen;
		TRACE("fraglen=%ld\n", This->fraglen);
	}
	/* calculate the 10ms write lead */
	This->writelead = (This->pwfx->nSamplesPerSec / 100) * sw;
}

static HRESULT DSOUND_PrimaryOpen(IDirectSoundImpl *This)
{
	HRESULT err = DS_OK;
	TRACE("(%p)\n",This);

	/* are we using waveOut stuff? */
	if (!This->driver) {
		LPBYTE newbuf;
		DWORD buflen;
		HRESULT merr = DS_OK;
		/* Start in pause mode, to allow buffers to get filled */
		waveOutPause(This->hwo);
		if (This->state == STATE_PLAYING) This->state = STATE_STARTING;
		else if (This->state == STATE_STOPPING) This->state = STATE_STOPPED;
		/* use fragments of 10ms (1/100s) each (which should get us within
		 * the documented write cursor lead of 10-15ms) */
		buflen = ((This->pwfx->nAvgBytesPerSec / 100) & ~3) * DS_HEL_FRAGS;
		TRACE("desired buflen=%ld, old buffer=%p\n", buflen, This->buffer);
		/* reallocate emulated primary buffer */

		if (This->buffer)
			newbuf = HeapReAlloc(GetProcessHeap(),0,This->buffer,buflen);
		else
			newbuf = HeapAlloc(GetProcessHeap(),0,buflen);

		if (newbuf == NULL) {
			ERR("failed to allocate primary buffer\n");
			merr = DSERR_OUTOFMEMORY;
			/* but the old buffer might still exist and must be re-prepared */
		} else {
			This->buffer = newbuf;
			This->buflen = buflen;
		}
		if (This->buffer) {
			unsigned c;

			This->fraglen = This->buflen / DS_HEL_FRAGS;

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

			This->pwplay = 0;
			This->pwwrite = 0;
			This->pwqueue = 0;
			This->playpos = 0;
			This->mixpos = 0;
			FillMemory(This->buffer, This->buflen, (This->pwfx->wBitsPerSample == 16) ? 0 : 128);
			TRACE("fraglen=%ld\n", This->fraglen);
			DSOUND_WaveQueue(This, (DWORD)-1);
		}
		if ((err == DS_OK) && (merr != DS_OK))
			err = merr;
	} else if (!This->hwbuf) {
		err = IDsDriver_CreateSoundBuffer(This->driver,This->pwfx,
						  DSBCAPS_PRIMARYBUFFER,0,
						  &(This->buflen),&(This->buffer),
						  (LPVOID*)&(This->hwbuf));
		if (err != DS_OK) {
			WARN("IDsDriver_CreateSoundBuffer failed\n");
			return err;
		}

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

	return err;
}


static void DSOUND_PrimaryClose(IDirectSoundImpl *This)
{
	TRACE("(%p)\n",This);

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

		This->pwqueue = (DWORD)-1; /* resetting queues */
		waveOutReset(This->hwo);
		for (c=0; c<DS_HEL_FRAGS; c++)
			waveOutUnprepareHeader(This->hwo, This->pwave[c], sizeof(WAVEHDR));
		This->pwqueue = 0;
	} else {
		if (IDsDriverBuffer_Release(This->hwbuf) == 0)
			This->hwbuf = 0;
	}
}

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

	This->buflen = This->pwfx->nAvgBytesPerSec;

	/* FIXME: verify that hardware capabilities (DSCAPS_PRIMARY flags) match */

	if (This->driver) {
		err = IDsDriver_CreateSoundBuffer(This->driver,This->pwfx,
						  DSBCAPS_PRIMARYBUFFER,0,
						  &(This->buflen),&(This->buffer),
						  (LPVOID*)&(This->hwbuf));
		if (err != DS_OK) {
			WARN("IDsDriver_CreateSoundBuffer failed\n");
			return err;
		}
	}
	if (!This->hwbuf) {
		/* Allocate memory for HEL buffer headers */
		unsigned c;
		for (c=0; c<DS_HEL_FRAGS; c++) {
			This->pwave[c] = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(WAVEHDR));
			if (!This->pwave[c]) {
				/* Argh, out of memory */
				while (c--) {
					HeapFree(GetProcessHeap(),0,This->pwave[c]);
				}
				WARN("out of memory\n");
				return DSERR_OUTOFMEMORY;
			}
		}
	}

	err = DSOUND_PrimaryOpen(This);

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

	/* calculate fragment size and write lead */
	DSOUND_RecalcPrimary(This);
	This->state = STATE_STOPPED;
	return DS_OK;
}

HRESULT DSOUND_PrimaryDestroy(IDirectSoundImpl *This)
{
	TRACE("(%p)\n",This);

	DSOUND_PrimaryClose(This);
	if (This->driver) {
		if (This->hwbuf) {
			if (IDsDriverBuffer_Release(This->hwbuf) == 0)
				This->hwbuf = 0;
		}
	} else {
		unsigned c;
		for (c=0; c<DS_HEL_FRAGS; c++) {
			HeapFree(GetProcessHeap(),0,This->pwave[c]);
		}
	}
        HeapFree(GetProcessHeap(),0,This->pwfx);
        This->pwfx=NULL;
	return DS_OK;
}

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

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

	return err;
}

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

	if (This->hwbuf) {
		err = IDsDriverBuffer_Stop(This->hwbuf);
		if (err == DSERR_BUFFERLOST) {
			DWORD flags = CALLBACK_FUNCTION;
			if (ds_hw_accel != DS_HW_ACCEL_EMULATION)
				flags |= WAVE_DIRECTSOUND;
			/* Wine-only: the driver wants us to reopen the device */
			/* FIXME: check for errors */
			IDsDriverBuffer_Release(This->hwbuf);
			waveOutClose(This->hwo);
			This->hwo = 0;
			err = mmErr(waveOutOpen(&(This->hwo), This->drvdesc.dnDevNode,
						This->pwfx, (DWORD)DSOUND_callback, (DWORD)This,
						flags));
			if (err == DS_OK) {
				err = IDsDriver_CreateSoundBuffer(This->driver,This->pwfx,
								  DSBCAPS_PRIMARYBUFFER,0,
								  &(This->buflen),&(This->buffer),
								  (LPVOID)&(This->hwbuf));
				if (err != DS_OK)
					WARN("IDsDriver_CreateSoundBuffer failed\n");
			} else {
				WARN("waveOutOpen failed\n");
			}
		} else if (err != DS_OK) {
			WARN("IDsDriverBuffer_Stop failed\n");
		}
	} else {
		err = mmErr(waveOutPause(This->hwo));
		if (err != DS_OK)
			WARN("waveOutPause failed\n");
	}
	return err;
}

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

	if (This->hwbuf) {
		HRESULT err=IDsDriverBuffer_GetPosition(This->hwbuf,playpos,writepos);
		if (err) {
			WARN("IDsDriverBuffer_GetPosition failed\n");
			return err;
		}
	} else {
		if (playpos) {
			MMTIME mtime;
			mtime.wType = TIME_BYTES;
			waveOutGetPosition(This->hwo, &mtime, sizeof(mtime));
			mtime.u.cb = mtime.u.cb % This->buflen;
			*playpos = mtime.u.cb;
		}
		if (writepos) {
			/* the writepos should only be used by apps with WRITEPRIMARY priority,
			 * in which case our software mixer is disabled anyway */
			*writepos = (This->pwplay + ds_hel_margin) * This->fraglen;
			while (*writepos >= This->buflen)
				*writepos -= This->buflen;
		}
	}
	TRACE("playpos = %ld, writepos = %ld (%p, time=%ld)\n", playpos?*playpos:0, writepos?*writepos:0, This, GetTickCount());
	return DS_OK;
}

/*******************************************************************************
 *		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(
	LPDIRECTSOUNDBUFFER8 iface,LPCWAVEFORMATEX wfex
) {
	PrimaryBufferImpl *This = (PrimaryBufferImpl *)iface;
	IDirectSoundImpl* dsound = This->dsound;
	HRESULT err = DS_OK;
	int i, alloc_size, cp_size;
	DWORD nSamplesPerSec;
	TRACE("(%p,%p)\n",This,wfex);

	if (This->dsound->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=%ld,"
	      "bytespersec=%ld,blockalign=%d,bitspersamp=%d,cbSize=%d)\n",
	      wfex->wFormatTag, wfex->nChannels, wfex->nSamplesPerSec,
	      wfex->nAvgBytesPerSec, wfex->nBlockAlign,
	      wfex->wBitsPerSample, wfex->cbSize);

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

	if (wfex->wFormatTag == WAVE_FORMAT_PCM) {
            alloc_size = sizeof(WAVEFORMATEX);
            cp_size = sizeof(PCMWAVEFORMAT);
        } else
            alloc_size = cp_size = sizeof(WAVEFORMATEX) + wfex->cbSize;

        dsound->pwfx = HeapReAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,dsound->pwfx,alloc_size);

	nSamplesPerSec = dsound->pwfx->nSamplesPerSec;

        CopyMemory(dsound->pwfx, wfex, cp_size);

	if (dsound->drvdesc.dwFlags & DSDDESC_DOMMSYSTEMSETFORMAT) {
		DWORD flags = CALLBACK_FUNCTION;
		if (ds_hw_accel != DS_HW_ACCEL_EMULATION)
			flags |= WAVE_DIRECTSOUND;
		/* FIXME: check for errors */
		DSOUND_PrimaryClose(dsound);
		waveOutClose(dsound->hwo);
		dsound->hwo = 0;
                err = mmErr(waveOutOpen(&(dsound->hwo), dsound->drvdesc.dnDevNode,
                                        dsound->pwfx, (DWORD)DSOUND_callback, (DWORD)dsound,
                                        flags));
                if (err == DS_OK) {
                    err = DSOUND_PrimaryOpen(dsound);
		    if (err != DS_OK) {
			WARN("DSOUND_PrimaryOpen failed\n");
			goto done;
		    }
		} else {
			WARN("waveOutOpen failed\n");
			goto done;
		}
	} else if (dsound->hwbuf) {
		err = IDsDriverBuffer_SetFormat(dsound->hwbuf, dsound->pwfx);
		if (err == DSERR_BUFFERLOST) {
			/* Wine-only: the driver wants us to recreate the HW buffer */
			IDsDriverBuffer_Release(dsound->hwbuf);
			err = IDsDriver_CreateSoundBuffer(dsound->driver,dsound->pwfx,
							  DSBCAPS_PRIMARYBUFFER,0,
							  &(dsound->buflen),&(dsound->buffer),
							  (LPVOID)&(dsound->hwbuf));
			if (err != DS_OK) {
				WARN("IDsDriver_CreateSoundBuffer failed\n");
				goto done;
			}
			if (dsound->state == STATE_PLAYING) dsound->state = STATE_STARTING;
			else if (dsound->state == STATE_STOPPING) dsound->state = STATE_STOPPED;
		} else {
			WARN("IDsDriverBuffer_SetFormat failed\n");
			goto done;
		}
                /* FIXME: should we set err back to DS_OK in all cases ? */
	}
	DSOUND_RecalcPrimary(dsound);

	if (nSamplesPerSec != dsound->pwfx->nSamplesPerSec) {
		IDirectSoundBufferImpl** dsb = dsound->buffers;
		for (i = 0; i < dsound->nrofbuffers; i++, dsb++) {
			/* **** */
			EnterCriticalSection(&((*dsb)->lock));

			(*dsb)->freqAdjust = ((*dsb)->freq << DSOUND_FREQSHIFT) /
				wfex->nSamplesPerSec;

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

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

	return err;
}

static HRESULT WINAPI PrimaryBufferImpl_SetVolume(
	LPDIRECTSOUNDBUFFER8 iface,LONG vol
) {
	PrimaryBufferImpl *This = (PrimaryBufferImpl *)iface;
	IDirectSoundImpl* dsound = This->dsound;
	DWORD ampfactors;
	DSVOLUMEPAN volpan;
        HRESULT hres = DS_OK;

	TRACE("(%p,%ld)\n",This,vol);

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

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

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

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

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

	return hres;
}

static HRESULT WINAPI PrimaryBufferImpl_GetVolume(
	LPDIRECTSOUNDBUFFER8 iface,LPLONG vol
) {
	PrimaryBufferImpl *This = (PrimaryBufferImpl *)iface;
	DWORD ampfactors;
	DSVOLUMEPAN volpan;
	TRACE("(%p,%p)\n",This,vol);

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

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

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

static HRESULT WINAPI PrimaryBufferImpl_SetFrequency(
	LPDIRECTSOUNDBUFFER8 iface,DWORD freq
) {
	PrimaryBufferImpl *This = (PrimaryBufferImpl *)iface;

	TRACE("(%p,%ld)\n",This,freq);

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

static HRESULT WINAPI PrimaryBufferImpl_Play(
	LPDIRECTSOUNDBUFFER8 iface,DWORD reserved1,DWORD reserved2,DWORD flags
) {
	PrimaryBufferImpl *This = (PrimaryBufferImpl *)iface;
	IDirectSoundImpl* dsound = This->dsound;

	TRACE("(%p,%08lx,%08lx,%08lx)\n",
		This,reserved1,reserved2,flags
	);

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

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

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

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

	return DS_OK;
}

static HRESULT WINAPI PrimaryBufferImpl_Stop(LPDIRECTSOUNDBUFFER8 iface)
{
	PrimaryBufferImpl *This = (PrimaryBufferImpl *)iface;
	IDirectSoundImpl* dsound = This->dsound;

	TRACE("(%p)\n",This);

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

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

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

	return DS_OK;
}

static ULONG WINAPI PrimaryBufferImpl_AddRef(LPDIRECTSOUNDBUFFER8 iface) {
	PrimaryBufferImpl *This = (PrimaryBufferImpl *)iface;
	TRACE("(%p) ref was %ld, thread is %04lx\n",This, This->ref, GetCurrentThreadId());
	return InterlockedIncrement(&(This->ref));
}

static ULONG WINAPI PrimaryBufferImpl_Release(LPDIRECTSOUNDBUFFER8 iface) {
	PrimaryBufferImpl *This = (PrimaryBufferImpl *)iface;
	DWORD ref;

	TRACE("(%p) ref was %ld, thread is %04lx\n",This, This->ref, GetCurrentThreadId());
	ref = InterlockedDecrement(&(This->ref));

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

	return ref;
}

static HRESULT WINAPI PrimaryBufferImpl_GetCurrentPosition(
	LPDIRECTSOUNDBUFFER8 iface,LPDWORD playpos,LPDWORD writepos
) {
	HRESULT	hres;
	PrimaryBufferImpl *This = (PrimaryBufferImpl *)iface;
	IDirectSoundImpl* dsound = This->dsound;

	TRACE("(%p,%p,%p)\n",This,playpos,writepos);
	hres = DSOUND_PrimaryGetPosition(dsound, playpos, writepos);
	if (hres != DS_OK) {
		WARN("DSOUND_PrimaryGetPosition failed\n");
		return hres;
	}
	if (writepos) {
		if (dsound->state != STATE_STOPPED)
			/* apply the documented 10ms lead to writepos */
			*writepos += dsound->writelead;
		while (*writepos >= dsound->buflen) *writepos -= dsound->buflen;
	}
	TRACE("playpos = %ld, writepos = %ld (%p, time=%ld)\n", playpos?*playpos:0, writepos?*writepos:0, This, GetTickCount());
	return DS_OK;
}

static HRESULT WINAPI PrimaryBufferImpl_GetStatus(
	LPDIRECTSOUNDBUFFER8 iface,LPDWORD status
) {
	PrimaryBufferImpl *This = (PrimaryBufferImpl *)iface;
	TRACE("(%p,%p), thread is %04lx\n",This,status,GetCurrentThreadId());

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

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

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


static HRESULT WINAPI PrimaryBufferImpl_GetFormat(
    LPDIRECTSOUNDBUFFER8 iface,
    LPWAVEFORMATEX lpwf,
    DWORD wfsize,
    LPDWORD wfwritten)
{
    DWORD size;
    PrimaryBufferImpl *This = (PrimaryBufferImpl *)iface;
    TRACE("(%p,%p,%ld,%p)\n",This,lpwf,wfsize,wfwritten);

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

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

    return DS_OK;
}

static HRESULT WINAPI PrimaryBufferImpl_Lock(
	LPDIRECTSOUNDBUFFER8 iface,DWORD writecursor,DWORD writebytes,LPVOID lplpaudioptr1,LPDWORD audiobytes1,LPVOID lplpaudioptr2,LPDWORD audiobytes2,DWORD flags
) {
	PrimaryBufferImpl *This = (PrimaryBufferImpl *)iface;
	IDirectSoundImpl* dsound = This->dsound;

	TRACE("(%p,%ld,%ld,%p,%p,%p,%p,0x%08lx) at %ld\n",
		This,
		writecursor,
		writebytes,
		lplpaudioptr1,
		audiobytes1,
		lplpaudioptr2,
		audiobytes2,
		flags,
		GetTickCount()
	);

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

	if (flags & DSBLOCK_FROMWRITECURSOR) {
		DWORD writepos;
		HRESULT hres;
		/* GetCurrentPosition does too much magic to duplicate here */
		hres = IDirectSoundBuffer_GetCurrentPosition(iface, NULL, &writepos);
		if (hres != DS_OK) {
			WARN("IDirectSoundBuffer_GetCurrentPosition failed\n");
			return hres;
		}
		writecursor += writepos;
	}
	while (writecursor >= dsound->buflen)
		writecursor -= dsound->buflen;
	if (flags & DSBLOCK_ENTIREBUFFER)
		writebytes = dsound->buflen;
	if (writebytes > dsound->buflen)
		writebytes = dsound->buflen;

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

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

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

static HRESULT WINAPI PrimaryBufferImpl_SetPan(
	LPDIRECTSOUNDBUFFER8 iface,LONG pan
) {
	PrimaryBufferImpl *This = (PrimaryBufferImpl *)iface;
	IDirectSoundImpl* dsound = This->dsound;
	DWORD ampfactors;
	DSVOLUMEPAN volpan;
        HRESULT hres = DS_OK;

	TRACE("(%p,%ld)\n",This,pan);

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

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

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

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

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

	return hres;
}

static HRESULT WINAPI PrimaryBufferImpl_GetPan(
	LPDIRECTSOUNDBUFFER8 iface,LPLONG pan
) {
	PrimaryBufferImpl *This = (PrimaryBufferImpl *)iface;
	DWORD ampfactors;
	DSVOLUMEPAN volpan;
	TRACE("(%p,%p)\n",This,pan);

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

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

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

static HRESULT WINAPI PrimaryBufferImpl_Unlock(
	LPDIRECTSOUNDBUFFER8 iface,LPVOID p1,DWORD x1,LPVOID p2,DWORD x2
) {
	PrimaryBufferImpl *This = (PrimaryBufferImpl *)iface;
	IDirectSoundImpl* dsound = This->dsound;

	TRACE("(%p,%p,%ld,%p,%ld)\n", This,p1,x1,p2,x2);

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

	if (!(dsound->drvdesc.dwFlags & DSDDESC_DONTNEEDPRIMARYLOCK) && dsound->hwbuf) {
		HRESULT	hres;
		
		hres = IDsDriverBuffer_Unlock(dsound->hwbuf, p1, x1, p2, x2);
		if (hres != DS_OK) {
			WARN("IDsDriverBuffer_Unlock failed\n");
			return hres;
		}
	}

	return DS_OK;
}

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

static HRESULT WINAPI PrimaryBufferImpl_GetFrequency(
	LPDIRECTSOUNDBUFFER8 iface,LPDWORD freq
) {
	PrimaryBufferImpl *This = (PrimaryBufferImpl *)iface;
	TRACE("(%p,%p)\n",This,freq);

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

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

	*freq = This->dsound->pwfx->nSamplesPerSec;
	TRACE("-> %ld\n", *freq);

	return DS_OK;
}

static HRESULT WINAPI PrimaryBufferImpl_SetFX(
	LPDIRECTSOUNDBUFFER8 iface,DWORD dwEffectsCount,LPDSEFFECTDESC pDSFXDesc,LPDWORD pdwResultCodes
) {
	PrimaryBufferImpl *This = (PrimaryBufferImpl *)iface;
	DWORD u;

	FIXME("(%p,%lu,%p,%p): stub\n",This,dwEffectsCount,pDSFXDesc,pdwResultCodes);

	if (pdwResultCodes)
		for (u=0; u<dwEffectsCount; u++) pdwResultCodes[u] = DSFXR_UNKNOWN;

	WARN("control unavailable\n");
	return DSERR_CONTROLUNAVAIL;
}

static HRESULT WINAPI PrimaryBufferImpl_AcquireResources(
	LPDIRECTSOUNDBUFFER8 iface,DWORD dwFlags,DWORD dwEffectsCount,LPDWORD pdwResultCodes
) {
	PrimaryBufferImpl *This = (PrimaryBufferImpl *)iface;
	DWORD u;

	FIXME("(%p,%08lu,%lu,%p): stub\n",This,dwFlags,dwEffectsCount,pdwResultCodes);

	if (pdwResultCodes)
		for (u=0; u<dwEffectsCount; u++) pdwResultCodes[u] = DSFXR_UNKNOWN;

	WARN("control unavailable\n");
	return DSERR_CONTROLUNAVAIL;
}

static HRESULT WINAPI PrimaryBufferImpl_GetObjectInPath(
	LPDIRECTSOUNDBUFFER8 iface,REFGUID rguidObject,DWORD dwIndex,REFGUID rguidInterface,LPVOID* ppObject
) {
	PrimaryBufferImpl *This = (PrimaryBufferImpl *)iface;

	FIXME("(%p,%s,%lu,%s,%p): stub\n",This,debugstr_guid(rguidObject),dwIndex,debugstr_guid(rguidInterface),ppObject);

	WARN("control unavailable\n");
	return DSERR_CONTROLUNAVAIL;
}

static HRESULT WINAPI PrimaryBufferImpl_Initialize(
	LPDIRECTSOUNDBUFFER8 iface,LPDIRECTSOUND dsound,LPCDSBUFFERDESC dbsd
) {
	PrimaryBufferImpl *This = (PrimaryBufferImpl *)iface;
	FIXME("(%p,%p,%p):stub\n",This,dsound,dbsd);
	DPRINTF("Re-Init!!!\n");
	WARN("already initialized\n");
	return DSERR_ALREADYINITIALIZED;
}

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

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

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

	caps->dwFlags = This->dsound->dsbd.dwFlags;
	if (This->dsound->hwbuf) caps->dwFlags |= DSBCAPS_LOCHARDWARE;
	else caps->dwFlags |= DSBCAPS_LOCSOFTWARE;

	caps->dwBufferBytes = This->dsound->buflen;

	/* This value represents the speed of the "unlock" command.
	   As unlock is quite fast (it does not do anything), I put
	   4096 ko/s = 4 Mo / s */
	/* FIXME: hwbuf speed */
	caps->dwUnlockTransferRate = 4096;
	caps->dwPlayCpuOverhead = 0;

	return DS_OK;
}

static HRESULT WINAPI PrimaryBufferImpl_QueryInterface(
	LPDIRECTSOUNDBUFFER8 iface,REFIID riid,LPVOID *ppobj
) {
	PrimaryBufferImpl *This = (PrimaryBufferImpl *)iface;
	TRACE("(%p,%s,%p)\n",This,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 (!This->dsound->listener)
			IDirectSound3DListenerImpl_Create(This, &This->dsound->listener);
		if (This->dsound->listener) {
			*ppobj = This->dsound->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 IDirectSoundBuffer8Vtbl 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,
	PrimaryBufferImpl_SetFX,
	PrimaryBufferImpl_AcquireResources,
	PrimaryBufferImpl_GetObjectInPath
};

HRESULT WINAPI PrimaryBufferImpl_Create(
	IDirectSoundImpl *ds,
	PrimaryBufferImpl **pdsb,
	LPCDSBUFFERDESC dsbd)
{
	PrimaryBufferImpl *dsb;

	TRACE("%p,%p,%p)\n",ds,pdsb,dsbd);

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

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

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

	dsb->ref = 0;
	dsb->dsound = ds;
	dsb->lpVtbl = &dspbvt;

	CopyMemory(&ds->dsbd, dsbd, sizeof(*dsbd));

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

	*pdsb = dsb;
	return S_OK;
}
