diff options
author | Matthew Hoops | 2012-06-10 21:23:28 -0400 |
---|---|---|
committer | Matthew Hoops | 2012-06-10 21:23:28 -0400 |
commit | 42f4fe359c16dfe5291e6274464b76168b117135 (patch) | |
tree | d08432d65c4784196906bb6c93fd0b86d67006cd /engines | |
parent | 264721a19405920a57fece9b5bd09d773055531c (diff) | |
download | scummvm-rg350-42f4fe359c16dfe5291e6274464b76168b117135.tar.gz scummvm-rg350-42f4fe359c16dfe5291e6274464b76168b117135.tar.bz2 scummvm-rg350-42f4fe359c16dfe5291e6274464b76168b117135.zip |
TONY: Convert FPSFX to our mixer code
Only thing missing is the hEndOfBuffer code, but this is a good start
Diffstat (limited to 'engines')
-rw-r--r-- | engines/tony/sound.cpp | 387 | ||||
-rw-r--r-- | engines/tony/sound.h | 22 |
2 files changed, 69 insertions, 340 deletions
diff --git a/engines/tony/sound.cpp b/engines/tony/sound.cpp index 2d4ff824f0..e63245586d 100644 --- a/engines/tony/sound.cpp +++ b/engines/tony/sound.cpp @@ -26,7 +26,10 @@ * Copyright (c) 1997-2003 Nayma Software */ -#include "audio/mixer.h" +#include "audio/audiostream.h" +#include "audio/decoders/adpcm.h" +#include "audio/decoders/raw.h" +#include "audio/decoders/wave.h" #include "common/textconsole.h" #include "tony/game.h" #include "tony/tony.h" @@ -182,7 +185,7 @@ void FPSOUND::GetMasterVolume(int *lpdwVolume) { /****************************************************************************\ * -* Function: FPSFX(LPDIRECTSOUND lpDS, bool bSoundOn); +* Function: FPSFX(bool bSoundOn); * * Description: Costruttore di default. *NON* bisogna dichiarare direttamente * un oggetto, ma crearlo piuttosto tramite FPSOUND::CreateSfx() @@ -190,40 +193,13 @@ void FPSOUND::GetMasterVolume(int *lpdwVolume) { \****************************************************************************/ FPSFX::FPSFX(bool bSoundOn) { -#ifdef REFACTOR_ME - - static char errbuf[128]; - - //hwnd=hWnd; bSoundSupported = bSoundOn; bFileLoaded = false; - bIsPlaying = false; - bPaused = false; - lpDSBuffer = NULL; - lpDSNotify = NULL; - lpDS = lpds; lastVolume = 63; hEndOfBuffer = CORO_INVALID_PID_VALUE; bIsVoice = false; - - if (bSoundSupported == false) - return; - - /* Poiché non abbiamo ancora nessun dato sull'effetto sonoro, non possiamo fare nulla */ -#else - bIsVoice = false; - lastVolume = 0; - dwFreq = 0; - hEndOfBuffer = CORO_INVALID_PID_VALUE; - bFileLoaded = false; - bSoundSupported = false; - bLoop = false; + _stream = 0; bPaused = false; - bStereo = false; - b16bit = false; - bIsPlaying = false; - bIsVoice = false; -#endif } @@ -238,21 +214,16 @@ FPSFX::FPSFX(bool bSoundOn) { \****************************************************************************/ FPSFX::~FPSFX() { -#ifdef REFACTOR_ME - if (!bSoundSupported) return; - if (bIsPlaying) - Stop(); - - RELEASE(lpDSNotify); + g_system->getMixer()->stopHandle(_handle); - if (hEndOfBuffer != CORO_INVALID_PID_VALUE) - CloseHandle(hEndOfBuffer); + delete _stream; - RELEASE(lpDSBuffer); -#endif + // FIXME + //if (hEndOfBuffer != CORO_INVALID_PID_VALUE) + // CloseHandle(hEndOfBuffer); } @@ -271,7 +242,6 @@ FPSFX::~FPSFX() { void FPSFX::Release() { delete this; -// return NULL; } @@ -291,87 +261,16 @@ void FPSFX::Release() { \****************************************************************************/ bool FPSFX::loadWave(Common::SeekableReadStream *stream) { -#ifdef REFACTOR_ME - static PCMWAVEFORMAT pcmwf; - static DSBUFFERDESC dsbdesc; - static HRESULT err; - static char errbuf[128]; - uint32 dwHi; - struct WAVH { - int nChunckSize; - uint16 wFormatTag; - uint16 nChannels; - int nSamplesPerSec; - int nAvgBytesPerSec; - uint16 nBlockAlign; - uint16 nBitsPerSample; - } *WAVHeader; - uint32 dwSize; - void *lpLock; - - if (!bSoundSupported) - return true; - - if (lpBuf[0] != 'W' || lpBuf[1] != 'A' || lpBuf[2] != 'V' || lpBuf[3] != 'E') - return false; - if (lpBuf[4] != 'f' || lpBuf[5] != 'm' || lpBuf[6] != 't' || lpBuf[7] != ' ') + if (!stream) return false; - WAVHeader = (WAVH *)(lpBuf + 8); - lpBuf += 8 + sizeof(WAVH); + _stream = Audio::makeWAVStream(stream, DisposeAfterUse::YES); - if (lpBuf[0] != 'd' || lpBuf[1] != 'a' || lpBuf[2] != 't' || lpBuf[3] != 'a') + if (!_stream) return false; - lpBuf += 4; - - dwSize = READ_LE_UINT32(lpBuf); - lpBuf += 4; - - b16bit = (WAVHeader->nBitsPerSample == 16); - bStereo = (WAVHeader->nChannels == 2); - dwFreq = WAVHeader->nSamplesPerSec; - - /* Setta le strutture necessarie per la creazione di un secondary buffer - Attiviamo inoltre il controllo del volume, in modo da poter abbassare - e alzare il volume della musica indipendentemente da quello generale. - Proviamo a buttarlo in sound ram. */ - pcmwf.wBitsPerSample = (b16bit ? 16 : 8); - pcmwf.wf.wFormatTag = WAVE_FORMAT_PCM; - pcmwf.wf.nChannels = (bStereo ? 2 : 1); - pcmwf.wf.nSamplesPerSec = dwFreq; - pcmwf.wf.nBlockAlign = (pcmwf.wBitsPerSample / 8) * pcmwf.wf.nChannels; - pcmwf.wf.nAvgBytesPerSec = (uint32)pcmwf.wf.nBlockAlign * (uint32)pcmwf.wf.nSamplesPerSec; - - dsbdesc.dwSize = sizeof(dsbdesc); - dsbdesc.dwFlags = DSBCAPS_CTRLVOLUME | DSBCAPS_GETCURRENTPOSITION2 | DSBCAPS_CTRLPOSITIONNOTIFY; - dsbdesc.dwBufferBytes = dwSize; - dsbdesc.lpwfxFormat = (LPWAVEFORMATEX)&pcmwf; - - if ((err = lpDS->CreateSoundBuffer(&dsbdesc, &lpDSBuffer, NULL)) != DS_OK) { - wsprintf(errbuf, "Error creating the secondary buffer (%lx)", err); - MessageBox(hwnd, errbuf, "FPSFX::FPSFX()", MB_OK); - return false; - } - - // Riempie il buffer - if ((err = lpDSBuffer->Lock(0, dwSize, &lpLock, (uint32 *)&dwHi, NULL, NULL, 0)) != DS_OK) { - MessageBox(hwnd, "Cannot lock sfx buffer!", "FPSFX::LoadFile()", MB_OK); - return false; - } - - /* Decomprime i dati dello stream direttamente dentro il buffer lockato */ - copyMemory(lpLock, lpBuf, dwSize); - - /* Unlocka il buffer */ - lpDSBuffer->Unlock(lpLock, dwSize, NULL, NULL); - - /* Setta volume iniziale */ - SetVolume(lastVolume); bFileLoaded = true; -#endif - - delete stream; // Just so we don't leak it + SetVolume(lastVolume); return true; } @@ -391,207 +290,59 @@ bool FPSFX::loadWave(Common::SeekableReadStream *stream) { \****************************************************************************/ bool FPSFX::LoadVoiceFromVDB(Common::File &vdbFP) { -#ifdef REFACTOR_ME - uint32 dwSize; - static PCMWAVEFORMAT pcmwf; - static DSBUFFERDESC dsbdesc; - byte *lpTempBuffer; - static HRESULT err; - uint32 dwHi; - void *lpBuf; - static char errbuf[128]; - if (!bSoundSupported) return true; - b16bit = true; - bStereo = false; + uint32 size = vdbFP.readUint32LE(); + uint32 rate = vdbFP.readUint32LE(); bIsVoice = true; -// fread(&dwSize,1,4,vdbFP); -// fread(&dwFreq,1,4,vdbFP); - ReadFile(vdbFP, &dwSize, 4, &dwHi, NULL); - ReadFile(vdbFP, &dwFreq, 4, &dwHi, NULL); - - dwSize *= 4; - - /* Setta le strutture necessarie per la creazione di un secondary buffer - Attiviamo inoltre il controllo del volume, in modo da poter abbassare - e alzare il volume della musica indipendentemente da quello generale. - Proviamo a buttarlo in sound ram. */ - pcmwf.wBitsPerSample = (b16bit ? 16 : 8); - pcmwf.wf.wFormatTag = WAVE_FORMAT_PCM; - pcmwf.wf.nChannels = (bStereo ? 2 : 1); - pcmwf.wf.nSamplesPerSec = dwFreq; - pcmwf.wf.nBlockAlign = (pcmwf.wBitsPerSample / 8) * pcmwf.wf.nChannels; - pcmwf.wf.nAvgBytesPerSec = (uint32)pcmwf.wf.nBlockAlign * (uint32)pcmwf.wf.nSamplesPerSec; - - dsbdesc.dwSize = sizeof(dsbdesc); - dsbdesc.dwFlags = DSBCAPS_CTRLVOLUME | DSBCAPS_GETCURRENTPOSITION2 | DSBCAPS_CTRLPOSITIONNOTIFY; - dsbdesc.dwBufferBytes = dwSize; - dsbdesc.lpwfxFormat = (LPWAVEFORMATEX)&pcmwf; - - if ((err = lpDS->CreateSoundBuffer(&dsbdesc, &lpDSBuffer, NULL)) != DS_OK) { - wsprintf(errbuf, "Error creating the secondary buffer (%lx)", err); - MessageBox(hwnd, errbuf, "FPSFX::FPSFX()", MB_OK); - return false; - } - - /* Alloca un buffer temporaneo */ - lpTempBuffer = (byte *)GlobalAlloc(GMEM_FIXED | GMEM_ZEROINIT, dwSize); - if (lpTempBuffer == NULL) - return false; - - lpCodec = new CODECADPCMMONO(bLoop, lpTempBuffer); - - /* Riempie il buffer */ - if ((err = lpDSBuffer->Lock(0, dwSize, &lpBuf, (uint32 *)&dwHi, NULL, NULL, 0)) != DS_OK) { - MessageBox(hwnd, "Cannot lock sfx buffer!", "FPSFX::LoadFile()", MB_OK); - return false; - } - - /* Decomprime i dati dello stream direttamente dentro il buffer lockato */ - lpCodec->Decompress(vdbFP, lpBuf, dwSize); + _stream = Audio::makeADPCMStream(vdbFP.readStream(size), DisposeAfterUse::YES, 0, Audio::kADPCMDVI, rate, 1); - /* Unlocka il buffer */ - lpDSBuffer->Unlock(lpBuf, dwSize, NULL, NULL); - - delete lpCodec; - - /* Crea il notify per avvertire quando raggiungiamo la fine della voce */ - err = lpDSBuffer->QueryInterface(IID_IDirectSoundNotify, (void **)&lpDSNotify); - if (FAILED(err)) { - wsprintf(errbuf, "Error creating notify object! (%lx)", err); - MessageBox(hwnd, errbuf, "FPSFX::LoadVoiceFromVDB()", MB_OK); - return false; - } - - hEndOfBuffer = CreateEvent(NULL, false, false, NULL); - - dspnHot[0].dwOffset = DSBPN_OFFSETSTOP; - dspnHot[0].hEventNotify = hEndOfBuffer; - - lpDSNotify->SetNotificationPositions(1, dspnHot); - - /* Tutto a posto, possiamo uscire */ bFileLoaded = true; SetVolume(62); - -#endif return true; } bool FPSFX::LoadFile(const char *lpszFileName, uint32 dwCodec) { -#ifdef REFACTOR_ME - static PCMWAVEFORMAT pcmwf; - static DSBUFFERDESC dsbdesc; - static HRESULT err; - static char errbuf[128]; - Common::File file; - uint32 dwSize; - byte *lpTempBuffer; - void *lpBuf; - uint32 dwHi; - struct { - char id[4]; - int freq; - int nChan; - } ADPHead; - if (!bSoundSupported) return true; - /* Apre il file di stream in lettura */ + Common::File file; if (!file.open(lpszFileName)) { - warning("FPSFX::LoadFile() : Cannot open sfx file!"); - return false; - } - - /* Leggiamo l'header */ - file.read(ADPHead.id, 4); - ADPHead.freq = file.readUint32LE(); - ADPHead.nChan = file.readUint32LE(); - - if (ADPHead.id[0] != 'A' || ADPHead.id[1] != 'D' || ADPHead.id[2] != 'P' || ADPHead.id[3] != 0x10) { - warning("FPSFX::LoadFile() : Invalid ADP header!"); - file.close(); + warning("FPSFX::LoadFile(): Cannot open sfx file!"); return false; } - b16bit = true; - bStereo = (ADPHead.nChan == 2); - dwFreq = ADPHead.freq; - - /* Si salva la lunghezza dello stream */ - dwSize = file.size() - 12 /*sizeof(ADPHead)*/; - file.seek(0); - - if (dwCodec == FPCODEC_ADPCM) - dwSize *= 4; - - /* Setta le strutture necessarie per la creazione di un secondary buffer - Attiviamo inoltre il controllo del volume, in modo da poter abbassare - e alzare il volume della musica indipendentemente da quello generale. - Proviamo a buttarlo in sound ram. */ - pcmwf.wBitsPerSample = (b16bit ? 16 : 8); - pcmwf.wf.wFormatTag = WAVE_FORMAT_PCM; - pcmwf.wf.nChannels = (bStereo ? 2 : 1); - pcmwf.wf.nSamplesPerSec = dwFreq; - pcmwf.wf.nBlockAlign = (pcmwf.wBitsPerSample / 8) * pcmwf.wf.nChannels; - pcmwf.wf.nAvgBytesPerSec = (uint32)pcmwf.wf.nBlockAlign * (uint32)pcmwf.wf.nSamplesPerSec; - - dsbdesc.dwSize = sizeof(dsbdesc); - dsbdesc.dwFlags = DSBCAPS_CTRLVOLUME | DSBCAPS_GETCURRENTPOSITION2 | DSBCAPS_CTRLPOSITIONNOTIFY; - dsbdesc.dwBufferBytes = dwSize; - dsbdesc.lpwfxFormat = (LPWAVEFORMATEX) & pcmwf; - - if ((err = lpDS->CreateSoundBuffer(&dsbdesc, &lpDSBuffer, NULL)) != DS_OK) { - wsprintf(errbuf, "Error creating the secondary buffer (%lx)", err); - MessageBox(hwnd, errbuf, "FPSFX::FPSFX()", MB_OK); + if (file.readUint32BE() != MKTAG('A', 'D', 'P', 0x10)) { + warning("FPSFX::LoadFile(): Invalid ADP header!"); return false; } - /* Alloca un buffer temporaneo */ - lpTempBuffer = (byte *)GlobalAlloc(GMEM_FIXED | GMEM_ZEROINIT, dwSize); - if (lpTempBuffer == NULL) - return false; + uint32 rate = file.readUint32LE(); + uint32 channels = file.readUint32LE(); - switch (dwCodec) { - case FPCODEC_RAW: - lpCodec = new CODECRAW(bLoop); - break; + Common::SeekableReadStream *buffer = file.readStream(file.size() - file.pos()); + Audio::RewindableAudioStream *stream; - case FPCODEC_ADPCM: - if (bStereo) - lpCodec = new CODECADPCMSTEREO(bLoop, lpTempBuffer); - else - lpCodec = new CODECADPCMMONO(bLoop, lpTempBuffer); - break; + if (dwCodec == FPCODEC_ADPCM) { + stream = Audio::makeADPCMStream(buffer, DisposeAfterUse::YES, 0, Audio::kADPCMDVI, rate, channels); + } else { + byte flags = Audio::FLAG_16BITS | Audio::FLAG_LITTLE_ENDIAN; - default: - return false; - G - } + if (channels == 2) + flags |= Audio::FLAG_STEREO; - /* Riempie il buffer */ - if ((err = lpDSBuffer->Lock(0, dwSize, &lpBuf, (uint32 *)&dwHi, NULL, NULL, 0)) != DS_OK) { - MessageBox(hwnd, "Cannot lock sfx buffer!", "FPSFX::LoadFile()", MB_OK); - return false; + stream = Audio::makeRawStream(buffer, rate, flags, DisposeAfterUse::YES); } - /* Decomprime i dati dello stream direttamente dentro il buffer lockato */ - lpCodec->Decompress(file, lpBuf, dwSize); - - /* Unlocka il buffer */ - lpDSBuffer->Unlock(lpBuf, dwSize, NULL, NULL); + if (bLoop) + _stream = Audio::makeLoopingAudioStream(stream, 0); + else + _stream = stream; - delete lpCodec; - file.close(); - - /* Tutto a posto, possiamo uscire */ bFileLoaded = true; -#endif return true; } @@ -607,19 +358,22 @@ bool FPSFX::LoadFile(const char *lpszFileName, uint32 dwCodec) { \****************************************************************************/ bool FPSFX::Play() { -#ifdef REFACTOR_ME + Stop(); // sanity check + if (bFileLoaded) { - if (hEndOfBuffer != CORO_INVALID_PID_VALUE) - ResetEvent(hEndOfBuffer); + // FIXME + //if (hEndOfBuffer != CORO_INVALID_PID_VALUE) + // ResetEvent(hEndOfBuffer); - lpDSBuffer->SetCurrentPosition(0); - bIsPlaying = true; + g_system->getMixer()->playStream(Audio::Mixer::kPlainSoundType, &_handle, _stream, -1, + Audio::Mixer::kMaxChannelVolume, 0, DisposeAfterUse::NO); - if (!bPaused) { - lpDSBuffer->Play(0, 0, (bLoop ? DSBPLAY_LOOPING : 0)); - } + SetVolume(lastVolume); + + if (bPaused) + g_system->getMixer()->pauseHandle(_handle, true); } -#endif + return true; } @@ -634,17 +388,12 @@ bool FPSFX::Play() { * \****************************************************************************/ -bool FPSFX::Stop(void) { -#ifdef REFACTOR_ME +bool FPSFX::Stop() { if (bFileLoaded) { - if (bPaused || bIsPlaying) { - lpDSBuffer->Stop(); - } - - bIsPlaying = false; + g_system->getMixer()->stopHandle(_handle); bPaused = false; } -#endif + return true; } @@ -671,21 +420,12 @@ void FPSFX::SetLoop(bool bLop) { } void FPSFX::Pause(bool bPause) { -#ifdef REFACTOR_ME if (bFileLoaded) { - if (bPause && bIsPlaying) { - lpDSBuffer->Stop(); - } else if (!bPause && bPaused) { - if (bIsPlaying && bLoop) - lpDSBuffer->Play(0, 0, (bLoop ? DSBPLAY_LOOPING : 0)); - } + if (g_system->getMixer()->isSoundHandleActive(_handle) && (bPause ^ bPaused)) + g_system->getMixer()->pauseHandle(_handle, bPause); - // Trucchetto per risettare il volume secondo le - // possibili nuove configurazioni sonore - SetVolume(lastVolume); bPaused = bPause; } -#endif } @@ -718,10 +458,9 @@ void FPSFX::SetVolume(int dwVolume) { if (dwVolume < 0) dwVolume = 0; } } -#ifdef REFACTOR_ME - if (bFileLoaded) - lpDSBuffer->SetVolume(dwVolume * (DSBVOLUME_MAX - DSBVOLUME_MIN) / 64 + DSBVOLUME_MIN); -#endif + + if (g_system->getMixer()->isSoundHandleActive(_handle)) + g_system->getMixer()->setChannelVolume(_handle, dwVolume * Audio::Mixer::kMaxChannelVolume / 63); } @@ -738,14 +477,10 @@ void FPSFX::SetVolume(int dwVolume) { \****************************************************************************/ void FPSFX::GetVolume(int *lpdwVolume) { -#ifdef REFACTOR_ME - if (bFileLoaded) - lpDSBuffer->GetVolume((uint32 *)lpdwVolume); - - *lpdwVolume -= (DSBVOLUME_MIN); - *lpdwVolume *= 64; - *lpdwVolume /= (DSBVOLUME_MAX - DSBVOLUME_MIN); -#endif + if (g_system->getMixer()->isSoundHandleActive(_handle)) + *lpdwVolume = g_system->getMixer()->getChannelVolume(_handle) * 63 / Audio::Mixer::kMaxChannelVolume; + else + *lpdwVolume = 0; } diff --git a/engines/tony/sound.h b/engines/tony/sound.h index be3c2da319..6ebf30f22b 100644 --- a/engines/tony/sound.h +++ b/engines/tony/sound.h @@ -29,11 +29,16 @@ #ifndef TONY_SOUND_H #define TONY_SOUND_H +#include "audio/mixer.h" #include "common/file.h" #include "tony/gfxcore.h" #include "tony/loc.h" #include "tony/utils.h" +namespace Audio { +class RewindableAudioStream; +} + namespace Tony { class FPSTREAM; @@ -181,27 +186,16 @@ class FPSFX { \****************************************************************************/ private: - /* - HWND hwnd; - LPDIRECTSOUND lpDS; - LPDIRECTSOUNDBUFFER lpDSBuffer; // Buffer DirectSound - */ bool bSoundSupported; // TRUE se il suono e' attivo bool bFileLoaded; // TRUE se e' stato aperto un file bool bLoop; // TRUE se bisogna loopare l'effetto sonoro - bool bPaused; int lastVolume; - bool bStereo; // TRUE se è stereo - bool b16bit; // TRUE se è 16 bit - uint32 dwFreq; // Frequenza originale di campionamento - - bool bIsPlaying; // TRUE se si sta playando l'effetto sonoro - bool bIsVoice; + bool bPaused; -// LPDIRECTSOUNDNOTIFY lpDSNotify; // Notify degli hotspot nel buffer -// DSBPOSITIONNOTIFY dspnHot[2]; + Audio::AudioStream *_stream; + Audio::SoundHandle _handle; public: uint32 hEndOfBuffer; |