#include "main.h"
#include <string.h>
int volume;
bool stopped;
bool loop;
LPDIRECTSOUND ds = NULL;
LPDIRECTSOUNDBUFFER song = NULL;
void delete_wave( LPDIRECTSOUNDBUFFER buf )
{
if ( buf == NULL )
return;
buf->lpVtbl->Release(buf);
}
LPDIRECTSOUNDBUFFER init_buffer( DWORD bytes )
{
HRESULT hr;
WAVEFORMATEX wfx;
ZeroMemory( &wfx, sizeof(WAVEFORMATEX));
wfx.wFormatTag = (WORD) WAVE_FORMAT_PCM;
wfx.nChannels = 1;
wfx.nSamplesPerSec = 22050;
wfx.wBitsPerSample = 8;
wfx.nBlockAlign = (WORD) (wfx.wBitsPerSample / 8 * wfx.nChannels);
wfx.nAvgBytesPerSec = (DWORD) (wfx.nSamplesPerSec * wfx.nBlockAlign);
DSBUFFERDESC dsbd;
ZeroMemory( &dsbd, sizeof(DSBUFFERDESC) );
dsbd.dwSize = sizeof(DSBUFFERDESC);
dsbd.dwFlags = DSBCAPS_CTRLVOLUME;
dsbd.dwBufferBytes = bytes;
dsbd.lpwfxFormat = &wfx;
LPDIRECTSOUNDBUFFER buffer = NULL;
hr = ds->lpVtbl->CreateSoundBuffer(ds, &dsbd, &buffer, NULL );
buffer->lpVtbl->SetFormat(buffer, &wfx);
if FAILED(hr)
return NULL;
return buffer;
}
LPDIRECTSOUNDBUFFER load_wave_from_file( LPSTR file, DWORD bytes )
{
if ( !file || file[0] == '\0' )
return NULL;
HMMIO wve = NULL;
wve = mmioOpen( file, NULL, MMIO_READ );
if ( wve == NULL )
{
mmioClose( wve, 0 );
return NULL;
}
VOID* locked = NULL; DWORD lsize = 0; LPDIRECTSOUNDBUFFER buf = init_buffer(bytes);
if ( buf == NULL )
{
mmioClose( wve, 0);
return NULL;
}
HRESULT hr;
hr = buf->lpVtbl->Lock(buf, 0, bytes, &locked, &lsize, NULL, NULL, DSBLOCK_ENTIREBUFFER);
if FAILED(hr)
{
delete_wave(buf);
mmioClose( wve, 0 );
return NULL;
}
mmioSeek( wve, 0, SEEK_SET);
int rt;
rt = mmioRead( wve, (HPSTR)locked, (LONG)bytes );
if ( rt == 0 )
lsize = bytes;
else if ( rt == -1 )
{
delete_wave(buf);
mmioClose( wve, 0 );
return NULL;
}
buf->lpVtbl->Unlock(buf, locked, lsize, NULL, 0 );
mmioClose( wve, 0 );
return buf;
}
void play_wave( LPDIRECTSOUNDBUFFER buf, bool loop )
{
if ( buf == NULL )
return;
if ( loop == TRUE )
buf->lpVtbl->Play(buf,0,0,DSBPLAY_LOOPING);
else
buf->lpVtbl->Play(buf,0,0,0);
stopped = FALSE;
}
void stop_wave( LPDIRECTSOUNDBUFFER buf )
{
if ( buf == NULL )
return;
buf->lpVtbl->Stop(buf);
stopped = TRUE;
}
void set_volume( LPDIRECTSOUNDBUFFER buf, LONG amount )
{
if ( buf == NULL )
return;
if ( amount > DSBVOLUME_MAX )
amount = DSBVOLUME_MAX;
else if ( amount < DSBVOLUME_MIN )
amount = DSBVOLUME_MIN;
volume = amount;
buf->lpVtbl->SetVolume(buf,amount);
}
bool init_dx( void )
{
bool ok = FALSE;
HWND hwnd = (HWND)GetForegroundWindow();
if ( DirectSoundCreate( 0, &ds, 0 ) == DS_OK )
if ( ds->lpVtbl->SetCooperativeLevel(ds,hwnd,DSSCL_PRIORITY) == DS_OK )
ok = TRUE;
if ( ok == TRUE )
{
loop = FALSE;
stopped = FALSE;
volume = -200;
wave = mmioOpen( SONG_FILE, NULL, MMIO_READ ); handle_dx(TRUE); return TRUE;
}
return FALSE;
}
LPDIRECTSOUNDBUFFER load_wave_from_resource( HGLOBAL mem, DWORD bytes )
{
if ( mem == NULL )
return NULL;
VOID* locked = NULL; DWORD lsize = 0; LPDIRECTSOUNDBUFFER buf = init_buffer(bytes);
if ( buf == NULL )
return NULL;
HRESULT hr;
hr = buf->lpVtbl->Lock(buf, 0, bytes, &locked, &lsize, NULL, NULL, DSBLOCK_ENTIREBUFFER);
if FAILED(hr)
{
delete_wave(buf);
return NULL;
}
BYTE *ptr;
ptr = mem;
memcpy(locked,&ptr[44],lsize);
buf->lpVtbl->Unlock(buf, locked, lsize, NULL, 0 );
return buf;
}
void handle_dx( bool restart )
{
if ( stopped == TRUE )
return;
static unsigned int seek_spot = 0;
LPDIRECTSOUNDBUFFER old = song; DWORD bytes = BUFFER_SIZE;
if ( restart == TRUE )
seek_spot = 0;
if ( seek_spot+bytes > SONG_BYTES )
bytes = SONG_BYTES-seek_spot; LPDIRECTSOUNDBUFFER d = init_buffer(bytes);
if ( wave == NULL )
{
mmioClose( wave, 0 );
return;
}
VOID* locked = NULL; DWORD lsize = 0; if ( d == NULL )
{
mmioClose( wave, 0);
return;
}
HRESULT hr;
hr = d->lpVtbl->Lock(d, 0, bytes, &locked, &lsize, NULL, NULL, DSBLOCK_ENTIREBUFFER);
if FAILED(hr)
{
delete_wave(d);
mmioClose( wave, 0 );
return;
}
mmioSeek( wave, seek_spot, SEEK_SET);
int rt = mmioRead( wave, (HPSTR)locked, (LONG)bytes );
if ( rt == 0 )
lsize = bytes;
else if ( rt == -1 )
{
delete_wave(d);
mmioClose( wave, 0 );
return;
}
d->lpVtbl->Unlock(d, locked, lsize, NULL, 0 );
seek_spot += bytes;
song = d; set_volume( song, volume );
play_wave(song,FALSE);
delete_wave(old);
if ( (bytes != BUFFER_SIZE) && (loop == TRUE)) seek_spot = 0;
else if ( (bytes != BUFFER_SIZE) )
{
stopped = TRUE;
printf( "\n\nDone playing, restart to hear again. Looping is off...\n\n" );
}
}