diff options
Diffstat (limited to 'engines/scumm/sound.cpp')
-rw-r--r-- | engines/scumm/sound.cpp | 220 |
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. |