aboutsummaryrefslogtreecommitdiff
path: root/engines/scumm/sound.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'engines/scumm/sound.cpp')
-rw-r--r--engines/scumm/sound.cpp220
1 files changed, 1 insertions, 219 deletions
diff --git a/engines/scumm/sound.cpp b/engines/scumm/sound.cpp
index a1cecfa0b3..57345126d3 100644
--- a/engines/scumm/sound.cpp
+++ b/engines/scumm/sound.cpp
@@ -1086,9 +1086,6 @@ void Sound::saveLoadWithSerializer(Serializer *ser) {
#pragma mark --- Sound resource handling ---
#pragma mark -
-static void convertMac0Resource(ResourceManager *res, ResId idx, byte *src_ptr, int size);
-
-
/*
* TODO: The way we handle sound/music resources really is one huge hack.
* We probably should reconsider how we do this, and maybe come up with a
@@ -1208,11 +1205,9 @@ int ScummEngine::readSoundResource(ResId idx) {
case MKTAG('M','a','c','0'):
_fileHandle->seek(-12, SEEK_CUR);
total_size = _fileHandle->readUint32BE() - 8;
- ptr = (byte *)calloc(total_size, 1);
+ ptr = _res->createResource(rtSound, idx, total_size);
_fileHandle->read(ptr, total_size);
//dumpResource("sound-", idx, ptr);
- convertMac0Resource(_res, idx, ptr, total_size);
- free(ptr);
return 1;
case MKTAG('M','a','c','1'):
@@ -1445,219 +1440,6 @@ static byte *writeVLQ(byte *ptr, int value) {
return ptr;
}
-static byte Mac0ToGMInstrument(uint32 type, int &transpose) {
- transpose = 0;
- switch (type) {
- case MKTAG('M','A','R','I'): return 12;
- case MKTAG('P','L','U','C'): return 45;
- case MKTAG('H','A','R','M'): return 22;
- case MKTAG('P','I','P','E'): return 19;
- case MKTAG('T','R','O','M'): transpose = -12; return 57;
- case MKTAG('S','T','R','I'): return 48;
- case MKTAG('H','O','R','N'): return 60;
- case MKTAG('V','I','B','E'): return 11;
- case MKTAG('S','H','A','K'): return 77;
- case MKTAG('P','A','N','P'): return 75;
- case MKTAG('W','H','I','S'): return 76;
- case MKTAG('O','R','G','A'): return 17;
- case MKTAG('B','O','N','G'): return 115;
- case MKTAG('B','A','S','S'): transpose = -24; return 35;
- default:
- error("Unknown Mac0 instrument %s found", tag2str(type));
- }
-}
-
-static void convertMac0Resource(ResourceManager *res, ResId idx, byte *src_ptr, int size) {
- /*
- From Markus Magnuson (superqult) we got this information:
- Mac0
- ---
- 4 bytes - 'SOUN'
- BE 4 bytes - block length
-
- 4 bytes - 'Mac0'
- BE 4 bytes - (blockLength - 27)
- 28 bytes - ???
-
- do this three times (once for each channel):
- 4 bytes - 'Chan'
- BE 4 bytes - channel length
- 4 bytes - instrument name (e.g. 'MARI')
-
- do this for ((chanLength-24)/4) times:
- 2 bytes - note duration
- 1 byte - note value
- 1 byte - note velocity
-
- 4 bytes - ???
- 4 bytes - 'Loop'/'Done'
- 4 bytes - ???
-
- 1 byte - 0x09
- ---
-
- Instruments (General Midi):
- "MARI" - Marimba (12)
- "PLUC" - Pizzicato Strings (45)
- "HARM" - Harmonica (22)
- "PIPE" - Church Organ? (19) or Flute? (73) or Bag Pipe (109)
- "TROM" - Trombone (57)
- "STRI" - String Ensemble (48 or 49)
- "HORN" - French Horn? (60) or English Horn? (69)
- "VIBE" - Vibraphone (11)
- "SHAK" - Shakuhachi? (77)
- "PANP" - Pan Flute (75)
- "WHIS" - Whistle (78) / Bottle (76)
- "ORGA" - Drawbar Organ (16; but could also be 17-20)
- "BONG" - Woodblock? (115)
- "BASS" - Bass (32-39)
-
-
- Now the task could be to convert this into MIDI, to be fed into iMuse.
- Or we do something similiar to what is done in Player_V3, assuming
- we can identify SFX in the MI datafiles for each of the instruments
- listed above.
- */
-
-#if 0
- byte *ptr = _res->createResource(rtSound, idx, size);
- memcpy(ptr, src_ptr, size);
-#else
- const int ppqn = 480;
- byte *ptr, *start_ptr;
-
- int total_size = 0;
- total_size += kMIDIHeaderSize; // Header
- total_size += 7; // Tempo META
- total_size += 3 * 3; // Three program change mesages
- total_size += 22; // Possible jump SysEx
- total_size += 5; // EOT META
-
- int i, len;
- byte track_instr[3];
- byte *track_data[3];
- int track_len[3];
- int track_transpose[3];
- bool looped = false;
-
- src_ptr += 8;
- // TODO: Decipher the unknown bytes in the header. For now, skip 'em
- src_ptr += 28;
-
- // Parse the three channels
- for (i = 0; i < 3; i++) {
- assert(READ_BE_UINT32(src_ptr) == MKTAG('C','h','a','n'));
- len = READ_BE_UINT32(src_ptr + 4);
- track_len[i] = len - 24;
- track_instr[i] = Mac0ToGMInstrument(READ_BE_UINT32(src_ptr + 8), track_transpose[i]);
- track_data[i] = src_ptr + 12;
- src_ptr += len;
- looped = (READ_BE_UINT32(src_ptr - 8) == MKTAG('L','o','o','p'));
-
- // For each note event, we need up to 6 bytes for the
- // Note On (3 VLQ, 3 event), and 6 bytes for the Note
- // Off (3 VLQ, 3 event). So 12 bytes total.
- total_size += 12 * track_len[i];
- }
- assert(*src_ptr == 0x09);
-
- // Create sound resource
- start_ptr = res->createResource(rtSound, idx, total_size);
-
- // Insert MIDI header
- ptr = writeMIDIHeader(start_ptr, "GMD ", ppqn, total_size);
-
- // Write a tempo change Meta event
- // 473 / 4 Hz, convert to micro seconds.
- uint32 dw = 1000000 * 437 / 4 / ppqn; // 1000000 * ppqn * 4 / 473;
- memcpy(ptr, "\x00\xFF\x51\x03", 4); ptr += 4;
- *ptr++ = (byte)((dw >> 16) & 0xFF);
- *ptr++ = (byte)((dw >> 8) & 0xFF);
- *ptr++ = (byte)(dw & 0xFF);
-
- // Insert program change messages
- *ptr++ = 0; // VLQ
- *ptr++ = 0xC0;
- *ptr++ = track_instr[0];
- *ptr++ = 0; // VLQ
- *ptr++ = 0xC1;
- *ptr++ = track_instr[1];
- *ptr++ = 0; // VLQ
- *ptr++ = 0xC2;
- *ptr++ = track_instr[2];
-
- // And now, the actual composition. Please turn all cell phones
- // and pagers off during the performance. Thank you.
- uint16 nextTime[3] = { 1, 1, 1 };
- int stage[3] = { 0, 0, 0 };
-
- while (track_len[0] | track_len[1] | track_len[2]) {
- int best = -1;
- uint16 bestTime = 0xFFFF;
- for (i = 0; i < 3; ++i) {
- if (track_len[i] && nextTime[i] < bestTime) {
- bestTime = nextTime[i];
- best = i;
- }
- }
- assert (best != -1);
-
- if (!stage[best]) {
- // We are STARTING this event.
- if (track_data[best][2] > 1) {
- // Note On
- ptr = writeVLQ(ptr, nextTime[best]);
- *ptr++ = 0x90 | best;
- *ptr++ = track_data[best][2] + track_transpose[best];
- *ptr++ = track_data[best][3] * 127 / 100; // Scale velocity
- for (i = 0; i < 3; ++i)
- nextTime[i] -= bestTime;
- }
- nextTime[best] += READ_BE_UINT16 (track_data[best]);
- stage[best] = 1;
- } else {
- // We are ENDING this event.
- if (track_data[best][2] > 1) {
- // There was a Note On, so do a Note Off
- ptr = writeVLQ(ptr, nextTime[best]);
- *ptr++ = 0x80 | best;
- *ptr++ = track_data[best][2] + track_transpose[best];
- *ptr++ = track_data[best][3] * 127 / 100; // Scale velocity
- for (i = 0; i < 3; ++i)
- nextTime[i] -= bestTime;
- }
- track_data[best] += 4;
- track_len[best] -= 4;
- stage[best] = 0;
- }
- }
-
- // Is this a looped song? If so, effect a loop by
- // using the S&M maybe_jump SysEx command.
- // FIXME: Jamieson630: The jump seems to be happening
- // too quickly! There should maybe be a pause after
- // the last Note Off? But I couldn't find one in the
- // MI1 Lookout music, where I was hearing problems.
- if (looped) {
- memcpy(ptr, "\x00\xf0\x13\x7d\x30\00", 6); ptr += 6; // maybe_jump
- memcpy(ptr, "\x00\x00", 2); ptr += 2; // cmd -> 0 means always jump
- memcpy(ptr, "\x00\x00\x00\x00", 4); ptr += 4; // track -> 0 (only track)
- memcpy(ptr, "\x00\x00\x00\x01", 4); ptr += 4; // beat -> 1 (first beat)
- memcpy(ptr, "\x00\x00\x00\x01", 4); ptr += 4; // tick -> 1
- memcpy(ptr, "\x00\xf7", 2); ptr += 2; // SysEx end marker
- }
-
- // Insert end of song META
- memcpy(ptr, "\x00\xff\x2f\x00\x00", 5); ptr += 5;
-
- assert(ptr <= start_ptr + total_size);
-
- // Rewrite MIDI header, this time with true size
- total_size = ptr - start_ptr;
- ptr = writeMIDIHeader(start_ptr, "GMD ", ppqn, total_size);
-#endif
-}
-
static void convertADResource(ResourceManager *res, const GameSettings& game, ResId idx, byte *src_ptr, int size) {
// We will ignore the PPQN in the original resource, because
// it's invalid anyway. We use a constant PPQN of 480.