[Scummvm-git-logs] scummvm master -> 7f6cc6b12ba6c70de3879d584da81f4f6a11ef3d
athrxx
noreply at scummvm.org
Sat Oct 5 12:50:39 UTC 2024
This automated email contains information about 1 new commit which have been
pushed to the 'scummvm' repo located at https://github.com/scummvm/scummvm .
Summary:
7f6cc6b12b SCI: (PCJr sound driver) - minor cleanup
Commit: 7f6cc6b12ba6c70de3879d584da81f4f6a11ef3d
https://github.com/scummvm/scummvm/commit/7f6cc6b12ba6c70de3879d584da81f4f6a11ef3d
Author: athrxx (athrxx at scummvm.org)
Date: 2024-10-05T14:50:15+02:00
Commit Message:
SCI: (PCJr sound driver) - minor cleanup
(remove emumidi dependance)
Changed paths:
engines/sci/sound/drivers/pcjr.cpp
diff --git a/engines/sci/sound/drivers/pcjr.cpp b/engines/sci/sound/drivers/pcjr.cpp
index ce3bcfd3ad1..b3d642c666a 100644
--- a/engines/sci/sound/drivers/pcjr.cpp
+++ b/engines/sci/sound/drivers/pcjr.cpp
@@ -22,7 +22,8 @@
#include "sci/sound/drivers/mididriver.h"
#include "sci/resource/resource.h"
-#include "audio/softsynth/emumidi.h"
+#include "audio/audiostream.h"
+#include "audio/mixer.h"
#include "common/debug.h"
#include "common/system.h"
@@ -334,7 +335,7 @@ void SoundChannel_PCJr_SCI1::reset() {
_ctrlVolume = _envVolume = 15;
_envData = nullptr;
_pbDiv = 170;
- updateChannelVolume();
+ updateChannelVolume();
}
void SoundChannel_PCJr_SCI1::updateChannelVolume() {
@@ -412,7 +413,7 @@ void SoundChannel_PCJr_SCI1::processInstrument() {
}
}
-class MidiDriver_PCJr : public MidiDriver_Emulated {
+class MidiDriver_PCJr : public MidiDriver, public Audio::AudioStream {
public:
friend class MidiPlayer_PCJr;
enum Properties {
@@ -431,17 +432,20 @@ public:
MidiChannel *getPercussionChannel() override { return nullptr; }
uint32 property(int prop, uint32 value) override;
void initTrack(SciSpan<const byte> &header);
-
+
// AudioStream
+ int readBuffer(int16 *buf, const int len) override { return generateSamples(buf, len); }
+ bool endOfData() const override { return false; }
bool isStereo() const override { return false; }
int getRate() const override { return _mixer->getOutputRate(); }
- // MidiDriver_Emulated
- void generateSamples(int16 *buf, int len) override;
+ // MidiDriver
+ void setTimerCallback(void *timer_param, Common::TimerManager::TimerProc timer_proc) override;
+ bool isOpen() const override { return _isOpen; }
+ uint32 getBaseTempo() override { return 16666; }
private:
bool loadInstruments(Resource &resource);
- void processEnvelopes();
void noteOn(byte part, byte note, byte velocity);
void noteOff(byte part, byte note);
@@ -456,6 +460,9 @@ private:
void assignFreeChannels(byte part);
byte allocateChannel(byte part);
+ int generateSamples(int16 *buf, int len);
+ void nextTick();
+
byte _masterVolume;
byte *_chanMapping;
byte *_chanMissing;
@@ -475,8 +482,71 @@ private:
const SciVersion _version;
const byte _numChannels;
const bool _pcsMode;
+
+ Audio::Mixer *_mixer;
+ Audio::SoundHandle _mixerSoundHandle;
+ Common::TimerManager::TimerProc _timerProc;
+ void *_timerProcPara;
+ bool _isOpen;
};
+MidiDriver_PCJr::MidiDriver_PCJr(Audio::Mixer *mixer, SciVersion version, bool pcsMode) : _mixer(mixer), _version(version), _pcsMode(pcsMode), _numChannels(pcsMode ? 1 : 3),
+ _masterVolume(0), _channels(nullptr), _instrumentOffsets(nullptr), _instrumentData(nullptr), _isOpen(false) {
+
+ uint16 *smpVolTable = new uint16[16]();
+ for (int i = 0; i < 15; ++i) // The last entry is left at zero.
+ smpVolTable[i] = (double)((32767 & ~_numChannels) / _numChannels) / pow(10.0, (double)i / 10.0);
+ Common::SharedPtr<const uint16> smpVolTablePtr(smpVolTable, Common::ArrayDeleter<const uint16>());
+
+ uint16 *freqTable = new uint16[48]();
+ assert(freqTable);
+ for (int i = 0; i < 48; ++i)
+ freqTable[i] = pow(2, (double)(288 + i) / 48.0) * 440.0;
+ Common::SharedPtr<const uint16> freqTablePtr(freqTable, Common::ArrayDeleter<const uint16>());
+
+ _chanMapping = new byte[16]();
+ _chanMissing = new byte[16]();
+ _program = new byte[16]();
+ _sustain = new byte[16]();
+
+ assert(_chanMapping);
+ assert(_chanMissing);
+ assert(_program);
+ assert(_sustain);
+
+ _channels = new SoundHWChannel*[_numChannels]();
+ assert(_channels);
+ for (int i = 0; i < _numChannels; ++i) {
+ if (pcsMode)
+ _channels[i] = new SoundChannel_PCSpeaker(freqTablePtr, smpVolTablePtr, _masterVolume, getRate());
+ else if (version <= SCI_VERSION_0_LATE)
+ _channels[i] = new SoundChannel_PCJr_SCI0(freqTablePtr, smpVolTablePtr, _masterVolume, getRate());
+ else
+ _channels[i] = new SoundChannel_PCJr_SCI1(freqTablePtr, smpVolTablePtr, _masterVolume, getRate(), _instrumentOffsets, _instrumentData, _program);
+ }
+
+ _sndUpdateSmpQty = (mixer->getOutputRate() << 16) / 0x3C0000;
+ _sndUpdateSmpQtyRem = (mixer->getOutputRate() << 16) % 0x3C0000;
+ _sndUpdateCountDown = _sndUpdateSmpQty;
+ _sndUpdateCountDownRem = 0;
+}
+
+MidiDriver_PCJr::~MidiDriver_PCJr() {
+ close();
+ if (_channels) {
+ for (int i = 0; i < _numChannels; ++i)
+ delete _channels[i];
+ delete[] _channels;
+ }
+
+ delete[] _instrumentOffsets;
+ delete[] _instrumentData;
+ delete[] _chanMapping;
+ delete[] _chanMissing;
+ delete[] _program;
+ delete[] _sustain;
+}
+
void MidiDriver_PCJr::send(uint32 b) {
byte command = b & 0xff;
byte op1 = (b >> 8) & 0xff;
@@ -490,8 +560,8 @@ void MidiDriver_PCJr::send(uint32 b) {
case 0x90:
if (!op2)
noteOff(part, op1);
- else
- noteOn(part, op1, op2);
+ else
+ noteOn(part, op1, op2);
break;
case 0xb0:
controlChange(part, op1, op2);
@@ -506,11 +576,6 @@ void MidiDriver_PCJr::send(uint32 b) {
debug(2, "Unused MIDI command %02x %02x %02x", command, op1, op2);
break;
}
-
- if (!_pcsMode) {
- _sndUpdateCountDown = 1;
- _sndUpdateCountDownRem = 0;
- }
}
uint32 MidiDriver_PCJr::property(int prop, uint32 value) {
@@ -563,85 +628,9 @@ void MidiDriver_PCJr::initTrack(SciSpan<const byte> &header) {
}
}
-void MidiDriver_PCJr::generateSamples(int16 *data, int len) {
- for (int i = 0; i < len; i++) {
- if (!--_sndUpdateCountDown) {
- _sndUpdateCountDown = _sndUpdateSmpQty;
- _sndUpdateCountDownRem += _sndUpdateSmpQtyRem;
- while (_sndUpdateCountDownRem >= (_sndUpdateSmpQty << 16)) {
- _sndUpdateCountDownRem -= (_sndUpdateSmpQty << 16);
- ++_sndUpdateCountDown;
- }
- processEnvelopes();
- }
-
- int16 result = 0;
-
- for (int chan = 0; chan < _numChannels; chan++) {
- if (!_channels[chan]->isPlaying())
- continue;
- _channels[chan]->recalcSample();
- result += _channels[chan]->currentSample();
- }
- data[i] = result;
- }
-}
-
-MidiDriver_PCJr::MidiDriver_PCJr(Audio::Mixer *mixer, SciVersion version, bool pcsMode) : MidiDriver_Emulated(mixer), _version(version), _pcsMode(pcsMode), _numChannels(pcsMode ? 1 : 3),
- _masterVolume(0), _channels(nullptr), _instrumentOffsets(nullptr), _instrumentData(nullptr) {
-
- uint16 *smpVolTable = new uint16[16]();
- for (int i = 0; i < 15; ++i) // The last entry is left at zero.
- smpVolTable[i] = (double)((32767 & ~_numChannels) / _numChannels) / pow(10.0, (double)i / 10.0);
- Common::SharedPtr<const uint16> smpVolTablePtr(smpVolTable, Common::ArrayDeleter<const uint16>());
-
- uint16 *freqTable = new uint16[48]();
- assert(freqTable);
- for (int i = 0; i < 48; ++i)
- freqTable[i] = pow(2, (double)(288 + i) / 48.0) * 440.0;
- Common::SharedPtr<const uint16> freqTablePtr(freqTable, Common::ArrayDeleter<const uint16>());
-
- _chanMapping = new byte[16]();
- _chanMissing = new byte[16]();
- _program = new byte[16]();
- _sustain = new byte[16]();
-
- assert(_chanMapping);
- assert(_chanMissing);
- assert(_program);
- assert(_sustain);
-
- _channels = new SoundHWChannel*[_numChannels]();
- assert(_channels);
- for (int i = 0; i < _numChannels; ++i) {
- if (pcsMode)
- _channels[i] = new SoundChannel_PCSpeaker(freqTablePtr, smpVolTablePtr, _masterVolume, getRate());
- else if (version <= SCI_VERSION_0_LATE)
- _channels[i] = new SoundChannel_PCJr_SCI0(freqTablePtr, smpVolTablePtr, _masterVolume, getRate());
- else
- _channels[i] = new SoundChannel_PCJr_SCI1(freqTablePtr, smpVolTablePtr, _masterVolume, getRate(), _instrumentOffsets, _instrumentData, _program);
- }
-
- _sndUpdateSmpQty = (mixer->getOutputRate() << 16) / 0x3C0000;
- _sndUpdateSmpQtyRem = (mixer->getOutputRate() << 16) % 0x3C0000;
- _sndUpdateCountDown = _sndUpdateSmpQty;
- _sndUpdateCountDownRem = 0;
-}
-
-MidiDriver_PCJr::~MidiDriver_PCJr() {
- close();
- if (_channels) {
- for (int i = 0; i < _numChannels; ++i)
- delete _channels[i];
- delete[] _channels;
- }
-
- delete[] _instrumentOffsets;
- delete[] _instrumentData;
- delete[] _chanMapping;
- delete[] _chanMissing;
- delete[] _program;
- delete[] _sustain;
+void MidiDriver_PCJr::setTimerCallback(void *timer_param, Common::TimerManager::TimerProc timer_proc) {
+ _timerProc = timer_proc;
+ _timerProcPara = timer_param;
}
int MidiDriver_PCJr::open() {
@@ -661,11 +650,11 @@ int MidiDriver_PCJr::open() {
return MERR_CANNOT_CONNECT;
}
- int res = MidiDriver_Emulated::open();
-
_mixer->playStream(Audio::Mixer::kPlainSoundType, &_mixerSoundHandle, this, -1, _mixer->kMaxChannelVolume, 0, DisposeAfterUse::NO);
- return res;
+ _isOpen = true;
+
+ return 0;
}
void MidiDriver_PCJr::close() {
@@ -697,7 +686,7 @@ bool MidiDriver_PCJr::loadInstruments(Resource &resource) {
for (int i = 0; i < 40; ++i) {
for (uint8 in = 0; writePos < 770 && in != 0xFF; ) {
in = resource.getUint8At(readPos++);
- instrumentData[writePos++] = in;
+ instrumentData[writePos++] = in;
}
}
@@ -707,13 +696,6 @@ bool MidiDriver_PCJr::loadInstruments(Resource &resource) {
return true;
}
-void MidiDriver_PCJr::processEnvelopes() {
- for (int i = 0; i < _numChannels; i++) {
- if (_channels[i]->isPlaying())
- _channels[i]->processEnvelope();
- }
-}
-
void MidiDriver_PCJr::noteOn(byte part, byte note, byte velocity) {
if (_pcsMode) {
if (!_channels[0]->isMappedToPart(part))
@@ -747,7 +729,7 @@ void MidiDriver_PCJr::noteOff(byte part, byte note) {
if (!_channels[i]->isMappedToPart(part) || !_channels[i]->hasNote(note))
continue;
_channels[i]->noteOff(_sustain[part]);
- }
+ }
}
void MidiDriver_PCJr::controlChange(byte part, byte controller, byte value) {
@@ -939,7 +921,7 @@ byte MidiDriver_PCJr::allocateChannel(byte part) {
continue;
res = c;
- oldest = ct;
+ oldest = ct;
}
if (oldest != 0) {
@@ -950,6 +932,39 @@ byte MidiDriver_PCJr::allocateChannel(byte part) {
return res;
}
+int MidiDriver_PCJr::generateSamples(int16 *data, int len) {
+ for (int i = 0; i < len; i++) {
+ if (!--_sndUpdateCountDown) {
+ _sndUpdateCountDown = _sndUpdateSmpQty;
+ _sndUpdateCountDownRem += _sndUpdateSmpQtyRem;
+ while (_sndUpdateCountDownRem >= (_sndUpdateSmpQty << 16)) {
+ _sndUpdateCountDownRem -= (_sndUpdateSmpQty << 16);
+ ++_sndUpdateCountDown;
+ }
+ nextTick();
+ }
+
+ int16 smp = 0;
+
+ for (int chan = 0; chan < _numChannels; chan++) {
+ if (!_channels[chan]->isPlaying())
+ continue;
+ _channels[chan]->recalcSample();
+ smp += _channels[chan]->currentSample();
+ }
+ data[i] = smp;
+ }
+ return len;
+}
+
+void MidiDriver_PCJr::nextTick() {
+ _timerProc(_timerProcPara);
+ for (int i = 0; i < _numChannels; i++) {
+ if (_channels[i]->isPlaying())
+ _channels[i]->processEnvelope();
+ }
+}
+
class MidiPlayer_PCJr : public MidiPlayer {
public:
MidiPlayer_PCJr(SciVersion version, bool pcsMode) : MidiPlayer(version) { _driver = new MidiDriver_PCJr(g_system->getMixer(), version, pcsMode); }
More information about the Scummvm-git-logs
mailing list