diff options
author | Paweł Kołodziejski | 2003-12-26 12:15:23 +0000 |
---|---|---|
committer | Paweł Kołodziejski | 2003-12-26 12:15:23 +0000 |
commit | a45e92efed3715b3bb0b1191b718207b191ab1ae (patch) | |
tree | 79e58723288257ce0e3e68a434b86f17110330d3 /sound | |
parent | 908fbe2ac563f41b039da0392baa60207331d64d (diff) | |
download | scummvm-rg350-a45e92efed3715b3bb0b1191b718207b191ab1ae.tar.gz scummvm-rg350-a45e92efed3715b3bb0b1191b718207b191ab1ae.tar.bz2 scummvm-rg350-a45e92efed3715b3bb0b1191b718207b191ab1ae.zip |
passthrought v7+ sound voices by imuse digital
svn-id: r11939
Diffstat (limited to 'sound')
-rw-r--r-- | sound/voc.cpp | 104 | ||||
-rw-r--r-- | sound/voc.h | 4 |
2 files changed, 108 insertions, 0 deletions
diff --git a/sound/voc.cpp b/sound/voc.cpp index 46dc6f6abc..7951d72633 100644 --- a/sound/voc.cpp +++ b/sound/voc.cpp @@ -22,9 +22,113 @@ #include "stdafx.h" #include "common/util.h" +#include "common/file.h" #include "sound/voc.h" +byte *readCreativeVoc(byte *ptr, int32 &size, int &rate) { + assert(strncmp((char *)ptr, "Creative Voice File\x1A", 20) == 0); + int32 offset = READ_LE_UINT16(ptr + 20); + int16 version = READ_LE_UINT16(ptr + 22); + int16 code = READ_LE_UINT16(ptr + 24); + assert(version == 0x010A || version == 0x0114); + assert(code == ~version + 0x1234); + bool quit = 0; + byte *ret_sound = 0; size = 0; + int loops = 0; + while (!quit) { + int len = READ_LE_UINT32(ptr + offset); + offset += 4; + code = len & 0xFF; + len >>= 8; + switch(code) { + case 0: quit = 1; break; + case 1: { + int time_constant = ptr[offset++]; + int packing = ptr[offset++]; + len -= 2; + rate = getSampleRateFromVOCRate(time_constant); + debug(9, "VOC Data Bloc : %d, %d, %d", rate, packing, len); + if (packing == 0) { + if (size) { + ret_sound = (byte *)realloc(ret_sound, size + len); + } else { + ret_sound = (byte *)malloc(len); + } + memcpy(ret_sound + size, ptr + offset, len); + size += len; + } else { + warning("VOC file packing %d unsupported", packing); + } + } break; + case 6: // begin of loop + loops = len + 1; + break; + case 7: // end of loop + break; + default: + warning("Invalid code in VOC file : %d", code); + quit = 1; + break; + } + // FIXME some FT samples (ex. 362) has bad length, 2 bytes too short + offset += len; + } + debug(9, "VOC Data Size : %d", size); + return ret_sound; +} + +enum { + SOUND_HEADER_SIZE = 26, + SOUND_HEADER_BIG_SIZE = 26 + 8 +}; + +byte *loadVocSample(File *file, int32 &size, int &rate) { + char ident[8]; + + if (file->read(ident, 8) != 8) + goto invalid; + + if (!memcmp(ident, "VTLK", 4)) { + file->seek(SOUND_HEADER_BIG_SIZE - 8, SEEK_CUR); + } else if (!memcmp(ident, "Creative", 8)) { + file->seek(SOUND_HEADER_SIZE - 8, SEEK_CUR); + } else { + invalid:; + warning("loadVocSample: invalid header"); + return NULL; + } + + VocBlockHeader voc_block_hdr; + + file->read(&voc_block_hdr, sizeof(voc_block_hdr)); + if (voc_block_hdr.blocktype != 1) { + warning("loadVocSample: Expecting block_type == 1, got %d", voc_block_hdr.blocktype); + return NULL; + } + + size = voc_block_hdr.size[0] + (voc_block_hdr.size[1] << 8) + (voc_block_hdr.size[2] << 16) - 2; + rate = getSampleRateFromVOCRate(voc_block_hdr.sr); + int comp = voc_block_hdr.pack; + + if (comp != 0) { + warning("loadVocSample: Unsupported compression type %d", comp); + return NULL; + } + + byte *data = (byte *)malloc(size); + if (data == NULL) { + error("loadVocSample: out of memory"); + } + + if (file->read(data, size) != size) { + /* no need to free the memory since error will shut down */ + error("startSfxSound: cannot read %d bytes", size); + } + + return data; +} + int getSampleRateFromVOCRate(int vocSR) { if (vocSR == 0xa5 || vocSR == 0xa6 || vocSR == 0x83) { return 11025; diff --git a/sound/voc.h b/sound/voc.h index 5768be2c19..f29e804b4e 100644 --- a/sound/voc.h +++ b/sound/voc.h @@ -26,6 +26,8 @@ #include "stdafx.h" #include "common/scummsys.h" +class File; + #if !defined(__GNUC__) #pragma START_PACK_STRUCTS #endif @@ -53,5 +55,7 @@ struct VocBlockHeader { * return the corresponding sample frequency. */ extern int getSampleRateFromVOCRate(int vocSR); +extern byte *readCreativeVoc(byte *ptr, int32 &size, int &rate); +extern byte *loadVocSample(File *file, int32 &size, int &rate); #endif |