aboutsummaryrefslogtreecommitdiff
path: root/sound/voc.cpp
diff options
context:
space:
mode:
authorPaweł Kołodziejski2003-12-26 12:15:23 +0000
committerPaweł Kołodziejski2003-12-26 12:15:23 +0000
commita45e92efed3715b3bb0b1191b718207b191ab1ae (patch)
tree79e58723288257ce0e3e68a434b86f17110330d3 /sound/voc.cpp
parent908fbe2ac563f41b039da0392baa60207331d64d (diff)
downloadscummvm-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/voc.cpp')
-rw-r--r--sound/voc.cpp104
1 files changed, 104 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;