mirror of
https://github.com/scummvm/scummvm.git
synced 2026-06-20 05:45:29 +00:00
SCUMM: Unified some more SMUSH audio channel code
svn-id: r24538
This commit is contained in:
@@ -0,0 +1,109 @@
|
||||
/* ScummVM - Scumm Interpreter
|
||||
* Copyright (C) 2002-2006 The ScummVM project
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*
|
||||
* $URL$
|
||||
* $Id$
|
||||
*
|
||||
*/
|
||||
|
||||
#include "common/stdafx.h"
|
||||
#include "scumm/smush/channel.h"
|
||||
|
||||
namespace Scumm {
|
||||
|
||||
SmushChannel::SmushChannel(int32 track) :
|
||||
_track(track),
|
||||
_tbuffer(0),
|
||||
_tbufferSize(0),
|
||||
_sbuffer(0),
|
||||
_sbufferSize(0),
|
||||
_dataSize(-1),
|
||||
_inData(false),
|
||||
_volume(0),
|
||||
_pan(0) {
|
||||
}
|
||||
|
||||
SmushChannel::~SmushChannel() {
|
||||
delete[] _tbuffer;
|
||||
delete[] _sbuffer;
|
||||
}
|
||||
|
||||
void SmushChannel::processBuffer() {
|
||||
assert(_tbuffer != 0);
|
||||
assert(_tbufferSize != 0);
|
||||
assert(_sbuffer == 0);
|
||||
assert(_sbufferSize == 0);
|
||||
|
||||
if (_inData) {
|
||||
if (_dataSize < _tbufferSize) {
|
||||
int32 offset = _dataSize;
|
||||
while (handleSubTags(offset))
|
||||
;
|
||||
_sbufferSize = _dataSize;
|
||||
_sbuffer = _tbuffer;
|
||||
if (offset < _tbufferSize) {
|
||||
int new_size = _tbufferSize - offset;
|
||||
_tbuffer = new byte[new_size];
|
||||
if (!_tbuffer)
|
||||
error("smush channel failed to allocate memory");
|
||||
memcpy(_tbuffer, _sbuffer + offset, new_size);
|
||||
_tbufferSize = new_size;
|
||||
} else {
|
||||
_tbuffer = 0;
|
||||
_tbufferSize = 0;
|
||||
}
|
||||
if (_sbufferSize == 0) {
|
||||
delete []_sbuffer;
|
||||
_sbuffer = 0;
|
||||
}
|
||||
} else {
|
||||
_sbufferSize = _tbufferSize;
|
||||
_sbuffer = _tbuffer;
|
||||
_tbufferSize = 0;
|
||||
_tbuffer = 0;
|
||||
}
|
||||
} else {
|
||||
int32 offset = 0;
|
||||
while (handleSubTags(offset))
|
||||
;
|
||||
if (_inData) {
|
||||
_sbufferSize = _tbufferSize - offset;
|
||||
assert(_sbufferSize);
|
||||
_sbuffer = new byte[_sbufferSize];
|
||||
if (!_sbuffer)
|
||||
error("smush channel failed to allocate memory");
|
||||
memcpy(_sbuffer, _tbuffer + offset, _sbufferSize);
|
||||
delete []_tbuffer;
|
||||
_tbuffer = 0;
|
||||
_tbufferSize = 0;
|
||||
} else {
|
||||
if (offset) {
|
||||
byte *old = _tbuffer;
|
||||
int32 new_size = _tbufferSize - offset;
|
||||
_tbuffer = new byte[new_size];
|
||||
if (!_tbuffer)
|
||||
error("smush channel failed to allocate memory");
|
||||
memcpy(_tbuffer, old + offset, new_size);
|
||||
_tbufferSize = new_size;
|
||||
delete []old;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
} // End of namespace Scumm
|
||||
@@ -45,32 +45,24 @@ protected:
|
||||
int32 _volume;
|
||||
int32 _pan;
|
||||
|
||||
void processBuffer();
|
||||
|
||||
virtual bool handleSubTags(int32 &offset) = 0;
|
||||
|
||||
public:
|
||||
SmushChannel(int32 track) :
|
||||
_track(track),
|
||||
_tbuffer(0),
|
||||
_tbufferSize(0),
|
||||
_sbuffer(0),
|
||||
_sbufferSize(0),
|
||||
_dataSize(-1),
|
||||
_inData(false),
|
||||
_volume(0),
|
||||
_pan(0) {
|
||||
}
|
||||
virtual ~SmushChannel() {
|
||||
delete[] _tbuffer;
|
||||
delete[] _sbuffer;
|
||||
}
|
||||
SmushChannel(int32 track);
|
||||
virtual ~SmushChannel();
|
||||
virtual bool appendData(Chunk &b, int32 size) = 0;
|
||||
virtual bool setParameters(int32, int32, int32, int32, int32) = 0;
|
||||
virtual bool checkParameters(int32, int32, int32, int32, int32) = 0;
|
||||
virtual bool isTerminated() const = 0;
|
||||
virtual int32 availableSoundData() const = 0;
|
||||
virtual int32 getAvailableSoundDataSize() const = 0;
|
||||
virtual void getSoundData(int16 *sound_buffer, int32 size) = 0;
|
||||
virtual void getSoundData(int8 *sound_buffer, int32 size) = 0;
|
||||
virtual int32 getRate() = 0;
|
||||
virtual bool getParameters(bool &stereo, bool &is_16bit, int32 &vol, int32 &pan) = 0;
|
||||
virtual int32 getTrackIdentifier() const = 0;
|
||||
|
||||
int32 getTrackIdentifier() const { return _track; };
|
||||
};
|
||||
|
||||
class SaudChannel : public SmushChannel {
|
||||
@@ -86,7 +78,6 @@ protected:
|
||||
void handleSmrk(Chunk &c);
|
||||
void handleShdr(Chunk &c);
|
||||
bool handleSubTags(int32 &offset);
|
||||
bool processBuffer();
|
||||
|
||||
public:
|
||||
SaudChannel(int32 track);
|
||||
@@ -95,7 +86,7 @@ public:
|
||||
bool setParameters(int32 duration, int32 flags, int32 vol1, int32 vol2, int32 index);
|
||||
bool checkParameters(int32 index, int32 duration, int32 flags, int32 vol1, int32 vol2);
|
||||
bool appendData(Chunk &b, int32 size);
|
||||
int32 availableSoundData() const;
|
||||
int32 getAvailableSoundDataSize() const;
|
||||
void getSoundData(int16 *sound_buffer, int32 size);
|
||||
void getSoundData(int8 *sound_buffer, int32 size) { error("8bit request for SAUD channel should never happen"); };
|
||||
int32 getRate() { return 22050; }
|
||||
@@ -106,7 +97,6 @@ public:
|
||||
pan = _pan;
|
||||
return true;
|
||||
};
|
||||
virtual int32 getTrackIdentifier() const { return _track; };
|
||||
};
|
||||
|
||||
class ImuseChannel : public SmushChannel {
|
||||
@@ -120,12 +110,11 @@ private:
|
||||
protected:
|
||||
int32 decode(int32 size, int32 &ret);
|
||||
void decode();
|
||||
bool processBuffer();
|
||||
bool handleMap(Chunk &);
|
||||
bool handleFormat(Chunk &);
|
||||
bool handleRegion(Chunk &);
|
||||
bool handleStop(Chunk &);
|
||||
bool handleSubTags(int32 & offset);
|
||||
bool handleMap(Chunk &c);
|
||||
bool handleFormat(Chunk &c);
|
||||
bool handleRegion(Chunk &c);
|
||||
bool handleStop(Chunk &c);
|
||||
bool handleSubTags(int32 &offset);
|
||||
|
||||
public:
|
||||
ImuseChannel(int32 track);
|
||||
@@ -134,7 +123,7 @@ public:
|
||||
bool setParameters(int32 nbframes, int32 size, int32 track_flags, int32 unk1, int32);
|
||||
bool checkParameters(int32 index, int32 nbframes, int32 size, int32 track_flags, int32 unk1);
|
||||
bool appendData(Chunk &b, int32 size);
|
||||
int32 availableSoundData() const;
|
||||
int32 getAvailableSoundDataSize() const;
|
||||
void getSoundData(int16 *sound_buffer, int32 size);
|
||||
void getSoundData(int8 *sound_buffer, int32 size);
|
||||
int32 getRate() { return _rate; }
|
||||
@@ -145,7 +134,6 @@ public:
|
||||
pan = _pan;
|
||||
return true;
|
||||
};
|
||||
virtual int32 getTrackIdentifier() const { return _track; };
|
||||
};
|
||||
|
||||
} // End of namespace Scumm
|
||||
|
||||
@@ -21,7 +21,9 @@
|
||||
*/
|
||||
|
||||
#include "common/stdafx.h"
|
||||
#include "scumm/scumm.h"
|
||||
#include "common/endian.h"
|
||||
|
||||
#include "scumm/scumm.h" // For DEBUG_SMUSH
|
||||
#include "scumm/util.h"
|
||||
#include "scumm/smush/channel.h"
|
||||
#include "scumm/smush/chunk.h"
|
||||
@@ -93,7 +95,14 @@ bool ImuseChannel::appendData(Chunk &b, int32 size) {
|
||||
b.read(_tbuffer, size);
|
||||
}
|
||||
}
|
||||
return processBuffer();
|
||||
|
||||
processBuffer();
|
||||
|
||||
_srbufferSize = _sbufferSize;
|
||||
if (_sbuffer && _bitsize == 12)
|
||||
decode();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ImuseChannel::handleFormat(Chunk &src) {
|
||||
@@ -237,72 +246,7 @@ bool ImuseChannel::handleSubTags(int32 &offset) {
|
||||
return false;
|
||||
}
|
||||
|
||||
bool ImuseChannel::processBuffer() {
|
||||
assert(_tbuffer != 0);
|
||||
assert(_tbufferSize != 0);
|
||||
assert(_sbuffer == 0);
|
||||
assert(_sbufferSize == 0);
|
||||
|
||||
if (_inData) {
|
||||
if (_dataSize < _tbufferSize) {
|
||||
int32 offset = _dataSize;
|
||||
while (handleSubTags(offset))
|
||||
;
|
||||
_sbufferSize = _dataSize;
|
||||
_sbuffer = _tbuffer;
|
||||
if (offset < _tbufferSize) {
|
||||
int new_size = _tbufferSize - offset;
|
||||
_tbuffer = new byte[new_size];
|
||||
if (!_tbuffer)
|
||||
error("imuse_channel failed to allocate memory");
|
||||
memcpy(_tbuffer, _sbuffer + offset, new_size);
|
||||
_tbufferSize = new_size;
|
||||
} else {
|
||||
_tbuffer = 0;
|
||||
_tbufferSize = 0;
|
||||
}
|
||||
if (_sbufferSize == 0) {
|
||||
delete []_sbuffer;
|
||||
_sbuffer = 0;
|
||||
}
|
||||
} else {
|
||||
_sbufferSize = _tbufferSize;
|
||||
_sbuffer = _tbuffer;
|
||||
_tbufferSize = 0;
|
||||
_tbuffer = 0;
|
||||
}
|
||||
} else {
|
||||
int32 offset = 0;
|
||||
while (handleSubTags(offset))
|
||||
;
|
||||
if (_inData) {
|
||||
_sbufferSize = _tbufferSize - offset;
|
||||
assert(_sbufferSize);
|
||||
_sbuffer = new byte[_sbufferSize];
|
||||
if (!_sbuffer)
|
||||
error("imuse_channel failed to allocate memory");
|
||||
memcpy(_sbuffer, _tbuffer + offset, _sbufferSize);
|
||||
delete []_tbuffer;
|
||||
_tbuffer = 0;
|
||||
_tbufferSize = 0;
|
||||
} else {
|
||||
if (offset) {
|
||||
byte * old = _tbuffer;
|
||||
int32 new_size = _tbufferSize - offset;
|
||||
_tbuffer = new byte[new_size];
|
||||
if (!_tbuffer) error("imuse_channel failed to allocate memory");
|
||||
memcpy(_tbuffer, old + offset, new_size);
|
||||
_tbufferSize = new_size;
|
||||
delete []old;
|
||||
}
|
||||
}
|
||||
}
|
||||
_srbufferSize = _sbufferSize;
|
||||
if (_sbuffer && _bitsize == 12) decode();
|
||||
return true;
|
||||
}
|
||||
|
||||
int32 ImuseChannel::availableSoundData(void) const {
|
||||
int32 ImuseChannel::getAvailableSoundDataSize(void) const {
|
||||
int32 ret = _sbufferSize;
|
||||
if (_channels == 2) ret /= 2;
|
||||
if (_bitsize > 8) ret /= 2;
|
||||
|
||||
@@ -92,75 +92,6 @@ bool SaudChannel::handleSubTags(int32 &offset) {
|
||||
return false;
|
||||
}
|
||||
|
||||
bool SaudChannel::processBuffer() {
|
||||
assert(_tbuffer != 0);
|
||||
assert(_tbufferSize != 0);
|
||||
assert(_sbuffer == 0);
|
||||
assert(_sbufferSize == 0);
|
||||
|
||||
if (_keepSize) {
|
||||
_sbufferSize = _tbufferSize;
|
||||
_sbuffer = _tbuffer;
|
||||
_tbufferSize = 0;
|
||||
_tbuffer = 0;
|
||||
} else if (_inData) {
|
||||
if (_dataSize < _tbufferSize) {
|
||||
int32 offset = _dataSize;
|
||||
while (handleSubTags(offset))
|
||||
;
|
||||
_sbufferSize = _dataSize;
|
||||
_sbuffer = _tbuffer;
|
||||
if (offset < _tbufferSize) {
|
||||
int new_size = _tbufferSize - offset;
|
||||
_tbuffer = new byte[new_size];
|
||||
if (!_tbuffer)
|
||||
error("SaudChannel failed to allocate memory");
|
||||
memcpy(_tbuffer, _sbuffer + offset, new_size);
|
||||
_tbufferSize = new_size;
|
||||
} else {
|
||||
_tbuffer = 0;
|
||||
_tbufferSize = 0;
|
||||
}
|
||||
if (_sbufferSize == 0) {
|
||||
delete []_sbuffer;
|
||||
_sbuffer = 0;
|
||||
}
|
||||
} else {
|
||||
_sbufferSize = _tbufferSize;
|
||||
_sbuffer = _tbuffer;
|
||||
_tbufferSize = 0;
|
||||
_tbuffer = 0;
|
||||
}
|
||||
} else {
|
||||
int32 offset = 0;
|
||||
while (handleSubTags(offset))
|
||||
;
|
||||
if (_inData) {
|
||||
_sbufferSize = _tbufferSize - offset;
|
||||
assert(_sbufferSize);
|
||||
_sbuffer = new byte[_sbufferSize];
|
||||
if (!_sbuffer)
|
||||
error("saud_channel failed to allocate memory");
|
||||
memcpy(_sbuffer, _tbuffer + offset, _sbufferSize);
|
||||
delete []_tbuffer;
|
||||
_tbuffer = 0;
|
||||
_tbufferSize = 0;
|
||||
} else {
|
||||
if (offset) {
|
||||
byte *old = _tbuffer;
|
||||
int32 new_size = _tbufferSize - offset;
|
||||
_tbuffer = new byte[new_size];
|
||||
if (!_tbuffer)
|
||||
error("SaudChannel failed to allocate memory");
|
||||
memcpy(_tbuffer, old + offset, new_size);
|
||||
_tbufferSize = new_size;
|
||||
delete []old;
|
||||
}
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
SaudChannel::SaudChannel(int32 track) : SmushChannel(track),
|
||||
_nbframes(0),
|
||||
_markReached(false),
|
||||
@@ -236,10 +167,20 @@ bool SaudChannel::appendData(Chunk &b, int32 size) {
|
||||
error("saud_channel failed to allocate memory");
|
||||
b.read(_tbuffer, _tbufferSize);
|
||||
}
|
||||
return processBuffer();
|
||||
|
||||
if (_keepSize) {
|
||||
_sbufferSize = _tbufferSize;
|
||||
_sbuffer = _tbuffer;
|
||||
_tbufferSize = 0;
|
||||
_tbuffer = 0;
|
||||
} else {
|
||||
processBuffer();
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
int32 SaudChannel::availableSoundData(void) const {
|
||||
int32 SaudChannel::getAvailableSoundDataSize(void) const {
|
||||
return _sbufferSize;
|
||||
}
|
||||
|
||||
|
||||
@@ -109,7 +109,7 @@ bool SmushMixer::handleFrame() {
|
||||
void *data;
|
||||
|
||||
_channels[i].chan->getParameters(stereo, is_16bit, vol, pan);
|
||||
int32 size = _channels[i].chan->availableSoundData();
|
||||
int32 size = _channels[i].chan->getAvailableSoundDataSize();
|
||||
byte flags = stereo ? Audio::Mixer::FLAG_STEREO : 0;
|
||||
|
||||
if (is_16bit) {
|
||||
|
||||
Reference in New Issue
Block a user