2008-07-06 17:33:38 +02:00
|
|
|
#include "../vgmstream.h"
|
2008-06-09 02:20:08 +02:00
|
|
|
#include "meta.h"
|
2010-09-11 20:28:43 +02:00
|
|
|
#include "../coding/coding.h"
|
2008-06-10 03:20:54 +02:00
|
|
|
#include "../layout/layout.h"
|
2008-06-09 02:20:08 +02:00
|
|
|
#include "../util.h"
|
2008-07-06 17:33:38 +02:00
|
|
|
#ifdef VGM_USE_MPEG
|
|
|
|
#include <mpg123.h>
|
|
|
|
#endif
|
2008-06-09 02:20:08 +02:00
|
|
|
|
|
|
|
/* GENH is an artificial "generic" header for headerless streams */
|
|
|
|
|
2008-06-10 03:20:54 +02:00
|
|
|
VGMSTREAM * init_vgmstream_genh(STREAMFILE *streamFile) {
|
2008-06-09 02:20:08 +02:00
|
|
|
|
2008-12-24 01:00:10 +01:00
|
|
|
VGMSTREAM * vgmstream = NULL;
|
2008-06-09 02:20:08 +02:00
|
|
|
|
2008-12-24 01:00:10 +01:00
|
|
|
int32_t channel_count;
|
2008-06-09 02:20:08 +02:00
|
|
|
int32_t interleave;
|
|
|
|
int32_t sample_rate;
|
|
|
|
int32_t loop_start;
|
|
|
|
int32_t loop_end;
|
2008-06-13 01:33:07 +02:00
|
|
|
int32_t start_offset;
|
|
|
|
int32_t header_size;
|
2008-12-24 01:00:10 +01:00
|
|
|
int32_t coef[2];
|
|
|
|
int32_t coef_splitted[2];
|
|
|
|
int32_t dsp_interleave_type;
|
|
|
|
int32_t coef_type;
|
2008-12-23 19:01:18 +01:00
|
|
|
|
2013-05-27 05:55:50 +02:00
|
|
|
char filename[PATH_LIMIT];
|
2008-06-10 03:20:54 +02:00
|
|
|
int coding;
|
2008-06-09 02:20:08 +02:00
|
|
|
|
|
|
|
/* check extension, case insensitive */
|
|
|
|
streamFile->get_name(streamFile,filename,sizeof(filename));
|
|
|
|
if (strcasecmp("genh",filename_extension(filename))) goto fail;
|
|
|
|
|
|
|
|
/* check header magic */
|
|
|
|
if (read_32bitBE(0x0,streamFile) != 0x47454e48) goto fail;
|
|
|
|
|
2008-06-13 01:50:45 +02:00
|
|
|
/* check channel count (needed for ADP/DTK check) */
|
|
|
|
channel_count = read_32bitLE(0x4,streamFile);
|
|
|
|
if (channel_count < 1) goto fail;
|
|
|
|
|
2008-06-10 03:20:54 +02:00
|
|
|
/* check format */
|
|
|
|
/* 0 = PSX ADPCM */
|
2008-06-13 01:33:07 +02:00
|
|
|
/* 1 = XBOX IMA ADPCM */
|
|
|
|
/* 2 = NGC ADP/DTK ADPCM */
|
2008-06-18 01:32:24 +02:00
|
|
|
/* 3 = 16bit big endian PCM */
|
|
|
|
/* 4 = 16bit little endian PCM */
|
2008-07-02 03:41:20 +02:00
|
|
|
/* 5 = 8bit PCM */
|
|
|
|
/* 6 = SDX2 */
|
|
|
|
/* 7 = DVI IMA */
|
2008-07-06 17:33:38 +02:00
|
|
|
/* 8 = MPEG-1 Layer III, possibly also the MPEG-2 and 2.5 extensions */
|
2008-07-18 07:25:05 +02:00
|
|
|
/* 9 = IMA */
|
2008-08-15 04:21:19 +02:00
|
|
|
/* 10 = AICA ADPCM */
|
2008-08-18 01:07:41 +02:00
|
|
|
/* 11 = MS ADPCM */
|
2008-11-17 19:28:14 +01:00
|
|
|
/* 12 = NGC DSP */
|
2008-11-24 19:27:28 +01:00
|
|
|
/* 13 = 8bit unsingned PCM */
|
2008-12-24 01:00:10 +01:00
|
|
|
/* 14 = PSX ADPCM (bad flagged) */
|
Extend GENH to support little-endian "Gamecube" DSP ADPCM coefficients, for some 3DS titles.
This involves a reinterpretation of byte 0x30 (coef type). Formerly this byte took on only two values, to indicate how the ADPCM coefficients (aka codebook) were stored:
0 - normal coefs: all 16 coefs interleaved into one array, offset given at 0x24 for left, 0x28 for right
1 - split coefs: 8 coefs in the main array, additional offset to 2nd array given at 0x34 for left, 0x38 for right
Now I am considering this to be indicated only by bit 0 of the coef type. Bit 1 is taking on an additional interpretation, if it is set, we consider the coefficients to be little endian rather than the normal big endian.
This should maintain backwards compatibility with old GENH files, which should have only used the value 0 or 1.
Thus, in effect we have:
0: normal, big endian
1: split, big endian
2: normal, little endian
3: split, little endian
I don't know of any situation in which 3 would be used (yet), but I'm sure devs will continue to surprise me.
2014-06-27 05:53:49 +02:00
|
|
|
/* 15 = Microsoft IMA (MS ADPCM) */
|
|
|
|
/* 16 = 8-bit PCM (unsigned) */
|
|
|
|
/* 17 = Apple Quicktime 4-bit IMA ADPCM */
|
|
|
|
|
2008-06-10 03:20:54 +02:00
|
|
|
switch (read_32bitLE(0x18,streamFile)) {
|
|
|
|
case 0:
|
|
|
|
coding = coding_PSX;
|
|
|
|
break;
|
|
|
|
case 1:
|
|
|
|
coding = coding_XBOX;
|
|
|
|
break;
|
2008-06-13 01:33:07 +02:00
|
|
|
case 2:
|
|
|
|
coding = coding_NGC_DTK;
|
|
|
|
if (channel_count != 2) goto fail;
|
|
|
|
break;
|
2008-06-18 01:32:24 +02:00
|
|
|
case 3:
|
|
|
|
coding = coding_PCM16BE;
|
|
|
|
break;
|
|
|
|
case 4:
|
|
|
|
coding = coding_PCM16LE;
|
|
|
|
break;
|
2008-07-01 05:19:02 +02:00
|
|
|
case 5:
|
|
|
|
coding = coding_PCM8;
|
|
|
|
break;
|
2008-07-01 18:10:18 +02:00
|
|
|
case 6:
|
|
|
|
coding = coding_SDX2;
|
|
|
|
break;
|
2008-07-02 03:41:20 +02:00
|
|
|
case 7:
|
|
|
|
coding = coding_DVI_IMA;
|
|
|
|
break;
|
2008-07-06 17:33:38 +02:00
|
|
|
#ifdef VGM_USE_MPEG
|
|
|
|
case 8:
|
|
|
|
/* we say MPEG-1 L3 here, but later find out exactly which */
|
|
|
|
coding = coding_MPEG1_L3;
|
|
|
|
break;
|
|
|
|
#endif
|
2008-07-18 07:25:05 +02:00
|
|
|
case 9:
|
|
|
|
coding = coding_IMA;
|
|
|
|
break;
|
2008-08-15 04:21:19 +02:00
|
|
|
case 10:
|
|
|
|
coding = coding_AICA;
|
|
|
|
break;
|
2008-08-18 01:07:41 +02:00
|
|
|
case 11:
|
|
|
|
coding = coding_MSADPCM;
|
|
|
|
break;
|
2008-11-17 19:28:14 +01:00
|
|
|
case 12:
|
|
|
|
coding = coding_NGC_DSP;
|
|
|
|
break;
|
2008-12-24 01:00:10 +01:00
|
|
|
case 13:
|
2008-11-24 19:27:28 +01:00
|
|
|
coding = coding_PCM8_U_int;
|
2008-12-18 20:04:35 +01:00
|
|
|
break;
|
2008-12-24 01:00:10 +01:00
|
|
|
case 14:
|
2008-12-18 20:04:35 +01:00
|
|
|
coding = coding_PSX_badflags;
|
2008-11-24 19:27:28 +01:00
|
|
|
break;
|
2009-03-09 13:48:53 +01:00
|
|
|
case 15:
|
|
|
|
coding = coding_MS_IMA;
|
|
|
|
break;
|
2009-04-28 18:52:49 +02:00
|
|
|
case 16:
|
|
|
|
coding = coding_PCM8_U;
|
|
|
|
break;
|
2011-06-20 18:40:32 +02:00
|
|
|
case 17:
|
|
|
|
coding = coding_APPLE_IMA4;
|
|
|
|
break;
|
2008-06-10 03:20:54 +02:00
|
|
|
default:
|
|
|
|
goto fail;
|
|
|
|
}
|
2008-06-09 02:20:08 +02:00
|
|
|
|
2008-11-17 19:28:14 +01:00
|
|
|
start_offset = read_32bitLE(0x1C,streamFile);
|
2008-06-13 01:50:45 +02:00
|
|
|
header_size = read_32bitLE(0x20,streamFile);
|
2008-06-13 01:33:07 +02:00
|
|
|
|
|
|
|
/* HACK to support old genh */
|
|
|
|
if (header_size == 0) {
|
|
|
|
start_offset = 0x800;
|
|
|
|
header_size = 0x800;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* check for audio data start past header end */
|
|
|
|
if (header_size > start_offset) goto fail;
|
|
|
|
|
2008-06-09 02:20:08 +02:00
|
|
|
interleave = read_32bitLE(0x8,streamFile);
|
|
|
|
sample_rate = read_32bitLE(0xc,streamFile);
|
|
|
|
loop_start = read_32bitLE(0x10,streamFile);
|
|
|
|
loop_end = read_32bitLE(0x14,streamFile);
|
2008-12-24 01:00:10 +01:00
|
|
|
|
|
|
|
coef[0] = read_32bitLE(0x24,streamFile);
|
|
|
|
coef[1] = read_32bitLE(0x28,streamFile);
|
|
|
|
dsp_interleave_type = read_32bitLE(0x2C,streamFile);
|
Extend GENH to support little-endian "Gamecube" DSP ADPCM coefficients, for some 3DS titles.
This involves a reinterpretation of byte 0x30 (coef type). Formerly this byte took on only two values, to indicate how the ADPCM coefficients (aka codebook) were stored:
0 - normal coefs: all 16 coefs interleaved into one array, offset given at 0x24 for left, 0x28 for right
1 - split coefs: 8 coefs in the main array, additional offset to 2nd array given at 0x34 for left, 0x38 for right
Now I am considering this to be indicated only by bit 0 of the coef type. Bit 1 is taking on an additional interpretation, if it is set, we consider the coefficients to be little endian rather than the normal big endian.
This should maintain backwards compatibility with old GENH files, which should have only used the value 0 or 1.
Thus, in effect we have:
0: normal, big endian
1: split, big endian
2: normal, little endian
3: split, little endian
I don't know of any situation in which 3 would be used (yet), but I'm sure devs will continue to surprise me.
2014-06-27 05:53:49 +02:00
|
|
|
|
|
|
|
/* DSP coefficient variants */
|
|
|
|
/* bit 0 - split coefs (2 arrays) */
|
|
|
|
/* bit 1 - little endian coefs */
|
|
|
|
coef_type = read_32bitLE(0x30,streamFile);
|
|
|
|
|
|
|
|
/* when using split coefficients, 2nd array is at: */
|
2008-12-24 01:00:10 +01:00
|
|
|
coef_splitted[0] = read_32bitLE(0x34,streamFile);
|
|
|
|
coef_splitted[1] = read_32bitLE(0x38,streamFile);
|
Extend GENH to support little-endian "Gamecube" DSP ADPCM coefficients, for some 3DS titles.
This involves a reinterpretation of byte 0x30 (coef type). Formerly this byte took on only two values, to indicate how the ADPCM coefficients (aka codebook) were stored:
0 - normal coefs: all 16 coefs interleaved into one array, offset given at 0x24 for left, 0x28 for right
1 - split coefs: 8 coefs in the main array, additional offset to 2nd array given at 0x34 for left, 0x38 for right
Now I am considering this to be indicated only by bit 0 of the coef type. Bit 1 is taking on an additional interpretation, if it is set, we consider the coefficients to be little endian rather than the normal big endian.
This should maintain backwards compatibility with old GENH files, which should have only used the value 0 or 1.
Thus, in effect we have:
0: normal, big endian
1: split, big endian
2: normal, little endian
3: split, little endian
I don't know of any situation in which 3 would be used (yet), but I'm sure devs will continue to surprise me.
2014-06-27 05:53:49 +02:00
|
|
|
|
2008-11-17 19:45:09 +01:00
|
|
|
//if (coding == coding_XBOX && channel_count != 2) goto fail;
|
2008-06-10 03:20:54 +02:00
|
|
|
|
2008-06-09 02:20:08 +02:00
|
|
|
/* build the VGMSTREAM */
|
|
|
|
vgmstream = allocate_vgmstream(channel_count,(loop_start!=-1));
|
|
|
|
if (!vgmstream) goto fail;
|
|
|
|
|
|
|
|
/* fill in the vital information */
|
|
|
|
|
|
|
|
vgmstream->channels = channel_count;
|
|
|
|
vgmstream->sample_rate = sample_rate;
|
|
|
|
vgmstream->num_samples = loop_end;
|
|
|
|
vgmstream->loop_start_sample = loop_start;
|
|
|
|
vgmstream->loop_end_sample = loop_end;
|
|
|
|
vgmstream->loop_flag = (loop_start != -1);
|
|
|
|
|
2008-06-10 03:20:54 +02:00
|
|
|
switch (coding) {
|
2008-11-24 19:27:28 +01:00
|
|
|
case coding_PCM8_U_int:
|
2008-12-24 01:00:10 +01:00
|
|
|
vgmstream->layout_type=layout_none;
|
|
|
|
break;
|
|
|
|
case coding_PCM16LE:
|
2008-06-18 12:40:35 +02:00
|
|
|
case coding_PCM16BE:
|
2008-07-01 05:19:02 +02:00
|
|
|
case coding_PCM8:
|
2009-04-28 18:52:49 +02:00
|
|
|
case coding_PCM8_U:
|
2008-07-01 18:10:18 +02:00
|
|
|
case coding_SDX2:
|
2008-06-10 03:20:54 +02:00
|
|
|
case coding_PSX:
|
2008-12-24 01:00:10 +01:00
|
|
|
case coding_PSX_badflags:
|
2008-07-02 03:41:20 +02:00
|
|
|
case coding_DVI_IMA:
|
2008-07-18 07:25:05 +02:00
|
|
|
case coding_IMA:
|
2008-08-15 04:21:19 +02:00
|
|
|
case coding_AICA:
|
2011-06-20 18:40:32 +02:00
|
|
|
case coding_APPLE_IMA4:
|
2008-06-10 03:20:54 +02:00
|
|
|
vgmstream->interleave_block_size = interleave;
|
|
|
|
if (channel_count > 1)
|
|
|
|
{
|
2008-07-14 22:42:49 +02:00
|
|
|
if (coding == coding_SDX2) {
|
|
|
|
coding = coding_SDX2_int;
|
|
|
|
vgmstream->coding_type = coding_SDX2_int;
|
|
|
|
}
|
2008-12-24 01:00:10 +01:00
|
|
|
if(vgmstream->interleave_block_size==0xffffffff)
|
|
|
|
vgmstream->layout_type=layout_none;
|
|
|
|
else {
|
|
|
|
vgmstream->layout_type = layout_interleave;
|
|
|
|
if(coding==coding_DVI_IMA)
|
|
|
|
coding=coding_INT_DVI_IMA;
|
|
|
|
if(coding==coding_IMA)
|
|
|
|
coding=coding_INT_IMA;
|
|
|
|
}
|
2008-06-10 03:20:54 +02:00
|
|
|
} else {
|
|
|
|
vgmstream->layout_type = layout_none;
|
|
|
|
}
|
|
|
|
break;
|
2009-03-09 13:48:53 +01:00
|
|
|
case coding_MS_IMA:
|
|
|
|
vgmstream->interleave_block_size = interleave;
|
|
|
|
vgmstream->layout_type = layout_none;
|
|
|
|
break;
|
2008-08-18 01:21:12 +02:00
|
|
|
case coding_MSADPCM:
|
|
|
|
if (channel_count != 2) goto fail;
|
|
|
|
vgmstream->interleave_block_size = interleave;
|
|
|
|
vgmstream->layout_type = layout_none;
|
|
|
|
break;
|
2008-06-10 03:20:54 +02:00
|
|
|
case coding_XBOX:
|
2008-08-10 22:08:03 +02:00
|
|
|
vgmstream->layout_type = layout_none;
|
2008-06-13 01:33:07 +02:00
|
|
|
break;
|
|
|
|
case coding_NGC_DTK:
|
2017-01-08 01:09:20 +01:00
|
|
|
vgmstream->layout_type = layout_none;
|
2008-06-10 03:20:54 +02:00
|
|
|
break;
|
2008-11-17 19:28:14 +01:00
|
|
|
case coding_NGC_DSP:
|
2008-12-24 01:00:10 +01:00
|
|
|
if (dsp_interleave_type == 0) {
|
|
|
|
vgmstream->layout_type = layout_interleave;
|
|
|
|
vgmstream->interleave_block_size = interleave;
|
|
|
|
} else if (dsp_interleave_type == 1) {
|
|
|
|
vgmstream->layout_type = layout_interleave_byte;
|
|
|
|
vgmstream->interleave_block_size = interleave;
|
|
|
|
} else if (dsp_interleave_type == 2) {
|
|
|
|
vgmstream->layout_type = layout_none;
|
|
|
|
}
|
|
|
|
break;
|
2008-11-17 19:28:14 +01:00
|
|
|
|
2008-07-06 17:33:38 +02:00
|
|
|
#ifdef VGM_USE_MPEG
|
|
|
|
case coding_MPEG1_L3:
|
|
|
|
vgmstream->layout_type = layout_mpeg;
|
|
|
|
break;
|
|
|
|
#endif
|
2008-06-09 12:26:17 +02:00
|
|
|
}
|
2008-06-09 02:20:08 +02:00
|
|
|
|
2008-12-24 01:00:10 +01:00
|
|
|
vgmstream->coding_type = coding;
|
|
|
|
vgmstream->meta_type = meta_GENH;
|
2008-06-09 02:20:08 +02:00
|
|
|
|
|
|
|
/* open the file for reading by each channel */
|
|
|
|
{
|
|
|
|
int i;
|
2008-12-24 01:00:10 +01:00
|
|
|
int j;
|
2008-11-17 19:28:14 +01:00
|
|
|
|
2008-06-13 01:33:07 +02:00
|
|
|
STREAMFILE * chstreamfile = NULL;
|
|
|
|
|
2008-06-09 02:20:08 +02:00
|
|
|
for (i=0;i<channel_count;i++) {
|
2008-06-13 01:33:07 +02:00
|
|
|
off_t chstart_offset = start_offset;
|
|
|
|
|
|
|
|
switch (coding) {
|
|
|
|
case coding_PSX:
|
2008-12-24 01:00:10 +01:00
|
|
|
case coding_PSX_badflags:
|
2008-06-18 01:32:24 +02:00
|
|
|
case coding_PCM16BE:
|
|
|
|
case coding_PCM16LE:
|
2008-07-01 18:10:18 +02:00
|
|
|
case coding_SDX2:
|
2008-07-14 22:42:49 +02:00
|
|
|
case coding_SDX2_int:
|
2008-07-02 03:41:20 +02:00
|
|
|
case coding_DVI_IMA:
|
2008-07-18 07:25:05 +02:00
|
|
|
case coding_IMA:
|
2008-07-01 05:19:02 +02:00
|
|
|
case coding_PCM8:
|
2009-04-28 18:52:49 +02:00
|
|
|
case coding_PCM8_U:
|
2008-11-24 19:27:28 +01:00
|
|
|
case coding_PCM8_U_int:
|
2008-08-15 04:21:19 +02:00
|
|
|
case coding_AICA:
|
2008-12-24 01:00:10 +01:00
|
|
|
case coding_INT_DVI_IMA:
|
|
|
|
case coding_INT_IMA:
|
2011-06-20 18:40:32 +02:00
|
|
|
case coding_APPLE_IMA4:
|
2009-04-22 00:35:14 +02:00
|
|
|
if (coding == coding_AICA) {
|
2009-04-22 00:32:01 +02:00
|
|
|
vgmstream->ch[i].adpcm_step_index = 0x7f;
|
|
|
|
}
|
2008-06-13 01:33:07 +02:00
|
|
|
if (vgmstream->layout_type == layout_interleave) {
|
2008-06-18 12:40:35 +02:00
|
|
|
if (interleave >= 512) {
|
|
|
|
chstreamfile =
|
|
|
|
streamFile->open(streamFile,filename,interleave);
|
|
|
|
} else {
|
|
|
|
if (!chstreamfile)
|
|
|
|
chstreamfile =
|
|
|
|
streamFile->open(streamFile,filename,STREAMFILE_DEFAULT_BUFFER_SIZE);
|
|
|
|
}
|
2008-06-13 01:33:07 +02:00
|
|
|
chstart_offset =
|
|
|
|
start_offset+vgmstream->interleave_block_size*i;
|
|
|
|
} else {
|
|
|
|
chstreamfile =
|
|
|
|
streamFile->open(streamFile,filename,
|
|
|
|
STREAMFILE_DEFAULT_BUFFER_SIZE);
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case coding_XBOX:
|
2008-08-18 01:07:41 +02:00
|
|
|
case coding_MSADPCM:
|
2009-03-09 13:48:53 +01:00
|
|
|
case coding_MS_IMA:
|
2008-06-13 01:33:07 +02:00
|
|
|
/* xbox's "interleave" is a lie, all channels start at same
|
|
|
|
* offset */
|
|
|
|
chstreamfile =
|
|
|
|
streamFile->open(streamFile,filename,
|
|
|
|
STREAMFILE_DEFAULT_BUFFER_SIZE);
|
|
|
|
break;
|
|
|
|
case coding_NGC_DTK:
|
|
|
|
if (!chstreamfile)
|
|
|
|
chstreamfile =
|
|
|
|
streamFile->open(streamFile,filename,32*0x400);
|
|
|
|
break;
|
2008-11-17 19:28:14 +01:00
|
|
|
case coding_NGC_DSP:
|
2008-11-17 19:45:09 +01:00
|
|
|
if (!chstreamfile)
|
|
|
|
chstreamfile =
|
|
|
|
streamFile->open(streamFile,filename,STREAMFILE_DEFAULT_BUFFER_SIZE);
|
|
|
|
|
Extend GENH to support little-endian "Gamecube" DSP ADPCM coefficients, for some 3DS titles.
This involves a reinterpretation of byte 0x30 (coef type). Formerly this byte took on only two values, to indicate how the ADPCM coefficients (aka codebook) were stored:
0 - normal coefs: all 16 coefs interleaved into one array, offset given at 0x24 for left, 0x28 for right
1 - split coefs: 8 coefs in the main array, additional offset to 2nd array given at 0x34 for left, 0x38 for right
Now I am considering this to be indicated only by bit 0 of the coef type. Bit 1 is taking on an additional interpretation, if it is set, we consider the coefficients to be little endian rather than the normal big endian.
This should maintain backwards compatibility with old GENH files, which should have only used the value 0 or 1.
Thus, in effect we have:
0: normal, big endian
1: split, big endian
2: normal, little endian
3: split, little endian
I don't know of any situation in which 3 would be used (yet), but I'm sure devs will continue to surprise me.
2014-06-27 05:53:49 +02:00
|
|
|
{
|
|
|
|
int16_t (*read_16bit)(off_t , STREAMFILE*);
|
|
|
|
if ((coef_type & 2) == 0) {
|
|
|
|
read_16bit = read_16bitBE;
|
|
|
|
} else {
|
|
|
|
read_16bit = read_16bitLE;
|
2008-12-24 01:00:10 +01:00
|
|
|
}
|
Extend GENH to support little-endian "Gamecube" DSP ADPCM coefficients, for some 3DS titles.
This involves a reinterpretation of byte 0x30 (coef type). Formerly this byte took on only two values, to indicate how the ADPCM coefficients (aka codebook) were stored:
0 - normal coefs: all 16 coefs interleaved into one array, offset given at 0x24 for left, 0x28 for right
1 - split coefs: 8 coefs in the main array, additional offset to 2nd array given at 0x34 for left, 0x38 for right
Now I am considering this to be indicated only by bit 0 of the coef type. Bit 1 is taking on an additional interpretation, if it is set, we consider the coefficients to be little endian rather than the normal big endian.
This should maintain backwards compatibility with old GENH files, which should have only used the value 0 or 1.
Thus, in effect we have:
0: normal, big endian
1: split, big endian
2: normal, little endian
3: split, little endian
I don't know of any situation in which 3 would be used (yet), but I'm sure devs will continue to surprise me.
2014-06-27 05:53:49 +02:00
|
|
|
|
|
|
|
if ((coef_type & 1) == 0) {
|
|
|
|
for (j=0;j<16;j++) {
|
|
|
|
vgmstream->ch[i].adpcm_coef[j] = read_16bit(coef[i]+j*2,streamFile);
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
for (j=0;j<8;j++) {
|
|
|
|
vgmstream->ch[i].adpcm_coef[j*2]=read_16bit(coef[i]+j*2,streamFile);
|
|
|
|
vgmstream->ch[i].adpcm_coef[j*2+1]=read_16bit(coef_splitted[i]+j*2,streamFile);
|
|
|
|
}
|
2008-12-24 01:00:10 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
chstart_offset =start_offset+vgmstream->interleave_block_size*i;
|
|
|
|
break;
|
2008-11-17 19:28:14 +01:00
|
|
|
|
2008-07-06 17:33:38 +02:00
|
|
|
#ifdef VGM_USE_MPEG
|
|
|
|
case coding_MPEG1_L3:
|
|
|
|
if (!chstreamfile)
|
|
|
|
chstreamfile =
|
|
|
|
streamFile->open(streamFile,filename,MPEG_BUFFER_SIZE);
|
|
|
|
break;
|
|
|
|
#endif
|
2008-06-13 01:33:07 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
if (!chstreamfile) goto fail;
|
2008-06-09 02:20:08 +02:00
|
|
|
|
2008-06-13 01:33:07 +02:00
|
|
|
vgmstream->ch[i].streamfile = chstreamfile;
|
2008-06-09 02:20:08 +02:00
|
|
|
|
|
|
|
vgmstream->ch[i].channel_start_offset=
|
2008-06-14 01:01:12 +02:00
|
|
|
vgmstream->ch[i].offset=chstart_offset;
|
2008-06-09 02:20:08 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2008-07-06 17:33:38 +02:00
|
|
|
#ifdef VGM_USE_MPEG
|
|
|
|
if (coding == coding_MPEG1_L3) {
|
2011-01-19 14:54:59 +01:00
|
|
|
vgmstream->codec_data = init_mpeg_codec_data(vgmstream->ch[0].streamfile, start_offset, vgmstream->sample_rate, vgmstream->channels, &(vgmstream->coding_type), NULL, NULL);
|
2010-09-10 23:49:56 +02:00
|
|
|
if (!vgmstream->codec_data) goto fail;
|
2008-07-06 17:33:38 +02:00
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
2008-06-09 02:20:08 +02:00
|
|
|
return vgmstream;
|
|
|
|
|
|
|
|
/* clean up anything we may have opened */
|
|
|
|
fail:
|
|
|
|
if (vgmstream) close_vgmstream(vgmstream);
|
|
|
|
return NULL;
|
|
|
|
}
|