[Scummvm-git-logs] scummvm master -> a64462a60f509dd8cd706884c44b856efca74629

sev- sev at scummvm.org
Sat May 2 18:09:28 UTC 2020


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:
a64462a60f AUDIO: Add support for loading Crusader AMF files


Commit: a64462a60f509dd8cd706884c44b856efca74629
    https://github.com/scummvm/scummvm/commit/a64462a60f509dd8cd706884c44b856efca74629
Author: Matthew Duggan (mgithub at guarana.org)
Date: 2020-05-02T20:09:23+02:00

Commit Message:
AUDIO: Add support for loading Crusader AMF files

Changed paths:
    audio/mods/module_mod_xm_s3m.cpp
    audio/mods/module_mod_xm_s3m.h


diff --git a/audio/mods/module_mod_xm_s3m.cpp b/audio/mods/module_mod_xm_s3m.cpp
index ea8b26d6dc..8dba1f1afc 100644
--- a/audio/mods/module_mod_xm_s3m.cpp
+++ b/audio/mods/module_mod_xm_s3m.cpp
@@ -134,6 +134,14 @@ bool ModuleModXmS3m::load(Common::SeekableReadStream &st) {
 	}
 	st.seek(setPos);
 
+	// amf file
+	char sigAmf[25] = {};
+	st.read(sigAmf, 24);
+	if (!memcmp(sigAmf, "ASYLUM Music Format V1.0", 24)) {
+		return loadAmf(st);
+	}
+	st.seek(setPos);
+
 	// mod file
 	return loadMod(st);
 }
@@ -812,9 +820,122 @@ bool ModuleModXmS3m::loadS3m(Common::SeekableReadStream &st) {
 	return true;
 }
 
+bool ModuleModXmS3m::loadAmf(Common::SeekableReadStream &st) {
+	// already skipped the signature ("ASYLUM Music Format V1.0")
+	// total signature length is 32 bytes (the rest are null)
+	st.skip(8);
+	memcpy(name, "Asylum Module", 14);
+
+	numChannels = 8;
+	defaultSpeed = st.readByte();
+	defaultTempo = st.readByte();
+	numInstruments = st.readByte(); // actually number of samples, but we'll do 1:1 mapping
+	numPatterns = st.readByte();
+	sequenceLen = st.readByte();
+	restartPos = st.readByte();
+
+	sequence = new byte[256];
+	st.read(sequence, 256); // Always 256 bytes in the file.
+
+	// Read sample headers..
+	instruments = new Instrument[numInstruments + 1];
+	memset(instruments, 0, sizeof(Instrument) * (numInstruments + 1));
+	instruments[0].numSamples = 1;
+	instruments[0].samples = new Sample[1];
+	memset(&instruments[0].samples[0], 0, sizeof(Sample));
+
+	for (int i = 1; i <= numInstruments; ++i) {
+		instruments[i].numSamples = 1;
+		instruments[i].samples = new Sample[1];
+		memset(&instruments[i].samples[0], 0, sizeof(Sample));
+
+		// load sample
+		Sample &sample = instruments[i].samples[0];
+		st.read((byte *)sample.name, 22);
+		sample.name[22] = '\0';
+
+		sample.finetune = static_cast<int8>(st.readByte() << 4);
+		sample.volume = st.readByte();
+		sample.relNote = st.readSByte(); // aka "transpose"
+		sample.length = st.readUint32LE();
+		sample.loopStart = st.readUint32LE();
+		sample.loopLength = st.readUint32LE();
+
+		if (sample.loopStart + sample.loopLength > sample.length) {
+			 sample.loopLength = sample.length - sample.loopStart;
+		}
+		if (sample.loopLength < 4) {
+			sample.loopStart = sample.length;
+			sample.loopLength = 0;
+		}
+
+		// Sample data comes later.
+	}
+
+	st.skip((64 - numInstruments) * 37); // 37 == sample header len
+
+	// load patterns
+	patterns = new Pattern[numPatterns];
+	memset(patterns, 0, numPatterns * sizeof(Pattern));
+	for (int i = 0; i < numPatterns; ++i) {
+		// Always 8 channels, 64 rows.
+		patterns[i].numChannels = 8;
+		patterns[i].numRows = 64;
+
+		// load notes
+		patterns[i].notes = new Note[8 * 64];
+		memset(patterns[i].notes, 0, 8 * 64 * sizeof(Note));
+		for (int row = 0; row < 64; row++) {
+			for (int channel = 0; channel < 8; channel++) {
+				Note &n = patterns[i].notes[row * 8 + channel];
+				uint8 note = st.readByte();
+				if (note != 0) {
+					note = note + 13;
+				}
+				n.key = note;
+				n.instrument = st.readByte();
+				n.effect = st.readByte();
+				n.param = st.readByte();
+				// TODO: copied from libmodplug .. is this needed?
+				if (n.effect < 1 || n.effect >= 0x0f) {
+					n.effect = n.param = 0;
+				}
+				// TODO: copied from mod loader.. is this needed?
+				if (n.param == 0 && (n.effect < 3 || n.effect == 0xA))
+					n.effect = 0;
+				if (n.param == 0 && (n.effect == 5 || n.effect == 6))
+					n.effect -= 2;
+				if (n.effect == 8) {
+					if (n.param > 128) {
+						n.param = 128;
+					} else {
+						n.param = (n.param * 255) >> 7;
+					}
+				}
+			}
+		}
+	}
+
+	// Load sample data
+	for (int i = 1; i <= numInstruments; ++i) {
+		Sample &sample = instruments[i].samples[0];
+		sample.data = new int16[sample.length];
+		readSampleSint8(st, sample.length, sample.data);
+	}
+
+	// default to panning to middle?
+	defaultPanning = new byte[numChannels];
+	for (int i = 0; i < numChannels; ++i) {
+		defaultPanning[i] = 128;
+	}
+
+	return true;
+}
+
+
 void ModuleModXmS3m::readSampleSint8(Common::SeekableReadStream &stream, int length, int16 *dest) {
 	for (int i = 0; i < length; ++i) {
-		dest[i] = (stream.readSByte() << 8);
+		dest[i] = static_cast<int16>(stream.readSByte() * 256);
 		dest[i] = (dest[i] & 0x7FFF) - (dest[i] & 0x8000);
 	}
 }
diff --git a/audio/mods/module_mod_xm_s3m.h b/audio/mods/module_mod_xm_s3m.h
index b4c984ad05..64473d17ed 100644
--- a/audio/mods/module_mod_xm_s3m.h
+++ b/audio/mods/module_mod_xm_s3m.h
@@ -162,6 +162,7 @@ private:
 	bool loadMod(Common::SeekableReadStream &stream);
 	bool loadXm(Common::SeekableReadStream &stream);
 	bool loadS3m(Common::SeekableReadStream &stream);
+	bool loadAmf(Common::SeekableReadStream &st);
 
 	void readSampleSint8(Common::SeekableReadStream &stream, int length, int16 *dest);
 	void readSampleSint16LE(Common::SeekableReadStream &stream, int length, int16 *dest);




More information about the Scummvm-git-logs mailing list