/*  			DirectSound
 * 
 * Copyright 1998 Marcus Meissner
 */
/*
 * 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"

#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

static int audiofd = -1;
static LPDIRECTSOUND	dsound = NULL;

static short playbuf[2048];

#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);
}

/*******************************************************************************
 *		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
 */
static HRESULT WINAPI IDirectSoundBuffer_SetFormat(
	LPDIRECTSOUNDBUFFER this,LPWAVEFORMATEX wfex
) {

	memcpy(&(this->wfx),wfex,sizeof(this->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);

	return 0;
}

static HRESULT WINAPI IDirectSoundBuffer_SetVolume(
	LPDIRECTSOUNDBUFFER this,LONG vol
) {
	TRACE(dsound,"(%p,%ld)\n",this,vol);
	this->volume = vol;
	this->volfac = ((double)vol+10000.0)/10000.0;

	return 0;
}

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);
	this->wfx.nSamplesPerSec = freq;
	this->wfx.nAvgBytesPerSec = freq*this->wfx.nChannels*(this->wfx.wBitsPerSample/8);
	return 0;
}

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->playpos = 0;
	this->playflags = flags;
	this->playing = 1;
	return 0;
}

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

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

	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) {
		memcpy(
			this->dsound->buffers+i,
			this->dsound->buffers+i+1,
			sizeof(LPDIRECTSOUNDBUFFER)*(this->dsound->nrofbuffers-i-1)
		);
		this->dsound->buffers = HeapReAlloc(GetProcessHeap(),0,this->dsound->buffers,sizeof(LPDIRECTSOUNDBUFFER)*this->dsound->nrofbuffers);
		this->dsound->nrofbuffers--;
		this->dsound->lpvtbl->fnRelease(this->dsound);
	}
	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);
	memcpy(lpwf,&(this->wfx),wfsize);
	if (wfwritten) *wfwritten = wfsize;
	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;
	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);
	}
	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 newpan
) {
	TRACE(dsound,"(%p,%ld)\n",this,newpan);
	this->pan = newpan;
	return 0;
}

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); */
	return 0;
}

static HRESULT WINAPI IDirectSoundBuffer_GetFrequency(
	LPDIRECTSOUNDBUFFER this,LPDWORD freq
) {
	TRACE(dsound,"(%p,%p)\n",this,freq);
	*freq = this->wfx.nSamplesPerSec;
	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
) {
	caps->dwSize = sizeof(*caps);
	caps->dwFlags = DSBCAPS_PRIMARYBUFFER|DSBCAPS_STATIC|DSBCAPS_CTRLALL|DSBCAPS_LOCSOFTWARE;
	caps->dwBufferBytes = 0;
	caps->dwUnlockTransferRate = 0;
	caps->dwPlayCpuOverhead = 0;
	return DS_OK;
}

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

	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;
	}
	WINE_StringFromCLSID(riid,xbuf);
	TRACE(dsound,"(%p,%s,%p)\n",this,xbuf,ppobj);
	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
) {
	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);
	}
	*ppdsb = (LPDIRECTSOUNDBUFFER)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(IDirectSoundBuffer));
	(*ppdsb)->ref =1;
	(*ppdsb)->buffer = (LPBYTE)HeapAlloc(GetProcessHeap(),0,dsbd->dwBufferBytes);
	(*ppdsb)->buflen = dsbd->dwBufferBytes;
	(*ppdsb)->playpos = 0;
	(*ppdsb)->writepos = 0;
	(*ppdsb)->lpvtbl = &dsbvt;
	(*ppdsb)->dsound = this;
	(*ppdsb)->playing = 0;
	(*ppdsb)->volfac = 1.0;
	memcpy(&((*ppdsb)->dsbd),dsbd,sizeof(*dsbd));

	/* 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);

	if (dsbd->lpwfxFormat) dsbvt.fnSetFormat(*ppdsb,dsbd->lpwfxFormat);
	return 0;
}

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;
	dsbvt.fnSetFormat(*ppdsb,&(pdsb->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_EMULDRIVER|DSCAPS_SECONDARYSTEREO|DSCAPS_SECONDARY16BIT;
	/* FIXME: query OSS */
	caps->dwMinSecondarySampleRate = 22050;
	caps->dwMaxSecondarySampleRate = 48000;
	caps->dwPrimaryBuffers = 1;
	/* FIXME: set the rest... hmm */
	return 0;
}

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

static ULONG WINAPI IDirectSound_Release(LPDIRECTSOUND this) {
	if (!--(this->ref)) {
		HeapFree(GetProcessHeap(),0,this);
		dsound = NULL;
		close(audiofd);audiofd = -1;
		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];

	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;


	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 */
		WARN(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 */
		WARN(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 LPDSBPOSITIONNOTIFY
DSOUND_nextevent(IDirectSoundBuffer *dsb) {
	int	i;

	if (dsb->nrofnotifies) {
		for (i=0;i<dsb->nrofnotifies;i++) {
			if (dsb->playpos<dsb->notifies[i].dwOffset)
				break;
		}
		if (i==dsb->nrofnotifies)
			i=0;
		return dsb->notifies+i;
	}
	return NULL;
}

#define CHECK_EVENT							\
	if (nextevent && (dsb->playpos == nextevent->dwOffset)) {	\
		SetEvent(nextevent->hEventNotify);			\
		TRACE(dsound,"signalled event %d\n",nextevent->hEventNotify);\
		nextevent = DSOUND_nextevent(dsb);			\
	}
		

static void 
DSOUND_MixInBuffer(IDirectSoundBuffer *dsb) {
	int	j,buflen = dsb->buflen;
	LPDSBPOSITIONNOTIFY	nextevent;
	int	xdiff = dsb->wfx.nSamplesPerSec-dsound->wfx.nSamplesPerSec;

	/* Insomnia - Going along with REAL author's style */
	long	Rvoldec, Lvoldec;
	long	pan = dsb->pan;
	long samp;	/* temporary sample workspace */

	{
		double	tmpr=dsb->volume-500;
		double  tmpl=tmpr;
		if(pan>0)  tmpl -= (double)pan;
		else  tmpr += (double)pan;
		tmpl /= 1000.0;
		tmpr /= 1000.0;
		tmpl = pow(2.0, tmpl);
		tmpr = pow(2.0, tmpr);
		tmpl *= 65536;	/* Set to the correct multiple times */
		tmpr *= 65536;	/* 65536 to be convenient for bit shifting */
		tmpl += 0.5;	/* Add .5 for rounding accuracy */
		tmpr += 0.5;
		Lvoldec = (long)tmpl;
		Rvoldec = (long)tmpr;
	}
	/* End Insomnia's mod */

	if (xdiff<0) xdiff=-xdiff;
	if (xdiff>1500) {
		WARN(dsound,"mixing in buffer of different frequency (%ld vs %ld), argh!\n",
                        dsb->wfx.nSamplesPerSec,dsound->wfx.nSamplesPerSec);
	}
	nextevent = DSOUND_nextevent(dsb);
/*	TRACE(dsound,"(%d.%d.%d.%d)\n",dsound->wfx.wBitsPerSample,dsb->wfx.wBitsPerSample,dsound->wfx.nChannels,dsb->wfx.nChannels);*/

	if (dsound->wfx.wBitsPerSample == 8) {
		char	*playbuf8 = (char*)playbuf;

		if (dsb->wfx.wBitsPerSample == 8) {
			unsigned char	*xbuf = (unsigned char*)(dsb->buffer);
			if (dsb->wfx.nChannels == 1) {
				for (j=0;j<sizeof(playbuf)/2;j++) {
			
					dsb->playpos=(dsb->playpos+1)%buflen;
					if (!dsb->playpos && !(dsb->playflags&DSBPLAY_LOOPING)) {
						dsb->playing = 0;
						dsb->playpos = buflen;
						return;
					}
					/* Insomnia- volume, panning, and correcting against wrap */
					/* Left Channel */
					samp = xbuf[dsb->playpos>>1];
					samp *= Lvoldec;
					samp >>= 16;
					samp += playbuf8[(j<<1)];
					if(samp > 127L)  samp = 127L;
					else if(samp < -128L)  samp = -128L;
					playbuf8[(j<<1)] = (short)samp;

					/* Right Channel */
					samp = xbuf[dsb->playpos>>1];
					samp *= Rvoldec;
					samp >>= 16;
					samp += playbuf8[(j<<1)+1];
					if(samp > 127L)  samp = 127L;
					else if(samp < -128L)  samp = -128L;
					playbuf8[(j<<1)+1] = (short)samp;
					/* End Insomnia's mod */

					CHECK_EVENT
				}
			} else {
				for (j=0;j<sizeof(playbuf);j++) {
					dsb->playpos=(dsb->playpos+1)%buflen;
					if (!dsb->playpos && !(dsb->playflags&DSBPLAY_LOOPING)) {
						dsb->playing = 0;
						dsb->playpos = buflen;
						return;
					}
					/* Insomnia- volume, panning, and correcting against wrap */
					samp = xbuf[dsb->playpos>>1];

					/* Right Channel */
					if(j&1) samp *= Rvoldec;
					/* Left Channel */
					else    samp *= Lvoldec;

					samp >>= 16;
					samp += playbuf8[j];
					if(samp > 127L)  samp = 127L;
					else if(samp < -128L)  samp = -128L;
					playbuf8[j] = (short)samp;
					/* End Insomnia's mod */

					CHECK_EVENT
				}
			}
		} else { /* 16 */
			short	*xbuf = (short*)(dsb->buffer);
			if (dsb->wfx.nChannels == 1) {
				for (j=0;j<sizeof(playbuf)/2;j++) {
					dsb->playpos=(dsb->playpos+2)%buflen;
					if (!dsb->playpos && !(dsb->playflags&DSBPLAY_LOOPING)) {
						dsb->playing = 0;
						dsb->playpos = buflen;
						return;
					}
					/* Insomnia- volume, panning, and correcting against wrap */
					/* Left Channel */
					samp = xbuf[dsb->playpos>>1];
					samp *= Lvoldec;
					samp >>= 24;
					samp += playbuf8[(j<<1)];
					if(samp > 127L)  samp = 127L;
					else if(samp < -128L)  samp = -128L;
					playbuf8[(j<<1)] = (short)samp;

					/* Right Channel */
					samp = xbuf[dsb->playpos>>1];
					samp *= Rvoldec;
					samp >>= 24;
					samp += playbuf8[(j<<1)+1];
					if(samp > 127L)  samp = 127L;
					else if(samp < -128L)  samp = -128L;
					playbuf8[(j<<1)+1] = (short)samp;
					/* End Insomnia's mod */

					CHECK_EVENT
				}
			} else {
				for (j=0;j<sizeof(playbuf);j++) {
					dsb->playpos=(dsb->playpos+2)%buflen;
					if (!dsb->playpos && !(dsb->playflags&DSBPLAY_LOOPING)) {
						dsb->playing = 0;
						dsb->playpos = buflen;
						return;
					}
					/* Insomnia- volume, panning, and correcting against wrap */
					samp = xbuf[dsb->playpos>>1];

					/* Right Channel */
					if(j&1) samp *= Rvoldec;
					/* Left Channel */
					else    samp *= Lvoldec;

					samp >>= 24;
					samp += playbuf8[j];
					if(samp > 127L)  samp = 127L;
					else if(samp < -128L)  samp = -128L;
					playbuf8[j] = (short)samp;
					/* End Insomnia's mod */

					CHECK_EVENT
				}
			}
		}
	} else { /* 16 bit */
		if (dsb->wfx.wBitsPerSample == 8) {
/*			unsigned char	*xbuf = (unsigned char*)(dsb->buffer); */
			char	*xbuf = dsb->buffer;
			if (dsb->wfx.nChannels == 1) {
				WARN(dsound,"Mixing 8-bit stereo into 16!!\n");
				for (j=0;j<sizeof(playbuf)/sizeof(playbuf[0])/2;j++) {
					dsb->playpos=(dsb->playpos+1)%buflen;
					if (!dsb->playpos && !(dsb->playflags&DSBPLAY_LOOPING)) {
						dsb->playing = 0;
						dsb->playpos = buflen;
						return;
					}
					/* Insomnia- volume, panning, and correcting against wrap */
					/* Left Channel */
					samp = xbuf[dsb->playpos>>1];
					samp *= Lvoldec;
					samp >>= 8;
					samp += playbuf[(j<<1)];
					if(samp > 32767L)  samp = 32767L;
					else if(samp < -32768L)  samp = -32768L;
					playbuf[(j<<1)] = (short)samp;

					/* Right Channel */
					samp = xbuf[dsb->playpos>>1];
					samp *= Rvoldec;
					samp >>= 8;
					samp += playbuf[(j<<1)+1];
					if(samp > 32767L)  samp = 32767L;
					else if(samp < -32768L)  samp = -32768L;
					playbuf[(j<<1)+1] = (short)samp;
					/* End Insomnia's mod */

					CHECK_EVENT
				}
			} else {
				for (j=0;j<sizeof(playbuf)/sizeof(playbuf[0]);j++) {
					dsb->playpos=(dsb->playpos+1)%buflen;
					if (!dsb->playpos && !(dsb->playflags&DSBPLAY_LOOPING)) {
						dsb->playing = 0;
						dsb->playpos = buflen;
						return;
					}
					/* Insomnia- volume, panning, and correcting against wrap */
					samp = xbuf[dsb->playpos>>1];

					/* Right Channel */
					if(j&1) samp *= Rvoldec;
					/* Left Channel */
					else    samp *= Lvoldec;

					samp >>= 8;
					samp += playbuf[j];
					if(samp > 32767L)  samp = 32767L;
					else if(samp < -32768L)  samp = -32768L;
					playbuf[j] = (short)samp;
					/* End Insomnia's mod */

					CHECK_EVENT
				}
			}
		} else { /* 16 */
			short	*xbuf = (short*)(dsb->buffer);
			if (dsb->wfx.nChannels == 1) {
				for (j=0;j<sizeof(playbuf)/sizeof(playbuf[0])/2;j++) {
					dsb->playpos=(dsb->playpos+2)%buflen;
					if (!dsb->playpos && !(dsb->playflags&DSBPLAY_LOOPING)) {
						dsb->playing = 0;
						dsb->playpos = buflen;
						return;
					}
					/* Insomnia- volume, panning, and correcting against wrap */
					/* Left Channel */
					samp = xbuf[dsb->playpos>>1];
					samp *= Lvoldec;
					samp >>= 16;
					samp += playbuf[(j<<1)];
					if(samp > 32767L)  samp = 32767L;
					else if(samp < -32768L)  samp = -32768L;
					playbuf[(j<<1)] = (short)samp;

					/* Right Channel */
					samp = xbuf[dsb->playpos>>1];
					samp *= Rvoldec;
					samp >>= 16;
					samp += playbuf[(j<<1)+1];
					if(samp > 32767L)  samp = 32767L;
					else if(samp < -32768L)  samp = -32768L;
					playbuf[(j<<1)+1] = (short)samp;
					/* End Insomnia's mod */

					CHECK_EVENT
				}
			} else {
				for (j=0;j<sizeof(playbuf)/sizeof(playbuf[0]);j++) {
					dsb->playpos=(dsb->playpos+2)%buflen;
					if (!dsb->playpos && !(dsb->playflags&DSBPLAY_LOOPING)) {
						dsb->playing = 0;
						dsb->playpos = buflen;
						return;
					}
					/* Insomnia- volume, panning, and correcting against wrap */
					samp = xbuf[dsb->playpos>>1];

					/* Right Channel */
					if(j&1) samp *= Rvoldec;
					/* Left Channel */
					else    samp *= Lvoldec;

					samp >>= 16;
					samp += playbuf[j];
					if(samp > 32767L)  samp = 32767L;
					else if(samp < -32768L)  samp = -32768L;
					playbuf[j] = (short)samp;
					/* End Insomnia's mod */

					CHECK_EVENT
				}
			}
		}
	}
}

static DWORD
DSOUND_thread(LPVOID arg) {
	int	res,i,curleft,playing,haveprimary = 0;

	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 (!dsound->nrofbuffers) {
			/* no soundbuffer yet... wait. */
			Sleep(1000);
			continue;
		}
		memset(playbuf,0,sizeof(playbuf));
		playing = 0;
		dsound->lpvtbl->fnAddRef(dsound); 
		haveprimary = 0;
		for (i=dsound->nrofbuffers;i--;) {
			IDirectSoundBuffer	*dsb = dsound->buffers[i];

			if (!dsb || !dsb->lpvtbl)
				continue;
			dsb->lpvtbl->fnAddRef(dsb);
			if (dsb->playing && dsb->buflen)
				playing++;
			if (dsb->dsbd.dwFlags & DSBCAPS_PRIMARYBUFFER) {
				haveprimary = 1;
				if (memcmp(&dsound->wfx,&(dsb->wfx),sizeof(dsound->wfx))) {
					DSOUND_setformat(&(dsb->wfx));
					memcpy(&dsound->wfx,&(dsb->wfx),sizeof(dsb->wfx));
				}
			}
			dsb->lpvtbl->fnRelease(dsb);
		}
		/* We have just one playbuffer, so use its format */
		if ((playing==1) && !haveprimary) {
			for (i=dsound->nrofbuffers;i--;) {
				IDirectSoundBuffer	*dsb = dsound->buffers[i];

				dsb->lpvtbl->fnAddRef(dsb);
				if (dsb->playing && dsb->buflen) {
					if (memcmp(&dsound->wfx,&(dsb->wfx),sizeof(dsound->wfx))) {
						DSOUND_setformat(&(dsb->wfx));
						memcpy(&dsound->wfx,&(dsb->wfx),sizeof(dsb->wfx));
					}
				}
				dsb->lpvtbl->fnRelease(dsb);
			}
		}
		for (i=dsound->nrofbuffers;i--;) {
			IDirectSoundBuffer	*dsb = dsound->buffers[i];

			if (!dsb || !dsb->lpvtbl)
				continue;
			dsb->lpvtbl->fnAddRef(dsb);
			if (dsb->buflen && dsb->playing) {
				playing++;
				DSOUND_MixInBuffer(dsb);
			}
			dsb->lpvtbl->fnRelease(dsb);
		}
		dsound->lpvtbl->fnRelease(dsound);

		/*fputc('0'+playing,stderr);*/
		curleft = 0;
		while (curleft < sizeof(playbuf)) {
			res = write(audiofd,(LPBYTE)playbuf+curleft,sizeof(playbuf)-curleft);
			if (res==-1) {
				if (errno==EINTR)
					continue;
				perror("write audiofd");
				ExitThread(0);
				break;
			}
			curleft+=res;
		}
	}
	ExitThread(0);
}

#endif /* HAVE_OSS */

HRESULT WINAPI DirectSoundCreate(LPGUID lpGUID,LPDIRECTSOUND *ppDS,IUnknown *pUnkOuter ) {
	int xx;
	if (lpGUID)
		TRACE(dsound,"(%p,%p,%p)\n",lpGUID,ppDS,pUnkOuter);
#ifdef HAVE_OSS
	if (audiofd>=0)
		return DSERR_ALLOCATED;
	audiofd = open("/dev/audio",O_WRONLY);
	if (audiofd==-1) {
		perror("open /dev/audio");
		audiofd=0;
		return DSERR_NODRIVER;
	}
	xx=0x0002000c;
	if (-1==ioctl(audiofd,SNDCTL_DSP_SETFRAGMENT,&xx))
		perror("ioctl SETFRAGMENT");
/*
	TRACE(dsound,"SETFRAGMENT. count is now %d, fragsize is %d\n",
		(xx>>16)+1,xx&0xffff
	);
 */

	*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;

	DSOUND_setformat(&((*ppDS)->wfx));

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

		dsound = (*ppDS);
		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;
}
