Skip to content

Commit

Permalink
BLADERUNNER: Split aud_decoder into aud_stream and adpcm_decoder
Browse files Browse the repository at this point in the history
  • Loading branch information
madmoose authored and sev- committed Sep 29, 2016
1 parent 2d8f421 commit 35ea849
Show file tree
Hide file tree
Showing 8 changed files with 218 additions and 129 deletions.
Expand Up @@ -20,7 +20,7 @@
*
*/

#include "bladerunner/aud_decoder.h"
#include "bladerunner/adpcm_decoder.h"

#include "common/util.h"

Expand Down
Expand Up @@ -20,8 +20,8 @@
*
*/

#ifndef BLADERUNNER_AUD_DECODER_H
#define BLADERUNNER_AUD_DECODER_H
#ifndef BLADERUNNER_ADPCM_DECODER_H
#define BLADERUNNER_ADPCM_DECODER_H

#include "common/types.h"

Expand All @@ -45,6 +45,6 @@ class ADPCMWestwoodDecoder {
void decode(uint8 *in, size_t size, int16 *out);
};

}
} // End of namespace BladeRunner

#endif
110 changes: 110 additions & 0 deletions engines/bladerunner/aud_stream.cpp
@@ -0,0 +1,110 @@
/* ScummVM - Graphic Adventure Engine
*
* ScummVM is the legal property of its developers, whose names
* are too numerous to list here. Please refer to the COPYRIGHT
* file distributed with this source distribution.
*
* 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.
*
*/

#include "bladerunner/aud_stream.h"

#include "bladerunner/audio_player.h"

#include "common/util.h"

namespace BladeRunner {

AudStream::AudStream(byte *data)
: _cache(nullptr)
{
init(data);
}

AudStream::AudStream(AudioCache *cache, int32 hash)
: _cache(cache), _hash(hash)
{
_cache->incRef(_hash);

init(_cache->findByHash(_hash));
}

void AudStream::init(byte *data)
{
_data = data;
_end = _data + READ_LE_UINT32(_data + 2) + 12;
assert(_end - _data >= 12);

_compressionType = *(_data + 11);

_deafBlockRemain = 0;
_p = _data + 12;
}

AudStream::~AudStream() {
if (_cache)
_cache->decRef(_hash);
}

int AudStream::readBuffer(int16 *buffer, const int numSamples) {
int samplesRead = 0;

assert(numSamples % 2 == 0);

if (_compressionType == 99) {
while (samplesRead < numSamples) {
if (_deafBlockRemain == 0) {
if (_end - _p == 0)
break;

assert(_end - _p >= 6);

uint16 blockSize = READ_LE_UINT16(_p);
uint16 blockOutSize = READ_LE_UINT16(_p + 2);
uint32 sig = READ_LE_UINT32(_p + 4);
_p += 8;

assert(sig == 0xdeaf);
assert(_end - _p >= blockSize);
assert(blockOutSize = 4 * blockSize);

_deafBlockRemain = blockSize;
}

assert(_end - _p >= _deafBlockRemain);

int bytesConsumed = MIN<int>(_deafBlockRemain, (numSamples - samplesRead) / 2);

_decoder.decode(_p, bytesConsumed, buffer + samplesRead);
_p += bytesConsumed;
_deafBlockRemain -= bytesConsumed;

samplesRead += 2 * bytesConsumed;
}
} else {
assert(0 && "readBuffer: Unimplemented");
}

return samplesRead;
}

bool AudStream::rewind() {
_p = _data + 12;
_decoder.setParameters(0, 0);
return true;
}

} // End of namespace BladeRunner
63 changes: 63 additions & 0 deletions engines/bladerunner/aud_stream.h
@@ -0,0 +1,63 @@
/* ScummVM - Graphic Adventure Engine
*
* ScummVM is the legal property of its developers, whose names
* are too numerous to list here. Please refer to the COPYRIGHT
* file distributed with this source distribution.
*
* 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.
*
*/

#ifndef BLADERUNNER_AUD_STREAM_H
#define BLADERUNNER_AUD_STREAM_H

#include "bladerunner/adpcm_decoder.h"

#include "audio/audiostream.h"
#include "common/endian.h"
#include "common/types.h"

namespace BladeRunner {

class AudioCache;

class AudStream : public Audio::RewindableAudioStream {
byte *_data;
byte *_p;
byte *_end;
AudioCache *_cache;
int32 _hash;
byte _compressionType;
uint16 _deafBlockRemain;

ADPCMWestwoodDecoder _decoder;

void init(byte *data);

public:
AudStream(byte *data);
AudStream(AudioCache *cache, int32 hash);
~AudStream();

int readBuffer(int16 *buffer, const int numSamples);
bool isStereo() const { return false; }
int getRate() const { return READ_LE_UINT16(_data); };
bool endOfData() const { return _p == _end; }
bool rewind();
};

} // End of namespace BladeRunner

#endif
124 changes: 1 addition & 123 deletions engines/bladerunner/audio_player.cpp
Expand Up @@ -23,16 +23,14 @@
#include "audio_player.h"

#include "bladerunner/archive.h"
#include "bladerunner/aud_decoder.h"
#include "bladerunner/aud_stream.h"

#include "bladerunner/bladerunner.h"

#include "audio/audiostream.h"
#include "audio/mixer.h"

#include "common/array.h"
#include "common/debug.h"
#include "common/mutex.h"
#include "common/stream.h"

namespace Common {
Expand All @@ -41,41 +39,6 @@ namespace Common {

namespace BladeRunner {

/*
* This is a poor imitation of Bladerunner's resource cache
*/
class AudioCache {
struct cacheItem {
int32 hash;
int refs;
uint lastAccess;
byte *data;
uint32 size;
};

Common::Mutex _mutex;
Common::Array<cacheItem> _cacheItems;

uint32 _totalSize;
uint32 _maxSize;
uint32 _accessCounter;
public:
AudioCache() :
_totalSize(0),
_maxSize(2457600),
_accessCounter(0)
{}
~AudioCache();

bool canAllocate(uint32 size);
bool dropOldest();
byte *findByHash(int32 hash);
void storeByHash(int32 hash, Common::SeekableReadStream *stream);

void incRef(int32 hash);
void decRef(int32 hash);
};

AudioCache::~AudioCache() {
for (uint i = 0; i != _cacheItems.size(); ++i) {
free(_cacheItems[i].data);
Expand Down Expand Up @@ -163,91 +126,6 @@ void AudioCache::decRef(int32 hash) {
assert(0 && "AudioCache::decRef: hash not found");
}

class AudStream : public Audio::RewindableAudioStream {
byte *_data;
byte *_p;
byte *_end;
AudioCache *_cache;
int32 _hash;
byte _compressionType;
uint16 _deafBlockRemain;

ADPCMWestwoodDecoder _decoder;

public:
AudStream(AudioCache *cache, int32 hash)
: _cache(cache), _hash(hash)
{
_data = _cache->findByHash(_hash);
_end = _data + READ_LE_UINT32(_data + 2) + 12;
_cache->incRef(_hash);

assert(_end - _data >= 12);

_compressionType = *(_data + 11);

_deafBlockRemain = 0;
_p = _data + 12;
}
~AudStream() {
_cache->decRef(_hash);
}

int readBuffer(int16 *buffer, const int numSamples);
bool isStereo() const { return false; }
int getRate() const { return READ_LE_UINT16(_data); };
bool endOfData() const { return _p == _end; }
bool rewind();
};

int AudStream::readBuffer(int16 *buffer, const int numSamples) {
int samplesRead = 0;

assert(numSamples % 2 == 0);

if (_compressionType == 99) {
while (samplesRead < numSamples) {
if (_deafBlockRemain == 0) {
if (_end - _p == 0)
break;

assert(_end - _p >= 6);

uint16 blockSize = READ_LE_UINT16(_p);
uint16 blockOutSize = READ_LE_UINT16(_p + 2);
uint32 sig = READ_LE_UINT32(_p + 4);
_p += 8;

assert(sig == 0xdeaf);
assert(_end - _p >= blockSize);
assert(blockOutSize = 4 * blockSize);

_deafBlockRemain = blockSize;
}

assert(_end - _p >= _deafBlockRemain);

int bytesConsumed = MIN<int>(_deafBlockRemain, (numSamples - samplesRead) / 2);

_decoder.decode(_p, bytesConsumed, buffer + samplesRead);
_p += bytesConsumed;
_deafBlockRemain -= bytesConsumed;

samplesRead += 2 * bytesConsumed;
}
} else {
assert(0 && "readBuffer: Unimplemented");
}

return samplesRead;
}

bool AudStream::rewind() {
_p = _data + 12;
_decoder.setParameters(0, 0);
return true;
}

AudioPlayer::AudioPlayer(BladeRunnerEngine *vm)
: _vm(vm)
{
Expand Down

0 comments on commit 35ea849

Please sign in to comment.