/*  			DirectSound
 * 
 * Copyright 1998 Marcus Meissner
 * Copyright 1998 Rob Riggs
 */
/*
 * Note: This file requires multithread ability. It is not possible to
 * implement the stuff in a single thread anyway. And most DirectX apps
 * require threading themselves.
 *
 * FIXME: This file is full of race conditions and unlocked variable access
 * from two threads. But we usually don't need to bother.
 *
 * Tested with a Soundblaster clone and a Gravis UltraSound Classic.
 *
 * Status:
 * - Wing Commander 4/W95:
 *   The intromovie plays without problems. Nearly lipsynchron.
 * - DiscWorld 2
 *   The sound works, but noticeable chunks are left out (from the sound and
 *   the animation). Don't know why yet.
 * - Diablo:
 *   Sound works, but slows down the movieplayer.
 * - XvT: 
 *   Doesn't sound yet.
 * - Monkey Island 3:
 *   The background sound of the startscreen works ;)
 * - WingCommander Prophecy Demo:
 *   Sound works for the intromovie.
 */

#include "config.h"
#include <assert.h>
#include <errno.h>
#include <sys/types.h>
#include <sys/time.h>
#include <sys/fcntl.h>
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>	/* Insomnia - pow() function */
#include "windows.h"
#include "winerror.h"
#include "interfaces.h"
#include "mmsystem.h"
#include "dsound.h"
#include "thread.h"
#include "debug.h"
#include "xmalloc.h"

#ifdef HAVE_OSS
# include <sys/ioctl.h>
# ifdef HAVE_MACHINE_SOUNDCARD_H
#  include <machine/soundcard.h>
# endif
# ifdef HAVE_SYS_SOUNDCARD_H
#  include <sys/soundcard.h>
# endif

/* #define USE_DSOUND3D 1 */

static int audiofd = -1;
static int audioOK = 0;

static LPDIRECTSOUND	dsound = NULL;

static LPDIRECTSOUNDBUFFER	primarybuf = NULL;

static int DSOUND_setformat(LPWAVEFORMATEX wfex);
static void DSOUND_CloseAudio(void);

#endif

HRESULT WINAPI DirectSoundEnumerate32A(LPDSENUMCALLBACK32A enumcb,LPVOID context) {
#ifdef HAVE_OSS
	enumcb(NULL,"WINE DirectSound using Open Sound System","sound",context);
#endif
	return 0;
}

#ifdef HAVE_OSS
static void _dump_DSBCAPS(DWORD xmask) {
	struct {
		DWORD	mask;
		char	*name;
	} flags[] = {
#define FE(x) { x, #x },
		FE(DSBCAPS_PRIMARYBUFFER)
		FE(DSBCAPS_STATIC)
		FE(DSBCAPS_LOCHARDWARE)
		FE(DSBCAPS_LOCSOFTWARE)
		FE(DSBCAPS_CTRLFREQUENCY)
		FE(DSBCAPS_CTRLPAN)
		FE(DSBCAPS_CTRLVOLUME)
		FE(DSBCAPS_CTRLDEFAULT)
		FE(DSBCAPS_CTRLALL)
		FE(DSBCAPS_STICKYFOCUS)
		FE(DSBCAPS_GETCURRENTPOSITION2)
	};
	int	i;

	for (i=0;i<sizeof(flags)/sizeof(flags[0]);i++)
		if (flags[i].mask & xmask)
			fprintf(stderr,"%s ",flags[i].name);
}

/*******************************************************************************
 *              IDirectSound3DBuffer
 */

// IUnknown methods
static HRESULT WINAPI IDirectSound3DBuffer_QueryInterface(
	LPDIRECTSOUND3DBUFFER this, REFIID riid, LPVOID *ppobj)
{
	char xbuf[50];

	WINE_StringFromCLSID(riid,xbuf);
	TRACE(dsound,"(%p,%s,%p)\n",this,xbuf,ppobj);
	return E_FAIL;
}
	
static ULONG WINAPI IDirectSound3DBuffer_AddRef(LPDIRECTSOUND3DBUFFER this)
{
	this->ref++;
	return this->ref;
}

static ULONG WINAPI IDirectSound3DBuffer_Release(LPDIRECTSOUND3DBUFFER this)
{
	if(--this->ref)
		return this->ref;

	HeapFree(GetProcessHeap(),0,this->buffer);
	HeapFree(GetProcessHeap(),0,this);

	return 0;
}

// IDirectSound3DBuffer methods
static HRESULT WINAPI IDirectSound3DBuffer_GetAllParameters(
	LPDIRECTSOUND3DBUFFER this,
	LPDS3DBUFFER lpDs3dBuffer)
{
	FIXME(dsound,"stub\n");
	return DS_OK;
}

static HRESULT WINAPI IDirectSound3DBuffer_GetConeAngles(
	LPDIRECTSOUND3DBUFFER this,
	LPDWORD lpdwInsideConeAngle,
	LPDWORD lpdwOutsideConeAngle)
{
	FIXME(dsound,"stub\n");
	return DS_OK;
}

static HRESULT WINAPI IDirectSound3DBuffer_GetConeOrientation(
	LPDIRECTSOUND3DBUFFER this,
	LPD3DVECTOR lpvConeOrientation)
{
	FIXME(dsound,"stub\n");
	return DS_OK;
}

static HRESULT WINAPI IDirectSound3DBuffer_GetConeOutsideVolume(
	LPDIRECTSOUND3DBUFFER this,
	LPLONG lplConeOutsideVolume)
{
	FIXME(dsound,"stub\n");
	return DS_OK;
}

static HRESULT WINAPI IDirectSound3DBuffer_GetMaxDistance(
	LPDIRECTSOUND3DBUFFER this,
	LPD3DVALUE lpfMaxDistance)
{
	FIXME(dsound,"stub\n");
	return DS_OK;
}

static HRESULT WINAPI IDirectSound3DBuffer_GetMinDistance(
	LPDIRECTSOUND3DBUFFER this,
	LPD3DVALUE lpfMinDistance)
{
	FIXME(dsound,"stub\n");
	return DS_OK;
}

static HRESULT WINAPI IDirectSound3DBuffer_GetMode(
	LPDIRECTSOUND3DBUFFER this,
	LPDWORD lpdwMode)
{
	FIXME(dsound,"stub\n");
	return DS_OK;
}

static HRESULT WINAPI IDirectSound3DBuffer_GetPosition(
	LPDIRECTSOUND3DBUFFER this,
	LPD3DVECTOR lpvPosition)
{
	FIXME(dsound,"stub\n");
	return DS_OK;
}

static HRESULT WINAPI IDirectSound3DBuffer_GetVelocity(
	LPDIRECTSOUND3DBUFFER this,
	LPD3DVECTOR lpvVelocity)
{
	FIXME(dsound,"stub\n");
	return DS_OK;
}

static HRESULT WINAPI IDirectSound3DBuffer_SetAllParameters(
	LPDIRECTSOUND3DBUFFER this,
	LPCDS3DBUFFER lpcDs3dBuffer,
	DWORD dwApply)
{
	FIXME(dsound,"stub\n");
	return DS_OK;
}

static HRESULT WINAPI IDirectSound3DBuffer_SetConeAngles(
	LPDIRECTSOUND3DBUFFER this,
	DWORD dwInsideConeAngle,
	DWORD dwOutsideConeAngle,
	DWORD dwApply)
{
	FIXME(dsound,"stub\n");
	return DS_OK;
}

static HRESULT WINAPI IDirectSound3DBuffer_SetConeOrientation(
	LPDIRECTSOUND3DBUFFER this,
	D3DVALUE x, D3DVALUE y, D3DVALUE z,
	DWORD dwApply)
{
	FIXME(dsound,"stub\n");
	return DS_OK;
}

static HRESULT WINAPI IDirectSound3DBuffer_SetConeOutsideVolume(
	LPDIRECTSOUND3DBUFFER this,
	LONG lConeOutsideVolume,
	DWORD dwApply)
{
	FIXME(dsound,"stub\n");
	return DS_OK;
}

static HRESULT WINAPI IDirectSound3DBuffer_SetMaxDistance(
	LPDIRECTSOUND3DBUFFER this,
	D3DVALUE fMaxDistance,
	DWORD dwApply)
{
	FIXME(dsound,"stub\n");
	return DS_OK;
}

static HRESULT WINAPI IDirectSound3DBuffer_SetMinDistance(
	LPDIRECTSOUND3DBUFFER this,
	D3DVALUE fMinDistance,
	DWORD dwApply)
{
	FIXME(dsound,"stub\n");
	return DS_OK;
}

static HRESULT WINAPI IDirectSound3DBuffer_SetMode(
	LPDIRECTSOUND3DBUFFER this,
	DWORD dwMode,
	DWORD dwApply)
{
	TRACE(dsound, "mode = %lx\n", dwMode);
	this->ds3db.dwMode = dwMode;
	return DS_OK;
}

static HRESULT WINAPI IDirectSound3DBuffer_SetPosition(
	LPDIRECTSOUND3DBUFFER this,
	D3DVALUE x, D3DVALUE y, D3DVALUE z,
	DWORD dwApply)
{
	FIXME(dsound,"stub\n");
	return DS_OK;
}

static HRESULT WINAPI IDirectSound3DBuffer_SetVelocity(
	LPDIRECTSOUND3DBUFFER this,
	D3DVALUE x, D3DVALUE y, D3DVALUE z,
	DWORD dwApply)
{
	FIXME(dsound,"stub\n");
	return DS_OK;
}

IDirectSound3DBuffer_VTable ds3dbvt = {
	// IUnknown methods
	IDirectSound3DBuffer_QueryInterface,
	IDirectSound3DBuffer_AddRef,
	IDirectSound3DBuffer_Release,
	// IDirectSound3DBuffer methods
	IDirectSound3DBuffer_GetAllParameters,
	IDirectSound3DBuffer_GetConeAngles,
	IDirectSound3DBuffer_GetConeOrientation,
	IDirectSound3DBuffer_GetConeOutsideVolume,
	IDirectSound3DBuffer_GetMaxDistance,
	IDirectSound3DBuffer_GetMinDistance,
	IDirectSound3DBuffer_GetMode,
	IDirectSound3DBuffer_GetPosition,
	IDirectSound3DBuffer_GetVelocity,
	IDirectSound3DBuffer_SetAllParameters,
	IDirectSound3DBuffer_SetConeAngles,
	IDirectSound3DBuffer_SetConeOrientation,
	IDirectSound3DBuffer_SetConeOutsideVolume,
	IDirectSound3DBuffer_SetMaxDistance,
	IDirectSound3DBuffer_SetMinDistance,
	IDirectSound3DBuffer_SetMode,
	IDirectSound3DBuffer_SetPosition,
	IDirectSound3DBuffer_SetVelocity,
};

#ifdef USE_DSOUND3D
static int DSOUND_Create3DBuffer(LPDIRECTSOUNDBUFFER dsb)
{
	DWORD	i, temp, iSize, oSize, offset;
	LPBYTE	bIbuf, bObuf, bTbuf = NULL;
	LPWORD	wIbuf, wObuf, wTbuf = NULL;

	// Inside DirectX says it's stupid but allowed
	if (dsb->wfx.nChannels == 2) {
		// Convert to mono
		if (dsb->wfx.wBitsPerSample == 16) {
			iSize = dsb->buflen / 4;
			wTbuf = malloc(dsb->buflen / 2);
			if (wTbuf == NULL)
				return DSERR_OUTOFMEMORY;
			for (i = 0; i < iSize; i++)
				wTbuf[i] = (dsb->buffer[i] + dsb->buffer[(i * 2) + 1]) / 2;
			wIbuf = wTbuf;
		} else {
			iSize = dsb->buflen / 2;
			bTbuf = malloc(dsb->buflen / 2);
			if (bTbuf == NULL)
				return DSERR_OUTOFMEMORY;
			for (i = 0; i < iSize; i++)
				bTbuf[i] = (dsb->buffer[i] + dsb->buffer[(i * 2) + 1]) / 2;
			bIbuf = bTbuf;
		}
	} else {
		if (dsb->wfx.wBitsPerSample == 16) {
			iSize = dsb->buflen / 2;
			wIbuf = (LPWORD) dsb->buffer;
		} else {
			bIbuf = (LPBYTE) dsb->buffer;
			iSize = dsb->buflen;
		}
	}

	if (primarybuf->wfx.wBitsPerSample == 16) {
		wObuf = (LPWORD) dsb->ds3db->buffer;
		oSize = dsb->ds3db->buflen / 2;
	} else {
		bObuf = (LPBYTE) dsb->ds3db->buffer;
		oSize = dsb->ds3db->buflen;
	}

	offset = primarybuf->wfx.nSamplesPerSec / 100;		// 10ms
	if (primarybuf->wfx.wBitsPerSample == 16 && dsb->wfx.wBitsPerSample == 16)
		for (i = 0; i < iSize; i++) {
			temp = wIbuf[i];
			if (i >= offset)
				temp += wIbuf[i - offset] >> 9;
			else
				temp += wIbuf[i + iSize - offset] >> 9;
			wObuf[i * 2] = temp;
			wObuf[(i * 2) + 1] = temp;
		}
	else if (primarybuf->wfx.wBitsPerSample == 8 && dsb->wfx.wBitsPerSample == 8)
		for (i = 0; i < iSize; i++) {
			temp = bIbuf[i];
			if (i >= offset)
				temp += bIbuf[i - offset] >> 5;
			else
				temp += bIbuf[i + iSize - offset] >> 5;
			bObuf[i * 2] = temp;
			bObuf[(i * 2) + 1] = temp;
		}
	
	if (wTbuf)
		free(wTbuf);
	if (bTbuf)
		free(bTbuf);

	return DS_OK;
}
#endif
/*******************************************************************************
 *              IDirectSound3DListener
 */

// IUnknown methods
static HRESULT WINAPI IDirectSound3DListener_QueryInterface(
	LPDIRECTSOUND3DLISTENER this, REFIID riid, LPVOID *ppobj)
{
	char xbuf[50];

	WINE_StringFromCLSID(riid,xbuf);
	TRACE(dsound,"(%p,%s,%p)\n",this,xbuf,ppobj);
	return E_FAIL;
}
	
static ULONG WINAPI IDirectSound3DListener_AddRef(LPDIRECTSOUND3DLISTENER this)
{
	this->ref++;
	return this->ref;
}

static ULONG WINAPI IDirectSound3DListener_Release(LPDIRECTSOUND3DLISTENER this)
{
	this->ref--;
	return this->ref;
}

// IDirectSound3DListener methods
static HRESULT WINAPI IDirectSound3DListener_GetAllParameter(
	LPDIRECTSOUND3DLISTENER this,
	LPDS3DLISTENER lpDS3DL)
{
	FIXME(dsound,"stub\n");
	return DS_OK;
}

static HRESULT WINAPI IDirectSound3DListener_GetDistanceFactor(
	LPDIRECTSOUND3DLISTENER this,
	LPD3DVALUE lpfDistanceFactor)
{
	FIXME(dsound,"stub\n");
	return DS_OK;
}

static HRESULT WINAPI IDirectSound3DListener_GetDopplerFactor(
	LPDIRECTSOUND3DLISTENER this,
	LPD3DVALUE lpfDopplerFactor)
{
	FIXME(dsound,"stub\n");
	return DS_OK;
}

static HRESULT WINAPI IDirectSound3DListener_GetOrientation(
	LPDIRECTSOUND3DLISTENER this,
	LPD3DVECTOR lpvOrientFront,
	LPD3DVECTOR lpvOrientTop)
{
	FIXME(dsound,"stub\n");
	return DS_OK;
}

static HRESULT WINAPI IDirectSound3DListener_GetPosition(
	LPDIRECTSOUND3DLISTENER this,
	LPD3DVECTOR lpvPosition)
{
	FIXME(dsound,"stub\n");
	return DS_OK;
}

static HRESULT WINAPI IDirectSound3DListener_GetRolloffFactor(
	LPDIRECTSOUND3DLISTENER this,
	LPD3DVALUE lpfRolloffFactor)
{
	FIXME(dsound,"stub\n");
	return DS_OK;
}

static HRESULT WINAPI IDirectSound3DListener_GetVelocity(
	LPDIRECTSOUND3DLISTENER this,
	LPD3DVECTOR lpvVelocity)
{
	FIXME(dsound,"stub\n");
	return DS_OK;
}

static HRESULT WINAPI IDirectSound3DListener_SetAllParameters(
	LPDIRECTSOUND3DLISTENER this,
	LPCDS3DLISTENER lpcDS3DL,
	DWORD dwApply)
{
	FIXME(dsound,"stub\n");
	return DS_OK;
}

static HRESULT WINAPI IDirectSound3DListener_SetDistanceFactor(
	LPDIRECTSOUND3DLISTENER this,
	D3DVALUE fDistanceFactor,
	DWORD dwApply)
{
	FIXME(dsound,"stub\n");
	return DS_OK;
}

static HRESULT WINAPI IDirectSound3DListener_SetDopplerFactor(
	LPDIRECTSOUND3DLISTENER this,
	D3DVALUE fDopplerFactor,
	DWORD dwApply)
{
	FIXME(dsound,"stub\n");
	return DS_OK;
}

static HRESULT WINAPI IDirectSound3DListener_SetOrientation(
	LPDIRECTSOUND3DLISTENER this,
	D3DVALUE xFront, D3DVALUE yFront, D3DVALUE zFront,
	D3DVALUE xTop, D3DVALUE yTop, D3DVALUE zTop,
	DWORD dwApply)
{
	FIXME(dsound,"stub\n");
	return DS_OK;
}

static HRESULT WINAPI IDirectSound3DListener_SetPosition(
	LPDIRECTSOUND3DLISTENER this,
	D3DVALUE x, D3DVALUE y, D3DVALUE z,
	DWORD dwApply)
{
	FIXME(dsound,"stub\n");
	return DS_OK;
}

static HRESULT WINAPI IDirectSound3DListener_SetRolloffFactor(
	LPDIRECTSOUND3DLISTENER this,
	D3DVALUE fRolloffFactor,
	DWORD dwApply)
{
	FIXME(dsound,"stub\n");
	return DS_OK;
}

static HRESULT WINAPI IDirectSound3DListener_SetVelocity(
	LPDIRECTSOUND3DLISTENER this,
	D3DVALUE x, D3DVALUE y, D3DVALUE z,
	DWORD dwApply)
{
	FIXME(dsound,"stub\n");
	return DS_OK;
}

static HRESULT WINAPI IDirectSound3DListener_CommitDeferredSettings(
	LPDIRECTSOUND3DLISTENER this)

{
	FIXME(dsound,"stub\n");
	return DS_OK;
}

IDirectSound3DListener_VTable ds3dlvt = {
	// IUnknown methods
	IDirectSound3DListener_QueryInterface,
	IDirectSound3DListener_AddRef,
	IDirectSound3DListener_Release,
	// IDirectSound3DListener methods
	IDirectSound3DListener_GetAllParameter,
	IDirectSound3DListener_GetDistanceFactor,
	IDirectSound3DListener_GetDopplerFactor,
	IDirectSound3DListener_GetOrientation,
	IDirectSound3DListener_GetPosition,
	IDirectSound3DListener_GetRolloffFactor,
	IDirectSound3DListener_GetVelocity,
	IDirectSound3DListener_SetAllParameters,
	IDirectSound3DListener_SetDistanceFactor,
	IDirectSound3DListener_SetDopplerFactor,
	IDirectSound3DListener_SetOrientation,
	IDirectSound3DListener_SetPosition,
	IDirectSound3DListener_SetRolloffFactor,
	IDirectSound3DListener_SetVelocity,
	IDirectSound3DListener_CommitDeferredSettings,
};

/*******************************************************************************
 *		IDirectSoundNotify
 */
static HRESULT WINAPI IDirectSoundNotify_QueryInterface(
	LPDIRECTSOUNDNOTIFY this,REFIID riid,LPVOID *ppobj
) {
	char xbuf[50];

	WINE_StringFromCLSID(riid,xbuf);
	TRACE(dsound,"(%p,%s,%p)\n",this,xbuf,ppobj);
	return E_FAIL;
}

static ULONG WINAPI IDirectSoundNotify_AddRef(LPDIRECTSOUNDNOTIFY this) {
	return ++(this->ref);
}

static ULONG WINAPI IDirectSoundNotify_Release(LPDIRECTSOUNDNOTIFY this) {
	this->ref--;
	if (!this->ref) {
		this->dsb->lpvtbl->fnRelease(this->dsb);
		HeapFree(GetProcessHeap(),0,this);
		return 0;
	}
	return this->ref;
}

static int _sort_notifies(const void *a,const void *b) {
	LPDSBPOSITIONNOTIFY	na = (LPDSBPOSITIONNOTIFY)a;
	LPDSBPOSITIONNOTIFY	nb = (LPDSBPOSITIONNOTIFY)b;

	return na->dwOffset-nb->dwOffset;
}

static HRESULT WINAPI IDirectSoundNotify_SetNotificationPositions(
	LPDIRECTSOUNDNOTIFY this,DWORD howmuch,LPCDSBPOSITIONNOTIFY notify
) {
	int	i;

	if (TRACE_ON(dsound)) {
	    TRACE(dsound,"(%p,0x%08lx,%p)\n",this,howmuch,notify);
	    for (i=0;i<howmuch;i++)
		    TRACE(dsound,"notify at %ld to 0x%08lx\n",
                            notify[i].dwOffset,(DWORD)notify[i].hEventNotify);
	}
	this->dsb->notifies = HeapReAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,this->dsb->notifies,(this->dsb->nrofnotifies+howmuch)*sizeof(DSBPOSITIONNOTIFY));
	memcpy(	this->dsb->notifies+this->dsb->nrofnotifies,
		notify,
		howmuch*sizeof(DSBPOSITIONNOTIFY)
	);
	this->dsb->nrofnotifies+=howmuch;
	qsort(this->dsb->notifies,this->dsb->nrofnotifies,sizeof(DSBPOSITIONNOTIFY),_sort_notifies);
	return 0;
}

IDirectSoundNotify_VTable dsnvt = {
	IDirectSoundNotify_QueryInterface,
	IDirectSoundNotify_AddRef,
	IDirectSoundNotify_Release,
	IDirectSoundNotify_SetNotificationPositions,
};

/*******************************************************************************
 *		IDirectSoundBuffer
 */

// This sets this format for the <em>Primary Buffer Only</em>
// See file:///cdrom/sdk52/docs/worddoc/dsound.doc page 120
static HRESULT WINAPI IDirectSoundBuffer_SetFormat(
	LPDIRECTSOUNDBUFFER this,LPWAVEFORMATEX wfex
) {
	LPDIRECTSOUNDBUFFER	*dsb;
	int			i;

	if (primarybuf->wfx.nSamplesPerSec != wfex->nSamplesPerSec) {
		dsb = dsound->buffers;
		for (i = 0; i < dsound->nrofbuffers; i++, dsb++)
			(*dsb)->freqAdjust = ((*dsb)->freq << 14) / wfex->nSamplesPerSec;
	}

	memcpy(&(primarybuf->wfx),wfex,sizeof(primarybuf->wfx));
	TRACE(dsound,"(%p,%p)\n", this,wfex);
	TRACE(dsound,"(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);
	
	if (this->dsbd.dwFlags & DSBCAPS_PRIMARYBUFFER) {
		this->wfx.nAvgBytesPerSec =
			this->wfx.nSamplesPerSec * this->wfx.nBlockAlign;
		DSOUND_CloseAudio();
		return DS_OK;
	}

	return 0;
}

static HRESULT WINAPI IDirectSoundBuffer_SetVolume(
	LPDIRECTSOUNDBUFFER this,LONG vol
) {
	double	temp;

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

	// I'm not sure if we need this for primary buffer
	if (!(this->dsbd.dwFlags & DSBCAPS_CTRLVOLUME))
		return DSERR_CONTROLUNAVAIL;

	if ((vol > DSBVOLUME_MAX) || (vol < DSBVOLUME_MIN))
		return DSERR_INVALIDPARAM;

	// This needs to adjust the soundcard volume when
	// called for the primary buffer
	if (this->dsbd.dwFlags & DSBCAPS_PRIMARYBUFFER) {
		FIXME(dsound, "Volume control of primary unimplemented.\n");
		this->volume = vol;
		return DS_OK;
	}

	this->volume = vol;

	temp = (double) (this->volume + (this->pan < 0 ? this->pan : 0));
	this->lVolAdjust = (ULONG) (pow(2.0, temp / 600.0) * 65536.0);
	temp = (double) (this->volume - (this->pan > 0 ? this->pan : 0));
	this->rVolAdjust = (ULONG) (pow(2.0, temp / 600.0) * 65536.0);

	TRACE(dsound, "left = %lx, right = %lx\n", this->lVolAdjust, this->rVolAdjust);

	return DS_OK;
}

static HRESULT WINAPI IDirectSoundBuffer_GetVolume(
	LPDIRECTSOUNDBUFFER this,LPLONG vol
) {
	TRACE(dsound,"(%p,%p)\n",this,vol);
	*vol = this->volume;
	return 0;
}

static HRESULT WINAPI IDirectSoundBuffer_SetFrequency(
	LPDIRECTSOUNDBUFFER this,DWORD freq
) {
	TRACE(dsound,"(%p,%ld)\n",this,freq);

	// You cannot set the frequency of the primary buffer
	if (!(this->dsbd.dwFlags & DSBCAPS_CTRLFREQUENCY) ||
	    (this->dsbd.dwFlags & DSBCAPS_PRIMARYBUFFER))
		return DSERR_CONTROLUNAVAIL;

	if ((freq < DSBFREQUENCY_MIN) || (freq > DSBFREQUENCY_MAX))
		return DSERR_INVALIDPARAM;

	this->freq = freq;
	this->freqAdjust = (freq << 14) / primarybuf->wfx.nSamplesPerSec;
	this->nAvgBytesPerSec = freq * (this->wfx.wBitsPerSample >> 3) * this->wfx.nChannels;

	return DS_OK;
}

static HRESULT WINAPI IDirectSoundBuffer_Play(
	LPDIRECTSOUNDBUFFER this,DWORD reserved1,DWORD reserved2,DWORD flags
) {
	TRACE(dsound,"(%p,%08lx,%08lx,%08lx)\n",
		this,reserved1,reserved2,flags
	);
	this->playflags = flags;
	this->playing = 1;
	return 0;
}

static HRESULT WINAPI IDirectSoundBuffer_Stop(LPDIRECTSOUNDBUFFER this) {
	TRACE(dsound,"(%p)\n",this);
	this->playing = 0;
	return 0;
}

static DWORD WINAPI IDirectSoundBuffer_AddRef(LPDIRECTSOUNDBUFFER this) {
//	TRACE(dsound,"(%p) ref was %ld\n",this, this->ref);

	return ++(this->ref);
}
static DWORD WINAPI IDirectSoundBuffer_Release(LPDIRECTSOUNDBUFFER this) {
	int	i;

//	TRACE(dsound,"(%p) ref was %ld\n",this, this->ref);

	if (--this->ref)
		return this->ref;
	for (i=0;i<this->dsound->nrofbuffers;i++)
		if (this->dsound->buffers[i] == this)
			break;
	if (i < this->dsound->nrofbuffers) {
		/* Put the last buffer of the list in the (now empty) position */
		this->dsound->buffers[i] = this->dsound->buffers[this->dsound->nrofbuffers - 1];
		this->dsound->buffers = HeapReAlloc(GetProcessHeap(),0,this->dsound->buffers,sizeof(LPDIRECTSOUNDBUFFER)*this->dsound->nrofbuffers);
		this->dsound->nrofbuffers--;
		this->dsound->lpvtbl->fnRelease(this->dsound);
	}

	if (this->ds3db && this->ds3db->lpvtbl)
		this->ds3db->lpvtbl->fnRelease(this->ds3db);
	HeapFree(GetProcessHeap(),0,this->buffer);
	HeapFree(GetProcessHeap(),0,this);
	return 0;
}

static HRESULT WINAPI IDirectSoundBuffer_GetCurrentPosition(
	LPDIRECTSOUNDBUFFER this,LPDWORD playpos,LPDWORD writepos
) {
	TRACE(dsound,"(%p,%p,%p)\n",this,playpos,writepos);
	if (playpos) *playpos = this->playpos;
	if (writepos) *writepos = this->writepos;
	return 0;
}

static HRESULT WINAPI IDirectSoundBuffer_GetStatus(
	LPDIRECTSOUNDBUFFER this,LPDWORD status
) {
	TRACE(dsound,"(%p,%p)\n",this,status);
	*status = 0;
	if (this->playing)
		*status |= DSBSTATUS_PLAYING;
	if (this->playflags & DSBPLAY_LOOPING)
		*status |= DSBSTATUS_LOOPING;
	return 0;
}


static HRESULT WINAPI IDirectSoundBuffer_GetFormat(
	LPDIRECTSOUNDBUFFER this,LPWAVEFORMATEX lpwf,DWORD wfsize,LPDWORD wfwritten
) {
	TRACE(dsound,"(%p,%p,%ld,%p)\n",this,lpwf,wfsize,wfwritten);
	if (wfsize>sizeof(this->wfx))
		wfsize = sizeof(this->wfx);
	if (lpwf) {	// NULL is valid
		memcpy(lpwf,&(this->wfx),wfsize);
		if (wfwritten)
			*wfwritten = wfsize;
	} else
		if (wfwritten)
			*wfwritten = sizeof(this->wfx);
		else
			return DSERR_INVALIDPARAM;

	return 0;
}

static HRESULT WINAPI IDirectSoundBuffer_Lock(
	LPDIRECTSOUNDBUFFER this,DWORD writecursor,DWORD writebytes,LPVOID lplpaudioptr1,LPDWORD audiobytes1,LPVOID lplpaudioptr2,LPDWORD audiobytes2,DWORD flags
) {

	TRACE(dsound,"(%p,%ld,%ld,%p,%p,%p,%p,0x%08lx)\n",
		this,
		writecursor,
		writebytes,
		lplpaudioptr1,
		audiobytes1,
		lplpaudioptr2,
		audiobytes2,
		flags
	);
	if (flags & DSBLOCK_FROMWRITECURSOR)
		writecursor = this->writepos;
	if (flags & DSBLOCK_ENTIREBUFFER)
		writebytes = this->buflen;
	if (writebytes > this->buflen)
		writebytes = this->buflen;

	assert(audiobytes1!=audiobytes2);
	assert(lplpaudioptr1!=lplpaudioptr2);
	if (writecursor+writebytes <= this->buflen) {
		*(LPBYTE*)lplpaudioptr1 = this->buffer+writecursor;
		*audiobytes1 = writebytes;
		if (lplpaudioptr2)
			*(LPBYTE*)lplpaudioptr2 = NULL;
		if (audiobytes2)
			*audiobytes2 = 0;
		TRACE(dsound,"->%ld.0\n",writebytes);
	} else {
		*(LPBYTE*)lplpaudioptr1 = this->buffer+writecursor;
		*audiobytes1 = this->buflen-writecursor;
		if (lplpaudioptr2)
			*(LPBYTE*)lplpaudioptr2 = this->buffer;
		if (audiobytes2)
			*audiobytes2 = writebytes-(this->buflen-writecursor);
		TRACE(dsound,"->%ld.%ld\n",*audiobytes1,audiobytes2?*audiobytes2:0);
	}
	// No. See file:///cdrom/sdk52/docs/worddoc/dsound.doc page 21
	// this->writepos=(writecursor+writebytes)%this->buflen;
	return 0;
}

static HRESULT WINAPI IDirectSoundBuffer_SetCurrentPosition(
	LPDIRECTSOUNDBUFFER this,DWORD newpos
) {
	TRACE(dsound,"(%p,%ld)\n",this,newpos);
	this->playpos = newpos;
	return 0;
}

static HRESULT WINAPI IDirectSoundBuffer_SetPan(
	LPDIRECTSOUNDBUFFER this,LONG pan
) {
	double	temp;

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

	// What do we do if some moron uses SetPan with
	// a mono primary buffer?

	// You cannot set the pan of the primary buffer
	// and you cannot use both pan and 3D controls
	if (!(this->dsbd.dwFlags & DSBCAPS_CTRLPAN) ||
	    (this->dsbd.dwFlags & DSBCAPS_CTRL3D) ||
	    (this->dsbd.dwFlags & DSBCAPS_PRIMARYBUFFER))
		return DSERR_CONTROLUNAVAIL;

	if ((pan > DSBPAN_RIGHT) || (pan < DSBPAN_LEFT))
		return DSERR_INVALIDPARAM;

	this->pan = pan;
	
	temp = (double) (this->volume + (this->pan < 0 ? this->pan : 0));
	this->lVolAdjust = (ULONG) (pow(2.0, temp / 600.0) * 65536.0);
	temp = (double) (this->volume - (this->pan > 0 ? this->pan : 0));
	this->rVolAdjust = (ULONG) (pow(2.0, temp / 600.0) * 65536.0);

	return DS_OK;
}

static HRESULT WINAPI IDirectSoundBuffer_GetPan(
	LPDIRECTSOUNDBUFFER this,LPLONG pan
) {
	TRACE(dsound,"(%p,%p)\n",this,pan);
	*pan = this->pan;
	return 0;
}

static HRESULT WINAPI IDirectSoundBuffer_Unlock(
	LPDIRECTSOUNDBUFFER this,LPVOID p1,DWORD x1,LPVOID p2,DWORD x2
) {
	FIXME(dsound,"(%p,%p,%ld,%p,%ld):stub\n", this,p1,x1,p2,x2);
	this->writepos = this->playpos + (this->wfx.nAvgBytesPerSec >> 4);
	this->writepos %= this->buflen;

#if 0
	// This is highly experimental and liable to break things
	if (this->dsbd.dwFlags & DSBCAPS_CTRL3D)
		DSOUND_Create3DBuffer(this);
#endif
	return 0;
}

static HRESULT WINAPI IDirectSoundBuffer_GetFrequency(
	LPDIRECTSOUNDBUFFER this,LPDWORD freq
) {
	TRACE(dsound,"(%p,%p)\n",this,freq);
	*freq = this->freq;
	return 0;
}

static HRESULT WINAPI IDirectSoundBuffer_Initialize(
	LPDIRECTSOUNDBUFFER this,LPDIRECTSOUND dsound,LPDSBUFFERDESC dbsd
) {
	FIXME(dsound,"(%p,%p,%p):stub\n",this,dsound,dbsd);
	printf("Re-Init!!!\n");
	return DSERR_ALREADYINITIALIZED;
}

static HRESULT WINAPI IDirectSoundBuffer_GetCaps(
	LPDIRECTSOUNDBUFFER this,LPDSBCAPS caps
) {
  	TRACE(dsound,"(%p)->(%p)\n",this,caps);
  
	caps->dwSize = sizeof(*caps);
	caps->dwFlags = this->dsbd.dwFlags | DSBCAPS_LOCSOFTWARE;
	caps->dwBufferBytes = this->dsbd.dwBufferBytes;
	/* 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 */
	caps->dwUnlockTransferRate = 4096;
	caps->dwPlayCpuOverhead = 0;
	
	return DS_OK;
}

static HRESULT WINAPI IDirectSoundBuffer_QueryInterface(
	LPDIRECTSOUNDBUFFER this,REFIID riid,LPVOID *ppobj
) {
	char	xbuf[50];

	WINE_StringFromCLSID(riid,xbuf);
	TRACE(dsound,"(%p,%s,%p)\n",this,xbuf,ppobj);

	if (!memcmp(&IID_IDirectSoundNotify,riid,sizeof(*riid))) {
		IDirectSoundNotify	*dsn;

		dsn = (LPDIRECTSOUNDNOTIFY)HeapAlloc(GetProcessHeap(),0,sizeof(*dsn));
		dsn->ref = 1;
		dsn->dsb = this;
		this->lpvtbl->fnAddRef(this);
		dsn->lpvtbl = &dsnvt;
		*ppobj = (LPVOID)dsn;
		return 0;
	}

	if (!memcmp(&IID_IDirectSound3DBuffer,riid,sizeof(*riid))) {
		*ppobj = this->ds3db;
		if (*ppobj)
			return DS_OK;
	}

	return E_FAIL;
}

static struct tagLPDIRECTSOUNDBUFFER_VTABLE dsbvt = {
	IDirectSoundBuffer_QueryInterface,
	IDirectSoundBuffer_AddRef,
	IDirectSoundBuffer_Release,
	IDirectSoundBuffer_GetCaps,
	IDirectSoundBuffer_GetCurrentPosition,
	IDirectSoundBuffer_GetFormat,
	IDirectSoundBuffer_GetVolume,
	IDirectSoundBuffer_GetPan,
        IDirectSoundBuffer_GetFrequency,
	IDirectSoundBuffer_GetStatus,
	IDirectSoundBuffer_Initialize,
	IDirectSoundBuffer_Lock,
	IDirectSoundBuffer_Play,
	IDirectSoundBuffer_SetCurrentPosition,
	IDirectSoundBuffer_SetFormat,
	IDirectSoundBuffer_SetVolume,
	IDirectSoundBuffer_SetPan,
	IDirectSoundBuffer_SetFrequency,
	IDirectSoundBuffer_Stop,
	IDirectSoundBuffer_Unlock
};

/*******************************************************************************
 *		IDirectSound
 */

static HRESULT WINAPI IDirectSound_SetCooperativeLevel(
	LPDIRECTSOUND this,HWND32 hwnd,DWORD level
) {
	FIXME(dsound,"(%p,%08lx,%ld):stub\n",this,(DWORD)hwnd,level);
	return 0;
}


static HRESULT WINAPI IDirectSound_CreateSoundBuffer(
	LPDIRECTSOUND this,LPDSBUFFERDESC dsbd,LPLPDIRECTSOUNDBUFFER ppdsb,LPUNKNOWN lpunk
) {
	LPWAVEFORMATEX	wfex = dsbd->lpwfxFormat;

	if (TRACE_ON(dsound)) {
		TRACE(dsound,"(%p,%p,%p,%p)\n",this,dsbd,ppdsb,lpunk);
		TRACE(dsound,"(size=%ld)\n",dsbd->dwSize);
		TRACE(dsound,"(flags=0x%08lx\n",dsbd->dwFlags);
		_dump_DSBCAPS(dsbd->dwFlags);
		TRACE(dsound,"(bufferbytes=%ld)\n",dsbd->dwBufferBytes);
		TRACE(dsound,"(lpwfxFormat=%p)\n",dsbd->lpwfxFormat);
	}

	if (wfex)
		TRACE(dsound,"(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);

	if (dsbd->dwFlags & DSBCAPS_PRIMARYBUFFER) {
		if (primarybuf) {
			*ppdsb = primarybuf;
			return DS_OK;
		} // Else create primarybuf
	}

	*ppdsb = (LPDIRECTSOUNDBUFFER)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(IDirectSoundBuffer));
	if (*ppdsb == NULL)
		return DSERR_OUTOFMEMORY;
	(*ppdsb)->ref =1;

	TRACE(dsound, "Created buffer at %p\n", *ppdsb);

	if (dsbd->dwFlags & DSBCAPS_PRIMARYBUFFER)
		(*ppdsb)->buflen = dsound->wfx.nAvgBytesPerSec;
	else
		(*ppdsb)->buflen = dsbd->dwBufferBytes;
	(*ppdsb)->buffer = (LPBYTE)HeapAlloc(GetProcessHeap(),0,(*ppdsb)->buflen);
	if ((*ppdsb)->buffer == NULL) {
		HeapFree(GetProcessHeap(),0,(*ppdsb));
		*ppdsb = NULL;
		return DSERR_OUTOFMEMORY;
	}
	(*ppdsb)->playpos = 0;
	(*ppdsb)->writepos = 0;
	(*ppdsb)->lpvtbl = &dsbvt;
	(*ppdsb)->dsound = this;
	(*ppdsb)->playing = 0;
	(*ppdsb)->lVolAdjust = (1 << 16);
	(*ppdsb)->rVolAdjust = (1 << 16);
	(*ppdsb)->freq = dsbd->lpwfxFormat->nSamplesPerSec;

	if (!(dsbd->dwFlags & DSBCAPS_PRIMARYBUFFER)) {
		(*ppdsb)->freqAdjust = ((*ppdsb)->freq << 14) /
			primarybuf->wfx.nSamplesPerSec;
		(*ppdsb)->nAvgBytesPerSec = (*ppdsb)->freq *
			(dsbd->lpwfxFormat->wBitsPerSample >> 3) *
			dsbd->lpwfxFormat->nChannels;
	}

	memcpy(&((*ppdsb)->dsbd),dsbd,sizeof(*dsbd));

	/* register buffer */
	if (!(dsbd->dwFlags & DSBCAPS_PRIMARYBUFFER)) {
		this->buffers = (LPDIRECTSOUNDBUFFER*)HeapReAlloc(GetProcessHeap(),0,this->buffers,sizeof(LPDIRECTSOUNDBUFFER)*(this->nrofbuffers+1));
		this->buffers[this->nrofbuffers] = *ppdsb;
		this->nrofbuffers++;
		this->lpvtbl->fnAddRef(this);
	}

	if (dsbd->lpwfxFormat && !(dsbd->dwFlags & DSBCAPS_PRIMARYBUFFER))
		memcpy(&((*ppdsb)->wfx), dsbd->lpwfxFormat,
		    sizeof((*ppdsb)->wfx));
	
#if 0
	if (dsbd->dwFlags & DSBCAPS_CTRL3D) {
		IDirectSound3DBuffer	*ds3db;

		ds3db = (LPDIRECTSOUND3DBUFFER)HeapAlloc(GetProcessHeap(),
			0,sizeof(*ds3db));
		ds3db->ref = 1;
		ds3db->dsb = (*ppdsb);
		ds3db->lpvtbl = &ds3dbvt;
		(*ppdsb)->ds3db = ds3db;
		ds3db->ds3db.dwSize = sizeof(DS3DBUFFER);
		ds3db->ds3db.vPosition.x = 0.0;
		ds3db->ds3db.vPosition.y = 0.0;
		ds3db->ds3db.vPosition.z = 0.0;
		ds3db->ds3db.vVelocity.x = 0.0;
		ds3db->ds3db.vVelocity.y = 0.0;
		ds3db->ds3db.vVelocity.z = 0.0;
		ds3db->ds3db.dwInsideConeAngle = DS3D_DEFAULTCONEANGLE;
		ds3db->ds3db.dwOutsideConeAngle = DS3D_DEFAULTCONEANGLE;
		ds3db->ds3db.vConeOrientation.x = 0.0;
		ds3db->ds3db.vConeOrientation.y = 0.0;
		ds3db->ds3db.vConeOrientation.z = 0.0;
		ds3db->ds3db.lConeOutsideVolume = DS3D_DEFAULTCONEOUTSIDEVOLUME;
		ds3db->ds3db.flMinDistance = DS3D_DEFAULTMINDISTANCE;
		ds3db->ds3db.flMaxDistance = DS3D_DEFAULTMAXDISTANCE;
		ds3db->ds3db.dwMode = DS3DMODE_NORMAL;
		ds3db->buflen = ((*ppdsb)->buflen * primarybuf->wfx.nBlockAlign) /
			(*ppdsb)->wfx.nBlockAlign;
		ds3db->buffer = HeapAlloc(GetProcessHeap(), 0, ds3db->buflen);
		if (ds3db->buffer == NULL) {
			ds3db->buflen = 0;
			ds3db->ds3db.dwMode = DS3DMODE_DISABLE;
		}
	}
#endif
	return DS_OK;
}

static HRESULT WINAPI IDirectSound_DuplicateSoundBuffer(
	LPDIRECTSOUND this,LPDIRECTSOUNDBUFFER pdsb,LPLPDIRECTSOUNDBUFFER ppdsb
) {
	TRACE(dsound,"(%p,%p,%p)\n",this,pdsb,ppdsb);

	*ppdsb = (LPDIRECTSOUNDBUFFER)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(IDirectSoundBuffer));

	(*ppdsb)->ref =1;
	(*ppdsb)->buffer = (LPBYTE)HeapAlloc(GetProcessHeap(),0,pdsb->buflen);
	memcpy((*ppdsb)->buffer,pdsb->buffer,pdsb->buflen);
	(*ppdsb)->buflen = pdsb->buflen;
	(*ppdsb)->playpos = 0;
	(*ppdsb)->writepos = 0;
	(*ppdsb)->lpvtbl = &dsbvt;
	(*ppdsb)->dsound = this;
	memcpy(&((*ppdsb)->wfx), &(pdsb->wfx), sizeof((*ppdsb)->wfx));
	/* register buffer */
	this->buffers = (LPDIRECTSOUNDBUFFER*)HeapReAlloc(GetProcessHeap(),0,this->buffers,sizeof(LPDIRECTSOUNDBUFFER)*(this->nrofbuffers+1));
	this->buffers[this->nrofbuffers] = *ppdsb;
	this->nrofbuffers++;
	this->lpvtbl->fnAddRef(this);
	return 0;
}


static HRESULT WINAPI IDirectSound_GetCaps(LPDIRECTSOUND this,LPDSCAPS caps) {
	TRACE(dsound,"(%p,%p)\n",this,caps);
	TRACE(dsound,"(flags=0x%08lx)\n",caps->dwFlags);

	caps->dwSize = sizeof(*caps);
	caps->dwFlags =
		DSCAPS_PRIMARYSTEREO |
		DSCAPS_PRIMARY16BIT |
		DSCAPS_SECONDARYSTEREO |
		DSCAPS_SECONDARY16BIT |
		DSCAPS_CONTINUOUSRATE;
	/* FIXME: query OSS */
	caps->dwMinSecondarySampleRate		= DSBFREQUENCY_MIN;
	caps->dwMaxSecondarySampleRate		= DSBFREQUENCY_MAX;

	caps->dwPrimaryBuffers			= 1;

	caps->dwMaxHwMixingAllBuffers		= 0;
	caps->dwMaxHwMixingStaticBuffers	= 0;
	caps->dwMaxHwMixingStreamingBuffers	= 0;

	caps->dwFreeHwMixingAllBuffers		= 0;
	caps->dwFreeHwMixingStaticBuffers	= 0;
	caps->dwFreeHwMixingStreamingBuffers	= 0;

	caps->dwMaxHw3DAllBuffers		= 0;
	caps->dwMaxHw3DStaticBuffers		= 0;
	caps->dwMaxHw3DStreamingBuffers		= 0;

	caps->dwFreeHw3DAllBuffers		= 0;
	caps->dwFreeHw3DStaticBuffers		= 0;
	caps->dwFreeHw3DStreamingBuffers	= 0;

	caps->dwTotalHwMemBytes			= 0;

	caps->dwFreeHwMemBytes			= 0;

	caps->dwMaxContigFreeHwMemBytes		= 0;

	caps->dwUnlockTransferRateHwBuffers	= 4096;	// But we have none...

	caps->dwPlayCpuOverheadSwBuffers	= 1;	// 1%

	return 0;
}

static ULONG WINAPI IDirectSound_AddRef(LPDIRECTSOUND this) {
	return ++(this->ref);
}

static ULONG WINAPI IDirectSound_Release(LPDIRECTSOUND this) {
	TRACE(dsound,"(%p), ref was %ld\n",this,this->ref);
	if (!--(this->ref)) {
		HeapFree(GetProcessHeap(),0,this);
		dsound = NULL;
		DSOUND_CloseAudio();
		return 0;
	}
	return this->ref;
}

static HRESULT WINAPI IDirectSound_SetSpeakerConfig(
	LPDIRECTSOUND this,DWORD config
) {
	FIXME(dsound,"(%p,0x%08lx):stub\n",this,config);
	return 0;
}

static HRESULT WINAPI IDirectSound_QueryInterface(
	LPDIRECTSOUND this,REFIID riid,LPVOID *ppobj
) {
	char xbuf[50];

	if (!memcmp(&IID_IDirectSound3DListener,riid,sizeof(*riid))) {

		if (this->listener) {
			*ppobj = this->listener;
			return DS_OK;
		}
		this->listener = (LPDIRECTSOUND3DLISTENER)HeapAlloc(
			GetProcessHeap(), 0, sizeof(*(this->listener)));
		this->listener->ref = 1;
		this->listener->lpvtbl = &ds3dlvt;
		this->lpvtbl->fnAddRef(this);
		this->listener->ds3dl.dwSize = sizeof(DS3DLISTENER);
		this->listener->ds3dl.vPosition.x = 0.0;
		this->listener->ds3dl.vPosition.y = 0.0;
		this->listener->ds3dl.vPosition.z = 0.0;
		this->listener->ds3dl.vVelocity.x = 0.0;
		this->listener->ds3dl.vVelocity.y = 0.0;
		this->listener->ds3dl.vVelocity.z = 0.0;
		this->listener->ds3dl.vOrientFront.x = 0.0;
		this->listener->ds3dl.vOrientFront.y = 0.0;
		this->listener->ds3dl.vOrientFront.z = 1.0;
		this->listener->ds3dl.vOrientTop.x = 0.0;
		this->listener->ds3dl.vOrientTop.y = 1.0;
		this->listener->ds3dl.vOrientTop.z = 0.0;
		this->listener->ds3dl.flDistanceFactor = DS3D_DEFAULTDISTANCEFACTOR;
		this->listener->ds3dl.flRolloffFactor = DS3D_DEFAULTROLLOFFFACTOR;
		this->listener->ds3dl.flDopplerFactor = DS3D_DEFAULTDOPPLERFACTOR;
		*ppobj = (LPVOID)this->listener;
		return DS_OK;
	}

	WINE_StringFromCLSID(riid,xbuf);
	TRACE(dsound,"(%p,%s,%p)\n",this,xbuf,ppobj);
	return E_FAIL;
}

static struct tagLPDIRECTSOUND_VTABLE dsvt = {
	IDirectSound_QueryInterface,
	IDirectSound_AddRef,
	IDirectSound_Release,
	IDirectSound_CreateSoundBuffer,
	IDirectSound_GetCaps,
	IDirectSound_DuplicateSoundBuffer,
	IDirectSound_SetCooperativeLevel,
	(void *)8,
        (void *)9,
        IDirectSound_SetSpeakerConfig,
        (void *)11
};

static int
DSOUND_setformat(LPWAVEFORMATEX wfex) {
	int	xx,channels,speed,format,nformat;

	// Race condition here...  called by DSOUND_thread() and SetFormat()
	if (!audioOK) {
		TRACE(dsound, "(%p) deferred\n", wfex);
		return 0;
	}
	switch (wfex->wFormatTag) {
	default:
		WARN(dsound,"unknown WAVE_FORMAT tag %d\n",wfex->wFormatTag);
		return DSERR_BADFORMAT;
	case WAVE_FORMAT_PCM:
		break;
	}
	if (wfex->wBitsPerSample==8)
		format = AFMT_U8;
	else
		format = AFMT_S16_LE;

	if (-1==ioctl(audiofd,SNDCTL_DSP_GETFMTS,&xx)) {
		perror("ioctl SNDCTL_DSP_GETFMTS");
		return -1;
	}
	if ((xx&format)!=format) {/* format unsupported */
		FIXME(dsound,"SNDCTL_DSP_GETFMTS: format not supported\n"); 
		return -1;
	}
	nformat = format;
	if (-1==ioctl(audiofd,SNDCTL_DSP_SETFMT,&nformat)) {
		perror("ioctl SNDCTL_DSP_SETFMT");
		return -1;
	}
	if (nformat!=format) {/* didn't work */
		FIXME(dsound,"SNDCTL_DSP_GETFMTS: format not set\n"); 
		return -1;
	}

	channels = wfex->nChannels-1;
	if (-1==ioctl(audiofd,SNDCTL_DSP_STEREO,&channels)) {
		perror("ioctl SNDCTL_DSP_STEREO");
		return -1;
	}
	speed = wfex->nSamplesPerSec;
	if (-1==ioctl(audiofd,SNDCTL_DSP_SPEED,&speed)) {
		perror("ioctl SNDCTL_DSP_SPEED");
		return -1;
	}
	TRACE(dsound,"(freq=%ld,channels=%d,bits=%d)\n",
		wfex->nSamplesPerSec,wfex->nChannels,wfex->wBitsPerSample
	);
	return 0;
}

static void DSOUND_CheckEvent(IDirectSoundBuffer *dsb, int len)
{
	int			i;
	DWORD			offset;
	LPDSBPOSITIONNOTIFY	event;

	if (dsb->nrofnotifies == 0)
		return;

	TRACE(dsound,"(%p)\n", dsb);
	for (i = 0; i < dsb->nrofnotifies; i++) {
		event = dsb->notifies + i;
		offset = event->dwOffset;
		if ((dsb->playpos + len) >= dsb->buflen)
			if ((offset <= (dsb->playpos + len - dsb->buflen)) ||
			    (offset > dsb->playpos)) {
				SetEvent(event->hEventNotify);
				TRACE(dsound,"signalled event %d\n", event->hEventNotify);
			}
		else
			if ((offset > dsb->playpos) || (offset <= (dsb->playpos + len))) {
				SetEvent(event->hEventNotify);
				TRACE(dsound,"signalled event %d\n", event->hEventNotify);
			}
	}
}

// This should be the correct way to do this.
// Anyone want to do the optimized assembly?
static inline short cvt8to16(char byte)
{
	short	s = 0, sbit = 1;
	char	cbit = 1;
	int	i;

	for (i = 0; i < 8; i++) {
		if (byte & cbit)
			s |= sbit;
		cbit <<= 1;
		sbit <<= 2;
	}
	if (byte < 0)
		s |= 0x8000;	// sign bit
	return s;
}

static inline char cvt16to8(short word)
{
	char	c = 0, cbit = 1;
	short	sbits = 3;
	int	i;

	for (i = 0; i < 7; i++) {
		if (word & sbits)
			c |= cbit;
		cbit <<= 1;
		sbits <<= 2;
	}
	if (word < 0)
		c |= 0x80;	// sign bit
	return c;
}

static inline void get_fields(const IDirectSoundBuffer *dsb, char *buf, int *fl, int *fr)
{
	short	*bufs = (short *) buf;

	// TRACE(dsound, "(%p)", buf);
	if ((dsb->wfx.wBitsPerSample == 8) && dsb->wfx.nChannels == 2) {
		*fl = cvt8to16(*buf);
		*fr = cvt8to16(*(buf + 1));
		return;
	}

	if ((dsb->wfx.wBitsPerSample == 16) && dsb->wfx.nChannels == 2) {
		*fl = *bufs;
		*fr = *(bufs + 1);
		return;
	}

	if ((dsb->wfx.wBitsPerSample == 8) && dsb->wfx.nChannels == 1) {
		*fr = *fl = cvt8to16(*buf);
		return;
	}

	if ((dsb->wfx.wBitsPerSample == 16) && dsb->wfx.nChannels == 1) {
		*fr = *fl = *bufs;
		return;
	}

	FIXME(dsound, "get_fields found an unsupported configuration\n");
	return;
}

static inline void set_fields(char *buf, int fl, int fr)
{
	short *bufs = (short *) buf;

	if ((primarybuf->wfx.wBitsPerSample == 8) && (primarybuf->wfx.nChannels == 2)) {
		*buf = cvt16to8(fl);
		*(buf + 1) = cvt16to8(fr);
		return;
	}

	if ((primarybuf->wfx.wBitsPerSample == 16) && (primarybuf->wfx.nChannels == 2)) {
		*bufs = fl;
		*(bufs + 1) = fr;
		return;
	}

	if ((primarybuf->wfx.wBitsPerSample == 8) && (primarybuf->wfx.nChannels == 1)) {
		*buf = cvt16to8((fl + fr) / 2);
		return;
	}

	if ((primarybuf->wfx.wBitsPerSample == 16) && (primarybuf->wfx.nChannels == 1)) {
		*bufs = (fl + fr) / 2;
		return;
	}
	FIXME(dsound, "set_fields found an unsupported configuration\n");
	return;
}

// Now with PerfectPitch (tm) technology
static void DSOUND_MixerNorm(IDirectSoundBuffer *dsb, char *buf, int len)
{
	int	i, ipos, fieldL, fieldR;
	char	*ibp, *obp;
	int	iAdvance = dsb->wfx.nBlockAlign;
	int	oAdvance = primarybuf->wfx.nBlockAlign;

	ibp = dsb->buffer + dsb->playpos;
	obp = buf;

	TRACE(dsound, "(%p, %p, %p), playpos=%8.8lx\n", dsb, ibp, obp, dsb->playpos);
	// Check for the best case
	if ((dsb->freq == primarybuf->wfx.nSamplesPerSec) &&
	    (dsb->wfx.wBitsPerSample == primarybuf->wfx.wBitsPerSample) &&
	    (dsb->wfx.nChannels == primarybuf->wfx.nChannels)) {
		TRACE(dsound, "(%p) Best case\n", dsb);
	    	if ((ibp + len) <= (char *)(dsb->buffer + dsb->buflen))
			memcpy(obp, ibp, len);
		else { // wrap
			memcpy(obp, ibp, dsb->buflen - dsb->playpos);
			memcpy(obp + (dsb->buflen - dsb->playpos),
			    dsb->buffer,
			    len - (dsb->buflen - dsb->playpos));
		}
		return;
	}
	
	// Check for same sample rate
	if (dsb->freq == primarybuf->wfx.nSamplesPerSec) {
		TRACE(dsound, "(%p) Same sample rate %ld = primary %ld\n", dsb,
			dsb->freq, primarybuf->wfx.nSamplesPerSec);
		for (i = 0; i < len; i += oAdvance) {
			get_fields(dsb, ibp, &fieldL, &fieldR);
			ibp += iAdvance;
			set_fields(obp, fieldL, fieldR);
			obp += oAdvance;
			if (ibp > (char *)(dsb->buffer + dsb->buflen))
				ibp = dsb->buffer;	// wrap
		}
		return;
	}

	// Mix in different sample rates
	//
	// New PerfectPitch(tm) Technology (c) 1998 Rob Riggs
	// Patent Pending :-]
	for (i = 0; i < len; i += oAdvance) {

		ipos = (iAdvance * ((i * dsb->freqAdjust) >> 14)) + dsb->playpos;

		if (ipos >= dsb->buflen)
			ipos %= dsb->buflen;	// wrap

		get_fields(dsb, (dsb->buffer + ipos), &fieldL, &fieldR);
		set_fields(obp, fieldL, fieldR);
		obp += oAdvance;
	}
	return;
}

static void DSOUND_MixerVol(IDirectSoundBuffer *dsb, char *buf, int len)
{
	int	i;
	char	*bpc;
	short	*bps;
	
	TRACE(dsound, "(%p) left = %lx, right = %lx\n", dsb,
		dsb->lVolAdjust, dsb->rVolAdjust);
	if ((!(dsb->dsbd.dwFlags & DSBCAPS_CTRLPAN) || (dsb->pan == 0)) &&
	    (!(dsb->dsbd.dwFlags & DSBCAPS_CTRLVOLUME) || (dsb->volume == 0)) &&
	    !(dsb->dsbd.dwFlags & DSBCAPS_CTRL3D))
		return;		// Nothing to do

	// If we end up with some bozo coder using panning or 3D sound
	// with a mono primary buffer, it could sound very weird using
	// this method. Oh well, tough patooties.

	for (i = 0; i < len; i += (primarybuf->wfx.wBitsPerSample >> 3)) {
		register int	val;

		switch (primarybuf->wfx.wBitsPerSample) {

		case 8:
			bpc = buf + i;
			val = *bpc;
			val = (val * (i & 1 ? dsb->rVolAdjust : dsb->lVolAdjust)) >> 16;
			*bpc = (char) val;
			break;
		case 16:
			bps = (short *) (buf + i);
			val = *bps;
			val = (val * (i & 1 ? dsb->rVolAdjust : dsb->lVolAdjust)) >> 16;
			*bps = (short) val;
			break;
		default:
			// Very ugly!
			FIXME(dsound, "MixerVol had a nasty error\n");
		}
	}		
}

#ifdef USE_DSOUND3D
static void DSOUND_Mixer3D(IDirectSoundBuffer *dsb, char *buf, int len)
{
	char	*ibp, *obp;
	DWORD	buflen, playpos;

	buflen = dsb->ds3db->buflen;
	playpos = (dsb->playpos * primarybuf->wfx.nBlockAlign) / dsb->wfx.nBlockAlign;
	ibp = dsb->ds3db->buffer + playpos;
	obp = buf;

	if (playpos > buflen) {
		FIXME(dsound, "Major breakage");
		return;
	}

	if (len <= (playpos + buflen))
		memcpy(obp, ibp, len);
	else { // wrap
		memcpy(obp, ibp, buflen - playpos);
		memcpy(obp + (buflen - playpos),
		    dsb->buffer,
		    len - (buflen - playpos));
	}
	return;
}
#endif

static DWORD DSOUND_MixInBuffer(IDirectSoundBuffer *dsb)
{
	int	i, len, ilen, temp, field;
	int	advance = primarybuf->wfx.wBitsPerSample >> 3;
	char	*buf, *ibuf, *obuf;
	short	*ibufs, *obufs;

	// The most we will use
	len = primarybuf->wfx.nAvgBytesPerSec >> 4;	// 60 ms
	len &= ~3;					// 4 byte alignment
	if (!(dsb->playflags & DSBPLAY_LOOPING)) {
		temp = ((primarybuf->wfx.nAvgBytesPerSec * dsb->buflen) /
			dsb->wfx.nAvgBytesPerSec) -
			((primarybuf->wfx.nAvgBytesPerSec * dsb->playpos) /
			dsb->nAvgBytesPerSec);
		len = (len > temp) ? temp : len;
	}

	ilen = (len * dsb->nAvgBytesPerSec) / primarybuf->wfx.nAvgBytesPerSec;
	
	if ((buf = ibuf = (char *) malloc(len)) == NULL)
		return 0;

	TRACE(dsound, "MixInBuffer (%p) len = %d\n", dsb, len);

	DSOUND_MixerNorm(dsb, ibuf, len);
	if ((dsb->dsbd.dwFlags & DSBCAPS_CTRLPAN) ||
	    (dsb->dsbd.dwFlags & DSBCAPS_CTRLVOLUME))
		DSOUND_MixerVol(dsb, ibuf, len);

	TRACE(dsound, "Mixing buffer - advance = %d\n", advance);
	obuf = primarybuf->buffer + primarybuf->playpos;
	for (i = 0; i < len; i += advance) {
		obufs = (short *) obuf;
		ibufs = (short *) ibuf;
		if (primarybuf->wfx.wBitsPerSample == 8) {
			field = (char) *ibuf;
			field += (char) *obuf;
			field = field > 127 ? 127 : field;
			field = field < -128 ? -128 : field;
			*obuf = (char) field;
		} else {
			field = *ibufs;
			field += *obufs;
			field = field > 32767 ? 32767 : field;
			field = field < -32768 ? -32768 : field;
			*obufs = field;
		}
		ibuf += advance;
		obuf += advance;
		if (obuf > (char *)(primarybuf->buffer + primarybuf->buflen))
			obuf = primarybuf->buffer;
	}
	free(buf);

	if (dsb->dsbd.dwFlags & DSBCAPS_CTRLPOSITIONNOTIFY)
		DSOUND_CheckEvent(dsb, len);

	dsb->playpos += ilen;
	dsb->writepos += ilen;
	
	if (dsb->playpos >= dsb->buflen) {
		if (!(dsb->playflags & DSBPLAY_LOOPING)) {
			dsb->playing = 0;
			dsb->writepos = 0;
			dsb->playpos = 0;
		} else
			dsb->playpos -= dsb->buflen;		// wrap
	}
	
	if (dsb->writepos > dsb->buflen)
		dsb->writepos -= dsb->buflen;

	return len;
}

static DWORD WINAPI DSOUND_MixPrimary(void)
{
	int			i, len, maxlen = 0;
	IDirectSoundBuffer	*dsb;

	for (i = dsound->nrofbuffers - 1; i >= 0; i--) {
		dsb = dsound->buffers[i];

		if (!dsb || !(dsb->lpvtbl))
			continue;
		dsb->lpvtbl->fnAddRef(dsb);
 		if (dsb->buflen && dsb->playing) {
			len = DSOUND_MixInBuffer(dsb);
			maxlen = len > maxlen ? len : maxlen;
		}
		dsb->lpvtbl->fnRelease(dsb);
	}
	
	if (maxlen > 0) {
		primarybuf->writepos += maxlen;
		if (primarybuf->writepos > primarybuf->buflen)
			primarybuf->writepos -= primarybuf->buflen;
	}
	
	return maxlen;
}

static int DSOUND_OpenAudio(void)
{
	int	audioFragment;

	if (primarybuf == NULL)
		return DSERR_OUTOFMEMORY;

	while (audiofd != -1)
		sleep(5);
	audiofd = open("/dev/audio",O_WRONLY);
	if (audiofd==-1) {
		perror("open /dev/audio");
		audiofd = -1;
		return DSERR_NODRIVER;
	}

	audioFragment=0x0002000c;
	if (-1==ioctl(audiofd,SNDCTL_DSP_SETFRAGMENT,&audioFragment))
		perror("ioctl SETFRAGMENT");

	audioOK = 1;
	DSOUND_setformat(&(primarybuf->wfx));

	return 0;
}

static void DSOUND_CloseAudio(void)
{
	audioOK = 0;	// race condition
	Sleep(5);
	close(audiofd);
	primarybuf->playpos = 0;
	primarybuf->writepos = primarybuf->wfx.nAvgBytesPerSec >> 4;
	memset(primarybuf->buffer, 0, primarybuf->buflen);
	audiofd = -1;
	TRACE(dsound, "Audio stopped\n");
}
	
static int DSOUND_WriteAudio(char *buf, int len)
{
	int	result, left = 0;

	while (left < len) {
		result = write(audiofd, buf + left, len - left);
		if (result == -1)
			if (errno == EINTR)
				continue;
			else
				return result;
		left += result;
	}
	return 0;
}

static DWORD WINAPI DSOUND_thread(LPVOID arg)
{
	int	maxlen = primarybuf->wfx.nAvgBytesPerSec >> 4;
	int	len;

	TRACE(dsound,"dsound is at pid %d\n",getpid());
	while (1) {
		if (!dsound) {
			WARN(dsound,"DSOUND thread giving up.\n");
			ExitThread(0);
		}
		if (getppid()==1) {
			WARN(dsound,"DSOUND father died? Giving up.\n");
			ExitThread(0);
		}
		/* RACE: dsound could be deleted */
		dsound->lpvtbl->fnAddRef(dsound);
		if (primarybuf == NULL) {		// Should never happen
			/* no soundbuffer yet... wait. */
			Sleep(100);
			dsound->lpvtbl->fnRelease(dsound);
			continue;
		}
		len = DSOUND_MixPrimary();
		if (primarybuf->playing)
			len = maxlen > len ? maxlen : len;
		if (len) {
			if (audioOK == 0)
				DSOUND_OpenAudio();
			if (primarybuf->playpos + len > primarybuf->buflen) {
				if (DSOUND_WriteAudio(
				    primarybuf->buffer + primarybuf->playpos,
				    primarybuf->buflen - primarybuf->playpos)
				    != 0) {
					perror("DSOUND_WriteAudio");
					ExitThread(0);
				}
				memset(primarybuf->buffer + primarybuf->playpos, 0,
				    primarybuf->buflen - primarybuf->playpos);
				if (DSOUND_WriteAudio(primarybuf->buffer,
				    len - (primarybuf->buflen - primarybuf->playpos)) != 0) {
					perror("DSOUND_WriteAudio");
					ExitThread(0);
				}
				memset(primarybuf->buffer, 0,
				    len - (primarybuf->buflen - primarybuf->playpos));
			} else {
				if (DSOUND_WriteAudio(
				    primarybuf->buffer + primarybuf->playpos,
				    len) != 0) {
					perror("DSOUND_WriteAudio");
					ExitThread(0);
				}
				memset(primarybuf->buffer + primarybuf->playpos, 0, len);
			}
			primarybuf->playpos += len;
			if (primarybuf->playpos >= primarybuf->buflen)
				primarybuf->playpos -= primarybuf->buflen;
			primarybuf->writepos = primarybuf->playpos + maxlen;
			if (primarybuf->writepos >= primarybuf->buflen)
				primarybuf->writepos -= primarybuf->buflen;
		} else {
			/* no soundbuffer. close and wait. */
			if (audioOK)
				DSOUND_CloseAudio();
			Sleep(100);
		}
		dsound->lpvtbl->fnRelease(dsound);
	}
	ExitThread(0);
}

#endif /* HAVE_OSS */

HRESULT WINAPI DirectSoundCreate(LPGUID lpGUID,LPDIRECTSOUND *ppDS,IUnknown *pUnkOuter )
{
	if (lpGUID)
		TRACE(dsound,"(%p,%p,%p)\n",lpGUID,ppDS,pUnkOuter);
	else
		TRACE(dsound,"DirectSoundCreate\n");
#ifdef HAVE_OSS
	if (primarybuf)
		return DSERR_ALLOCATED;

	*ppDS = (LPDIRECTSOUND)HeapAlloc(GetProcessHeap(),0,sizeof(IDirectSound));
	(*ppDS)->ref		= 1;
	(*ppDS)->lpvtbl		= &dsvt;
	(*ppDS)->buffers	= NULL;
	(*ppDS)->nrofbuffers	= 0;

	(*ppDS)->wfx.wFormatTag		= 1;
	(*ppDS)->wfx.nChannels		= 2;
	(*ppDS)->wfx.nSamplesPerSec	= 22050;
	(*ppDS)->wfx.nAvgBytesPerSec	= 44100;
	(*ppDS)->wfx.nBlockAlign	= 2;
	(*ppDS)->wfx.wBitsPerSample	= 8;

	if (!dsound) {
		HANDLE32	hnd;
		DWORD		xid;

		dsound = (*ppDS);
		if (primarybuf == NULL) {
			DSBUFFERDESC	dsbd;
			HRESULT		hr;

			dsbd.dwSize = sizeof(DSBUFFERDESC);
			dsbd.dwFlags = DSBCAPS_PRIMARYBUFFER;
			dsbd.dwBufferBytes = 0;
			dsbd.lpwfxFormat = &(dsound->wfx);
			hr = IDirectSound_CreateSoundBuffer(*ppDS, &dsbd, &primarybuf, NULL);
			if (hr != DS_OK) {
				dsound->primary = primarybuf;
				return hr;
			}
		}
		
		hnd = CreateThread(NULL,0,DSOUND_thread,0,0,&xid);
	}
	return 0;
#else
	MessageBox32A(0,"DirectSound needs the Open Sound System Driver, which has not been found by ./configure.","WINE DirectSound",MB_OK|MB_ICONSTOP);
	return DSERR_NODRIVER;
#endif
}


/*******************************************************************************
 * DllGetClassObject [DSOUND.4]
 * Retrieves class object from a DLL object
 *
 * NOTES
 *    Docs say returns STDAPI
 *
 * PARAMS
 *    rclsid [I] CLSID for the class object
 *    riid   [I] Reference to identifier of interface for class object
 *    ppv    [O] Address of variable to receive interface pointer for riid
 *
 * RETURNS
 *    Success: S_OK
 *    Failure: CLASS_E_CLASSNOTAVAILABLE, E_OUTOFMEMORY, E_INVALIDARG,
 *             E_UNEXPECTED
 */
DWORD WINAPI DllGetClassObject( REFCLSID rclsid, REFIID riid, LPVOID *ppv )
{
    FIXME(dsound, "(%p,%p,%p): stub\n", rclsid, riid, ppv);
    return S_OK;
}


/*******************************************************************************
 * DllCanUnloadNow [DSOUND.3]  Determines whether the DLL is in use.
 *
 * RETURNS
 *    Success: S_OK
 *    Failure: S_FALSE
 */
DWORD WINAPI DllCanUnloadNow(void)
{
    FIXME(dsound, "(void): stub\n");
    return S_FALSE;
}
