KYRA: (LOK/Mac) - improve sound driver

(talkie version adjustments )
This commit is contained in:
athrxx 2022-08-12 23:27:07 +02:00
parent 6a1f0077ad
commit 3589e5cf1b
5 changed files with 78 additions and 50 deletions

View File

@ -407,7 +407,7 @@ public:
static HSSoundSystem *open(SoundMacRes *res, Audio::Mixer *mixer); static HSSoundSystem *open(SoundMacRes *res, Audio::Mixer *mixer);
static void close(); static void close();
bool init(bool hiQuality, uint8 interpolationMode, bool output16bit); bool init(bool hiQuality, uint8 interpolationMode, uint8 numChanSfx, bool output16bit);
void registerSamples(const uint16 *resList, bool registerOnly); void registerSamples(const uint16 *resList, bool registerOnly);
void releaseSamples(); void releaseSamples();
int changeSystemVoices(int numChanMusicTotal, int numChanMusicPoly, int numChanSfx); int changeSystemVoices(int numChanMusicTotal, int numChanMusicPoly, int numChanSfx);
@ -1295,16 +1295,18 @@ void HSLowLevelDriver::createTables() {
for (int i = 0; i < 16; ++i) for (int i = 0; i < 16; ++i)
_chan[i].status = -1; _chan[i].status = -1;
int sfxChanMult = 1;
// sample convert buffer // sample convert buffer
if (_sampleConvertBuffer) { if (_sampleConvertBuffer) {
if (_song._convertUnitSize != _convertUnitSizeLast || _song._numChanSfx != _numChanSfxLast || _convertBufferNumUnits - _song._numChanSfx != _song._numChanMusic) { if (_song._convertUnitSize != _convertUnitSizeLast || _song._numChanSfx != _numChanSfxLast || _convertBufferNumUnits - _song._numChanSfx * sfxChanMult != _song._numChanMusic) {
delete[] _sampleConvertBuffer; delete[] _sampleConvertBuffer;
_sampleConvertBuffer = nullptr; _sampleConvertBuffer = nullptr;
} }
} }
if (!_sampleConvertBuffer || _convertBufferNumUnits - _song._numChanSfx != _song._numChanMusic) { if (!_sampleConvertBuffer || _convertBufferNumUnits - _song._numChanSfx * sfxChanMult != _song._numChanMusic) {
_convertBufferNumUnits = _song._numChanMusic + _song._numChanSfx; _convertBufferNumUnits = _song._numChanMusic + _song._numChanSfx * sfxChanMult;
_convertUnitSizeLast = _song._convertUnitSize; _convertUnitSizeLast = _song._convertUnitSize;
_numChanSfxLast = _song._numChanSfx; _numChanSfxLast = _song._numChanSfx;
_sampleConvertBuffer = new uint8[(_convertBufferNumUnits << 8) + 64]; _sampleConvertBuffer = new uint8[(_convertBufferNumUnits << 8) + 64];
@ -2054,7 +2056,7 @@ void HSSoundSystem::close() {
} }
} }
bool HSSoundSystem::init(bool hiQuality, uint8 interpolationMode, bool output16bit) { bool HSSoundSystem::init(bool hiQuality, uint8 interpolationMode, uint8 numChanSfx, bool output16bit) {
if (_ready) if (_ready)
return true; return true;
@ -2069,15 +2071,13 @@ bool HSSoundSystem::init(bool hiQuality, uint8 interpolationMode, bool output16b
_vblTask = new HSAudioStream::CallbackProc(this, &HSSoundSystem::vblTaskProc); _vblTask = new HSAudioStream::CallbackProc(this, &HSSoundSystem::vblTaskProc);
_voicestr->setVblCallback(_vblTask); _voicestr->setVblCallback(_vblTask);
int numChanSfx = 1;
assert(interpolationMode < 3); assert(interpolationMode < 3);
if (hiQuality) { if (hiQuality) {
_driver->send(21, 7, 4, numChanSfx); _driver->send(21, 8 - numChanSfx, 4, numChanSfx);
_driver->send(24, (interpolationMode << 8) + 22); _driver->send(24, (interpolationMode << 8) + 22);
} else { } else {
_driver->send(21, 4, 3, numChanSfx); _driver->send(21, 4, 2 + numChanSfx, numChanSfx);
_driver->send(24, (interpolationMode << 8) + 11); _driver->send(24, (interpolationMode << 8) + 11);
} }
@ -2623,18 +2623,18 @@ bool HSVolumeScaler::process(const ShStBuffer &src, uint8 *dst, uint16 para1, ui
para1 = 1; para1 = 1;
if (!para2) if (!para2)
para2 = 1; para2 = 1;
int f = 1 << para2;
const uint8 *s = src.ptr; const uint8 *s = src.ptr;
uint32 len = src.len - copySndHeader(s, dst); uint32 len = src.len - copySndHeader(s, dst);
for (uint32 i = 0; i < len; ++i) { for (uint32 i = 0; i < len; ++i) {
int16 a = ((int16)i - 128) * para1; int16 a = (int16)*s++;
a = (a - 128) * para1;
if (a > 0) if (a > 0)
a += f; a += (para2 << 1);
else else
a -= f; a -= (para2 << 1);
a = CLIP<int16>(a / para2, -128, 127) - 128; a = CLIP<int16>(a / para2, -128, 127) + 128;
*dst++ = (a & 0xff); *dst++ = (a & 0xff);
} }
@ -2754,8 +2754,8 @@ HalestormDriver::~HalestormDriver() {
_hs = nullptr; _hs = nullptr;
} }
bool HalestormDriver::init(bool hiQuality, InterpolationMode imode, bool output16bit) { bool HalestormDriver::init(bool hiQuality, InterpolationMode imode, int numChanSfx, bool output16bit) {
return _hs->init(hiQuality, (uint8)imode, output16bit); return _hs->init(hiQuality, (uint8)imode, numChanSfx, output16bit);
} }
void HalestormDriver::registerSamples(const uint16 *resList, bool registerOnly) { void HalestormDriver::registerSamples(const uint16 *resList, bool registerOnly) {

View File

@ -51,7 +51,7 @@ public:
// higher (up to 12 bits, depending on the channel use). I have // higher (up to 12 bits, depending on the channel use). I have
// added an "output16bit" option which will output the unmodified // added an "output16bit" option which will output the unmodified
// intermediate data (but converting it from unsigned to signed). // intermediate data (but converting it from unsigned to signed).
bool init(bool hiQuality, InterpolationMode imode, bool output16bit); bool init(bool hiQuality, InterpolationMode imode, int numChanSfx, bool output16bit);
void registerSamples(const uint16 *resList, bool registerOnly); void registerSamples(const uint16 *resList, bool registerOnly);
void releaseSamples(); void releaseSamples();

View File

@ -383,6 +383,7 @@ private:
SoundMacRes *_res; SoundMacRes *_res;
HalestormDriver *_driver; HalestormDriver *_driver;
const int _talkieFlag;
bool _ready; bool _ready;
const uint16 *_resIDMusic; const uint16 *_resIDMusic;
@ -391,8 +392,8 @@ private:
static const uint16 _resIDMusicIntro[4]; static const uint16 _resIDMusicIntro[4];
static const uint16 _resIDMusicIngame[35]; static const uint16 _resIDMusicIngame[35];
static const uint8 _musicLoopTable[35]; static const uint8 _musicLoopTable[35];
static const uint16 _resIDSfxIntro[39]; static const uint16 _resIDSfxIntro[2][39];
static const uint16 _resIDSfxIngame[39]; static const uint16 _resIDSfxIngame[2][39];
struct SoundEffectDef { struct SoundEffectDef {
uint8 note; uint8 note;

View File

@ -33,12 +33,10 @@
#define HS_16BITOUTPUT false #define HS_16BITOUTPUT false
#define HS_INTERPOLATION kNone
namespace Kyra { namespace Kyra {
SoundMacRes::SoundMacRes(KyraEngine_v1 *vm) : _resMan(0), _stuffItArchive(nullptr) { SoundMacRes::SoundMacRes(KyraEngine_v1 *vm) : _resMan(0), _stuffItArchive(nullptr), _isTalkie(vm->gameFlags().isTalkie) {
_resMan = new Common::MacResManager[2]; _resMan = new Common::MacResManager[2];
if (vm->gameFlags().useInstallerPackage) { if (vm->gameFlags().useInstallerPackage) {
@ -60,6 +58,8 @@ bool SoundMacRes::init() {
return false; return false;
_kyraMacExe = _stuffItArchive ? "Legend of Kyrandia\xaa" : Util::findMacResourceFile("Legend of Kyrandia"); _kyraMacExe = _stuffItArchive ? "Legend of Kyrandia\xaa" : Util::findMacResourceFile("Legend of Kyrandia");
if (_kyraMacExe.empty() && _isTalkie)
_kyraMacExe = Util::findMacResourceFile("LK");
if (_kyraMacExe.empty()) { if (_kyraMacExe.empty()) {
warning("SoundMacRes::init(): Legend of Kyrandia resource fork not found"); warning("SoundMacRes::init(): Legend of Kyrandia resource fork not found");
@ -126,7 +126,7 @@ bool SoundMacRes::setQuality(bool hi) {
return true; return true;
} }
SoundMac::SoundMac(KyraEngine_v1 *vm, Audio::Mixer *mixer) : Sound(vm, mixer), _driver(nullptr), _res(nullptr), _currentResourceSet(-1), _resIDMusic(nullptr), _ready(false) { SoundMac::SoundMac(KyraEngine_v1 *vm, Audio::Mixer *mixer) : Sound(vm, mixer), _driver(nullptr), _res(nullptr), _currentResourceSet(-1), _resIDMusic(nullptr), _talkieFlag(vm->gameFlags().isTalkie ? 1 : 0), _ready(false) {
} }
SoundMac::~SoundMac() { SoundMac::~SoundMac() {
@ -148,7 +148,7 @@ bool SoundMac::init(bool hiQuality) {
_driver = new HalestormDriver(_res, _mixer); _driver = new HalestormDriver(_res, _mixer);
if (!(_driver && _driver->init(hiQuality, HalestormDriver::HS_INTERPOLATION, HS_16BITOUTPUT))) if (!(_driver && _driver->init(hiQuality, (hiQuality && _talkieFlag) ? HalestormDriver::kSimple : HalestormDriver::kNone, 1 + _talkieFlag, HS_16BITOUTPUT)))
return false; return false;
setQuality(hiQuality); setQuality(hiQuality);
@ -211,11 +211,11 @@ void SoundMac::playSoundEffect(uint16 track, uint8) {
if (_currentResourceSet == kMusicIntro) { if (_currentResourceSet == kMusicIntro) {
if (track > 21 && track < 38) if (track > 21 && track < 38)
_driver->startSoundEffect(_resIDSfxIntro[_soundEffectDefsIntro[track - 22].number]); _driver->startSoundEffect(_resIDSfxIntro[_talkieFlag][_soundEffectDefsIntro[track - 22].number]);
} else { } else {
const SoundEffectDef *se = &_soundEffectDefsIngame[track]; const SoundEffectDef *se = &_soundEffectDefsIngame[track];
if (se->note) if (se->note)
_driver->enqueueSoundEffect(_resIDSfxIngame[se->number], se->rate, se->note); _driver->enqueueSoundEffect(_resIDSfxIngame[_talkieFlag][se->number], se->rate, se->note);
} }
} }
@ -253,11 +253,19 @@ void SoundMac::enableMusic(int enable) {
} }
void SoundMac::setQuality(bool hi) { void SoundMac::setQuality(bool hi) {
static const uint16 resIds[] = { static const uint16 resIDs[2][30] = {
0x1b5b, 0x1b5c, 0x1b5e, 0x1b62, 0x1b63, 0x1b6b, 0x1b6c, 0x1b6d, {
0x1b6e, 0x1b6f, 0x1b70, 0x1b71, 0x1b72, 0x1b73, 0x1b74, 0x1b75, 0x1b5b, 0x1b5c, 0x1b5e, 0x1b62, 0x1b63, 0x1b6b, 0x1b6c, 0x1b6d,
0x1b76, 0x1b77, 0x1b78, 0x1b79, 0x1b7a, 0x1b7b, 0x1b7c, 0x1b7d, 0x1b6e, 0x1b6f, 0x1b70, 0x1b71, 0x1b72, 0x1b73, 0x1b74, 0x1b75,
0x1b7e, 0x1b8a, 0x1bbc, 0x1bbd, 0x1bbe, 0xffff 0x1b76, 0x1b77, 0x1b78, 0x1b79, 0x1b7a, 0x1b7b, 0x1b7c, 0x1b7d,
0x1b7e, 0x1b8a, 0x1bbc, 0x1bbd, 0x1bbe, 0xffff
},
{
0x1b97, 0x1b98, 0x1b9a, 0x1b9e, 0x1b9f, 0x1b6b, 0x1b6c, 0x1b6d,
0x1b6e, 0x1b6f, 0x1b70, 0x1b71, 0x1b72, 0x1b73, 0x1b74, 0x1b75,
0x1b76, 0x1b77, 0x1b78, 0x1b79, 0x1b7a, 0x1b7b, 0x1b7c, 0x1b7d,
0x1b7e, 0x1b8a, 0x1bbc, 0x1bbd, 0x1bbe, 0xffff
}
}; };
if (!(_driver && _res)) if (!(_driver && _res))
@ -270,21 +278,21 @@ void SoundMac::setQuality(bool hi) {
_res->setQuality(hi); _res->setQuality(hi);
if (hi) { if (hi) {
_driver->changeSystemVoices(7, 4, 1); _driver->changeSystemVoices(7 - _talkieFlag, 4, 1 + _talkieFlag);
_driver->doCommand(HalestormDriver::kSetRateAndIntrplMode, 3); _driver->doCommand(HalestormDriver::kSetRateAndIntrplMode, 3 + (_talkieFlag << 1));
} else { } else {
_driver->changeSystemVoices(4, 3, 1); _driver->changeSystemVoices(4, 3 + _talkieFlag, 1 + _talkieFlag);
_driver->doCommand(HalestormDriver::kSetRateAndIntrplMode, 2); _driver->doCommand(HalestormDriver::kSetRateAndIntrplMode, 2 + _talkieFlag);
} }
_driver->registerSamples(resIds, true); _driver->registerSamples(resIDs[_talkieFlag], true);
} }
const uint16 SoundMac::_resIDMusicIntro[4] { const uint16 SoundMac::_resIDMusicIntro[4] {
0x00c8, 0x00c9, 0x00ca, 0x00cb 0x00c8, 0x00c9, 0x00ca, 0x00cb
}; };
const uint16 SoundMac::_resIDMusicIngame[35] { const uint16 SoundMac::_resIDMusicIngame[35] = {
0x0064, 0x0065, 0x0066, 0x0067, 0x0068, 0x0069, 0x006a, 0x006b, 0x0064, 0x0065, 0x0066, 0x0067, 0x0068, 0x0069, 0x006a, 0x006b,
0x006c, 0x006d, 0x006e, 0x006f, 0x0070, 0x0071, 0x0072, 0x0073, 0x006c, 0x006d, 0x006e, 0x006f, 0x0070, 0x0071, 0x0072, 0x0073,
0x0074, 0x0075, 0x0076, 0x0077, 0x0078, 0x0079, 0x007a, 0x01f4, 0x0074, 0x0075, 0x0076, 0x0077, 0x0078, 0x0079, 0x007a, 0x01f4,
@ -293,7 +301,7 @@ const uint16 SoundMac::_resIDMusicIngame[35] {
}; };
const uint8 SoundMac::_musicLoopTable[35] { const uint8 SoundMac::_musicLoopTable[35] = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x01, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x00, 0x01, 0x01, 0x01, 0x00, 0x01, 0x01,
0x00, 0x00, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01,
@ -301,20 +309,38 @@ const uint8 SoundMac::_musicLoopTable[35] {
0x01, 0x00, 0x00 0x01, 0x00, 0x00
}; };
const uint16 SoundMac::_resIDSfxIntro[39] { const uint16 SoundMac::_resIDSfxIntro[2][39] = {
0x1b58, 0x1b59, 0x1b5a, 0x1b5b, 0x1b5c, 0x1b5d, 0x1b5e, 0x1b5f, {
0x1b60, 0x1b61, 0x1b62, 0x1b63, 0x1b64, 0x1b65, 0x1b66, 0x1b67, 0x1b58, 0x1b59, 0x1b5a, 0x1b5b, 0x1b5c, 0x1b5d, 0x1b5e, 0x1b5f,
0x1b68, 0x1b69, 0x1b6a, 0x1b6d, 0x1b6c, 0x1b7a, 0x1bbc, 0x1bbd, 0x1b60, 0x1b61, 0x1b62, 0x1b63, 0x1b64, 0x1b65, 0x1b66, 0x1b67,
0x1bbe, 0x1b71, 0x1b72, 0x1b73, 0x1b74, 0x1b75, 0x1b76, 0x1b77, 0x1b68, 0x1b69, 0x1b6a, 0x1b6d, 0x1b6c, 0x1b7a, 0x1bbc, 0x1bbd,
0x1b78, 0x1b79, 0x1b7a, 0x1b7b, 0x1b7c, 0x1b7d, 0x1b7e 0x1bbe, 0x1b71, 0x1b72, 0x1b73, 0x1b74, 0x1b75, 0x1b76, 0x1b77,
0x1b78, 0x1b79, 0x1b7a, 0x1b7b, 0x1b7c, 0x1b7d, 0x1b7e
},
{
0x1b94, 0x1b95, 0x1b96, 0x1b97, 0x1b8b, 0x1b99, 0x1b9a, 0x1b9b,
0x1b9c, 0x1b9d, 0x1b9e, 0x1b9f, 0x1ba0, 0x1ba1, 0x1ba2, 0x1ba3,
0x1ba4, 0x1b69, 0x1b6a, 0x1b6d, 0x1b6c, 0x1b7a, 0x1bbc, 0x1bbd,
0x1bbe, 0x1b71, 0x1b72, 0x1b73, 0x1b74, 0x1b75, 0x1b76, 0x1b77,
0x1b78, 0x1b79, 0x1b7a, 0x1b7b, 0x1b7c, 0x1b7d, 0x1b7e
}
}; };
const uint16 SoundMac::_resIDSfxIngame[39] { const uint16 SoundMac::_resIDSfxIngame[2][39] = {
0x1b58, 0x1b59, 0x1b5a, 0x1b5b, 0x1b5c, 0x1b5d, 0x1b5e, 0x1b5f, {
0x1b60, 0x1b61, 0x1b62, 0x1b63, 0x1b64, 0x1b65, 0x1b66, 0x1b67, 0x1b58, 0x1b59, 0x1b5a, 0x1b5b, 0x1b5c, 0x1b5d, 0x1b5e, 0x1b5f,
0x1b68, 0x1b69, 0x1b6a, 0x1b6b, 0x1b6c, 0x1b6d, 0x1b6e, 0x1b6f, 0x1b60, 0x1b61, 0x1b62, 0x1b63, 0x1b64, 0x1b65, 0x1b66, 0x1b67,
0x1b70, 0x1b71, 0x1b72, 0x1b73, 0x1b74, 0x1b75, 0x1b76, 0x1b77, 0x1b68, 0x1b69, 0x1b6a, 0x1b6b, 0x1b6c, 0x1b6d, 0x1b6e, 0x1b6f,
0x1b78, 0x1b8a, 0x1b7a, 0x1b7b, 0x1b7c, 0x1b7d, 0x1b7e 0x1b70, 0x1b71, 0x1b72, 0x1b73, 0x1b74, 0x1b75, 0x1b76, 0x1b77,
0x1b78, 0x1b8a, 0x1b7a, 0x1b7b, 0x1b7c, 0x1b7d, 0x1b7e
},
{
0x1b94, 0x1b95, 0x1b96, 0x1b97, 0x1b98, 0x1b99, 0x1b9a, 0x1b9b,
0x1b9c, 0x1b9d, 0x1b9e, 0x1b9f, 0x1ba0, 0x1ba1, 0x1ba2, 0x1ba3,
0x1ba4, 0x1b69, 0x1b6a, 0x1b6b, 0x1b6c, 0x1b6d, 0x1b6e, 0x1b6f,
0x1b70, 0x1b71, 0x1b72, 0x1b73, 0x1b74, 0x1b75, 0x1b76, 0x1b77,
0x1b78, 0x1b8a, 0x1b7a, 0x1b7b, 0x1b7c, 0x1b7d, 0x1b7e
}
}; };
const SoundMac::SoundEffectDef SoundMac::_soundEffectDefsIntro[16] = { const SoundMac::SoundEffectDef SoundMac::_soundEffectDefsIntro[16] = {

View File

@ -49,6 +49,7 @@ private:
Common::MacResManager *_resMan; Common::MacResManager *_resMan;
Common::Archive *_stuffItArchive; Common::Archive *_stuffItArchive;
Common::Mutex _mutex; Common::Mutex _mutex;
const bool _isTalkie;
}; };
} // End of namespace Kyra } // End of namespace Kyra