[Scummvm-git-logs] scummvm branch-2-6 -> fccca40cedc3ea377881d33091f8a310b6474e7f
NMIError
noreply at scummvm.org
Tue Jun 14 12:52:42 UTC 2022
This automated email contains information about 2 new commits which have been
pushed to the 'scummvm' repo located at https://github.com/scummvm/scummvm .
Summary:
e57f63cf70 AUDIO: Make subclassing Module and ProtrackerStream easier
fccca40ced AUDIO: Make module dtor virtual
Commit: e57f63cf70ac5793b55fd1a5f75be84a76227712
https://github.com/scummvm/scummvm/commit/e57f63cf70ac5793b55fd1a5f75be84a76227712
Author: Coen Rampen (crampen at gmail.com)
Date: 2022-06-14T14:49:46+02:00
Commit Message:
AUDIO: Make subclassing Module and ProtrackerStream easier
To implement a MOD variant for the Chewy engine, this commit makes some changes
to make subclassing of the ProtrackerStream and associated Module class easier.
Changed paths:
audio/mods/module.h
audio/mods/paula.cpp
audio/mods/paula.h
audio/mods/protracker.cpp
audio/mods/protracker.h
diff --git a/audio/mods/module.h b/audio/mods/module.h
index b08aca7b016..47e11e5f5f0 100644
--- a/audio/mods/module.h
+++ b/audio/mods/module.h
@@ -76,11 +76,11 @@ public:
Module();
~Module();
- bool load(Common::SeekableReadStream &stream, int offs);
+ virtual bool load(Common::SeekableReadStream &stream, int offs);
static byte periodToNote(int16 period, byte finetune = 0);
static int16 noteToPeriod(byte note, byte finetune = 0);
-private:
+protected:
static const int16 periods[16][60];
static const uint32 signatures[];
};
diff --git a/audio/mods/paula.cpp b/audio/mods/paula.cpp
index 01dae134d4d..371b52a5724 100644
--- a/audio/mods/paula.cpp
+++ b/audio/mods/paula.cpp
@@ -52,10 +52,10 @@ Paula::Paula(bool stereo, int rate, uint interruptFreq, FilterMode filterMode, i
_filterState.a0[2] = filterCalculateA0(rate, 7000);
clearVoices();
- _voice[0].panning = 191;
- _voice[1].panning = 63;
- _voice[2].panning = 63;
- _voice[3].panning = 191;
+ _voice[0].panning = PANNING_RIGHT;
+ _voice[1].panning = PANNING_LEFT;
+ _voice[2].panning = PANNING_LEFT;
+ _voice[3].panning = PANNING_RIGHT;
if (_intFreq == 0)
_intFreq = _rate;
diff --git a/audio/mods/paula.h b/audio/mods/paula.h
index a7b7b920725..f3ac433f1e2 100644
--- a/audio/mods/paula.h
+++ b/audio/mods/paula.h
@@ -36,6 +36,10 @@ namespace Audio {
class Paula : public AudioStream {
public:
static const int NUM_VOICES = 4;
+ // Default panning value for left channels.
+ static const int PANNING_LEFT = 63;
+ // Default panning value for right channels.
+ static const int PANNING_RIGHT = 191;
enum {
kPalSystemClock = 7093790,
kNtscSystemClock = 7159090,
diff --git a/audio/mods/protracker.cpp b/audio/mods/protracker.cpp
index c79fbd9f141..70928d21fa8 100644
--- a/audio/mods/protracker.cpp
+++ b/audio/mods/protracker.cpp
@@ -28,114 +28,6 @@
namespace Modules {
-class ProtrackerStream : public ::Audio::Paula {
-private:
- Module _module;
-
- int _tick;
- int _row;
- int _pos;
-
- int _speed;
- int _bpm;
-
- // For effect 0xB - Jump To Pattern;
- bool _hasJumpToPattern;
- int _jumpToPattern;
-
- // For effect 0xD - PatternBreak;
- bool _hasPatternBreak;
- int _skipRow;
-
- // For effect 0xE6 - Pattern Loop
- bool _hasPatternLoop;
- int _patternLoopCount;
- int _patternLoopRow;
-
- // For effect 0xEE - Pattern Delay
- byte _patternDelay;
-
- static const int16 sinetable[];
-
- struct Track {
- byte sample;
- byte lastSample;
- uint16 period;
- Offset offset;
-
- byte vol;
- byte finetune;
-
- // For effect 0x0 - Arpeggio
- bool arpeggio;
- byte arpeggioNotes[3];
-
- // For effect 0x3 - Porta to note
- uint16 portaToNote;
- byte portaToNoteSpeed;
-
- // For effect 0x4 - Vibrato
- int vibrato;
- byte vibratoPos;
- byte vibratoSpeed;
- byte vibratoDepth;
-
- // For effect 0xED - Delay sample
- byte delaySample;
- byte delaySampleTick;
- } _track[4];
-
-public:
- ProtrackerStream(Common::SeekableReadStream *stream, int offs, int rate, bool stereo);
-
- Modules::Module *getModule() {
- // Ordinarily, the Module is not meant to be seen outside of
- // this class, but occasionally, it's useful to be able to
- // manipulate it directly. The Hopkins engine uses this to
- // repair a broken song.
- return &_module;
- }
-
-private:
- void interrupt() override;
-
- void doPorta(int track) {
- if (_track[track].portaToNote && _track[track].portaToNoteSpeed) {
- int distance = _track[track].period - _track[track].portaToNote;
- int sign = distance > 0 ? 1 : -1;
-
- if ((sign * distance) > _track[track].portaToNoteSpeed)
- _track[track].period -= sign * _track[track].portaToNoteSpeed;
- else
- _track[track].period = _track[track].portaToNote;
- }
- }
- void doVibrato(int track) {
- _track[track].vibrato =
- (_track[track].vibratoDepth * sinetable[_track[track].vibratoPos]) / 128;
- _track[track].vibratoPos += _track[track].vibratoSpeed;
- _track[track].vibratoPos %= 64;
- }
- void doVolSlide(int track, byte ex, byte ey) {
- int vol = _track[track].vol;
- if (ex == 0)
- vol -= ey;
- else if (ey == 0)
- vol += ex;
-
- if (vol < 0)
- vol = 0;
- else if (vol > 64)
- vol = 64;
-
- _track[track].vol = vol;
- }
-
- void updateRow();
- void updateEffects();
-
-};
-
const int16 ProtrackerStream::sinetable[64] = {
0, 24, 49, 74, 97, 120, 141, 161,
180, 197, 212, 224, 235, 244, 250, 253,
@@ -147,10 +39,8 @@ const int16 ProtrackerStream::sinetable[64] = {
-180, -161, -141, -120, -97, -74, -49, -24
};
-ProtrackerStream::ProtrackerStream(Common::SeekableReadStream *stream, int offs, int rate, bool stereo) :
- Paula(stereo, rate, rate/50) {
- bool result = _module.load(*stream, offs);
- assert(result);
+ProtrackerStream::ProtrackerStream(int rate, bool stereo) : Paula(stereo, rate, rate / 50) {
+ _module = nullptr;
_tick = _row = _pos = 0;
@@ -170,17 +60,31 @@ ProtrackerStream::ProtrackerStream(Common::SeekableReadStream *stream, int offs,
_patternDelay = 0;
ARRAYCLEAR(_track);
+}
+
+ProtrackerStream::ProtrackerStream(Common::SeekableReadStream *stream, int offs, int rate, bool stereo) :
+ ProtrackerStream(rate, stereo) {
+ _module = new Module();
+ bool result = _module->load(*stream, offs);
+ assert(result);
startPaula();
}
+ProtrackerStream::~ProtrackerStream() {
+ if (_module) {
+ delete _module;
+ _module = nullptr;
+ }
+}
+
void ProtrackerStream::updateRow() {
for (int track = 0; track < 4; track++) {
_track[track].arpeggio = false;
_track[track].vibrato = 0;
_track[track].delaySampleTick = 0;
const note_t note =
- _module.pattern[_module.songpos[_pos]][_row][track];
+ _module->pattern[_module->songpos[_pos]][_row][track];
const int effect = note.effect >> 8;
@@ -190,14 +94,14 @@ void ProtrackerStream::updateRow() {
}
_track[track].sample = note.sample;
_track[track].lastSample = note.sample;
- _track[track].finetune = _module.sample[note.sample - 1].finetune;
- _track[track].vol = _module.sample[note.sample - 1].vol;
+ _track[track].finetune = _module->sample[note.sample - 1].finetune;
+ _track[track].vol = _module->sample[note.sample - 1].vol;
}
if (note.period) {
if (effect != 3 && effect != 5) {
if (_track[track].finetune)
- _track[track].period = _module.noteToPeriod(note.note, _track[track].finetune);
+ _track[track].period = _module->noteToPeriod(note.note, _track[track].finetune);
else
_track[track].period = note.period;
@@ -215,7 +119,7 @@ void ProtrackerStream::updateRow() {
case 0x0:
if (exy) {
_track[track].arpeggio = true;
- byte trackNote = _module.periodToNote(_track[track].period);
+ byte trackNote = _module->periodToNote(_track[track].period);
_track[track].arpeggioNotes[0] = trackNote;
_track[track].arpeggioNotes[1] = trackNote + ex;
_track[track].arpeggioNotes[2] = trackNote + ey;
@@ -276,10 +180,10 @@ void ProtrackerStream::updateRow() {
break;
case 0x5: // Set finetune
_track[track].finetune = ey;
- _module.sample[_track[track].sample].finetune = ey;
+ _module->sample[_track[track].sample].finetune = ey;
if (note.period) {
if (ey)
- _track[track].period = _module.noteToPeriod(note.note, ey);
+ _track[track].period = _module->noteToPeriod(note.note, ey);
else
_track[track].period = note.period;
}
@@ -342,7 +246,7 @@ void ProtrackerStream::updateEffects() {
_track[track].vibrato = 0;
const note_t note =
- _module.pattern[_module.songpos[_pos]][_row][track];
+ _module->pattern[_module->songpos[_pos]][_row][track];
const int effect = note.effect >> 8;
@@ -355,7 +259,7 @@ void ProtrackerStream::updateEffects() {
if (exy) {
const int idx = (_tick == 1) ? 0 : (_tick % 3);
_track[track].period =
- _module.noteToPeriod(_track[track].arpeggioNotes[idx],
+ _module->noteToPeriod(_track[track].arpeggioNotes[idx],
_track[track].finetune);
}
break;
@@ -395,7 +299,7 @@ void ProtrackerStream::updateEffects() {
_track[track].sample = _track[track].delaySample;
_track[track].offset = Offset(0);
if (_track[track].sample)
- _track[track].vol = _module.sample[_track[track].sample - 1].vol;
+ _track[track].vol = _module->sample[_track[track].sample - 1].vol;
}
break;
default:
@@ -414,7 +318,7 @@ void ProtrackerStream::interrupt() {
for (track = 0; track < 4; track++) {
_track[track].offset = getChannelOffset(track);
if (_tick == 0 && _track[track].arpeggio) {
- _track[track].period = _module.noteToPeriod(_track[track].arpeggioNotes[0],
+ _track[track].period = _module->noteToPeriod(_track[track].arpeggioNotes[0],
_track[track].finetune);
}
}
@@ -427,7 +331,7 @@ void ProtrackerStream::interrupt() {
} else if (_hasPatternBreak) {
_hasPatternBreak = false;
_row = _skipRow;
- _pos = (_pos + 1) % _module.songlen;
+ _pos = (_pos + 1) % _module->songlen;
_patternLoopRow = 0;
} else if (_hasPatternLoop) {
_hasPatternLoop = false;
@@ -435,7 +339,7 @@ void ProtrackerStream::interrupt() {
}
if (_row >= 64) {
_row = 0;
- _pos = (_pos + 1) % _module.songlen;
+ _pos = (_pos + 1) % _module->songlen;
_patternLoopRow = 0;
}
@@ -453,7 +357,7 @@ void ProtrackerStream::interrupt() {
setChannelVolume(track, _track[track].vol);
setChannelPeriod(track, _track[track].period + _track[track].vibrato);
if (_track[track].sample) {
- sample_t &sample = _module.sample[_track[track].sample - 1];
+ sample_t &sample = _module->sample[_track[track].sample - 1];
setChannelData(track,
sample.data,
sample.replen > 2 ? sample.data + sample.repeat : nullptr,
@@ -465,6 +369,40 @@ void ProtrackerStream::interrupt() {
}
}
+void ProtrackerStream::doPorta(int track) {
+ if (_track[track].portaToNote && _track[track].portaToNoteSpeed) {
+ int distance = _track[track].period - _track[track].portaToNote;
+ int sign = distance > 0 ? 1 : -1;
+
+ if ((sign * distance) > _track[track].portaToNoteSpeed)
+ _track[track].period -= sign * _track[track].portaToNoteSpeed;
+ else
+ _track[track].period = _track[track].portaToNote;
+ }
+}
+
+void ProtrackerStream::doVibrato(int track) {
+ _track[track].vibrato =
+ (_track[track].vibratoDepth * sinetable[_track[track].vibratoPos]) / 128;
+ _track[track].vibratoPos += _track[track].vibratoSpeed;
+ _track[track].vibratoPos %= 64;
+}
+
+void ProtrackerStream::doVolSlide(int track, byte ex, byte ey) {
+ int vol = _track[track].vol;
+ if (ex == 0)
+ vol -= ey;
+ else if (ey == 0)
+ vol += ex;
+
+ if (vol < 0)
+ vol = 0;
+ else if (vol > 64)
+ vol = 64;
+
+ _track[track].vol = vol;
+}
+
} // End of namespace Modules
namespace Audio {
diff --git a/audio/mods/protracker.h b/audio/mods/protracker.h
index 73913521777..9c08c09ffd8 100644
--- a/audio/mods/protracker.h
+++ b/audio/mods/protracker.h
@@ -26,17 +26,107 @@
* - parallaction
* - gob
* - hopkins
+ * - chewy (subclass)
*/
#ifndef AUDIO_MODS_PROTRACKER_H
#define AUDIO_MODS_PROTRACKER_H
+#include "audio/mods/paula.h"
+#include "audio/mods/module.h"
+
namespace Common {
class SeekableReadStream;
}
namespace Modules {
-class Module;
+
+class ProtrackerStream : public ::Audio::Paula {
+protected:
+ Module *_module;
+
+private:
+ int _tick;
+ int _row;
+ int _pos;
+
+ int _speed;
+ int _bpm;
+
+ // For effect 0xB - Jump To Pattern;
+ bool _hasJumpToPattern;
+ int _jumpToPattern;
+
+ // For effect 0xD - PatternBreak;
+ bool _hasPatternBreak;
+ int _skipRow;
+
+ // For effect 0xE6 - Pattern Loop
+ bool _hasPatternLoop;
+ int _patternLoopCount;
+ int _patternLoopRow;
+
+ // For effect 0xEE - Pattern Delay
+ byte _patternDelay;
+
+ static const int16 sinetable[];
+
+ struct Track {
+ byte sample;
+ byte lastSample;
+ uint16 period;
+ Offset offset;
+
+ byte vol;
+ byte finetune;
+
+ // For effect 0x0 - Arpeggio
+ bool arpeggio;
+ byte arpeggioNotes[3];
+
+ // For effect 0x3 - Porta to note
+ uint16 portaToNote;
+ byte portaToNoteSpeed;
+
+ // For effect 0x4 - Vibrato
+ int vibrato;
+ byte vibratoPos;
+ byte vibratoSpeed;
+ byte vibratoDepth;
+
+ // For effect 0xED - Delay sample
+ byte delaySample;
+ byte delaySampleTick;
+ } _track[4];
+
+public:
+ ProtrackerStream(Common::SeekableReadStream *stream, int offs, int rate, bool stereo);
+
+protected:
+ ProtrackerStream(int rate, bool stereo);
+
+public:
+ virtual ~ProtrackerStream();
+
+ Modules::Module *getModule() {
+ // Ordinarily, the Module is not meant to be seen outside of
+ // this class, but occasionally, it's useful to be able to
+ // manipulate it directly. The Hopkins engine uses this to
+ // repair a broken song.
+ return _module;
+ }
+
+private:
+ void interrupt() override;
+
+ void doPorta(int track);
+ void doVibrato(int track);
+ void doVolSlide(int track, byte ex, byte ey);
+
+ void updateRow();
+ void updateEffects();
+};
+
}
namespace Audio {
Commit: fccca40cedc3ea377881d33091f8a310b6474e7f
https://github.com/scummvm/scummvm/commit/fccca40cedc3ea377881d33091f8a310b6474e7f
Author: Coen Rampen (crampen at gmail.com)
Date: 2022-06-14T14:49:46+02:00
Commit Message:
AUDIO: Make module dtor virtual
Changed paths:
audio/mods/module.h
diff --git a/audio/mods/module.h b/audio/mods/module.h
index 47e11e5f5f0..72fb97dbf99 100644
--- a/audio/mods/module.h
+++ b/audio/mods/module.h
@@ -74,7 +74,7 @@ public:
pattern_t *pattern;
Module();
- ~Module();
+ virtual ~Module();
virtual bool load(Common::SeekableReadStream &stream, int offs);
static byte periodToNote(int16 period, byte finetune = 0);
More information about the Scummvm-git-logs
mailing list