aboutsummaryrefslogtreecommitdiff
path: root/engines
diff options
context:
space:
mode:
authorAlyssa Milburn2012-06-20 17:58:01 +0200
committerAlyssa Milburn2012-06-20 19:36:25 +0200
commit1ee68078c1272287db82f819f2fdc99c6fe04622 (patch)
tree6d5cb7c92e885bd1089e9514b4ef6d9eaf036747 /engines
parentaa775b4497746d978599dda06ca9a385c5e6dc59 (diff)
downloadscummvm-rg350-1ee68078c1272287db82f819f2fdc99c6fe04622.tar.gz
scummvm-rg350-1ee68078c1272287db82f819f2fdc99c6fe04622.tar.bz2
scummvm-rg350-1ee68078c1272287db82f819f2fdc99c6fe04622.zip
TONY: Replace the FPStream code.
This just removes the original code and replaces it with a quickly- written trivial implementation similar to clone2727's sfx code. It seems to at least sort of work. :-)
Diffstat (limited to 'engines')
-rw-r--r--engines/tony/sound.cpp937
-rw-r--r--engines/tony/sound.h32
-rw-r--r--engines/tony/tony.cpp2
3 files changed, 79 insertions, 892 deletions
diff --git a/engines/tony/sound.cpp b/engines/tony/sound.cpp
index 75ae82298d..b0a2c69fd6 100644
--- a/engines/tony/sound.cpp
+++ b/engines/tony/sound.cpp
@@ -36,401 +36,6 @@
namespace Tony {
-
-#define RELEASE(x) {if ((x) != NULL) { (x)->release(); x = NULL; }}
-
-
-/****************************************************************************\
-*****************************************************************************
-* class CODECRAW
-* --------------
-* Description: CODEC to play hard from pure samples
-*****************************************************************************
-\****************************************************************************/
-
-class CODECRAW : public CODEC {
-public:
- CODECRAW(bool _bLoop = true);
-
- virtual ~CODECRAW();
- virtual uint32 decompress(Common::SeekableReadStream *stream, void *lpBuf, uint32 dwSize);
- virtual void loopReset();
-};
-
-
-/****************************************************************************\
-*****************************************************************************
-* class CODECADPCM
-* ----------------
-* Description: Play ADPCM compressed data
-*****************************************************************************
-\****************************************************************************/
-
-class CODECADPCM : public CODECRAW {
-protected:
- byte *lpTemp;
- static const int indexTable[16];
- static const int stepSizeTable[89];
-
-public:
- CODECADPCM(bool _bLoop = true, byte *lpTempBuffer = NULL);
- virtual ~CODECADPCM();
- virtual uint32 decompress(Common::SeekableReadStream *stream, void *lpBuf, uint32 dwSize) = 0;
- virtual void loopReset() = 0;
-};
-
-class CODECADPCMSTEREO : public CODECADPCM {
-protected:
- int valpred[2], index[2];
-
-public:
- CODECADPCMSTEREO(bool _bLoop=true, byte *lpTempBuffer = NULL);
- virtual ~CODECADPCMSTEREO();
- virtual uint32 decompress(Common::SeekableReadStream *stream, void *lpBuf, uint32 dwSize);
- virtual void loopReset();
-};
-
-class CODECADPCMMONO : public CODECADPCM {
-protected:
- int valpred, index;
-
-public:
- CODECADPCMMONO(bool _bLoop = true, byte *lpTempBuffer = NULL);
- virtual ~CODECADPCMMONO();
- virtual uint32 decompress(Common::SeekableReadStream *stream, void *lpBuf, uint32 dwSize);
- virtual void loopReset();
-};
-
-/****************************************************************************\
-* CODEC Methods
-\****************************************************************************/
-
-/**
- * Standard cosntructor. It's possible to specify whether you want to
- * enable or disable the loop (which by default, and 'active).
- *
- * @param loop True if you want to loop, false to disable
- */
-CODEC::CODEC(bool loop) {
- _bLoop = loop;
- _bEndReached = false;
-}
-
-CODEC::~CODEC() {
-}
-
-/**
- * Tell whether we have reached the end of the stream
- *
- * @return True if we're done, false otherwise.
- */
-bool CODEC::endOfStream() {
- return _bEndReached;
-}
-
-
-/****************************************************************************\
-* CODECRAW Methods
-\****************************************************************************/
-
-/**
- * Standard cosntructor. Simply calls the inherited constructor
- */
-CODECRAW::CODECRAW(bool loop) : CODEC(loop) {
-}
-
-CODECRAW::~CODECRAW() {
-}
-
-/**
- * Reset the stream to the beginning of the file. In the case of RAW files, does nothing
- */
-void CODECRAW::loopReset() {
-}
-
-/**
- * Manage the RAW format. Simply copies the file's stream buffer
- *
- * @return Indicates the position of the file for the end of the loop
- */
-uint32 CODECRAW::decompress(Common::SeekableReadStream *stream, void *buf, uint32 dwSize) {
- byte *lpBuf = (byte *)buf;
- uint32 dwRead;
- uint32 dwEOF;
-
- _bEndReached = false;
- dwEOF = 0;
- dwRead = stream->read(lpBuf, dwSize);
-
- if (dwRead < dwSize) {
- dwEOF = dwRead;
- _bEndReached = true;
-
- if (!_bLoop) {
- Common::fill(lpBuf + dwRead, lpBuf + dwRead + (dwSize - dwRead), 0);
- } else {
- stream->seek(0);
- dwRead = stream->read(lpBuf + dwRead, dwSize - dwRead);
- }
- }
-
- return dwEOF;
-}
-
-/****************************************************************************\
-* CODECADPCM Methods
-\****************************************************************************/
-
-const int CODECADPCM::indexTable[16] = {
- -1, -1, -1, -1, 2, 4, 6, 8,
- -1, -1, -1, -1, 2, 4, 6, 8,
-};
-
-const int CODECADPCM::stepSizeTable[89] = {
- 7, 8, 9, 10, 11, 12, 13, 14, 16, 17,
- 19, 21, 23, 25, 28, 31, 34, 37, 41, 45,
- 50, 55, 60, 66, 73, 80, 88, 97, 107, 118,
- 130, 143, 157, 173, 190, 209, 230, 253, 279, 307,
- 337, 371, 408, 449, 494, 544, 598, 658, 724, 796,
- 876, 963, 1060, 1166, 1282, 1411, 1552, 1707, 1878, 2066,
- 2272, 2499, 2749, 3024, 3327, 3660, 4026, 4428, 4871, 5358,
- 5894, 6484, 7132, 7845, 8630, 9493, 10442, 11487, 12635, 13899,
- 15289, 16818, 18500, 20350, 22385, 24623, 27086, 29794, 32767
-};
-
-#define MAXDECODESIZE (44100 * 2 * 2)
-
-/**
- * Standard constructor. Initialises and allocates temporary memory tables
- */
-CODECADPCM::CODECADPCM(bool loop, byte *lpTempBuffer) : CODECRAW(loop) {
- // Alloca la memoria temporanea
- if (lpTempBuffer != NULL) {
- lpTemp = lpTempBuffer;
- } else {
- lpTemp = (byte *)globalAlloc(GMEM_FIXED | GMEM_ZEROINIT, MAXDECODESIZE);
-
- if (lpTemp == NULL) {
- error("Insufficient memory!");
- return;
- }
- }
-}
-
-
-CODECADPCMMONO::CODECADPCMMONO(bool loop, byte *lpTempBuffer) : CODECADPCM(loop,lpTempBuffer) {
- // Inizializza per il playing
- loopReset();
-}
-
-CODECADPCMMONO::~CODECADPCMMONO() {
-}
-
-
-CODECADPCMSTEREO::CODECADPCMSTEREO(bool loop, byte *lpTempBuffer) : CODECADPCM(loop, lpTempBuffer) {
- // Initialise for playing
- loopReset();
-}
-
-CODECADPCMSTEREO::~CODECADPCMSTEREO() {
-}
-
-/**
- * Destructor. Free the buffer
- */
-CODECADPCM::~CODECADPCM() {
- globalDestroy(lpTemp);
-}
-
-
-/**
- * Reset the player before each play or loop
- */
-void CODECADPCMSTEREO::loopReset() {
- valpred[0] = 0;
- valpred[1] = 0;
- index[0] = 0;
- index[1] = 0;
-}
-
-void CODECADPCMMONO::loopReset() {
- valpred = 0;
- index = 0;
-}
-
-
-/**
- * Manages decompressing the ADPCM 16:4 format.
- */
-uint32 CODECADPCMMONO::decompress(Common::SeekableReadStream *stream, void *buf, uint32 dwSize) {
- uint16 *lpBuf = (uint16 *)buf;
- byte *inp;
- int bufferstep;
- int cache = 0;
- int delta;
- int sign;
- int vpdiff;
- uint32 eof, i;
- int step;
-
- bufferstep = 1;
- step = stepSizeTable[index];
-
- // Invokes the raw codec to read the stream from disk to loop.
- eof = CODECRAW::decompress(stream, lpTemp, dwSize / 4);
- inp = lpTemp;
-
- eof *= 2;
-
- // If you must do an immediate loop
- if (endOfStream() && eof == 0) {
- loopReset();
- bufferstep = 1;
- step = stepSizeTable[index];
- } else if (!endOfStream())
- eof = 0;
-
- dwSize /= 2;
- for (i = 0; i < dwSize; i++) {
- // Check if we are at the end of the file, and are looping
- if (eof != 0 && i == eof) {
- loopReset();
- bufferstep=1;
- step = stepSizeTable[index];
- }
-
- // Read the delta (4 bits)
- if (bufferstep) {
- cache = *inp++;
- delta = (cache >> 4) & 0xF;
- } else
- delta = cache & 0xF;
-
- // Find the new index
- index += indexTable[delta];
- if (index < 0) index = 0;
- if (index > 88) index = 88;
-
- // Reads the sign and separates it
- sign = delta & 8;
- delta = delta & 7;
-
- // Find the difference from the previous value
- vpdiff = step >> 3;
- if (delta & 4) vpdiff += step;
- if (delta & 2) vpdiff += step >> 1;
- if (delta & 1) vpdiff += step >> 2;
-
- if (sign)
- valpred -= vpdiff;
- else
- valpred += vpdiff;
-
- // Check the limits of the found value
- if (valpred > 32767)
- valpred = 32767;
- else if (valpred < -32768)
- valpred = -32768;
-
- // Update the step
- step = stepSizeTable[index];
-
- // Write the value found
- *lpBuf++ = (uint16)valpred;
-
- bufferstep = !bufferstep;
- }
-
- return eof / 2;
-}
-
-uint32 CODECADPCMSTEREO::decompress(Common::SeekableReadStream *stream, void *buf, uint32 dwSize) {
- uint16 *lpBuf=(uint16 *)buf;
- byte *inp;
- int bufferstep;
- int cache = 0;
- int delta;
- int sign;
- int vpdiff;
- uint32 eof, i;
- int step[2];
-
- bufferstep = 1;
- step[0] = stepSizeTable[index[0]];
- step[1] = stepSizeTable[index[1]];
-
- // Invokes the RAW codec to read the stream from disk.
- eof = CODECRAW::decompress(stream, lpTemp, dwSize / 4);
- inp = lpTemp;
-
- eof *= 2;
-
- // If you must do an immediate loop
- if (endOfStream() && eof == 0) {
- loopReset();
- bufferstep = 1;
- step[0] = stepSizeTable[index[0]];
- step[1] = stepSizeTable[index[1]];
-
- } else if (!endOfStream())
- eof = 0;
-
- dwSize /= 2;
-
- for (i = 0;i < dwSize; i++) {
- // If you must do an immediate loop
- if (eof != 0 && i == eof) {
- loopReset();
- bufferstep = 1;
- step[0] = stepSizeTable[index[0]];
- step[1] = stepSizeTable[index[1]];
- }
-
- // Reads the delta (4 bits)
- if (bufferstep) {
- cache = *inp++;
- delta = cache & 0xF;
- } else
- delta = (cache >> 4) & 0xF;
-
- // Find the new index
- index[bufferstep] += indexTable[delta];
- if (index[bufferstep] < 0) index[bufferstep] = 0;
- if (index[bufferstep] > 88) index[bufferstep] = 88;
-
- // Reads the sign and separates it
- sign = delta & 8;
- delta = delta & 7;
-
- // Find the difference from the previous value
- vpdiff = step[bufferstep] >> 3;
- if (delta & 4) vpdiff += step[bufferstep];
- if (delta & 2) vpdiff += step[bufferstep] >> 1;
- if (delta & 1) vpdiff += step[bufferstep] >> 2;
-
- if (sign)
- valpred[bufferstep] -= vpdiff;
- else
- valpred[bufferstep] += vpdiff;
-
- // Check the limits of the value
- if (valpred[bufferstep] > 32767)
- valpred[bufferstep] = 32767;
- else if (valpred[bufferstep] < -32768)
- valpred[bufferstep] =- 32768;
-
- // Update the step
- step[bufferstep] = stepSizeTable[index[bufferstep]];
-
- // Write the found value
- *lpBuf++ = (uint16)valpred[bufferstep];
-
- bufferstep = !bufferstep;
- }
-
- return eof / 2;
-}
-
/****************************************************************************\
* FPSOUND Methods
\****************************************************************************/
@@ -818,94 +423,17 @@ void FPSfx::soundCheckProcess(CORO_PARAM, const void *param) {
* create it using FPSound::CreateStream()
*/
FPStream::FPStream(bool bSoundOn) {
-#ifdef REFACTOR_ME
- hwnd=hWnd;
- lpDS = LPDS;
- _lpDSBuffer = NULL;
- _lpDSNotify = NULL;
-#endif
_bSoundSupported = bSoundOn;
_bFileLoaded = false;
- _bIsPlaying = false;
_bPaused = false;
_bLoop = false;
_bDoFadeOut = false;
_bSyncExit = false;
- _hHot1 = _hHot2 = _hHot3 = CORO_INVALID_PID_VALUE;
- _hPlayThread = _hPlayThreadPlayFast = _hPlayThreadPlayNormal = CORO_INVALID_PID_VALUE;
- _hThreadEnd = CORO_INVALID_PID_VALUE;
_dwBufferSize = _dwSize = 0;
- _dwCodec = 0;
_lastVolume = 0;
- _lpTempBuffer = NULL;
_syncToPlay = NULL;
- _codec = NULL;
-}
-
-bool FPStream::createBuffer(int nBufSize) {
-#ifdef REFACTOR_ME
- static PCMWAVEFORMAT pcmwf;
- static DSBUFFERDESC dsbdesc;
- static HRESULT err;
- static char errbuf[128];
-
- if (bSoundSupported == false)
- return true;
-
- /* Set the required structures for the creation of a secondary buffer for the stream containing exactly 1 second of music.
- Also activate the volume control, in order to lower and raise the volume of the music regardless of the general volume.
- Obviously it is a buffer in RAM */
-
- pcmwf.wBitsPerSample = 16;
- pcmwf.wf.wFormatTag = WAVE_FORMAT_PCM;
- pcmwf.wf.nChannels = 2;
- pcmwf.wf.nSamplesPerSec = 44100;
- 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;
- dwBufferSize = dsbdesc.dwBufferBytes = (((uint32)(pcmwf.wf.nAvgBytesPerSec * nBufSize) / 1000 + 31) / 32) * 32;
- 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, "FPStream::FPStream()", MB_OK);
- bSoundSupported = false;
- return false;
- }
- SetVolume(63);
-
-
- /* Create an alert when key positions are reached in the stream.
- Key positions are located, respectively, immediately after
- the start and immediately after the middle of the buffer */
- err = lpDSBuffer->QueryInterface(IID_IDirectSoundNotify, (void **)&lpDSNotify);
-
- if (FAILED(err)) {
- wsprintf(errbuf, "Error creating notify object! (%lx)", err);
- MessageBox(hwnd, errbuf, "FPStream::FPStream()", MB_OK);
- bSoundSupported = false;
- return false;
- }
-
- hHot1 = CreateEvent(NULL, false, false, NULL);
- hHot2 = CreateEvent(NULL, false, false, NULL);
- hHot3 = CreateEvent(NULL, false, false, NULL);
- hPlayThread_PlayFast = CreateEvent(NULL, false, false, NULL);
-
- dspnHot[0].dwOffset = 32;
- dspnHot[0].hEventNotify = hHot1;
-
- dspnHot[1].dwOffset = dwBufferSize / 2 + 32;
- dspnHot[1].hEventNotify = hHot2;
-
- dspnHot[2].dwOffset = dwBufferSize - 32; //DSBPN_OFFSETSTOP;
- dspnHot[2].hEventNotify = hHot3;
-
- lpDSNotify->SetNotificationPositions(3, dspnHot);
-#endif
- return true;
+ _loopStream = NULL;
+ _rewindableStream = NULL;
}
/**
@@ -918,38 +446,13 @@ FPStream::~FPStream() {
if (!_bSoundSupported)
return;
- if (_bIsPlaying)
+ if (g_system->getMixer()->isSoundHandleActive(_handle))
stop();
if (_bFileLoaded)
unloadFile();
- if (_hHot1) {
- CoroScheduler.closeEvent(_hHot1);
- _hHot1 = CORO_INVALID_PID_VALUE;
- }
- if (_hHot2) {
- CoroScheduler.closeEvent(_hHot2);
- _hHot2 = CORO_INVALID_PID_VALUE;
- }
- if (_hHot3) {
- CoroScheduler.closeEvent(_hHot3);
- _hHot3 = CORO_INVALID_PID_VALUE;
- }
- if (_hPlayThreadPlayFast != CORO_INVALID_PID_VALUE) {
- CoroScheduler.closeEvent(_hPlayThreadPlayFast);
- _hPlayThreadPlayFast = CORO_INVALID_PID_VALUE;
- }
- if (_hPlayThreadPlayNormal != CORO_INVALID_PID_VALUE) {
- CoroScheduler.closeEvent(_hPlayThreadPlayNormal);
- _hPlayThreadPlayNormal = CORO_INVALID_PID_VALUE;
- }
-
_syncToPlay = NULL;
-#ifdef REFACTOR_ME
- RELEASE(lpDSNotify);
- RELEASE(lpDSBuffer);
-#endif
}
/**
@@ -976,13 +479,12 @@ bool FPStream::loadFile(const Common::String &fileName, uint32 dwCodType, int nB
if (!_bSoundSupported)
return true;
+ if (_bFileLoaded)
+ unloadFile();
+
// Save the codec type
_dwCodec = dwCodType;
- // Create the buffer
- if (!createBuffer(nBufSize))
- return true;
-
// Open the file stream for reading
if (!_file.open(fileName))
return false;
@@ -990,11 +492,26 @@ bool FPStream::loadFile(const Common::String &fileName, uint32 dwCodType, int nB
// Save the size of the stream
_dwSize = _file.size();
+ switch (_dwCodec) {
+ case FPCODEC_RAW:
+ _rewindableStream = Audio::makeRawStream(&_file, 44100, Audio::FLAG_16BITS | Audio::FLAG_LITTLE_ENDIAN | Audio::FLAG_STEREO, DisposeAfterUse::NO);
+ break;
+
+ case FPCODEC_ADPCM:
+ _rewindableStream = Audio::makeADPCMStream(&_file, DisposeAfterUse::NO, 0, Audio::kADPCMDVI, 44100, 2);
+ break;
+
+ default:
+ _file.close();
+ return false;
+ }
+
// All done
_bFileLoaded = true;
- _bIsPlaying = false;
_bPaused = false;
+ setVolume(63);
+
return true;
}
@@ -1011,12 +528,12 @@ bool FPStream::unloadFile() {
if (!_bSoundSupported || !_bFileLoaded)
return true;
+ assert(!g_system->getMixer()->isSoundHandleActive(_handle));
+
/* Closes the file handle stream */
+ delete _loopStream;
+ delete _rewindableStream;
_file.close();
-#ifdef REFACTOR_ME
- RELEASE(lpDSNotify);
- RELEASE(lpDSBuffer);
-#endif
// Flag that the file is no longer in memory
_bFileLoaded = false;
@@ -1024,96 +541,6 @@ bool FPStream::unloadFile() {
return true;
}
-void FPStream::prefetch() {
- void *lpBuf = NULL;
-
- if (!_bSoundSupported || !_bFileLoaded)
- return;
-
- // Allocates a temporary buffer
- _lpTempBuffer = (byte *)globalAlloc(GMEM_FIXED | GMEM_ZEROINIT, _dwBufferSize / 2);
- if (_lpTempBuffer == NULL)
- return;
-
- if (_dwCodec == FPCODEC_RAW) {
- _codec = new CODECRAW(_bLoop);
- } else if (_dwCodec == FPCODEC_ADPCM) {
- _codec = new CODECADPCMSTEREO(_bLoop);
- } else {
- return;
- }
-
- // reset the file position
- _file.seek(0);
-
-#ifdef REFACTOR_ME
- // Fills the buffer for the data already ready
- if ((err = lpDSBuffer->Lock(0, dwBufferSize / 2, &lpBuf, (uint32 *)&dwHi, NULL, NULL, 0)) != DS_OK) {
- _vm->GUIError("Cannot lock stream buffer!", "soundLoadStream()");
- return;
- }
-#else
- // Return, since lpBuf hasn't been set
- return;
-#endif
-
- // Uncompress the data from the stream directly into the locked buffer
- _codec->decompress(_file.readStream(_file.size()), lpBuf, _dwBufferSize / 2);
-
- // Unlock the buffer
-#ifdef REFACTOR_ME
- lpDSBuffer->unlock(lpBuf, _dwBufferSize / 2, NULL, NULL);
-#endif
-
- // Create a thread to play the stream
- _hThreadEnd = CoroScheduler.createEvent(false, false);
- _hPlayThread = CoroScheduler.createProcess(playThread, this, sizeof(FPStream *));
-
- // Start to play the buffer
-#ifdef REFACTOR_ME
- lpDSBuffer->setCurrentPosition(0);
-#endif
- _bIsPlaying = true;
-
-#ifdef REFACTOR_ME
- _dspnHot[0].dwOffset = 32;
- _dspnHot[0].hEventNotify = _hHot1;
-
- _dspnHot[1].dwOffset = dwBufferSize / 2 + 32;
- _dspnHot[1].hEventNotify = _hHot2;
-
- _dspnHot[2].dwOffset = dwBufferSize - 32; //DSBPN_OFFSETSTOP;
- _dspnHot[2].hEventNotify = _hHot3;
-
- if (FAILED(lpDSNotify->SetNotificationPositions(3, dspnHot))) {
- int a = 1;
- }
-#endif
-}
-
-void FPStream::playFast() {
-#ifdef REFACTOR_ME
- dspnHot[0].dwOffset = 32;
- dspnHot[0].hEventNotify = hHot1;
-
- dspnHot[1].dwOffset = dwBufferSize / 2 + 32;
- dspnHot[1].hEventNotify = hHot2;
-
- dspnHot[2].dwOffset = dwBufferSize - 32; //DSBPN_OFFSETSTOP;
- dspnHot[2].hEventNotify = hHot3;
-
- lpDSBuffer->Stop();
-
- if (FAILED(lpDSNotify->SetNotificationPositions(3, dspnHot))) {
- warning("PlayFast SNP failed!");
- }
-
- if (FAILED(lpDSBuffer->Play(0, 0, DSBPLAY_LOOPING))) {
- warning("PlayFast failed!\n");
- }
-#endif
-}
-
/**
* Play the stream.
*
@@ -1121,79 +548,27 @@ void FPStream::playFast() {
*/
bool FPStream::play() {
-#ifdef REFACTOR_ME
- uint32 dwId;
- void *lpBuf;
- uint32 dwHi;
- HRESULT err;
-
- if (!bSoundSupported || !bFileLoaded)
- return false;
-
- /* Allocate a temporary buffer */
- lpTempBuffer = (byte *)GlobalAlloc(GMEM_FIXED | GMEM_ZEROINIT, dwBufferSize / 2);
- if (lpTempBuffer == NULL)
- return false;
-
- switch (dwCodec) {
- case FPCODEC_RAW:
- _codec = new CODECRAW(_bLoop);
- break;
-
- case FPCODEC_ADPCM:
- _codec = new CODECADPCMSTEREO(_bLoop);
- break;
-
- default:
+ if (!_bSoundSupported || !_bFileLoaded)
return false;
- }
-
- /* Reset the file position */
- _file.seek(0);
- lpDSBuffer->Stop();
- lpDSBuffer->SetCurrentPosition(0);
-
- /* Fills the buffer for the data already ready */
- if ((err = lpDSBuffer->Lock(0, dwBufferSize / 2, &lpBuf, (uint32 *)&dwHi, NULL, NULL, 0)) != DS_OK) {
- error("Cannot lock stream buffer!", "soundLoadStream()");
- }
-
- /* Uncompress the data from the stream directly into the locked buffer */
- _codec->Decompress(hFile, lpBuf, dwBufferSize / 2);
-
- /* Unlock the buffer */
- lpDSBuffer->Unlock(lpBuf, dwBufferSize / 2, NULL, NULL);
-
- /* Create a thread to play the stream */
- hThreadEnd = CreateEvent(NULL, false, false, NULL);
- hPlayThread = CreateThread(NULL, 10240, (LPTHREAD_START_ROUTINE)PlayThread, (void *)this, 0, &dwId);
- SetThreadPriority(hPlayThread, THREAD_PRIORITY_HIGHEST);
- SetEvent(hPlayThread_PlayFast);
+ stop();
-#if 0
- /* Start to play the buffer */
- lpDSBuffer->SetCurrentPosition(0);
+ _rewindableStream->rewind();
- dspnHot[0].dwOffset = 32;
- dspnHot[0].hEventNotify = hHot1;
+ Audio::AudioStream *stream = _rewindableStream;
- dspnHot[1].dwOffset = dwBufferSize / 2 + 32;
- dspnHot[1].hEventNotify = hHot2;
+ if (_bLoop) {
+ if (!_loopStream)
+ _loopStream = new Audio::LoopingAudioStream(_rewindableStream, 0, DisposeAfterUse::NO);
- dspnHot[2].dwOffset = dwBufferSize - 32; //DSBPN_OFFSETSTOP;
- dspnHot[2].hEventNotify = hHot3;
-
- if (FAILED(lpDSNotify->SetNotificationPositions(3, dspnHot))) {
- int a = 1;
+ stream = _loopStream;
}
+ // FIXME: Should this be kMusicSoundType or KPlainSoundType?
+ g_system->getMixer()->playStream(Audio::Mixer::kMusicSoundType, &_handle, stream, -1, Audio::Mixer::kMaxChannelVolume, 0, DisposeAfterUse::NO);
+ setVolume(_lastVolume);
+ _bPaused = false;
- lpDSBuffer->Play(0, 0, DSBPLAY_LOOPING);
-#endif
-
- bIsPlaying = true;
-#endif
return true;
}
@@ -1205,177 +580,37 @@ bool FPStream::play() {
*/
bool FPStream::stop(bool bSync) {
-#ifdef REFACTOR_ME
-
- if (!bSoundSupported)
+ if (!_bSoundSupported)
return true;
- if (!bFileLoaded)
+ if (!_bFileLoaded)
return false;
- if (!bIsPlaying)
+ if (!g_system->getMixer()->isSoundHandleActive(_handle))
return false;
if (bSync) {
-// bSyncExit = true;
-// lpDSBuffer->Stop();
-// lpDSBuffer->Play(0, 0, 0);
+ // The caller intends to call waitForSync.
+ // FIXME: Why call this in that case?! Looks like old code. Remove that parameter.
return true;
} else {
- /* Close the DirectSound buffer */
- lpDSBuffer->Stop();
-
- /* Notify the thread is should stop */
- SetEvent(hThreadEnd);
- WaitForSingleObject(hPlayThread, CORO_INFINITE);
-
- /* Closes the handle used by the stream and free its memory */
- CloseHandle(hPlayThread);
- CloseHandle(hThreadEnd);
- GlobalFree(lpTempBuffer);
-
- /* Close and free the CODEC */
- delete _codec;
+ g_system->getMixer()->stopHandle(_handle);
- bIsPlaying = false;
- bPaused = false;
+ _bPaused = false;
}
-#endif
+
return true;
}
void FPStream::waitForSync(FPStream *toplay) {
-#ifdef REFACTOR_ME
- if (!bSoundSupported)
- return;
-
- if (!bFileLoaded)
- return;
-
- if (!bIsPlaying)
- return;
-
- SyncToPlay = toplay;
- bSyncExit = true;
-
- char buf[1024];
- sprintf(buf, "Wait for sync: %x (SyncToPlay: [%x]=%x, SyncExit: [%x]=%d) MyThread: 0x%x\n",
- this->lpDSBuffer, &this->SyncToPlay, SyncToPlay, &bSyncExit, bSyncExit, GetCurrentThreadId());
- warning(buf);
-
- WaitForSingleObject(hPlayThread, CORO_INFINITE);
-
- /* Closes the handle used by the stream and free its memory */
- CloseHandle(hPlayThread);
- CloseHandle(hThreadEnd);
- GlobalFree(lpTempBuffer);
-
- /* Close and free the CODEC */
- delete _codec;
-#endif
- _bIsPlaying = false;
-}
-
-/**
- * Thread playing the stream
- *
- */
-
-void FPStream::playThread(CORO_PARAM, const void *param) {
- CORO_BEGIN_CONTEXT;
- byte *lpLockBuf;
- uint32 dwResult;
- byte *lpLockBuf2;
- uint32 dwResult2;
- bool cicla;
- uint32 countEnd;
- bool bPrecache;
- char buf[1024];
- uint32 hList[5];
- CORO_END_CONTEXT(_ctx);
-
-// FPStream *This = *(FPStream **)param;
-
- CORO_BEGIN_CODE(_ctx);
-#ifdef REFACTOR_ME
- // Events that signal when you need to do something
- _ctx->hList[0] = This->_hThreadEnd;
- _ctx->hList[1] = This->_hHot1;
- _ctx->hList[2] = This->_hHot2;
- _ctx->hList[3] = This->_hHot3;
- _ctx->hList[4] = This->_hPlayThreadPlayFast;
-
- _ctx->cicla = true;
- _ctx->bPrecache = true;
- _ctx->countEnd = 0;
- while (_ctx->cicla) {
- if (This->_codec->endOfStream() && This->_codec->_bLoop == false) {
- _ctx->countEnd++;
- if (_ctx->countEnd == 3)
- break;
- }
-
- // Uncompresses the data being written into the temporary buffer
- if (This->_lastVolume == 0)
- ZeroMemory(This->_lpTempBuffer, This->_dwBufferSize / 2);
- else if (_ctx->bPrecache)
- This->_codec->decompress(This->_file.readStream(This->_file.size()), This->_lpTempBuffer, This->_dwBufferSize / 2);
-
- _ctx->bPrecache = false;
-
- // Waits for an event. Since they are all in automatic reset, there is no need to reset it after
-
- uint32 dwBufStatus;
-
- CORO_INVOKE_4(CoroScheduler.waitForMultipleObjects, 5, _ctx->hList, false, CORO_INFINITE, &_ctx->dwResult);
-
- // Check to determine which event has been set
- if (CoroScheduler.getEvent(This->_hThreadEnd)->signalled) {
- /* Must leave the thread */
- _ctx->cicla = false;
-
- } else if (CoroScheduler.getEvent(This->_hHot1)->signalled) {
- // Must fill the second half of the buffer
- This->lpDSBuffer->Lock(This->_dwBufferSize / 2, This->_dwBufferSize / 2, (void **)&_ctx->lpLockBuf, &_ctx->dwResult, (void **)&_ctx->lpLockBuf2, &_ctx->dwResult2, 0);
+ // FIXME: The idea here is that you wait for this stream to reach
+ // a buffer which is a multiple of nBufSize/nSync, and then the
+ // thread stops it and immediately starts the 'toplay' stream.
- copyMemory(_ctx->lpLockBuf, This->_lpTempBuffer, This->_dwBufferSize / 2);
- This->lpDSBuffer->Unlock(_ctx->lpLockBuf, This->_dwBufferSize / 2, _ctx->lpLockBuf2, 0);
-
- _ctx->bPrecache = true;
-
- } else if (CoroScheduler.getEvent(This->_hHot2)->signalled) {
- This->lpDSBuffer->Lock(0, This->_dwBufferSize / 2, (void **)&_ctx->lpLockBuf, &_ctx->dwResult, NULL, NULL, 0);
-
- copyMemory(_ctx->lpLockBuf, This->_lpTempBuffer, This->_dwBufferSize / 2);
- This->lpDSBuffer->Unlock(_ctx->lpLockBuf, This->_dwBufferSize / 2, NULL, NULL);
-
- _ctx->bPrecache = true;
-
- } else if (CoroScheduler.getEvent(This->_hHot3)->signalled) {
-
- if (This->_bSyncExit) {
- CoroScheduler.setEvent(This->_syncToPlay->_hPlayThreadPlayFast);
-
- // Transfer immediatly control to the other threads
- CORO_SLEEP(1);
-
- This->_bSyncExit = false;
- _ctx->cicla = false;
- break;
- }
- } else if (CoroScheduler.getEvent(This->_hPlayThreadPlayFast)->signalled) {
- This->playFast();
- }
- }
-
- // Close the DirectSound buffer
- This->lpDSBuffer->Stop();
-#endif
-
- CORO_END_CODE;
+ stop();
+ toplay->play();
}
-
/**
* Unables or disables stream loop.
*
@@ -1389,44 +624,25 @@ void FPStream::setLoop(bool loop) {
_bLoop = loop;
}
-
/**
* Pause sound effect
*
* @param bPause True enables pause, False disables it
*/
void FPStream::pause(bool bPause) {
- if (_bFileLoaded) {
- if (bPause && _bIsPlaying) {
-#ifdef REFACTOR_ME
- _lpDSBuffer->Stop();
-#endif
- _bIsPlaying = false;
- _bPaused = true;
- } else if (!bPause && _bPaused) {
-#ifdef REFACTOR_ME
- _dspnHot[0].dwOffset = 32;
- _dspnHot[0].hEventNotify = hHot1;
-
- _dspnHot[1].dwOffset = dwBufferSize / 2 + 32;
- _dspnHot[1].hEventNotify = hHot2;
-
- _dspnHot[2].dwOffset = dwBufferSize - 32; //DSBPN_OFFSETSTOP;
- _dspnHot[2].hEventNotify = hHot3;
-
- if (FAILED(lpDSNotify->SetNotificationPositions(3, dspnHot))) {
- int a = 1;
- }
-
- lpDSBuffer->Play(0, 0, _bLoop);
-#endif
- _bIsPlaying = true;
- _bPaused = false;
-
- // Trick to reset the volume after a possible new sound configuration
- setVolume(_lastVolume);
- }
- }
+ if (!_bFileLoaded)
+ return;
+
+ if (bPause == _bPaused)
+ return;
+
+ if (g_system->getMixer()->isSoundHandleActive(_handle))
+ g_system->getMixer()->pauseHandle(_handle, bPause);
+
+ _bPaused = bPause;
+
+ // Trick to reset the volume after a possible new sound configuration
+ setVolume(_lastVolume);
}
/**
@@ -1437,38 +653,33 @@ void FPStream::pause(bool bPause) {
*/
void FPStream::setVolume(int dwVolume) {
-#ifdef REFACTOR_ME
if (dwVolume > 63) dwVolume = 63;
if (dwVolume < 0) dwVolume = 0;
- lastVolume = dwVolume;
+ _lastVolume = dwVolume;
- if (!GLOBALS.bCfgMusic) dwVolume = 0;
+ if (!GLOBALS._bCfgMusic) dwVolume = 0;
else {
- dwVolume -= (10 - GLOBALS.nCfgMusicVolume) * 2;
+ dwVolume -= (10 - GLOBALS._nCfgMusicVolume) * 2;
if (dwVolume < 0) dwVolume = 0;
}
- if (lpDSBuffer)
- 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);
}
/**
- * Gets the vgolume of the stream
+ * Gets the volume of the stream
*
* @param lpdwVolume Variable that will contain the current volume
*
*/
void FPStream::getVolume(int *lpdwVolume) {
-#ifdef REFACTOR_ME
- if (lpDSBuffer)
- 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;
}
} // End of namespace Tony
diff --git a/engines/tony/sound.h b/engines/tony/sound.h
index 38ce6de2a7..585247db83 100644
--- a/engines/tony/sound.h
+++ b/engines/tony/sound.h
@@ -265,23 +265,11 @@ public:
class FPStream {
private:
- // HWND hwnd;
- // LPDIRECTSOUND lpDS;
- // LPDIRECTSOUNDBUFFER lpDSBuffer; // DirectSound circular buffer
- // LPDIRECTSOUNDNOTIFY lpDSNotify; // Notify hotspots in the buffer
-
- byte *_lpTempBuffer; // Temporary buffer use for decompression
-
uint32 _dwBufferSize; // Buffer size (bytes)
uint32 _dwSize; // Stream size (bytes)
uint32 _dwCodec; // CODEC used
- uint32 _hThreadEnd; // Event used to close thread
Common::File _file; // File handle used for the stream
- uint32 _hPlayThread; // Handle of the Play thread
- uint32 _hHot1, _hHot2, _hHot3; // Events set by DirectSoundNotify
- uint32 _hPlayThreadPlayFast;
- uint32 _hPlayThreadPlayNormal;
bool _bSoundSupported; // True if the sound is active
bool _bFileLoaded; // True if the file is open
@@ -291,21 +279,10 @@ private:
bool _bPaused;
int _lastVolume;
FPStream *_syncToPlay;
- CODEC *_codec;
-
- // DSBPOSITIONNOTIFY dspnHot[3];
-
- bool createBuffer(int nBufSize);
-public:
- bool _bIsPlaying; // True if the stream is playing
-
-private:
- /**
- * Thread playing the stream
- *
- */
- static void playThread(CORO_PARAM, const void *param);
+ Audio::AudioStream *_loopStream;
+ Audio::RewindableAudioStream *_rewindableStream;
+ Audio::SoundHandle _handle;
public:
@@ -368,7 +345,6 @@ public:
bool play();
void playFast();
- void prefetch();
/**
* Closes the stream.
@@ -408,7 +384,7 @@ public:
void setVolume(int dwVolume);
/**
- * Gets the vgolume of the stream
+ * Gets the volume of the stream
*
* @param lpdwVolume Variable that will contain the current volume
*
diff --git a/engines/tony/tony.cpp b/engines/tony/tony.cpp
index 8ae95af862..475683d0f4 100644
--- a/engines/tony/tony.cpp
+++ b/engines/tony/tony.cpp
@@ -268,7 +268,7 @@ void TonyEngine::doNextMusic(CORO_PARAM, const void *param) {
}
streams[GLOBALS._nextChannel]->setLoop(GLOBALS._nextLoop);
- streams[GLOBALS._nextChannel]->prefetch();
+ //streams[GLOBALS._nextChannel]->prefetch();
streams[GLOBALS._curChannel]->stop(true);
streams[GLOBALS._curChannel]->waitForSync(streams[GLOBALS._nextChannel]);