#include "app.h" #ifndef _XBOX #pragma warning (disable:4201) #include #include #endif static IDirectSound *DSound=NULL; static IDirectSoundBuffer *LoopBuffer=NULL; static int LoopLen=0,LoopWrite=0; // Next position in loop to write short *DSoundNext=NULL; // Buffer for next sound data to put in loop static int LoopBlank() { void *mema=NULL,*memb=NULL; DWORD sizea=0,sizeb=0; LoopBuffer->Lock(0,LoopLen<<((PicoOpt&8) ? 2 : 1), &mema,&sizea, &memb,&sizeb, 0); if (mema) memset(mema,0,sizea); LoopBuffer->Unlock(mema,sizea, memb,sizeb); return 0; } int DSoundInit() { DSBUFFERDESC dsbd; WAVEFORMATEX wfx; memset(&dsbd,0,sizeof(dsbd)); memset(&wfx,0,sizeof(wfx)); // Make wave format: wfx.wFormatTag=WAVE_FORMAT_PCM; wfx.nChannels=(unsigned short)((PicoOpt&8) ? 2 : 1); // Stereo/mono wfx.nSamplesPerSec=PsndRate; wfx.wBitsPerSample=16; wfx.nBlockAlign=(WORD)((wfx.nChannels*wfx.wBitsPerSample)>>3); wfx.nAvgBytesPerSec=wfx.nBlockAlign*wfx.nSamplesPerSec; // Make buffer for the next seg to put into the loop: DSoundNext=(short *)malloc((PsndLen<<2)+64); if (DSoundNext==NULL) return 1; memset(DSoundNext,0,PsndLen<<2); // lprintf("p %p\n", DSoundNext); // Create the DirectSound interface: DirectSoundCreate(NULL,&DSound,NULL); if (DSound==NULL) return 1; LoopLen=PsndLen<<1; // 2 segs #ifndef _XBOX LoopLen<<=1; // 4 segs DSound->SetCooperativeLevel(FrameWnd,DSSCL_PRIORITY); dsbd.dwFlags=DSBCAPS_GLOBALFOCUS; // Play in background #endif // Create the looping buffer: dsbd.dwSize=sizeof(dsbd); dsbd.dwBufferBytes=LoopLen<CreateSoundBuffer(&dsbd,&LoopBuffer,NULL); if (LoopBuffer==NULL) return 1; LoopBlank(); LoopBuffer->Play(0,0,DSBPLAY_LOOPING); return 0; } void DSoundExit() { if (LoopBuffer) LoopBuffer->Stop(); RELEASE(LoopBuffer) RELEASE(DSound) DSound=0; if (DSoundNext) free(DSoundNext); DSoundNext=NULL; } static int WriteSeg() { void *mema=NULL,*memb=NULL; DWORD sizea=0,sizeb=0; int ret; // Lock the segment at 'LoopWrite' and copy the next segment in ret = LoopBuffer->Lock(LoopWrite<<((PicoOpt&8) ? 2 : 1),PsndLen<<((PicoOpt&8) ? 2 : 1), &mema,&sizea, &memb,&sizeb, 0); if (ret) lprintf("LoopBuffer->Lock() failed: %i\n", ret); if (mema) memcpy(mema,DSoundNext,sizea); // if (memb) memcpy(memb,DSoundNext+sizea,sizeb); if (sizeb != 0) lprintf("sizeb is not 0! (%i)\n", sizeb); ret = LoopBuffer->Unlock(mema,sizea, memb,0); if (ret) lprintf("LoopBuffer->Unlock() failed: %i\n", ret); return 0; } static int DSoundFake() { static int ticks_old = 0; int ticks = GetTickCount() * 1000; int diff; diff = ticks - ticks_old; if (diff >= 0 && diff < 1000000/60*4) { while (diff >= 0 && diff < 1000000/60) { Sleep(1); diff = GetTickCount()*1000 - ticks_old; } ticks_old += 1000000/60; } else ticks_old = ticks; return 0; } int DSoundUpdate() { DWORD play=0; int pos=0; if (LoopBuffer==NULL) return DSoundFake(); LoopBuffer->GetCurrentPosition(&play,NULL); pos=play>>((PicoOpt&8) ? 2 : 1); // 'LoopWrite' is the next seg in the loop that we want to write // First check that the sound 'play' pointer has moved out of it: if (pos>=LoopWrite && posLoopLen) LoopWrite=0; return 0; }