AUDIO: Add Paula per-channel DMA interrupts

These will be needed for proper emulation of the Amiga SCUMM V2/V3
sound engines.
This commit is contained in:
Quietust 2021-12-08 15:58:51 -06:00 committed by Eugene Sandulenko
parent 8a87d1030c
commit 3f4d59800d
2 changed files with 18 additions and 0 deletions

View File

@ -81,6 +81,7 @@ void Paula::clearVoice(byte voice) {
_voice[voice].volume = 0;
_voice[voice].offset = Offset(0);
_voice[voice].dmaCount = 0;
_voice[voice].interrupt = false;
}
int Paula::readBuffer(int16 *buffer, const int numSamples) {
@ -239,6 +240,15 @@ int Paula::readBufferIntern(int16 *buffer, const int numSamples) {
ch.data = ch.dataRepeat;
ch.length = ch.lengthRepeat;
// The Paula chip can generate an interrupt after it copies a channel's
// location and length values to its internal registers, signaling that
// it's safe to modify them. Some sound engines use this feature in order
// to control sound looping.
// NOTE: the real Paula would also do this during enableChannel() and in
// the middle of setChannelData(); for simplicity, we only do it here.
if (ch.interrupt)
interruptChannel(voice);
}
// If we have not yet generated enough samples, and looping is active: loop!

View File

@ -112,6 +112,7 @@ protected:
Offset offset;
byte panning; // For stereo mixing: 0 = far left, 255 = far right
int dmaCount;
bool interrupt;
};
bool _end;
@ -119,6 +120,8 @@ protected:
virtual void interrupt() = 0;
virtual void interruptChannel(byte channel) { }
void startPaula() {
_playing = true;
_end = false;
@ -149,6 +152,11 @@ protected:
// ch.period = ch.periodRepeat;
}
void setChannelInterrupt(byte channel, bool enable) {
assert(channel < NUM_VOICES);
_voice[channel].interrupt = enable;
}
void setChannelPeriod(byte channel, int16 period) {
assert(channel < NUM_VOICES);
_voice[channel].period = period;