Exemple #1
0
/* set up for the block at the given offset */
void thp_block_update(off_t block_offset, VGMSTREAM * vgmstream) {
    int i,j;
	STREAMFILE *streamFile=vgmstream->ch[0].streamfile;
	off_t	start_offset;
	int32_t	nextFrameSize;

	vgmstream->current_block_offset = block_offset;
	nextFrameSize=read_32bitBE(vgmstream->current_block_offset,streamFile);

	vgmstream->next_block_offset = vgmstream->current_block_offset
		                         + vgmstream->full_block_size;
	vgmstream->full_block_size = nextFrameSize;

	start_offset=vgmstream->current_block_offset
		         + read_32bitBE(vgmstream->current_block_offset+0x08,streamFile)+0x10;
	vgmstream->current_block_size=read_32bitBE(start_offset,streamFile);
	start_offset+=8;

	for(i=0;i<vgmstream->channels;i++) {
		for(j=0;j<16;j++) {
			vgmstream->ch[i].adpcm_coef[j]=read_16bitBE(start_offset+(i*0x20)+(j*2),streamFile);
		}
		vgmstream->ch[i].adpcm_history1_16=read_16bitBE(start_offset + (0x20*vgmstream->channels) + (i*4),streamFile);
		vgmstream->ch[i].adpcm_history2_16=read_16bitBE(start_offset + (0x20*vgmstream->channels) + (i*4) + 2,streamFile);
        vgmstream->ch[i].offset = start_offset + (0x24*vgmstream->channels)+(i*vgmstream->current_block_size);
	}
}
Exemple #2
0
void decode_pcm16be(VGMSTREAMCHANNEL * stream, sample * outbuf, int channelspacing, int32_t first_sample, int32_t samples_to_do) {
    int i;
    int32_t sample_count;

    for (i=first_sample,sample_count=0; i<first_sample+samples_to_do; i++,sample_count+=channelspacing) {
        outbuf[sample_count]=read_16bitBE(stream->offset+i*2,stream->streamfile);
    }
}
Exemple #3
0
VGMSTREAM * init_vgmstream_g1l(STREAMFILE *streamFile) {
	VGMSTREAM * vgmstream = NULL;
	char filename[260];

	coding_t coding_type;

	off_t head_offset;

	int channel_count;
	int loop_flag;
	off_t start_offset;

	/* check extension, case insensitive */
	streamFile->get_name(streamFile, filename, sizeof(filename));
	if (strcasecmp("g1l", filename_extension(filename)))
		goto fail;


	/* check header */
	if ((uint32_t)read_32bitBE(0, streamFile) != 0x47314C5F) /* "G1L_" */
		goto fail;
	if ((uint32_t)read_32bitBE(0x1c, streamFile) != 0x57696942) /* "WiiB" */
		goto fail;

	/* check type details */
//	loop_flag = read_8bit(head_offset + 0x21, streamFile);
	if (read_32bitBE(0x30, streamFile) > 0)
		loop_flag = 1;
	else
		loop_flag = 0;
	channel_count = read_8bit(0x3f, streamFile);


	coding_type = coding_NGC_DSP;
	

	if (channel_count < 1) goto fail;

	/* build the VGMSTREAM */

	vgmstream = allocate_vgmstream(channel_count, loop_flag);
	if (!vgmstream) goto fail;

	/* fill in the vital statistics */
	vgmstream->num_samples = read_32bitBE(0x2c, streamFile);
	vgmstream->sample_rate = (uint16_t)read_16bitBE(0x42, streamFile);
	/* channels and loop flag are set by allocate_vgmstream */
	
	vgmstream->loop_start_sample = read_32bitBE(0x30, streamFile);
	vgmstream->loop_end_sample = vgmstream->num_samples;
	

	vgmstream->coding_type = coding_type;
	if (channel_count == 1)
		vgmstream->layout_type = layout_none;
	
	vgmstream->layout_type = layout_interleave_byte;
	
	vgmstream->meta_type = meta_G1L;

	vgmstream->interleave_block_size = 0x1;	

	if (vgmstream->coding_type == coding_NGC_DSP) {
		off_t coef_offset = 0x78;
		
		int i, j;
		int coef_spacing = 0x60;


		for (j = 0; j<vgmstream->channels; j++) {
			for (i = 0; i<16; i++) {
				vgmstream->ch[j].adpcm_coef[i] = read_16bitBE(coef_offset + j*coef_spacing + i * 2, streamFile);
			}
		}
	}

	if (vgmstream->coding_type == coding_NGC_DSP)
		start_offset = 0x81c;
	else // Will add AT3 G1L support later
		goto fail;



	/* open the file for reading by each channel */
	{
		int i;
		for (i = 0; i<channel_count; i++) {
			if (vgmstream->layout_type == layout_interleave_shortblock)
				vgmstream->ch[i].streamfile = streamFile->open(streamFile, filename,
				vgmstream->interleave_block_size);
			else if (vgmstream->layout_type == layout_interleave)
				vgmstream->ch[i].streamfile = streamFile->open(streamFile, filename,
				STREAMFILE_DEFAULT_BUFFER_SIZE);
			else
				vgmstream->ch[i].streamfile = streamFile->open(streamFile, filename,
				0x1000);

			if (!vgmstream->ch[i].streamfile) goto fail;

			vgmstream->ch[i].channel_start_offset =
				vgmstream->ch[i].offset =
				start_offset + i*vgmstream->interleave_block_size;
		}
	}

	return vgmstream;

	/* clean up anything we may have opened */
fail:
	if (vgmstream) close_vgmstream(vgmstream);
	return NULL;
}
Exemple #4
0
VGMSTREAM * init_vgmstream_afc(STREAMFILE *streamFile) {
    VGMSTREAM * vgmstream = NULL;
    char filename[PATH_LIMIT];

    int loop_flag;
    const int channel_count = 2;    /* .afc seems to be stereo only */

    /* check extension, case insensitive */
    streamFile->get_name(streamFile,filename,sizeof(filename));
    if (strcasecmp("afc",filename_extension(filename))) goto fail;

    /* don't grab AIFF-C with .afc extension */
    if ((uint32_t)read_32bitBE(0x0,streamFile)==0x464F524D) /* FORM */
        goto fail;

    /* we will get a sample rate, that's as close to checking as I think
     * we can get */

    /* build the VGMSTREAM */

    loop_flag = read_32bitBE(0x10,streamFile);

    vgmstream = allocate_vgmstream(channel_count,loop_flag);
    if (!vgmstream) goto fail;

    /* fill in the vital statistics */
    vgmstream->num_samples = read_32bitBE(0x04,streamFile);
    vgmstream->sample_rate = (uint16_t)read_16bitBE(0x08,streamFile);
    /* channels and loop flag are set by allocate_vgmstream */
    vgmstream->loop_start_sample = read_32bitBE(0x14,streamFile);
    vgmstream->loop_end_sample = vgmstream->num_samples;

    vgmstream->coding_type = coding_NGC_AFC;
    vgmstream->layout_type = layout_interleave;
    vgmstream->meta_type = meta_AFC;

    /* frame-level interleave (9 bytes) */
    vgmstream->interleave_block_size = 9;

    /* open the file for reading by each channel */
    {
        STREAMFILE *chstreamfile;
        int i;

        /* both channels use same buffer, as interleave is so small */
        chstreamfile = streamFile->open(streamFile,filename,STREAMFILE_DEFAULT_BUFFER_SIZE);
        if (!chstreamfile) goto fail;

        for (i=0;i<channel_count;i++) {
            vgmstream->ch[i].streamfile = chstreamfile;

            vgmstream->ch[i].channel_start_offset=
                vgmstream->ch[i].offset=
                0x20 + i*vgmstream->interleave_block_size;
        }
    }

    return vgmstream;

    /* clean up anything we may have opened */
fail:
    if (vgmstream) close_vgmstream(vgmstream);
    return NULL;
}
Exemple #5
0
/* CRI's UTF wrapper around DSP */
VGMSTREAM * init_vgmstream_utf_dsp(STREAMFILE *streamFile) {
    
	VGMSTREAM * vgmstream = NULL;
    char filename[1024];
    int table_error = 0;

    int loop_flag = 0;

    const long top_offset = 0;

    int channel_count;
    int sample_rate;
    long sample_count;

    long top_data_offset, segment_count;
    long body_offset, body_size;
    long header_offset, header_size;

    /* check extension, case insensitive */
    streamFile->get_name(streamFile,filename,sizeof(filename));
    //if (strcasecmp("aax",filename_extension(filename))) goto fail;

    /* get entry count, data offset */
    {
        struct utf_query_result result;
        long top_string_table_offset;
        long top_string_table_size;
        long name_offset;
       
        result = query_utf_nofail(streamFile, top_offset, NULL, &table_error);
        if (table_error) goto fail;
        segment_count = result.rows;
        if (segment_count != 1) goto fail; // only simple stuff for now
        top_string_table_offset = top_offset + 8 + result.string_table_offset;
        top_data_offset = top_offset + 8 + result.data_offset;
        top_string_table_size = top_data_offset - top_string_table_offset;

        if (result.name_offset+10 > top_string_table_size) goto fail;

        name_offset = top_string_table_offset + result.name_offset;
        if (read_32bitBE(name_offset, streamFile) != 0x41445043   ||// "ADPC"
            read_32bitBE(name_offset+4, streamFile) != 0x4D5F5749 ||// "M_WI"
            read_16bitBE(name_offset+8, streamFile) != 0x4900)      // "I\0"
            goto fail;
    }

    {
        struct offset_size_pair offset_size;

        offset_size = query_utf_data(streamFile, top_offset, 0, "data", &table_error);
        if (table_error) goto fail;
        body_offset = top_data_offset + offset_size.offset;
        body_size = offset_size.size;

        offset_size = query_utf_data(streamFile, top_offset, 0, "header", &table_error);
        if (table_error) goto fail;
        header_offset = top_data_offset + offset_size.offset;
        header_size = offset_size.size;
    }

    channel_count = query_utf_1byte(streamFile, top_offset, 0, "nch", &table_error);
    sample_count = query_utf_4byte(streamFile, top_offset, 0, "nsmpl", &table_error);
    sample_rate = query_utf_4byte(streamFile, top_offset, 0, "sfreq", &table_error);
    if (table_error) goto fail;
    if (channel_count != 1 && channel_count != 2) goto fail;
    if (header_size != channel_count * 0x60) goto fail;

    vgmstream = allocate_vgmstream(channel_count,loop_flag);

    vgmstream->num_samples = sample_count;
    vgmstream->sample_rate = sample_rate;

    vgmstream->coding_type = coding_NGC_DSP;
    vgmstream->layout_type = layout_none;
    vgmstream->meta_type = meta_UTF_DSP;

    {
        int i,j;
        long channel_size = (body_size+7)/8*8/channel_count;
        for (i = 0; i < channel_count; i++)
        {
            vgmstream->ch[i].streamfile = streamFile->open(streamFile,filename,STREAMFILE_DEFAULT_BUFFER_SIZE);
            if (!vgmstream->ch[i].streamfile) goto fail;
            vgmstream->ch[i].channel_start_offset =
                vgmstream->ch[i].offset = body_offset + i * channel_size;
            for (j=0;j<16;j++)
            {
                vgmstream->ch[i].adpcm_coef[j] =
                    read_16bitBE(header_offset + 0x60*i + 0x1c + j*2, streamFile);
            }
        }
    }

    return vgmstream;

    /* clean up anything we may have opened */
fail:
    if (vgmstream) close_vgmstream(vgmstream);
    return NULL;
}
Exemple #6
0
/* ADS (from Gauntlet Dark Legends (GC)) */
VGMSTREAM * init_vgmstream_ads(STREAMFILE *streamFile) {
    VGMSTREAM * vgmstream = NULL;
    char filename[PATH_LIMIT];
    off_t start_offset;
    int loop_flag;
    int channel_count;
    int identifer_byte;

    /* check extension, case insensitive */
    streamFile->get_name(streamFile,filename,sizeof(filename));
    if (strcasecmp("ads",filename_extension(filename))) goto fail;

    /* check dhSS Header */
    if (read_32bitBE(0x00,streamFile) != 0x64685353)
        goto fail;

    /* check dbSS Header */
    if (read_32bitBE(0x20,streamFile) != 0x64625353)
        goto fail;
    
    loop_flag = 1;
    channel_count = read_32bitBE(0x10,streamFile);

    if (channel_count > 0x2)
        goto fail;

    /* build the VGMSTREAM */
    vgmstream = allocate_vgmstream(channel_count,loop_flag);
    if (!vgmstream) goto fail;

    /* fill in the vital statistics */
    identifer_byte = read_32bitBE(0x08,streamFile);
    switch (identifer_byte) {
        case 0x00000020:
            start_offset = 0xE8;
            vgmstream->channels = channel_count;
            vgmstream->sample_rate = read_32bitBE(0x0c,streamFile);
            vgmstream->coding_type = coding_NGC_DSP;
            vgmstream->num_samples = read_32bitBE(0x28,streamFile);
        if (loop_flag) {
            vgmstream->loop_start_sample = 0;
            vgmstream->loop_end_sample = vgmstream->num_samples;
        }
        
        if (channel_count == 1){
            vgmstream->layout_type = layout_none;
        } else if (channel_count == 2){
            vgmstream->layout_type = layout_interleave;
            vgmstream->interleave_block_size = read_32bitBE(0x14,streamFile);
        }
    break;
        case 0x00000021:
            start_offset = 0x28;
            vgmstream->channels = channel_count;
            vgmstream->sample_rate = read_32bitBE(0x0c,streamFile);
            vgmstream->coding_type = coding_INT_XBOX;
            vgmstream->num_samples = (read_32bitBE(0x24,streamFile) / 36 *64 / vgmstream->channels)-64; // to avoid the "pop" at the loop point
            vgmstream->layout_type = layout_interleave;
            vgmstream->interleave_block_size = 0x24;
        if (loop_flag) {
            vgmstream->loop_start_sample = 0;
            vgmstream->loop_end_sample = vgmstream->num_samples;
        }
        break;
    default:
goto fail;
}

    vgmstream->meta_type = meta_ADS;

        {
        int i;
        for (i=0;i<16;i++)
            vgmstream->ch[0].adpcm_coef[i] = read_16bitBE(0x44+i*2,streamFile);
        if (channel_count == 2) {
        for (i=0;i<16;i++)
            vgmstream->ch[1].adpcm_coef[i] = read_16bitBE(0xA4+i*2,streamFile);
    }
        }


    /* open the file for reading */
    if (vgmstream->coding_type == coding_NGC_DSP) {
        int i,c;
        for (c=0;c<channel_count;c++) {
            for (i=0;i<16;i++) {
                vgmstream->ch[c].adpcm_coef[i] =
                    read_16bitBE(0x44+c*0x60 +i*2,streamFile);
            }
        }
    }

    /* open the file for reading */
    {
        int i;
        STREAMFILE * file;
        file = streamFile->open(streamFile,filename,STREAMFILE_DEFAULT_BUFFER_SIZE);
        if (!file) goto fail;
        for (i=0;i<channel_count;i++) {
            vgmstream->ch[i].streamfile = file;

            
            vgmstream->ch[i].channel_start_offset=
                start_offset+vgmstream->interleave_block_size*i;
            vgmstream->ch[i].offset = vgmstream->ch[i].channel_start_offset;

        }
    }

    return vgmstream;

fail:
    /* clean up anything we may have opened */
    if (vgmstream) close_vgmstream(vgmstream);
    return NULL;
}
Exemple #7
0
/* PSND (from Crash Bandicoot Nitro Kart 2 (iOS) */
VGMSTREAM * init_vgmstream_ios_psnd(STREAMFILE *streamFile) {
    VGMSTREAM * vgmstream = NULL;
    char filename[PATH_LIMIT];
    off_t start_offset;

    int loop_flag;
   int channel_count;

    /* check extension, case insensitive */
    streamFile->get_name(streamFile,filename,sizeof(filename));
    if (strcasecmp("psnd",filename_extension(filename))) goto fail;

    /* check header */
    if (read_32bitBE(0x00,streamFile) != 0x50534E44) /* "PSND" */
        goto fail;

    if (read_16bitBE(0xC,streamFile)==0x2256){
		loop_flag = 1;
	}
	else {
		loop_flag = 0;
	}
	channel_count = read_8bit(0xE,streamFile);

   /* build the VGMSTREAM */
    vgmstream = allocate_vgmstream(channel_count,loop_flag);
    if (!vgmstream) goto fail;

   /* fill in the vital statistics */
    start_offset = 0x10;
    vgmstream->channels = channel_count;
	
	if (read_16bitBE(0xC,streamFile)==0x44AC){
		vgmstream->sample_rate = 44100;
	}
	else {
        vgmstream->sample_rate = read_16bitLE(0xC,streamFile);
	}

    vgmstream->coding_type = coding_PCM16LE;
    vgmstream->num_samples = (read_32bitLE(0x4,streamFile)-8)/4;
	if (loop_flag) {
        vgmstream->loop_start_sample = 0;
       vgmstream->loop_end_sample = vgmstream->num_samples;
    }
    vgmstream->layout_type = layout_interleave;
    vgmstream->interleave_block_size = 2;
    vgmstream->meta_type = meta_IOS_PSND;

    /* open the file for reading */
    {
        int i;
        STREAMFILE * file;
        file = streamFile->open(streamFile,filename,STREAMFILE_DEFAULT_BUFFER_SIZE);
        if (!file) goto fail;
        for (i=0;i<channel_count;i++) {
            vgmstream->ch[i].streamfile = file;

            vgmstream->ch[i].channel_start_offset=
                vgmstream->ch[i].offset=start_offset+
                vgmstream->interleave_block_size*i;

        }
    }

    return vgmstream;

    /* clean up anything we may have opened */
fail:
    if (vgmstream) close_vgmstream(vgmstream);
    return NULL;
}
Exemple #8
0
/* LPS (found in Rave Master (Groove Adventure Rave)(GC) */
VGMSTREAM * init_vgmstream_ngc_lps(STREAMFILE *streamFile) {
    VGMSTREAM * vgmstream = NULL;
    char filename[260];
    off_t start_offset;
	int loop_flag;
	int channel_count;

    /* check extension, case insensitive */
    streamFile->get_name(streamFile,filename,sizeof(filename));
    if (strcasecmp("lps",filename_extension(filename))) goto fail;

    /* check header */
    if (read_32bitBE(0x8,streamFile) != 0x10000000)
		goto fail;

    loop_flag = read_32bitBE(0x30,streamFile);
    channel_count = 1;
    
	/* build the VGMSTREAM */
    vgmstream = allocate_vgmstream(channel_count,loop_flag);
    if (!vgmstream) goto fail;

	/* fill in the vital statistics */
  start_offset = 0x60;
	vgmstream->channels = channel_count;
    vgmstream->sample_rate = read_32bitBE(0x28,streamFile);
    vgmstream->coding_type = coding_NGC_DSP;
    vgmstream->num_samples = (read_32bitBE(0x34,streamFile))/16*14;
    if (loop_flag) {
        vgmstream->loop_start_sample = (read_32bitBE(0x30,streamFile))/16*14;
        vgmstream->loop_end_sample = vgmstream->num_samples;
    }

    vgmstream->layout_type = layout_none;
    vgmstream->meta_type = meta_NGC_LPS;

    if (vgmstream->coding_type == coding_NGC_DSP) {
        int i;
        for (i=0;i<16;i++) {
            vgmstream->ch[0].adpcm_coef[i] = read_16bitBE(0x3C+i*2,streamFile);
        }
    }
    /* open the file for reading */
    {
        int i;
        STREAMFILE * file;
        file = streamFile->open(streamFile,filename,STREAMFILE_DEFAULT_BUFFER_SIZE);
        if (!file) goto fail;
        for (i=0;i<channel_count;i++) {
            vgmstream->ch[i].streamfile = file;

            vgmstream->ch[i].channel_start_offset=
                vgmstream->ch[i].offset=start_offset+
                vgmstream->interleave_block_size*i;

        }
    }

    return vgmstream;

	/* clean up anything we may have opened */
fail:
    if (vgmstream) close_vgmstream(vgmstream);
    return NULL;
}
Exemple #9
0
Fichier : ast.c Projet : 1c0n/xbmc
VGMSTREAM * init_vgmstream_ast(STREAMFILE *streamFile) {
    VGMSTREAM * vgmstream = NULL;
    char filename[260];

    coding_t coding_type;

    int codec_number;
    int channel_count;
    int loop_flag;

    size_t max_block;

    /* check extension, case insensitive */
    streamFile->get_name(streamFile,filename,sizeof(filename));
    if (strcasecmp("ast",filename_extension(filename))) goto fail;

    /* check header */
    if ((uint32_t)read_32bitBE(0,streamFile)!=0x5354524D || /* "STRM" */
            read_16bitBE(0xa,streamFile)!=0x10 ||
            /* check that file = header (0x40) + data */
            read_32bitBE(4,streamFile)+0x40!=get_streamfile_size(streamFile))
        goto fail;
    
    /* check for a first block */
    if (read_32bitBE(0x40,streamFile)!=0x424C434B)  /* "BLCK" */
        goto fail;

    /* check type details */
    codec_number = read_16bitBE(8,streamFile);
    loop_flag = read_16bitBE(0xe,streamFile);
    channel_count = read_16bitBE(0xc,streamFile);
    max_block = read_32bitBE(0x20,streamFile);

    switch (codec_number) {
        case 0:
            coding_type = coding_NGC_AFC;
            break;
        case 1:
            coding_type = coding_PCM16BE;
            break;
        default:
            goto fail;
    }

    /* build the VGMSTREAM */

    vgmstream = allocate_vgmstream(channel_count,loop_flag);
    if (!vgmstream) goto fail;

    /* fill in the vital statistics */
    vgmstream->num_samples = read_32bitBE(0x14,streamFile);
    vgmstream->sample_rate = read_32bitBE(0x10,streamFile);
    /* channels and loop flag are set by allocate_vgmstream */
    vgmstream->loop_start_sample = read_32bitBE(0x18,streamFile);
    vgmstream->loop_end_sample = read_32bitBE(0x1c,streamFile);

    vgmstream->coding_type = coding_type;
    vgmstream->layout_type = layout_ast_blocked;
    vgmstream->meta_type = meta_AST;

    /* open the file for reading by each channel */
    {
        int i;
        for (i=0;i<channel_count;i++) {
            vgmstream->ch[i].streamfile = streamFile->open(streamFile,filename,
                    (i==0?
                     max_block+0x20-4: /* first buffer a bit bigger to 
                                         read block header without
                                         inefficiency */
                     max_block
                    )
                    );

            if (!vgmstream->ch[i].streamfile) goto fail;
        }
    }

    /* start me up */
    ast_block_update(0x40,vgmstream);

    return vgmstream;

    /* clean up anything we may have opened */
fail:
    if (vgmstream) close_vgmstream(vgmstream);
    return NULL;
}
Exemple #10
0
VGMSTREAM * init_vgmstream_bfstm(STREAMFILE *streamFile) {
	VGMSTREAM * vgmstream = NULL;
	char filename[PATH_LIMIT];

	coding_t coding_type;

	off_t info_offset, seek_offset, data_offset, regn_offset, pdat_offset;
	size_t info_size, seek_size, data_size, regn_size, pdat_size;
	uint16_t temp_id;
	int codec_number;
	int channel_count;
	int loop_flag;
	int i, j;
	int ima = 0;
	off_t start_offset;
	int founddata;
	off_t tempoffset1;

	/* check extension, case insensitive */
	streamFile->get_name(streamFile, filename, sizeof(filename));
	if (strcasecmp("bfstm", filename_extension(filename)))
		goto fail;


	/* check header */
	if ((uint32_t)read_32bitBE(0, streamFile) != 0x4653544D) /* "FSTM" */
		goto fail;
	if ((uint16_t)read_16bitBE(4, streamFile) != 0xFEFF)
		goto fail;

	int section_count = read_16bitBE(0x10, streamFile);
	for (i = 0; i < section_count; i++) {
		temp_id = read_16bitBE(0x14 + i * 0xc, streamFile);
		switch(temp_id) {
			case 0x4000:
				info_offset = read_32bitBE(0x18 + i * 0xc, streamFile);
				info_size = read_32bitBE(0x1c + i * 0xc, streamFile);
				break;
			case 0x4001:
				seek_offset = read_32bitBE(0x18 + i * 0xc, streamFile);
				seek_size = read_32bitBE(0x1c + i * 0xc, streamFile);
				break;
			case 0x4002:
				data_offset = read_32bitBE(0x18 + i * 0xc, streamFile);
				data_size = read_32bitBE(0x1c + i * 0xc, streamFile);
				break;
			case 0x4003:
				regn_offset = read_32bitBE(0x18 + i * 0xc, streamFile);
				regn_size = read_32bitBE(0x1c + i * 0xc, streamFile);
				break;
			case 0x4004:
				pdat_offset = read_32bitBE(0x18 + i * 0xc, streamFile);
				pdat_size = read_32bitBE(0x1c + i * 0xc, streamFile);
				break;
			default:
				break;				
		}
	}
	

	if ((uint32_t)read_32bitBE(info_offset, streamFile) != 0x494E464F) /* "INFO" */
		goto fail;


	/* check type details */
	codec_number = read_8bit(info_offset + 0x20, streamFile);
	loop_flag = read_8bit(info_offset + 0x21, streamFile);
	channel_count = read_8bit(info_offset + 0x22, streamFile);

	switch (codec_number) {
	case 0:
		coding_type = coding_PCM8;
		break;
	case 1:
		coding_type = coding_PCM16BE;
		break;
	case 2:
		coding_type = coding_NGC_DSP;
		break;
	default:
		goto fail;
	}

	if (channel_count < 1) goto fail;

	/* build the VGMSTREAM */

	vgmstream = allocate_vgmstream(channel_count, loop_flag);
	if (!vgmstream) goto fail;

	/* fill in the vital statistics */
	vgmstream->num_samples = read_32bitBE(info_offset + 0x2c, streamFile);
	vgmstream->sample_rate = (uint16_t)read_16bitBE(info_offset + 0x26, streamFile);
	/* channels and loop flag are set by allocate_vgmstream */
	if (ima) //Shift the loop points back slightly to avoid stupid pops in some IMA streams due to DC offsetting
	{
		vgmstream->loop_start_sample = read_32bitBE(info_offset + 0x28, streamFile);
		if (vgmstream->loop_start_sample > 10000)
		{
			vgmstream->loop_start_sample -= 5000;
			vgmstream->loop_end_sample = vgmstream->num_samples - 5000;
		}
		else
			vgmstream->loop_end_sample = vgmstream->num_samples;
	}
	else
	{
		vgmstream->loop_start_sample = read_32bitBE(info_offset + 0x28, streamFile);
		vgmstream->loop_end_sample = vgmstream->num_samples;
	}

	vgmstream->coding_type = coding_type;
	if (channel_count == 1)
		vgmstream->layout_type = layout_none;
	else
	{
		if (ima)
			vgmstream->layout_type = layout_interleave;
		else
			vgmstream->layout_type = layout_interleave_shortblock;
	}
	vgmstream->meta_type = meta_FSTM;

	if (ima)
		vgmstream->interleave_block_size = 0x200;
	else {
		vgmstream->interleave_block_size = read_32bitBE(info_offset + 0x34, streamFile);
		vgmstream->interleave_smallblock_size = read_32bitBE(info_offset + 0x44, streamFile);
	}

	if (vgmstream->coding_type == coding_NGC_DSP) {
		VARDECL(off_t, coef_offset);
		ALLOC(coef_offset, channel_count, off_t);
		off_t coeff_ptr_table = read_32bitBE(info_offset + 0x1c, streamFile) + info_offset + 8;	// Getting pointer for coefficient pointer table
		
		for (i = 0; i < channel_count; i++) {
			tempoffset1 = read_32bitBE(coeff_ptr_table + 8 + i * 8, streamFile);
			coef_offset[i] = tempoffset1 + coeff_ptr_table;
			coef_offset[i] += read_32bitBE(coef_offset[i] + 4, streamFile);
		} 
		
		for (j = 0; j<vgmstream->channels; j++) {
			for (i = 0; i<16; i++) {
				vgmstream->ch[j].adpcm_coef[i] = read_16bitBE(coef_offset[j] + i * 2, streamFile);
			}
		}
	}

	if (ima) // No SEEK (ADPC) header, so just start where the SEEK header is supposed to be.
		start_offset = seek_offset;
	else
		start_offset = data_offset + 0x20;



	/* open the file for reading by each channel */
	{
		int i;
		for (i = 0; i<channel_count; i++) {
			if (vgmstream->layout_type == layout_interleave_shortblock)
				vgmstream->ch[i].streamfile = streamFile->open(streamFile, filename,
				vgmstream->interleave_block_size);
			else if (vgmstream->layout_type == layout_interleave)
				vgmstream->ch[i].streamfile = streamFile->open(streamFile, filename,
				STREAMFILE_DEFAULT_BUFFER_SIZE);
			else
				vgmstream->ch[i].streamfile = streamFile->open(streamFile, filename,
				0x1000);

			if (!vgmstream->ch[i].streamfile) goto fail;

			vgmstream->ch[i].channel_start_offset =
				vgmstream->ch[i].offset =
				start_offset + i*vgmstream->interleave_block_size;
		}
	}

	return vgmstream;

	/* clean up anything we may have opened */
fail:
	if (vgmstream) close_vgmstream(vgmstream);
	return NULL;
}
Exemple #11
0
/* return 0 if not found, 1 if found and set parameters */
static int find_key(STREAMFILE *file, uint8_t type, uint16_t *xor_start, uint16_t *xor_mult, uint16_t *xor_add)
{
    uint16_t * scales = NULL;
    uint16_t * prescales = NULL;
    int bruteframe=0,bruteframecount=-1;
    int startoff, endoff;
    int rc = 0;

    startoff=read_16bitBE(2, file)+4;
    endoff=(read_32bitBE(12, file)+31)/32*18*read_8bit(7, file)+startoff;

    /* how many scales? */
    {
        int framecount=(endoff-startoff)/18;
        if (framecount<bruteframecount || bruteframecount<0)
            bruteframecount=framecount;
    }

    /* find longest run of nonzero frames */
    {
        int longest=-1,longest_length=-1;
        int i;
        int length=0;
        for (i=0;i<bruteframecount;i++) {
            static const unsigned char zeroes[18]={0};
            unsigned char buf[18];
            read_streamfile(buf, startoff+i*18, 18, file);
            if (memcmp(zeroes,buf,18)) length++;
            else length=0;
            if (length > longest_length) {
                longest_length=length;
                longest=i-length+1;
                if (longest_length >= 0x8000) break;
            }
        }
        if (longest==-1) {
            goto find_key_cleanup;
        }
        bruteframecount = longest_length;
        bruteframe = longest;
    }

    {
        /* try to guess key */
#define MAX_FRAMES (INT_MAX/0x8000)
        int scales_to_do;
        int key_id;

        /* allocate storage for scales */
        scales_to_do = (bruteframecount > MAX_FRAMES ? MAX_FRAMES : bruteframecount);
        scales = malloc(scales_to_do*sizeof(uint16_t));
        if (!scales) {
            goto find_key_cleanup;
        }
        /* prescales are those scales before the first frame we test
         * against, we use these to compute the actual start */
        if (bruteframe > 0) {
            int i;
            /* allocate memory for the prescales */
            prescales = malloc(bruteframe*sizeof(uint16_t));
            if (!prescales) {
                goto find_key_cleanup;
            }
            /* read the prescales */
            for (i=0; i<bruteframe; i++) {
                prescales[i] = read_16bitBE(startoff+i*18, file);
            }
        }

        /* read in the scales */
        {
            int i;
            for (i=0; i < scales_to_do; i++) {
                scales[i] = read_16bitBE(startoff+(bruteframe+i)*18, file);
            }
        }

        if (type == 8)
        {
            /* guess each of the keys */
            for (key_id=0;key_id<keys_8_count;key_id++) {
                /* test pre-scales */
                uint16_t xor = keys_8[key_id].start;
                uint16_t mult = keys_8[key_id].mult;
                uint16_t add = keys_8[key_id].add;
                int i;

                for (i=0;i<bruteframe &&
                        ((prescales[i]&0x6000)==(xor&0x6000) ||
                         prescales[i]==0);
                        i++) {
                    xor = xor * mult + add;
                }

                if (i == bruteframe)
                {
                    /* test */
                    for (i=0;i<scales_to_do &&
                            (scales[i]&0x6000)==(xor&0x6000);i++) {
                        xor = xor * mult + add;
                    }
                    if (i == scales_to_do)
                    {
                        *xor_start = keys_8[key_id].start;
                        *xor_mult = keys_8[key_id].mult;
                        *xor_add = keys_8[key_id].add;

                        rc = 1;
                        goto find_key_cleanup;
                    }
                }
            }
        }
        else if (type == 9)
        {
            /* smarter XOR as seen in PSO2, can't do an exact match so we
             * have to search for the lowest */
            long best_score = MAX_FRAMES * 0x1fff;

            /* guess each of the keys */
            for (key_id=0;key_id<keys_9_count;key_id++) {
                /* run past pre-scales */
                uint16_t xor = keys_9[key_id].start;
                uint16_t mult = keys_9[key_id].mult;
                uint16_t add = keys_9[key_id].add;
                int i;
                long total_score = 0;

                for (i=0;i<bruteframe;i++) {
                    xor = xor * mult + add;
                }

                if (i == bruteframe)
                {
                    /* test */
                    for (i=0;i<scales_to_do && total_score < best_score;i++) {
                        xor = xor * mult + add;
                        total_score += (scales[i]^xor)&0x1fff;
                    }

                    if (total_score < best_score)
                    {
                        *xor_start = keys_9[key_id].start;
                        *xor_mult = keys_9[key_id].mult;
                        *xor_add = keys_9[key_id].add;

                        best_score = total_score;
                    }
                }
            }

            /* arbitrarily decide if we have won? */
            if (best_score < scales_to_do * 0x1000)
            {
                rc = 1;
            }
        }
    }

find_key_cleanup:
    if (scales) free(scales);
    if (prescales) free(prescales);
    return rc;
}
Exemple #12
0
VGMSTREAM * init_vgmstream_adx(STREAMFILE *streamFile) {
    VGMSTREAM * vgmstream = NULL;
    off_t stream_offset;
    uint16_t version_signature;
    int loop_flag=0;
    int channel_count, i, j, channel_header_spacing;
    int32_t loop_start_sample=0;
    int32_t loop_end_sample=0;
    meta_t header_type;
    int16_t coef1, coef2;
    uint16_t cutoff;
    char filename[PATH_LIMIT];
    int coding_type = coding_CRI_ADX;
    uint16_t xor_start=0,xor_mult=0,xor_add=0;
	/* Xenoblade Chronicles 3D uses an adx extension as with
	   the Wii version, but it's actually DSP ADPCM. Adding 
	   this flag to account for it. */
	int xb3d_flag = 0;
	
    /* check extension, case insensitive */
    streamFile->get_name(streamFile,filename,sizeof(filename));
    if (strcasecmp("adx",filename_extension(filename))) goto fail;

    /* check first 2 bytes */
    if ((uint16_t)read_16bitBE(0,streamFile)!=0x8000) {
		if (read_8bit(0,streamFile)!=2)goto fail;
		else {xb3d_flag = 1; coding_type = coding_NGC_DSP;}
	}
	
	if (xb3d_flag) {
		channel_count = read_32bitLE(0, streamFile);
		loop_flag = read_16bitLE(0x6e, streamFile);
		channel_header_spacing = 0x34;
	}
	else {
		/* get stream offset, check for CRI signature just before */
		stream_offset = (uint16_t)read_16bitBE(2,streamFile) + 4;
		if ((uint16_t)read_16bitBE(stream_offset-6,streamFile)!=0x2863 ||/* "(c" */
			(uint32_t)read_32bitBE(stream_offset-4,streamFile)!=0x29435249 /* ")CRI" */
		   ) goto fail;

		/* check for encoding type */
		/* 2 is for some unknown fixed filter, 3 is standard ADX, 4 is
		 * ADX with exponential scale, 0x11 is AHX */
		if (read_8bit(4,streamFile) != 3) goto fail;

		/* check for frame size (only 18 is supported at the moment) */
		if (read_8bit(5,streamFile) != 18) goto fail;

		/* check for bits per sample? (only 4 makes sense for ADX) */
		if (read_8bit(6,streamFile) != 4) goto fail;

		/* check version signature, read loop info */
		version_signature = read_16bitBE(0x12,streamFile);
		/* encryption */
		if (version_signature == 0x0408) {
			if (find_key(streamFile, 8, &xor_start, &xor_mult, &xor_add))
			{
				coding_type = coding_CRI_ADX_enc_8;
				version_signature = 0x0400;
			}
		}
		else if (version_signature == 0x0409) {
			if (find_key(streamFile, 9, &xor_start, &xor_mult, &xor_add))
			{
				coding_type = coding_CRI_ADX_enc_9;
				version_signature = 0x0400;
			}
		}

		if (version_signature == 0x0300) {      /* type 03 */
			header_type = meta_ADX_03;
			if (stream_offset-6 >= 0x2c) {   /* enough space for loop info? */
				loop_flag = (read_32bitBE(0x18,streamFile) != 0);
				loop_start_sample = read_32bitBE(0x1c,streamFile);
				//loop_start_offset = read_32bitBE(0x20,streamFile);
				loop_end_sample = read_32bitBE(0x24,streamFile);
				//loop_end_offset = read_32bitBE(0x28,streamFile);
			}
		} else if (version_signature == 0x0400) {

			off_t	ainf_info_length=0;

			if((uint32_t)read_32bitBE(0x24,streamFile)==0x41494E46) /* AINF Header */
				ainf_info_length = (off_t)read_32bitBE(0x28,streamFile);

			header_type = meta_ADX_04;
			if (stream_offset-ainf_info_length-6 >= 0x38) {   /* enough space for loop info? */
			if (read_32bitBE(0x24,streamFile) == 0xFFFEFFFE)
				loop_flag = 0;
			else
				loop_flag = (read_32bitBE(0x24,streamFile) != 0);

				loop_start_sample = read_32bitBE(0x28,streamFile);
				//loop_start_offset = read_32bitBE(0x2c,streamFile);
				loop_end_sample = read_32bitBE(0x30,streamFile);
				//loop_end_offset = read_32bitBE(0x34,streamFile);
			}
		} else if (version_signature == 0x0500) {			 /* found in some SFD : Buggy Heat, appears to have no loop */
			header_type = meta_ADX_05;
		} else goto fail;   /* not a known/supported version signature */

		/* At this point we almost certainly have an ADX file,
		 * so let's build the VGMSTREAM. */

		/* high-pass cutoff frequency, always 500 that I've seen */
		cutoff = (uint16_t)read_16bitBE(0x10,streamFile);

		if (loop_start_sample == 0 && loop_end_sample == 0) {
			loop_flag = 0;
		}

		channel_count = read_8bit(7,streamFile);
	}
    vgmstream = allocate_vgmstream(channel_count,loop_flag);
    if (!vgmstream) goto fail;

    /* fill in the vital statistics */
  
	if (xb3d_flag) {
		for (j=0;j<vgmstream->channels;j++) {
            for (i=0;i<16;i++) {
                vgmstream->ch[j].adpcm_coef[i]=read_16bitLE(4+j*channel_header_spacing+i*2,streamFile);
            }
        }
		vgmstream->layout_type = layout_none;
		vgmstream->coding_type = coding_type;
		vgmstream->meta_type = meta_XB3D_ADX;
		vgmstream->sample_rate = read_32bitLE(0x70,streamFile);
		vgmstream->num_samples = read_32bitLE(0x74, streamFile);
		vgmstream->loop_start_sample = read_32bitLE(0x78, streamFile);
		vgmstream->loop_end_sample = read_32bitLE(0x7c, streamFile);
		
		for (i = 0; i<channel_count; i++) {
			vgmstream->ch[i].streamfile = streamFile->open(streamFile, filename, 0x1000);
			vgmstream->ch[i].channel_start_offset = vgmstream->ch[i].offset
			= read_32bitLE(0x34+i*channel_header_spacing, streamFile);
			if (!vgmstream->ch[i].streamfile) goto fail;
		}
		
	}
	else {
		vgmstream->num_samples = read_32bitBE(0xc,streamFile);
		vgmstream->sample_rate = read_32bitBE(8,streamFile);
		/* channels and loop flag are set by allocate_vgmstream */
		vgmstream->loop_start_sample = loop_start_sample;
		vgmstream->loop_end_sample = loop_end_sample;

		vgmstream->coding_type = coding_type;
		if (channel_count==1)
			vgmstream->layout_type = layout_none;
		else
			vgmstream->layout_type = layout_interleave;
		vgmstream->meta_type = header_type;

		vgmstream->interleave_block_size=18;
		/* calculate filter coefficients */
		{
			double x,y,z,a,b,c;

			x = cutoff;
			y = vgmstream->sample_rate;
			z = cos(2.0*M_PI*x/y);

			a = M_SQRT2-z;
			b = M_SQRT2-1.0;
			c = (a-sqrt((a+b)*(a-b)))/b;

			coef1 = floor(c*8192);
			coef2 = floor(c*c*-4096);
		}

		{
			int i;
			STREAMFILE * chstreamfile;
		   
			/* ADX is so tightly interleaved that having two buffers is silly */
			chstreamfile = streamFile->open(streamFile,filename,18*0x400);
			if (!chstreamfile) goto fail;

			for (i=0;i<channel_count;i++) {
				vgmstream->ch[i].streamfile = chstreamfile;

				vgmstream->ch[i].channel_start_offset=
					vgmstream->ch[i].offset=
					stream_offset+18*i;

				vgmstream->ch[i].adpcm_coef[0] = coef1;
				vgmstream->ch[i].adpcm_coef[1] = coef2;

				if (coding_type == coding_CRI_ADX_enc_8 ||
					coding_type == coding_CRI_ADX_enc_9)
				{
					int j;
					vgmstream->ch[i].adx_channels = channel_count;
					vgmstream->ch[i].adx_xor = xor_start;
					vgmstream->ch[i].adx_mult = xor_mult;
					vgmstream->ch[i].adx_add = xor_add;

					for (j=0;j<i;j++)
						adx_next_key(&vgmstream->ch[i]);
				}
			}
		}
	}
    return vgmstream;

    /* clean up anything we may have opened */
fail:
    if (vgmstream) close_vgmstream(vgmstream);
    return NULL;
}
/* RAS (from Donkey Kong Country Returns) */
VGMSTREAM * init_vgmstream_wii_ras(STREAMFILE *streamFile) {
    VGMSTREAM * vgmstream = NULL;
    char filename[260];
    off_t start_offset;

    int loop_flag;
   int channel_count;

    /* check extension, case insensitive */
    streamFile->get_name(streamFile,filename,sizeof(filename));
    if (strcasecmp("ras",filename_extension(filename))) goto fail;

    /* check header */
    if (read_32bitBE(0x00,streamFile) != 0x5241535F) /* "RAS_" */
        goto fail;

    loop_flag = 0;
    if (read_32bitBE(0x30,streamFile) != 0 ||
        read_32bitBE(0x34,streamFile) != 0 ||
        read_32bitBE(0x38,streamFile) != 0 ||
        read_32bitBE(0x3C,streamFile) != 0) {
        loop_flag = 1;
    }
    channel_count = 2;

   /* build the VGMSTREAM */
    vgmstream = allocate_vgmstream(channel_count,loop_flag);
    if (!vgmstream) goto fail;

   /* fill in the vital statistics */
    start_offset = read_32bitBE(0x18,streamFile);
    vgmstream->channels = channel_count;
    vgmstream->sample_rate = read_32bitBE(0x14,streamFile);
    vgmstream->coding_type = coding_NGC_DSP;
    vgmstream->num_samples = read_32bitBE(0x1c,streamFile)/channel_count/8*14;
    vgmstream->layout_type = layout_interleave;
	vgmstream->interleave_block_size = read_32bitBE(0x20,streamFile);
    vgmstream->meta_type = meta_WII_RAS;

    if (loop_flag) {
        // loop is block + samples into block
        vgmstream->loop_start_sample = 
        read_32bitBE(0x30,streamFile)*vgmstream->interleave_block_size/8*14 + 
            read_32bitBE(0x34,streamFile);
        vgmstream->loop_end_sample =
        read_32bitBE(0x38,streamFile)*vgmstream->interleave_block_size/8*14 +
            read_32bitBE(0x3C,streamFile);
    }

	 if (vgmstream->coding_type == coding_NGC_DSP) {
         int i;
         for (i=0;i<16;i++) {
            vgmstream->ch[0].adpcm_coef[i] = read_16bitBE(0x40+i*2,streamFile);
        }
	if (channel_count == 2) {
		  for (i=0;i<16;i++)
			vgmstream->ch[1].adpcm_coef[i] = read_16bitBE(0x70+i*2,streamFile);
				}
    } else {
        goto fail;
    }

    /* open the file for reading */
   {
        int i;
        for (i=0;i<channel_count;i++) {
            if (vgmstream->layout_type==layout_interleave_shortblock)
                vgmstream->ch[i].streamfile = streamFile->open(streamFile,filename,
                    vgmstream->interleave_block_size);
            else
                vgmstream->ch[i].streamfile = streamFile->open(streamFile,filename,
                    0x1000);

            if (!vgmstream->ch[i].streamfile) goto fail;

            vgmstream->ch[i].channel_start_offset=
                vgmstream->ch[i].offset=
                start_offset + i*vgmstream->interleave_block_size;
        }
    }

    return vgmstream;

    /* clean up anything we may have opened */
fail:
    if (vgmstream) close_vgmstream(vgmstream);
    return NULL;
}
Exemple #14
0
VGMSTREAM * init_vgmstream_genh(STREAMFILE *streamFile) {
    
	VGMSTREAM * vgmstream = NULL;
    
	int32_t channel_count;
    int32_t interleave;
    int32_t sample_rate;
    int32_t loop_start;
    int32_t loop_end;
    int32_t start_offset;
    int32_t header_size;
	int32_t coef[2];
	int32_t dsp_interleave_type;
	
    char filename[260];
    int coding;
#ifdef VGM_USE_MPEG
    mpeg_codec_data *data = NULL;
#endif

    /* 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;

    /* check channel count (needed for ADP/DTK check) */
    channel_count = read_32bitLE(0x4,streamFile);
    if (channel_count < 1) goto fail;

    /* check format */
    /* 0 = PSX ADPCM */
    /* 1 = XBOX IMA ADPCM */
    /* 2 = NGC ADP/DTK ADPCM */
    /* 3 = 16bit big endian PCM */
    /* 4 = 16bit little endian PCM */
    /* 5 = 8bit PCM */
    /* 6 = SDX2 */
    /* 7 = DVI IMA */
    /* 8 = MPEG-1 Layer III, possibly also the MPEG-2 and 2.5 extensions */
    /* 9 = IMA */
    /* 10 = AICA ADPCM */
    /* 11 = MS ADPCM */
    /* 12 = NGC DSP */
    /* 13 = 8bit unsingned PCM */
	/* 14 = PSX ADPCM (bad flagged) */
    /* ... others to come */
    switch (read_32bitLE(0x18,streamFile)) {
        case 0:
            coding = coding_PSX;
            break;
        case 1:
            coding = coding_XBOX;
            break;
        case 2:
            coding = coding_NGC_DTK;
            if (channel_count != 2) goto fail;
            break;
        case 3:
            coding = coding_PCM16BE;
            break;
        case 4:
            coding = coding_PCM16LE;
            break;
        case 5:
            coding = coding_PCM8;
            break;
        case 6:
            coding = coding_SDX2;
            break;
        case 7:
            coding = coding_DVI_IMA;
            break;
#ifdef VGM_USE_MPEG
        case 8:
            /* we say MPEG-1 L3 here, but later find out exactly which */
            coding = coding_MPEG1_L3;
            break;
#endif
        case 9:
            coding = coding_IMA;
            break;
        case 10:
            coding = coding_AICA;
            break;
        case 11:
            coding = coding_MSADPCM;
            break;
        case 12:
            coding = coding_NGC_DSP;
            break;
		case 13:
            coding = coding_PCM8_U_int;
            break;
		case 14:
            coding = coding_PSX_badflags;
            break;
        default:
            goto fail;
    }

    start_offset = read_32bitLE(0x1C,streamFile);
    header_size = read_32bitLE(0x20,streamFile);

    /* 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;

    interleave = read_32bitLE(0x8,streamFile);
    sample_rate = read_32bitLE(0xc,streamFile);
    loop_start = read_32bitLE(0x10,streamFile);
    loop_end = read_32bitLE(0x14,streamFile);
	
	coef[0] = read_32bitLE(0x24,streamFile);
	coef[1] = read_32bitLE(0x28,streamFile);
	dsp_interleave_type = read_32bitLE(0x2C,streamFile);

    //if (coding == coding_XBOX && channel_count != 2) goto fail;

    /* 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);

    switch (coding) {
        case coding_PCM8_U_int:
			vgmstream->layout_type=layout_none;
			break;
		case coding_PCM16LE:
        case coding_PCM16BE:
        case coding_PCM8:
        case coding_SDX2:
        case coding_PSX:
		case coding_PSX_badflags:
        case coding_DVI_IMA:
        case coding_IMA:
        case coding_AICA:
            vgmstream->interleave_block_size = interleave;
            if (channel_count > 1)
            {
                if (coding == coding_SDX2) {
                    coding = coding_SDX2_int;
                    vgmstream->coding_type = coding_SDX2_int;
                }
				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;
				}
            } else {
                vgmstream->layout_type = layout_none;
            }
            break;
        case coding_MSADPCM:
            if (channel_count != 2) goto fail;
            vgmstream->interleave_block_size = interleave;
            vgmstream->layout_type = layout_none;
            break;
        case coding_XBOX:
            vgmstream->layout_type = layout_none;
            break;
        case coding_NGC_DTK:
            vgmstream->layout_type = layout_dtk_interleave;
            break;
        case coding_NGC_DSP:
        	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;
            
#ifdef VGM_USE_MPEG
        case coding_MPEG1_L3:
            vgmstream->layout_type = layout_mpeg;
            break;
#endif
    }
    
	vgmstream->coding_type = coding;
	vgmstream->meta_type = meta_GENH;
    
    /* open the file for reading by each channel */
    {
        int i;
		int j;

        STREAMFILE * chstreamfile = NULL;

        for (i=0;i<channel_count;i++) {
            off_t chstart_offset = start_offset;

            switch (coding) {
                case coding_PSX:
				case coding_PSX_badflags:
                case coding_PCM16BE:
                case coding_PCM16LE:
                case coding_SDX2:
                case coding_SDX2_int:
                case coding_DVI_IMA:
                case coding_IMA:
                case coding_PCM8:
                case coding_PCM8_U_int:
                case coding_AICA:
				case coding_INT_DVI_IMA:
				case coding_INT_IMA:
                    if (vgmstream->layout_type == layout_interleave) {
                        if (interleave >= 512) {
                            chstreamfile =
                                streamFile->open(streamFile,filename,interleave);
                        } else {
                            if (!chstreamfile)
                                chstreamfile =
                                    streamFile->open(streamFile,filename,STREAMFILE_DEFAULT_BUFFER_SIZE);
                        }
                        chstart_offset =
                            start_offset+vgmstream->interleave_block_size*i;
                    } else {
                        chstreamfile =
                            streamFile->open(streamFile,filename,
                                    STREAMFILE_DEFAULT_BUFFER_SIZE);
                    }
                    break;
                case coding_XBOX:
                case coding_MSADPCM:
                    /* 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;
                case coding_NGC_DSP:
                    if (!chstreamfile) 
                        chstreamfile =
                            streamFile->open(streamFile,filename,STREAMFILE_DEFAULT_BUFFER_SIZE);

					for (j=0;j<16;j++) 
            			vgmstream->ch[i].adpcm_coef[j] = read_16bitBE(coef[i]+j*2,streamFile);
							chstart_offset =start_offset+vgmstream->interleave_block_size*i;
					break;

#ifdef VGM_USE_MPEG
                case coding_MPEG1_L3:
                    if (!chstreamfile)
                        chstreamfile =
                            streamFile->open(streamFile,filename,MPEG_BUFFER_SIZE);
                    break;
#endif
            }

            if (!chstreamfile) goto fail;

            vgmstream->ch[i].streamfile = chstreamfile;

            vgmstream->ch[i].channel_start_offset=
                vgmstream->ch[i].offset=chstart_offset;
        }
    }

#ifdef VGM_USE_MPEG
    if (coding == coding_MPEG1_L3) {
        int rc;
        off_t read_offset;
        data = calloc(1,sizeof(mpeg_codec_data));
        if (!data) goto mpeg_fail;

        data->m = mpg123_new(NULL,&rc);
        if (rc==MPG123_NOT_INITIALIZED) {
            if (mpg123_init()!=MPG123_OK) goto mpeg_fail;
            data->m = mpg123_new(NULL,&rc);
            if (rc!=MPG123_OK) goto mpeg_fail;
        } else if (rc!=MPG123_OK) {
            goto mpeg_fail;
        }

        mpg123_param(data->m,MPG123_REMOVE_FLAGS,MPG123_GAPLESS,0.0);

        if (mpg123_open_feed(data->m)!=MPG123_OK) {
            goto mpeg_fail;
        }

        /* check format */
        read_offset=0;
        do {
            size_t bytes_done;
            if (read_streamfile(data->buffer, start_offset+read_offset,
                    MPEG_BUFFER_SIZE,vgmstream->ch[0].streamfile) !=
                    MPEG_BUFFER_SIZE) goto mpeg_fail;
            read_offset+=1;
            rc = mpg123_decode(data->m,data->buffer,MPEG_BUFFER_SIZE,
                    NULL,0,&bytes_done);
            if (rc != MPG123_OK && rc != MPG123_NEW_FORMAT &&
                    rc != MPG123_NEED_MORE) goto mpeg_fail;
        } while (rc != MPG123_NEW_FORMAT);

        {
            long rate;
            int channels,encoding;
            struct mpg123_frameinfo mi;
            rc = mpg123_getformat(data->m,&rate,&channels,&encoding);
            if (rc != MPG123_OK) goto mpeg_fail;
            if (rate != vgmstream->sample_rate ||
                    channels != vgmstream->channels ||
                    encoding != MPG123_ENC_SIGNED_16) goto mpeg_fail;
            mpg123_info(data->m,&mi);
            if (mi.rate != vgmstream->sample_rate) goto mpeg_fail;
            if (mi.version == MPG123_1_0 && mi.layer == 1)
                vgmstream->coding_type = coding_MPEG1_L1;
            else if (mi.version == MPG123_1_0 && mi.layer == 2)
                vgmstream->coding_type = coding_MPEG1_L2;
            else if (mi.version == MPG123_1_0 && mi.layer == 3)
                vgmstream->coding_type = coding_MPEG1_L3;
            else if (mi.version == MPG123_2_0 && mi.layer == 1)
                vgmstream->coding_type = coding_MPEG2_L1;
            else if (mi.version == MPG123_2_0 && mi.layer == 2)
                vgmstream->coding_type = coding_MPEG2_L2;
            else if (mi.version == MPG123_2_0 && mi.layer == 3)
                vgmstream->coding_type = coding_MPEG2_L3;
            else if (mi.version == MPG123_2_5 && mi.layer == 1)
                vgmstream->coding_type = coding_MPEG25_L1;
            else if (mi.version == MPG123_2_5 && mi.layer == 2)
                vgmstream->coding_type = coding_MPEG25_L2;
            else if (mi.version == MPG123_2_5 && mi.layer == 3)
                vgmstream->coding_type = coding_MPEG25_L3;
            else goto mpeg_fail;
        }

        /* reinit, to ignore the reading we've done so far */
        mpg123_open_feed(data->m);

        vgmstream->codec_data = data;
    }
#endif

    return vgmstream;

    /* clean up anything we may have opened */
#ifdef VGM_USE_MPEG
mpeg_fail:
    if (data) {
        mpg123_delete(data->m);
        free(data);
    }
#endif
fail:
    if (vgmstream) close_vgmstream(vgmstream);
    return NULL;
}
Exemple #15
0
VGMSTREAM * init_vgmstream_brstm(STREAMFILE *streamFile) {
    VGMSTREAM * vgmstream = NULL;
    char filename[260];

    coding_t coding_type;

    off_t head_offset;
    int codec_number;
    int channel_count;
    int loop_flag;
    /* Certain Super Paper Mario tracks have a 44.1KHz sample rate in the
     * header, but they should be played at 22.05KHz. We will make this
     * correction if we see a file with a .brstmspm extension. */
    int spm_flag = 0;
    /* Trauma Center Second Opinion has an odd, semi-corrupt header */
    int atlus_shrunken_head = 0;

    off_t start_offset;

    /* check extension, case insensitive */
    streamFile->get_name(streamFile,filename,sizeof(filename));
    if (strcasecmp("brstm",filename_extension(filename))) {
        if (strcasecmp("brstmspm",filename_extension(filename))) goto fail;
        else spm_flag = 1;
    }

    /* check header */
    if ((uint32_t)read_32bitBE(0,streamFile)!=0x5253544D) /* "RSTM" */
        goto fail;
    if ((uint32_t)read_32bitBE(4,streamFile)!=0xFEFF0100)
    {
        if ((uint32_t)read_32bitBE(4,streamFile)!=0xFEFF0001)
            goto fail;
        else
            atlus_shrunken_head = 1;
    }

    /* get head offset, check */
    head_offset = read_32bitBE(0x10,streamFile);
    if (atlus_shrunken_head)
    {
        /* the HEAD chunk is where we would expect to find the offset of that
         * chunk... */

        if ((uint32_t)head_offset!=0x48454144 || read_32bitBE(0x14,streamFile) != 8)
            goto fail;

        head_offset = -8;   /* most of the normal Nintendo RSTM offsets work
                               with this assumption */
    }
    else
    {
    if ((uint32_t)read_32bitBE(head_offset,streamFile)!=0x48454144) /* "HEAD" */
        goto fail;
    }

    /* check type details */
    codec_number = read_8bit(head_offset+0x20,streamFile);
    loop_flag = read_8bit(head_offset+0x21,streamFile);
    channel_count = read_8bit(head_offset+0x22,streamFile);

    switch (codec_number) {
        case 0:
            coding_type = coding_PCM8;
            break;
        case 1:
            coding_type = coding_PCM16BE;
            break;
        case 2:
            coding_type = coding_NGC_DSP;
            break;
        default:
            goto fail;
    }

    if (channel_count < 1) goto fail;

    /* build the VGMSTREAM */

    vgmstream = allocate_vgmstream(channel_count,loop_flag);
    if (!vgmstream) goto fail;

    /* fill in the vital statistics */
    vgmstream->num_samples = read_32bitBE(head_offset+0x2c,streamFile);
    vgmstream->sample_rate = (uint16_t)read_16bitBE(head_offset+0x24,streamFile);
    /* channels and loop flag are set by allocate_vgmstream */
    vgmstream->loop_start_sample = read_32bitBE(head_offset+0x28,streamFile);
    vgmstream->loop_end_sample = vgmstream->num_samples;

    vgmstream->coding_type = coding_type;
    if (channel_count==1)
        vgmstream->layout_type = layout_none;
    else
        vgmstream->layout_type = layout_interleave_shortblock;
    vgmstream->meta_type = meta_RSTM;
    if (atlus_shrunken_head)
        vgmstream->meta_type = meta_RSTM_shrunken;

    if (spm_flag&& vgmstream->sample_rate == 44100) {
        vgmstream->meta_type = meta_RSTM_SPM;
        vgmstream->sample_rate = 22050;
    }

    vgmstream->interleave_block_size = read_32bitBE(head_offset+0x38,streamFile);
    vgmstream->interleave_smallblock_size = read_32bitBE(head_offset+0x48,streamFile);

    if (vgmstream->coding_type == coding_NGC_DSP) {
        off_t coef_offset;
        off_t coef_offset1;
        off_t coef_offset2;
        int i,j;
        int coef_spacing = 0x38;

        if (atlus_shrunken_head)
        {
            coef_offset = 0x50;
            coef_spacing = 0x30;
        }
        else
        {
        coef_offset1=read_32bitBE(head_offset+0x1c,streamFile);
        coef_offset2=read_32bitBE(head_offset+0x10+coef_offset1,streamFile);
        coef_offset=coef_offset2+0x10;
        }

        for (j=0;j<vgmstream->channels;j++) {
            for (i=0;i<16;i++) {
                vgmstream->ch[j].adpcm_coef[i]=read_16bitBE(head_offset+coef_offset+j*coef_spacing+i*2,streamFile);
            }
        }
    }

    start_offset = read_32bitBE(head_offset+0x30,streamFile);

    /* open the file for reading by each channel */
    {
        int i;
        for (i=0;i<channel_count;i++) {
            if (vgmstream->layout_type==layout_interleave_shortblock)
                vgmstream->ch[i].streamfile = streamFile->open(streamFile,filename,
                    vgmstream->interleave_block_size);
            else
                vgmstream->ch[i].streamfile = streamFile->open(streamFile,filename,
                    0x1000);

            if (!vgmstream->ch[i].streamfile) goto fail;

            vgmstream->ch[i].channel_start_offset=
                vgmstream->ch[i].offset=
                start_offset + i*vgmstream->interleave_block_size;
        }
    }

    return vgmstream;

    /* clean up anything we may have opened */
fail:
    if (vgmstream) close_vgmstream(vgmstream);
    return NULL;
}
Exemple #16
0
/* GCUB - found in 'Sega Soccer Slam' */
VGMSTREAM * init_vgmstream_ngc_gcub(STREAMFILE *streamFile) {
    VGMSTREAM * vgmstream = NULL;
    char filename[PATH_LIMIT];
    off_t start_offset;
    int loop_flag;
    int channel_count;

    /* check extension, case insensitive */
    streamFile->get_name(streamFile,filename,sizeof(filename));
    if (strcasecmp("gcub",filename_extension(filename))) goto fail;

    /* check header */
    if (read_32bitBE(0x00,streamFile) != 0x47437562) /* "GCub" */
        goto fail;

    loop_flag = 0;
    channel_count = read_32bitBE(0x04,streamFile);

    /* build the VGMSTREAM */
    vgmstream = allocate_vgmstream(channel_count,loop_flag);
    if (!vgmstream) goto fail;

    /* fill in the vital statistics */
    if (read_32bitBE(0x60,streamFile) == 0x47437878) /* "GCxx" */
    {
        start_offset = 0x88;
    }
    else
    {
        start_offset = 0x60;
    }

    vgmstream->channels = channel_count;
    vgmstream->sample_rate = read_32bitBE(0x08,streamFile);
    vgmstream->coding_type = coding_NGC_DSP;
    vgmstream->num_samples = (read_32bitBE(0x0C,streamFile)-start_offset)/8/channel_count*14;
    if (loop_flag) {
        vgmstream->loop_start_sample = 0;
        vgmstream->loop_end_sample = (read_32bitBE(0x0C,streamFile)-start_offset)/8/channel_count*14;
    }


    if (channel_count == 1)
    {
        vgmstream->layout_type = layout_none;
    }
    else
    {
        vgmstream->layout_type = layout_interleave;
        vgmstream->interleave_block_size = 0x8000; // read_32bitBE(0x04,streamFile);
    }

    vgmstream->meta_type = meta_NGC_GCUB;


    if (vgmstream->coding_type == coding_NGC_DSP) {
        int i;
        for (i=0; i<16; i++) {
            vgmstream->ch[0].adpcm_coef[i] = read_16bitBE(0x10+i*2,streamFile);
        }
        if (vgmstream->channels == 2) {
            for (i=0; i<16; i++) {
                vgmstream->ch[1].adpcm_coef[i] = read_16bitBE(0x30+i*2,streamFile);
            }
        }
    }

    /* open the file for reading */
    {
        int i;
        STREAMFILE * file;
        file = streamFile->open(streamFile,filename,STREAMFILE_DEFAULT_BUFFER_SIZE);
        if (!file) goto fail;
        for (i=0; i<channel_count; i++) {
            vgmstream->ch[i].streamfile = file;

            /* The first channel */
            vgmstream->ch[0].channel_start_offset=
                vgmstream->ch[0].offset=start_offset;

            /* The second channel */
            if (channel_count == 2) {
                vgmstream->ch[1].streamfile = streamFile->open(streamFile,filename,STREAMFILE_DEFAULT_BUFFER_SIZE);

                if (!vgmstream->ch[1].streamfile) goto fail;

                vgmstream->ch[1].channel_start_offset=
                    vgmstream->ch[1].offset=start_offset+vgmstream->interleave_block_size;
            }
        }
    }

    return vgmstream;

    /* clean up anything we may have opened */
fail:
    if (vgmstream) close_vgmstream(vgmstream);
    return NULL;
}
Exemple #17
0
VGMSTREAM * init_vgmstream_wii_sts(STREAMFILE *streamFile) {
    VGMSTREAM * vgmstream = NULL;
    char filename[PATH_LIMIT];

    int loop_flag=0;
    int channel_count;
    int i,j;
    off_t	start_offset;

    /* check extension, case insensitive */
    streamFile->get_name(streamFile,filename,sizeof(filename));
    if (strcasecmp("sts",filename_extension(filename))) goto fail;

    /* First bytes contain the size of the file (-4) */
    if(read_32bitBE(0x0,streamFile)!=get_streamfile_size(streamFile)-4)
        goto fail;

    loop_flag = (read_32bitLE(0x4C,streamFile)!=0xFFFFFFFF);
    channel_count=read_8bit(0x8,streamFile)+1;

    /* build the VGMSTREAM */
    vgmstream = allocate_vgmstream(channel_count,loop_flag);
    if (!vgmstream) goto fail;

    /* fill in the vital statistics */
    vgmstream->channels = channel_count;
    vgmstream->sample_rate = read_32bitBE(0x0A,streamFile);
    vgmstream->coding_type = coding_NGC_DSP;

    if(vgmstream->channels==1)
        vgmstream->num_samples = (read_32bitBE(0x0,streamFile)+4-0x70)/8*14;
    else
        vgmstream->num_samples = (read_32bitBE(0x0,streamFile)+4-0x50-0x26)/8*14/2;

    vgmstream->layout_type = layout_none;
    vgmstream->meta_type = meta_STS_WII;

    if(loop_flag) {
        vgmstream->loop_start_sample=read_32bitLE(0x24,streamFile);
        vgmstream->loop_end_sample=vgmstream->num_samples;
    }

    /* setting coef tables */
    if(vgmstream->channels==1)
        start_offset = 0x70;
    else
        start_offset = 0x50;

    // First channel
    for(j=0; j<16; j++) {
        vgmstream->ch[0].adpcm_coef[j]=read_16bitBE(0x1E + (j*2),streamFile);
    }

    // Second channel ?
    if(vgmstream->channels==2) {
        start_offset+=read_32bitBE(0x1a,streamFile);
        for(j=0; j<16; j++) {
            vgmstream->ch[1].adpcm_coef[j]=read_16bitBE(start_offset+(j*2),streamFile);
        }
    }

    /* open the file for reading by each channel */
    {
        for (i=0; i<channel_count; i++) {
            vgmstream->ch[i].streamfile = streamFile->open(streamFile,filename,36);
            vgmstream->ch[i].offset = 0x50+(i*(start_offset+0x26-0x50));

            if (!vgmstream->ch[i].streamfile) goto fail;
        }
    }

    return vgmstream;

    /* clean up anything we may have opened */
fail:
    if (vgmstream) close_vgmstream(vgmstream);
    return NULL;
}
Exemple #18
0
void Parse_Header(STREAMFILE* streamFile,EA_STRUCT* ea, off_t offset, int length) {

	uint8_t byteRead;
	off_t	begin_offset=offset;

	// default value ...
	ea->channels=1;
	ea->compression_type=0;
	ea->compression_version=0x01;
	ea->platform=EA_GC;

	if(read_32bitBE(offset, streamFile)==0x47535452) { // GSTR
		ea->compression_version=0x03;
		offset+=8;
		ea->platform=6;
	} else {
		if(read_16bitBE(offset,streamFile)!=0x5054)  // PT
			offset+=4;

		ea->platform=(uint8_t)read_16bitLE(offset+2,streamFile);
		offset+=4;
	}

	do {
		byteRead = read_8bit(offset++,streamFile);

		switch(byteRead) {
			case 0xFF:
			case 0xFE:
			case 0xFC:
			case 0xFD:
				break;
			case 0x80: // compression version
				ea->compression_version = (uint8_t)readPatch(streamFile, &offset);
				break;
			case 0x82: // channels count
				ea->channels = (uint8_t)readPatch(streamFile, &offset);
				break;
			case 0x83: // compression type
				ea->compression_type = (uint8_t)readPatch(streamFile, &offset);
				if(ea->compression_type==0x07) ea->compression_type=0x30;
				break;
			case 0x84: // sample frequency
				ea->sample_rate = readPatch(streamFile,&offset);
				break;
			case 0x85: // samples count
				ea->num_samples = readPatch(streamFile, &offset);
				break;
			case 0x8A:
				offset+=4;
				if(ea->compression_type==0) ea->compression_type=EA_PCM_LE;
				break;
			case 0x86:
			case 0x87:
			case 0x8C:
			case 0x92:
			case 0x9C:
			case 0x9D: // unknown patch
				readPatch(streamFile, &offset);
				break;
			case 0x88: // interleave
				ea->interleave = readPatch(streamFile, &offset);
				break;
			case 0xA0: // compression type
				ea->compression_type = (uint8_t)readPatch(streamFile, &offset);
				break;
		}
	} while(offset-begin_offset<length);

	if(ea->platform==EA_PSX)
		ea->compression_type=EA_VAG;
	if(ea->compression_type==0)
		ea->compression_type=EA_EAXA;
}
/* EMFF - Eidos Music File Format (NGC/WII),
found in Tomb Raider Legend/Anniversary/Underworld, possibly more... */
VGMSTREAM * init_vgmstream_emff_ngc(STREAMFILE *streamFile) {
    VGMSTREAM * vgmstream = NULL;
    char filename[260];
    off_t start_offset;
    int loop_flag = 0;
    int channel_count;
    int frequency;
    int i;
    int j;

    /* check extension, case insensitive */
    streamFile->get_name(streamFile,filename,sizeof(filename));
    if (strcasecmp("emff",filename_extension(filename))) goto fail;

    /* do some checks on the file, cause we	have no magic words to check the header...
    it seems if 0x800 and 0x804 = 0 then the file has only audio, if 0x800 = 1
    it has a text section, if both are 1 it's video with a text section included... */
    if (read_32bitBE(0x800,streamFile) == 0x00000001 ||	/* "0x00000001" */
        read_32bitBE(0x804,streamFile) == 0x00000001)	/* "0x00000001" */
    goto fail;

    frequency = read_32bitBE(0x0,streamFile);
    channel_count = read_32bitBE(0xC,streamFile);

    if (frequency > 48000 ||
        channel_count > 8) {
        goto fail;
    }

    loop_flag = (read_32bitBE(0x4,streamFile) != 0xFFFFFFFF);

    /* build the VGMSTREAM */
    vgmstream = allocate_vgmstream(channel_count,loop_flag);
    if (!vgmstream) goto fail;

    /* fill in the vital statistics */
    start_offset = 0x800;
    vgmstream->sample_rate = frequency;
    vgmstream->channels = channel_count;
    vgmstream->coding_type = coding_NGC_DSP;

    /* Retrieving coefs and loops, depending on the file layout... */
    /* Found in Tomb Raider - Legend for GameCube */
    if (read_32bitBE(0xC8,streamFile) > 0x0) {
        off_t coef_table[8] = {0xC8,0xF6,0x124,0x152,0x180,0x1AE,0x1DC,0x20A};
        for (j=0;j<vgmstream->channels;j++) {
            for (i=0;i<16;i++) {
        vgmstream->ch[j].adpcm_coef[i] = read_16bitBE(coef_table[j]+i*2,streamFile);
            }
        }
    /* Found in Tomb Raider - Anniversary for WII */
    } else if (read_32bitBE(0xCC,streamFile) > 0x0) {
        off_t coef_table[8] = {0xCC,0xFA,0x128,0x156,0x184,0x1B2,0x1E0,0x20E};
        for (j=0;j<vgmstream->channels;j++) {
        for (i=0;i<16;i++) {
            vgmstream->ch[j].adpcm_coef[i] = read_16bitBE(coef_table[j]+i*2,streamFile);
    }
}   
    /* Found in Tomb Raider - Underworld for WII */
    } else if (read_32bitBE(0x2D0,streamFile) > 0x0) {
        off_t coef_table[8] = {0x2D0,0x2FE,0x32C,0x35A,0x388,0x3B6,0x3E4,0x412};
        for (j=0;j<vgmstream->channels;j++) {
        for (i=0;i<16;i++) {
            vgmstream->ch[j].adpcm_coef[i] = read_16bitBE(coef_table[j]+i*2,streamFile);
    }
} 

    } else {
        goto fail;
    }

    vgmstream->layout_type = layout_emff_ngc_blocked;
    vgmstream->interleave_block_size = 0x10;
    vgmstream->meta_type = meta_EMFF_NGC;

    /* open the file for reading */
    {
        STREAMFILE * file;
        file = streamFile->open(streamFile,filename,STREAMFILE_DEFAULT_BUFFER_SIZE);
        if (!file) goto fail;
        for (i=0;i<channel_count;i++) {
            vgmstream->ch[i].streamfile = file;
        }
    }

    /* Calc num_samples */
    emff_ngc_block_update(start_offset,vgmstream);
    vgmstream->num_samples = read_32bitBE(0x8,streamFile);;
    if (loop_flag) {
        vgmstream->loop_start_sample = (read_32bitBE(0x28,streamFile))*14/8/channel_count;
        vgmstream->loop_end_sample = read_32bitBE(0x8,streamFile);
    }

    return vgmstream;

/* clean up anything we may have opened */
fail:
    if (vgmstream) close_vgmstream(vgmstream);
    return NULL;
}
Exemple #20
0
/* GSP+GSB - 2008-11-28 - manakoAT
Super Swing Golf 1 & 2 (WII) */
VGMSTREAM * init_vgmstream_gsp_gsb(STREAMFILE *streamFile) {

    VGMSTREAM * vgmstream = NULL;
    STREAMFILE * streamFileGSP = NULL;
    char filename[PATH_LIMIT];
    char filenameGSP[PATH_LIMIT];
    int channel_count;
    int loop_flag;
    int header_len;
	int i;
	off_t coef1_start;
    off_t coef2_start;
    off_t start_offset;
	
    
    /* check extension, case insensitive */
    streamFile->get_name(streamFile,filename,sizeof(filename));
    if (strcasecmp("gsb",filename_extension(filename))) goto fail;


    strcpy(filenameGSP,filename);
    strcpy(filenameGSP+strlen(filenameGSP)-3,"gsp");

    streamFileGSP = streamFile->open(streamFile,filenameGSP,STREAMFILE_DEFAULT_BUFFER_SIZE);
    if (!streamFileGSP) goto fail;

    /* check header */
    if (read_32bitBE(0x00,streamFileGSP) != 0x47534E44)	/* "GSND" */
        goto fail;

    channel_count = (uint16_t)read_16bitBE(0x3A,streamFileGSP);
    loop_flag = (read_32bitBE(0x64,streamFileGSP) != 0xFFFFFFFF);
    header_len = read_32bitBE(0x1C,streamFileGSP);
    
    coef1_start = header_len-0x4C;
    coef2_start = header_len-0x1C;
    
    /* build the VGMSTREAM */
    vgmstream = allocate_vgmstream(channel_count,loop_flag);
    if (!vgmstream) goto fail;

    /* fill in the vital statistics */
    vgmstream->channels = channel_count;
    vgmstream->sample_rate = read_32bitBE(0x34,streamFileGSP);
    vgmstream->coding_type = coding_NGC_DSP;
    if(loop_flag) {
        vgmstream->loop_start_sample = read_32bitBE(0x64,streamFileGSP);
        vgmstream->loop_end_sample = read_32bitBE(0x68,streamFileGSP);
    }	

    if (channel_count == 1) {
        vgmstream->layout_type = layout_gsb_blocked;
    } else if (channel_count > 1) {
        vgmstream->layout_type = layout_gsb_blocked;
        vgmstream->interleave_block_size = read_32bitBE(header_len-0x64,streamFileGSP);
    }

    vgmstream->meta_type = meta_GSP_GSB;
    
    /* open the file for reading by each channel */
    {
        for (i=0;i<channel_count;i++) {
            vgmstream->ch[i].streamfile = streamFile->open(streamFile,filename,vgmstream->interleave_block_size);
            
        if (!vgmstream->ch[i].streamfile) goto fail;
            vgmstream->ch[i].channel_start_offset=
            vgmstream->ch[i].offset=i*vgmstream->interleave_block_size;
        }
    }

    if (vgmstream->coding_type == coding_NGC_DSP) {
        int i;
        for (i=0;i<16;i++) {
            vgmstream->ch[0].adpcm_coef[i] = read_16bitBE(coef1_start+i*2,streamFileGSP);
        }
        if (vgmstream->channels == 2) {
            for (i=0;i<16;i++) {
                vgmstream->ch[1].adpcm_coef[i] = read_16bitBE(coef2_start+i*2,streamFileGSP);
            }
        }
    }

    /* Calc num_samples */
    start_offset = 0x0;
    gsb_block_update(start_offset,vgmstream);
    vgmstream->num_samples=0;

    do {
    
    vgmstream->num_samples += vgmstream->current_block_size*14/8;
        gsb_block_update(vgmstream->next_block_offset,vgmstream);
    } while (vgmstream->next_block_offset<get_streamfile_size(streamFile));

    gsb_block_update(start_offset,vgmstream);

    close_streamfile(streamFileGSP); streamFileGSP=NULL;

    return vgmstream;


    /* clean up anything we may have opened */
fail:
    if (streamFileGSP) close_streamfile(streamFileGSP);
    if (vgmstream) close_vgmstream(vgmstream);
    return NULL;
}
/* Note: A "Flat Layout" has no interleave */
VGMSTREAM * init_vgmstream_waa_wac_wad_wam(STREAMFILE *streamFile) {
    VGMSTREAM * vgmstream = NULL;
    char filename[PATH_LIMIT];
	int i;
    off_t start_offset;
    int loop_flag;
	int channel_count;
	int coef1_start;
	int coef2_start;
	int second_channel_start = -1;

    // Check file extensions
    streamFile->get_name(streamFile,filename,sizeof(filename));
    if (strcasecmp("waa",filename_extension(filename)) && 
		strcasecmp("wac",filename_extension(filename)) && 
		strcasecmp("wad",filename_extension(filename)) && 
		strcasecmp("wam",filename_extension(filename))) goto fail;

    /* check header */
    if (read_32bitBE(0x00,streamFile) != 0x52494646 ||	/* "RIFF" */
		read_32bitBE(0x08,streamFile) != 0x57415645 ||	/* "WAVE" */
		read_32bitBE(0x0C,streamFile) != 0x666D7420 ||	/* "fmt\0x20" */
		read_32bitBE(0x10,streamFile) != 0x12000000) 	/* "0x12000000" */
	goto fail;

	/* files don't contain looping information,
	   so the looping is not done depending on extension.
	   wam and waa contain ambient sounds and music, so often they contain
	   looped music. Change extension to wac or wad to make the sound non-looping.
	*/
    loop_flag = strcasecmp("wac",filename_extension(filename)) && 
		    	strcasecmp("wad",filename_extension(filename));
    channel_count = (uint16_t)read_16bitLE(0x16,streamFile);

	/* build the VGMSTREAM */
    vgmstream = allocate_vgmstream(channel_count,loop_flag);
    if (!vgmstream) goto fail;

	/* Check what encoder is needed */
	//FIXME: //PC version uses pcm, but which encoder?

	vgmstream->channels = channel_count;
    vgmstream->sample_rate = read_32bitLE(0x18,streamFile);
	vgmstream->meta_type = meta_WAA_WAC_WAD_WAM;
    vgmstream->layout_type = layout_none;

    switch((uint16_t)read_16bitLE(0x14,streamFile))	{
    case 0x0069: // XBOX IMA ADPCM
		start_offset = 0x2E;
		vgmstream->coding_type = coding_XBOX;
		vgmstream->num_samples = (read_32bitLE(0x2A,streamFile))/36/channel_count*64;
		if (loop_flag) {
			vgmstream->loop_start_sample = 0;
			vgmstream->loop_end_sample = (read_32bitLE(0x2A,streamFile))/36/channel_count*64;
		}
    break;
    case 0xFFFF: // PS2 ADPCM
		start_offset = 0x2E;
		vgmstream->coding_type = coding_PSX;
		vgmstream->num_samples = (read_32bitLE(0x2A,streamFile))/16*28/channel_count;
		if (loop_flag) {
			vgmstream->loop_start_sample = 0;
			vgmstream->loop_end_sample = (read_32bitLE(0x2A,streamFile))/16*28/channel_count;
		}
            second_channel_start = (read_32bitLE(0x2A,streamFile)/2)+start_offset;
    break;
    case 0xFFFE: // GameCube/WII DSP
		start_offset = 0x5C;
		vgmstream->coding_type = coding_NGC_DSP;
		vgmstream->num_samples = (read_32bitLE(0x2A,streamFile))*14/8/channel_count;
		if (loop_flag) {
			vgmstream->loop_start_sample = 0;
			vgmstream->loop_end_sample = (read_32bitLE(0x2A,streamFile))*14/8/channel_count;
		}
		if(read_16bitLE(0x24,streamFile)==0x00)//is a wii file with no coeff table
		{
			//FIXME: WII version of WAM/WAD/WAC need some coeff table from somewhere
			for (i=0;i<16;i++)
					vgmstream->ch[0].adpcm_coef[i] = wad_coef[i];
			if (channel_count == 2) {
				for (i=0;i<16;i++)
					vgmstream->ch[1].adpcm_coef[i] = wad_coef[i];
			}
			goto fail;
		}
		else
		{
				second_channel_start = (read_32bitLE(0x2A,streamFile)/2)+0x8A;
				/* Retrieveing the coef tables */
				coef1_start = 0x2E;
				coef2_start = (read_32bitLE(0x2A,streamFile)/2)+0x5C;

			{
				int i;
				for (i=0;i<16;i++)
					vgmstream->ch[0].adpcm_coef[i] = read_16bitBE(coef1_start+i*2,streamFile);
				if (channel_count == 2) {
				for (i=0;i<16;i++)
					vgmstream->ch[1].adpcm_coef[i] = read_16bitBE(coef2_start+i*2,streamFile);
				}
			}
		}
        break;
		    default:
			    goto fail;
	}




    /* open the file for reading */
    {
        int i;
        STREAMFILE * file;
        file = streamFile->open(streamFile,filename,STREAMFILE_DEFAULT_BUFFER_SIZE);
        if (!file) goto fail;
        for (i=0;i<channel_count;i++) {
            vgmstream->ch[i].streamfile = file;
            
            if (vgmstream->coding_type == coding_XBOX) {
                /* xbox interleaving is a little odd */
                vgmstream->ch[i].channel_start_offset=start_offset;
            } else {
                vgmstream->ch[0].channel_start_offset=start_offset;
            if (channel_count == 2) {
                if (second_channel_start == -1) goto fail;
                vgmstream->ch[1].channel_start_offset=second_channel_start;
            }
        }
        vgmstream->ch[i].offset = vgmstream->ch[i].channel_start_offset;
    }
    }


    return vgmstream;

fail:
    /* clean up anything we may have opened */
    if (vgmstream) close_vgmstream(vgmstream);
    return NULL;
}
Exemple #22
0
/* .PAST (Bakugan Battle Brawlers */
VGMSTREAM * init_vgmstream_ps3_past(STREAMFILE *streamFile) {
    VGMSTREAM * vgmstream = NULL;
    char filename[1024];
    off_t start_offset;

	int loop_flag;
	int channel_count;

    /* check extension, case insensitive */
    streamFile->get_name(streamFile,filename,sizeof(filename));
    if (strcasecmp("past",filename_extension(filename))) goto fail;

    /* check header */
    if (read_32bitBE(0x0,streamFile) != 0x534E4450) /* SNDP */
        goto fail;

    loop_flag = (read_32bitBE(0x1C,streamFile)!=0);
    channel_count = (uint16_t)read_16bitBE(0xC,streamFile);
    
	/* build the VGMSTREAM */
    vgmstream = allocate_vgmstream(channel_count,loop_flag);
    if (!vgmstream) goto fail;

	/* fill in the vital statistics */
	start_offset = 0x30;
	vgmstream->channels = channel_count;
    vgmstream->sample_rate = read_32bitBE(0x10,streamFile);
    vgmstream->coding_type = coding_PCM16LE;
    vgmstream->num_samples = (read_32bitBE(0x14,streamFile))/2/channel_count;
    if (loop_flag) {
        vgmstream->loop_start_sample = read_32bitBE(0x18,streamFile)/2/channel_count;
        vgmstream->loop_end_sample = read_32bitBE(0x1C,streamFile)/2/channel_count;
    }

    if (channel_count == 1)
    {
		  vgmstream->layout_type = layout_none;
    }
    else
    {
      vgmstream->layout_type = layout_interleave;
		  vgmstream->interleave_block_size = 0x2;
    }

      vgmstream->meta_type = meta_PS3_PAST;

    /* open the file for reading */
    {
        int i;
        STREAMFILE * file;
        file = streamFile->open(streamFile,filename,STREAMFILE_DEFAULT_BUFFER_SIZE);
        if (!file) goto fail;
        for (i=0;i<channel_count;i++) {
            vgmstream->ch[i].streamfile = file;

            vgmstream->ch[i].channel_start_offset=
                vgmstream->ch[i].offset=start_offset+
                vgmstream->interleave_block_size*i;

        }
    }

    return vgmstream;

fail:
    /* clean up anything we may have opened */
    if (vgmstream) close_vgmstream(vgmstream);
    return NULL;
}
Exemple #23
0
/* @UTF table reading, abridged */
static struct utf_query_result analyze_utf(STREAMFILE *infile, const long offset, const struct utf_query *query)
{
    unsigned char buf[4];
    struct utf_table_info table_info;
    char *string_table = NULL;
    struct utf_column_info * schema = NULL;
    struct utf_query_result result;
    uint32_t table_name_string;
    int string_table_size;
    
    result.valid = 0;

    table_info.table_offset = offset;

    /* check header */
    {
        static const char UTF_signature[4] = "@UTF"; /* intentionally unterminated */
        if (4 != read_streamfile(buf, offset, 4, infile)) goto cleanup_error;
        if (memcmp(buf, UTF_signature, sizeof(UTF_signature)))
        {
            goto cleanup_error;
        }
    }

    /* get table size */
    table_info.table_size = read_32bitBE(offset+4, infile);

    table_info.schema_offset = 0x20;
    table_info.rows_offset = read_32bitBE(offset+8, infile);
    table_info.string_table_offset = read_32bitBE(offset+0xc,infile);
    table_info.data_offset = read_32bitBE(offset+0x10,infile);
    table_name_string = read_32bitBE(offset+0x14,infile);
    table_info.columns = read_16bitBE(offset+0x18,infile);
    table_info.row_width = read_16bitBE(offset+0x1a,infile);
    table_info.rows = read_32bitBE(offset+0x1c,infile);

    /* allocate for string table */
    string_table_size = table_info.data_offset-table_info.string_table_offset;
    string_table = malloc(string_table_size+1);
    if (!string_table) goto cleanup_error;
    table_info.string_table = string_table;
    memset(string_table, 0, string_table_size+1);

    /* load schema */
    schema = malloc(sizeof(struct utf_column_info) * table_info.columns);
    if (!schema) goto cleanup_error;

    {
        int i;
        long schema_current_offset = table_info.schema_offset;
        for (i = 0; i < table_info.columns; i++)
        {
            schema[i].type = read_8bit(schema_current_offset,infile);
            schema_current_offset ++;
            schema[i].column_name = string_table + read_32bitBE(schema_current_offset,infile);
            schema_current_offset += 4;

            if ((schema[i].type & COLUMN_STORAGE_MASK) == COLUMN_STORAGE_CONSTANT)
            {
                schema[i].constant_offset = schema_current_offset;
                switch (schema[i].type & COLUMN_TYPE_MASK)
                {
                    case COLUMN_TYPE_8BYTE:
                    case COLUMN_TYPE_DATA:
                        schema_current_offset+=8;
                        break;
                    case COLUMN_TYPE_STRING:
                    case COLUMN_TYPE_FLOAT:
                    case COLUMN_TYPE_4BYTE:
                        schema_current_offset+=4;
                        break;
                    case COLUMN_TYPE_2BYTE2:
                    case COLUMN_TYPE_2BYTE:
                        schema_current_offset+=2;
                        break;
                    case COLUMN_TYPE_1BYTE2:
                    case COLUMN_TYPE_1BYTE:
                        schema_current_offset++;
                        break;
                    default:
                        goto cleanup_error;
                }
            }
        }
    }

    table_info.schema = schema;

    /* read string table */
    read_streamfile((unsigned char *)string_table,
            table_info.string_table_offset+8+offset,
            string_table_size, infile);
    table_info.table_name = table_info.string_table+table_name_string;

    /* fill in the default stuff */
    result.found = 0;
    result.rows = table_info.rows;
    result.name_offset = table_name_string;
    result.string_table_offset = table_info.string_table_offset;
    result.data_offset = table_info.data_offset;

    /* explore the values */
    if (query) {
        int i, j;

        for (i = 0; i < table_info.rows; i++)
        {
            uint32_t row_offset =
                table_info.table_offset + 8 + table_info.rows_offset +
                i * table_info.row_width;
            const uint32_t row_start_offset = row_offset;

            if (query && i != query->index) continue;

            for (j = 0; j < table_info.columns; j++)
            {
                uint8_t type = table_info.schema[j].type;
                long constant_offset = table_info.schema[j].constant_offset;
                int constant = 0;

                int qthis = (query && i == query->index &&
                        !strcmp(table_info.schema[j].column_name, query->name));

                if (qthis)
                {
                    result.found = 1;
                    result.type = schema[j].type & COLUMN_TYPE_MASK;
                }

                switch (schema[j].type & COLUMN_STORAGE_MASK)
                {
                    case COLUMN_STORAGE_PERROW:
                        break;
                    case COLUMN_STORAGE_CONSTANT:
                        constant = 1;
                        break;
                    case COLUMN_STORAGE_ZERO:
                        if (qthis)
                        {
                            memset(&result.value, 0,
                                    sizeof(result.value));
                        }
                        continue;
                    default:
                        goto cleanup_error;
                }

                if (1)
                {
                    long data_offset;
                    int bytes_read;

                    if (constant)
                    {
                        data_offset = constant_offset;
                    }
                    else
                    {
                        data_offset = row_offset;
                    }

                    switch (type & COLUMN_TYPE_MASK)
                    {
                        case COLUMN_TYPE_STRING:
                            {
                                uint32_t string_offset;
                                string_offset = read_32bitBE(data_offset, infile);
                                bytes_read = 4;
                                if (qthis)
                                {
                                    result.value.value_string = string_offset;
                                }
                            }
                            break;
                        case COLUMN_TYPE_DATA:
                            {
                                uint32_t vardata_offset, vardata_size;

                                vardata_offset = read_32bitBE(data_offset, infile);
                                vardata_size = read_32bitBE(data_offset+4, infile);
                                bytes_read = 8;
                                if (qthis)
                                {
                                    result.value.value_data.offset = vardata_offset;
                                    result.value.value_data.size = vardata_size;
                                }
                            }
                            break;

                        case COLUMN_TYPE_8BYTE:
                            {
                                uint64_t value =
                                    read_32bitBE(data_offset, infile);
                                value <<= 32;
                                value |=
                                    read_32bitBE(data_offset+4, infile);
                                if (qthis)
                                {
                                    result.value.value_u64 = value;
                                }
                                bytes_read = 8;
                                break;
                            }
                        case COLUMN_TYPE_4BYTE:
                            {
                                uint32_t value =
                                    read_32bitBE(data_offset, infile);
                                if (qthis)
                                {
                                    result.value.value_u32 = value;
                                }
                                bytes_read = 4;
                            }
                            break;
                        case COLUMN_TYPE_2BYTE2:
                        case COLUMN_TYPE_2BYTE:
                            {
                                uint16_t value = 
                                    read_16bitBE(data_offset, infile);
                                if (qthis)
                                {
                                    result.value.value_u16 = value;
                                }
                                bytes_read = 2;
                            }
                            break;
                        case COLUMN_TYPE_FLOAT:
                            if (sizeof(float) == 4)
                            {
                                union {
                                    float float_value;
                                    uint32_t int_value;
                                } int_float;

                                int_float.int_value = read_32bitBE(data_offset, infile);
                                if (qthis)
                                {
                                    result.value.value_float = int_float.float_value;
                                }
                            }
                            else
                            {
                                read_32bitBE(data_offset, infile);
                                if (qthis)
                                {
                                    goto cleanup_error;
                                }
                            }
                            bytes_read = 4;
                            break;
                        case COLUMN_TYPE_1BYTE2:
                        case COLUMN_TYPE_1BYTE:
                            {
                                uint8_t value =
                                    read_8bit(data_offset, infile);
                                if (qthis)
                                {
                                    result.value.value_u8 = value;
                                }
                                bytes_read = 1;
                            }
                            break;
                        default:
                            goto cleanup_error;
                    }

                    if (!constant)
                    {
                        row_offset += bytes_read;
                    }
                } /* useless if end */
            } /* column for loop end */

            if (row_offset - row_start_offset != table_info.row_width)
                goto cleanup_error;

            if (query && i >= query->index) break;
        } /* row for loop end */
    } /* explore values block end */

//cleanup:

    result.valid = 1;
cleanup_error:

    if (string_table)
    {
        free(string_table);
        string_table = NULL;
    }

    if (schema)
    {
        free(schema);
        schema = NULL;
    }

    return result;
}
Exemple #24
0
VGMSTREAM * init_vgmstream_ngc_dsp_sth_str1(STREAMFILE *streamFile) {
  	VGMSTREAM * vgmstream = NULL;
    STREAMFILE * streamFileSTR = NULL;
    char filename[260];
	  char filenameSTR[260];
  	int i, j;
	  int channel_count;
	  int loop_flag;
    off_t coef_table[8] = {0x12C,0x18C,0x1EC,0x24C,0x2AC,0x30C,0x36C,0x3CC};

    /* check extension, case insensitive */
    streamFile->get_name(streamFile,filename,sizeof(filename));
    if (strcasecmp("sth",filename_extension(filename))) goto fail;

	  strcpy(filenameSTR,filename);
	  strcpy(filenameSTR+strlen(filenameSTR)-3,"str");
	  streamFileSTR = streamFile->open(streamFile,filenameSTR,STREAMFILE_DEFAULT_BUFFER_SIZE);
	    if (!streamFileSTR) goto fail;

    if (read_32bitBE(0x0,streamFile) != 0x0)
    {
      goto fail;
    }

    if (read_32bitBE(0x4,streamFile) != 0x800)
    {
      goto fail;
    }

    /* Not really channel_count, just 'included tracks * channels per track */
	  loop_flag = (read_32bitBE(0xD8,streamFile) != 0xFFFFFFFF);
    channel_count = (read_32bitBE(0x70,streamFile)) * (read_32bitBE(0x88,streamFile));
    
    if (channel_count > 8)
    {
      goto fail;
    }

    /* build the VGMSTREAM */
    vgmstream = allocate_vgmstream(channel_count,loop_flag);
      if (!vgmstream) goto fail;

    /* fill in the vital statistics */
	  vgmstream->channels = channel_count;
	  vgmstream->sample_rate = read_32bitBE(0x24,streamFile);
	  vgmstream->num_samples=get_streamfile_size(streamFileSTR)/8/channel_count*14;
	  vgmstream->coding_type = coding_NGC_DSP;
	
	  if(loop_flag)
    {
		  vgmstream->loop_start_sample = read_32bitBE(0xD8,streamFile);
		  vgmstream->loop_end_sample = read_32bitBE(0xDC,streamFile);
    }

	if (channel_count == 1)
  {
		vgmstream->layout_type = layout_none;
	}
  else
  {
		vgmstream->layout_type = layout_interleave;
		if (channel_count == 2)
    {
      vgmstream->interleave_block_size=0x10000;
    }
    else
    {
      vgmstream->interleave_block_size=0x8000;
    }
  }

  vgmstream->meta_type = meta_NGC_DSP_STH_STR;

    /* open the file for reading */
    for (i=0;i<channel_count;i++)
    {
      vgmstream->ch[i].streamfile = streamFileSTR->open(streamFileSTR,filenameSTR,0x8000);
        if (!vgmstream->ch[i].streamfile) goto fail;
      vgmstream->ch[i].channel_start_offset=vgmstream->ch[i].offset=i*vgmstream->interleave_block_size;
    }

    // COEFFS
    for (j=0;j<vgmstream->channels;j++)
    {
      for (i=0;i<16;i++)
      {
        vgmstream->ch[j].adpcm_coef[i] = read_16bitBE(coef_table[j]+i*2,streamFile);
      }
    }

  	close_streamfile(streamFileSTR); streamFileSTR=NULL;
    return vgmstream;

    /* clean up anything we may have opened */
fail:
    if (streamFileSTR) close_streamfile(streamFileSTR);
    if (vgmstream) close_vgmstream(vgmstream);
    return NULL;
}
Exemple #25
0
/* MTA2 - found in Metal Gear Solid 4 (PS3) */
VGMSTREAM * init_vgmstream_mta2(STREAMFILE *streamFile) {
    VGMSTREAM * vgmstream = NULL;
    off_t start_offset;
    int loop_flag, channel_count, sample_rate;
    int32_t loop_start, loop_end;
    uint32_t sample_rate_int;


    /* checks */
    if ( !check_extensions(streamFile,"mta2"))
        goto fail;

    if (read_32bitBE(0x00,streamFile) != 0x4d544132) /* "MTA2" */
        goto fail;
    /* allow truncated files for now? */
    //if (read_32bitBE(0x04, streamFile) + 0x08 != get_streamfile_size(streamFile))
    //    goto fail;

    /* base header (everything is very similar to MGS3's MTAF but BE) */
    /* 0x08(4): version? (1),  0x0c(52): null */

    /* HEAD chunk */
    if (read_32bitBE(0x40, streamFile) != 0x48454144) /* "HEAD" */
        goto fail;
    if (read_32bitBE(0x44, streamFile) != 0xB0) /* HEAD size */
        goto fail;

    /* 0x48(4): null,  0x4c: ? (0x10),   0x50(4): 0x7F (vol?),  0x54(2): 0x40 (pan?) */
    channel_count = read_16bitBE(0x56, streamFile); /* counting all tracks */
    /* 0x60(4): full block size (0x110 * channels), indirectly channels_per_track = channels / (block_size / 0x110) */
    /* 0x80 .. 0xf8: null */

    loop_start = read_32bitBE(0x58, streamFile);
    loop_end   = read_32bitBE(0x5c, streamFile);
    loop_flag = (loop_start != loop_end); /* also flag possibly @ 0x73 */
#if 0
    /* those values look like some kind of loop offsets */
    if (loop_start/0x100 != read_32bitBE(0x68, streamFile) ||
        loop_end  /0x100 != read_32bitBE(0x6C, streamFile) ) {
        VGM_LOG("MTA2: wrong loop points\n");
        goto fail;
    }
#endif

    sample_rate_int = read_32bitBE(0x7c, streamFile);
    if (sample_rate_int) { /* sample rate in 32b float (WHY?) typically 48000.0 */
        float* sample_float = (float*)&sample_rate_int;
        sample_rate = (int)*sample_float;
    } else { /* default when not specified (most of the time) */
        sample_rate = 48000;
    }


    /* TRKP chunks (x16) */
    /* just seem to contain pan/vol stuff (0x7f/0x40), TRKP per track (sometimes +1 main track?) */
    /* there is channel layout bitmask at 0x0f (ex. 1ch = 0x04, 3ch = 0x07, 4ch = 0x33, 6ch = 0x3f), surely:
     * FL 0x01, FR 0x02, FC = 0x04, BL = 0x08, BR = 0x10, BC = 0x20 */

    start_offset = 0x800;

    /* DATA chunk */
    if (read_32bitBE(0x7f8, streamFile) != 0x44415441) // "DATA"
        goto fail;
    //if (read_32bitBE(0x7fc, streamFile) + start_offset != get_streamfile_size(streamFile))
    //    goto fail;


    /* build the VGMSTREAM */
    vgmstream = allocate_vgmstream(channel_count,loop_flag);
    if (!vgmstream) goto fail;

    vgmstream->sample_rate = sample_rate;
    vgmstream->num_samples = loop_end;
    vgmstream->loop_start_sample = loop_start;
    vgmstream->loop_end_sample = loop_end;

    vgmstream->coding_type = coding_MTA2;
    vgmstream->layout_type = layout_none;
    vgmstream->meta_type = meta_MTA2;

    /* open the file for reading */
    if ( !vgmstream_open_stream(vgmstream, streamFile, start_offset) )
        goto fail;
    return vgmstream;

fail:
    close_vgmstream(vgmstream);
    return NULL;
}
Exemple #26
0
/* RWSD is quite similar to BRSTM, but can contain several streams.
 * Still, some games use it for single streams. We only support the
 * single stream form here */
VGMSTREAM * init_vgmstream_rwsd(STREAMFILE *streamFile) {
    VGMSTREAM * vgmstream = NULL;
    char filename[260];

    coding_t coding_type;

    off_t wave_offset;
    size_t wave_length;
    int codec_number;
    int channel_count;
    int loop_flag;

    off_t start_offset;
    size_t stream_size;

    /* check extension, case insensitive */
    streamFile->get_name(streamFile,filename,sizeof(filename));
    if (strcasecmp("rwsd",filename_extension(filename))) goto fail;

    /* check header */
    if ((uint32_t)read_32bitBE(0,streamFile)!=0x52575344 || /* "RWSD" */
            (uint32_t)read_32bitBE(4,streamFile)!=0xFEFF0102)
        goto fail;

    /* ideally we would look through the chunk list for a WAVE chunk,
     * but it's always in the same order */
    /* get WAVE offset, check */
    wave_offset = read_32bitBE(0x18,streamFile);
    if ((uint32_t)read_32bitBE(wave_offset,streamFile)!=0x57415645) /* "WAVE" */
        goto fail;
    /* get WAVE size, check */
    wave_length = read_32bitBE(0x1c,streamFile);
    if (read_32bitBE(wave_offset+4,streamFile)!=wave_length)
        goto fail;

    /* check wave count */
    if (read_32bitBE(wave_offset+8,streamFile) != 1)
        goto fail; /* only support 1 */

    /* get type details */
    codec_number = read_8bit(wave_offset+0x10,streamFile);
    loop_flag = read_8bit(wave_offset+0x11,streamFile);
    channel_count = read_8bit(wave_offset+0x12,streamFile);

    switch (codec_number) {
        case 0:
            coding_type = coding_PCM8;
            break;
        case 1:
            coding_type = coding_PCM16BE;
            break;
        case 2:
            coding_type = coding_NGC_DSP;
            break;
        default:
            goto fail;
    }

    if (channel_count < 1) goto fail;

    /* build the VGMSTREAM */

    vgmstream = allocate_vgmstream(channel_count,loop_flag);
    if (!vgmstream) goto fail;

    /* fill in the vital statistics */
    vgmstream->num_samples = dsp_nibbles_to_samples(read_32bitBE(wave_offset+0x1c,streamFile));
    vgmstream->sample_rate = (uint16_t)read_16bitBE(wave_offset+0x14,streamFile);
    /* channels and loop flag are set by allocate_vgmstream */
    vgmstream->loop_start_sample = dsp_nibbles_to_samples(read_32bitBE(wave_offset+0x18,streamFile));
    vgmstream->loop_end_sample = vgmstream->num_samples;

    vgmstream->coding_type = coding_type;
    vgmstream->layout_type = layout_none;

    vgmstream->meta_type = meta_RWSD;

    if (vgmstream->coding_type == coding_NGC_DSP) {
        off_t coef_offset;
        int i,j;

        coef_offset=0x6c;

        for (j=0;j<vgmstream->channels;j++) {
            for (i=0;i<16;i++) {
                vgmstream->ch[j].adpcm_coef[i]=read_16bitBE(wave_offset+coef_offset+j*0x30+i*2,streamFile);
            }
        }
    }

    start_offset = read_32bitBE(8,streamFile);
    stream_size = read_32bitBE(wave_offset+0x50,streamFile);

    /* open the file for reading by each channel */
    {
        int i;
        for (i=0;i<channel_count;i++) {
            vgmstream->ch[i].streamfile = streamFile->open(streamFile,filename,
                    0x1000);

            if (!vgmstream->ch[i].streamfile) goto fail;

            vgmstream->ch[i].channel_start_offset=
                vgmstream->ch[i].offset=
                start_offset + i*stream_size;
        }
    }

    return vgmstream;

    /* clean up anything we may have opened */
fail:
    if (vgmstream) close_vgmstream(vgmstream);
    return NULL;
}
Exemple #27
0
VGMSTREAM * init_vgmstream_stx(STREAMFILE *streamFile) {
    VGMSTREAM * vgmstream = NULL;
    char filename[260];

    const int loop_flag = 0;
    const int channel_count = 2;    /* .stx seems to be stereo only */

    /* check extension, case insensitive */
    streamFile->get_name(streamFile,filename,sizeof(filename));
    if (strcasecmp("stx",filename_extension(filename))) goto fail;

    /* length of data */
    if (read_32bitBE(0x00,streamFile) !=
        get_streamfile_size(streamFile) - 0x20) goto fail;

    /* bits per sample? */
    if (read_16bitBE(0x0a,streamFile) != 4) goto fail;

    /* samples per frame? */
    if (read_16bitBE(0x0c,streamFile) != 0x10) goto fail;

    /* ?? */
    if (read_16bitBE(0x0e,streamFile) != 0x1E) goto fail;

    /* build the VGMSTREAM */

    vgmstream = allocate_vgmstream(channel_count,loop_flag);
    if (!vgmstream) goto fail;


    /* fill in the vital statistics */
    vgmstream->num_samples = read_32bitBE(0x04,streamFile);
    vgmstream->sample_rate = (uint16_t)read_16bitBE(0x08,streamFile);
    /* channels and loop flag are set by allocate_vgmstream */

    vgmstream->coding_type = coding_NGC_AFC;
    vgmstream->layout_type = layout_interleave;
    vgmstream->meta_type = meta_STX;

    /* frame-level interleave (9 bytes) */
    vgmstream->interleave_block_size = 9;

    /* open the file for reading by each channel */
    {
        STREAMFILE *chstreamfile;
        int i;

        /* both channels use same buffer, as interleave is so small */
        chstreamfile = streamFile->open(streamFile,filename,9*channel_count*0x100);
        if (!chstreamfile) goto fail;

        for (i=0;i<channel_count;i++) {
            vgmstream->ch[i].streamfile = chstreamfile;

            vgmstream->ch[i].channel_start_offset=
                vgmstream->ch[i].offset=
                0x20 + i*vgmstream->interleave_block_size;
        }
    }

    return vgmstream;

    /* clean up anything we may have opened */
fail:
    if (vgmstream) close_vgmstream(vgmstream);
    return NULL;
}
Exemple #28
0
/* ZWDSP (hcs' custom DSP files from Zack & Wiki) */
VGMSTREAM * init_vgmstream_zwdsp(STREAMFILE *streamFile) {
    VGMSTREAM * vgmstream = NULL;
    char filename[PATH_LIMIT];
    int second_channel_start;
    int loop_flag;
    int channel_count = 2;
    off_t start_offset;

    /* check extension, case insensitive */
    streamFile->get_name(streamFile,filename,sizeof(filename));
    if (strcasecmp("zwdsp",filename_extension(filename))) goto fail;

    /* check header */
    if (read_32bitBE(0x00,streamFile) != 0x00000000) /* 0x0 */
        goto fail;

    /* Retrieve the loop flag, some files have 0x0 and some 0x02 as "no loop" */

    switch (read_32bitBE(0x10, streamFile)) {
        case 0:
        case 2:
            loop_flag = 0;
            break;
        default:
            loop_flag = 1;
    }

    /* build the VGMSTREAM */
    vgmstream = allocate_vgmstream(channel_count,loop_flag);
    if (!vgmstream) goto fail;

    /* fill in the vital statistics */
    start_offset = 0x90;
    vgmstream->channels = channel_count;
    vgmstream->sample_rate = read_32bitBE(0x08,streamFile);
    vgmstream->coding_type = coding_NGC_DSP;
    vgmstream->num_samples = read_32bitBE(0x18,streamFile)*14/8/channel_count;
    if (loop_flag) {
        vgmstream->loop_start_sample = read_32bitBE(0x10,streamFile)*14/8/channel_count;
        vgmstream->loop_end_sample = read_32bitBE(0x14,streamFile)*14/8/channel_count;
        // frequently end sample is one more than total samples in file
        if (vgmstream->loop_end_sample > vgmstream->num_samples)
        {
            vgmstream->loop_end_sample = vgmstream->num_samples;
        }
    }


    vgmstream->layout_type = layout_none;
    vgmstream->meta_type = meta_ZWDSP;


    if (vgmstream->coding_type == coding_NGC_DSP) {
        int i;
        for (i=0;i<16;i++) {
            vgmstream->ch[0].adpcm_coef[i] = read_16bitBE(0x20+i*2,streamFile);
        }
        if (vgmstream->channels == 2) {
            for (i=0;i<16;i++) {
                vgmstream->ch[1].adpcm_coef[i] = read_16bitBE(0x60+i*2,streamFile);
            }
        }
    }

    second_channel_start = (get_streamfile_size(streamFile)+start_offset)/2;
    {
        int i;
        STREAMFILE * file;
        file = streamFile->open(streamFile,filename,STREAMFILE_DEFAULT_BUFFER_SIZE);
        if (!file) goto fail;
        for (i=0;i<channel_count;i++) {
            vgmstream->ch[i].streamfile = file;

                vgmstream->ch[0].channel_start_offset=start_offset;
            if (channel_count == 2) {
                if (second_channel_start == -1) goto fail;
                vgmstream->ch[1].channel_start_offset=second_channel_start;
            }
        vgmstream->ch[i].offset = vgmstream->ch[i].channel_start_offset;
        }
    }

    return vgmstream;

    /* clean up anything we may have opened */
fail:
    if (vgmstream) close_vgmstream(vgmstream);
    return NULL;
}
Exemple #29
0
/* BO2 (Blood Omen 2 NGC) */
VGMSTREAM * init_vgmstream_ngc_bo2(STREAMFILE *streamFile) {
    VGMSTREAM * vgmstream = NULL;
    char filename[PATH_LIMIT];
    int loop_flag;
  	int channels;
    int channel_count;
    off_t start_offset;

    /* check extension, case insensitive */
    streamFile->get_name(streamFile,filename,sizeof(filename));
    if (strcasecmp("bo2",filename_extension(filename))) goto fail;

    /* check header */
    if (read_32bitBE(0x00,streamFile) != 0x0) /* "IDSP" */
        goto fail;

    switch (read_32bitBE(0x10,streamFile))
    {
    	case 0x0:
    	  channels = 1;
    	break;
      case 0x1:
        channels = 2;
      break;
        default:
          goto fail;
    }
    
    if ((get_streamfile_size(streamFile)) < ((read_32bitBE(0x0C,streamFile)/14*8*channels)+0x800))
    {
      goto fail;
    }

    channel_count = channels;
    loop_flag = (read_32bitBE(0x08,streamFile) != 0xFFFFFFFF);

	  /* build the VGMSTREAM */
    vgmstream = allocate_vgmstream(channel_count,loop_flag);
    if (!vgmstream) goto fail;

	  /* fill in the vital statistics */
    start_offset = 0x800;
	  vgmstream->channels = channel_count;
    vgmstream->sample_rate = read_32bitBE(0x04,streamFile);
    vgmstream->coding_type = coding_NGC_DSP;
    vgmstream->num_samples = read_32bitBE(0x0C,streamFile);
    if (loop_flag) {
        vgmstream->loop_start_sample = read_32bitBE(0x08,streamFile);
        vgmstream->loop_end_sample = read_32bitBE(0x0C,streamFile);
    }

    if (channel_count == 1)
    {
      vgmstream->layout_type = layout_none;
    }
    else
    {
      vgmstream->layout_type = layout_interleave;
      vgmstream->interleave_block_size = 0x400;
    }
    
    vgmstream->meta_type = meta_NGC_BO2;

			{
				int i;
				for (i=0;i<16;i++)
					vgmstream->ch[0].adpcm_coef[i] = read_16bitBE(0x24+i*2,streamFile);
				if (channel_count == 2) {
				for (i=0;i<16;i++)
					vgmstream->ch[1].adpcm_coef[i] = read_16bitBE(0x52+i*2,streamFile);
				}
      }

    /* open the file for reading */
    {
        int i;
        STREAMFILE * file;
        file = streamFile->open(streamFile,filename,STREAMFILE_DEFAULT_BUFFER_SIZE);
        if (!file) goto fail;
        for (i=0;i<channel_count;i++) {
            vgmstream->ch[i].streamfile = file;

            vgmstream->ch[i].channel_start_offset=
                vgmstream->ch[i].offset=start_offset+
                vgmstream->interleave_block_size*i;

        }
    }

    return vgmstream;

    /* clean up anything we may have opened */
fail:
    if (vgmstream) close_vgmstream(vgmstream);
    return NULL;
}
/* Ubisoft CKD (Rayman Origins - Wii) */
VGMSTREAM * init_vgmstream_ubi_ckd(STREAMFILE *streamFile) {
    VGMSTREAM * vgmstream = NULL;
    char filename[260];
    off_t start_offset;

	int loop_flag;
	int channel_count;

    /* check extension, case insensitive */
    streamFile->get_name(streamFile,filename,sizeof(filename));
    if (strcasecmp("ckd",filename_extension(filename))) goto fail;

    /* check header */
    if (read_32bitBE(0x0,streamFile) != 0x52494646) /* RIFF */
		goto fail;
	if (read_32bitBE(0x26,streamFile) != 0x6473704C) /* dspL */
        goto fail;

    loop_flag = 0;
    channel_count = read_16bitBE(0x16,streamFile);
    
	/* build the VGMSTREAM */
    vgmstream = allocate_vgmstream(channel_count,loop_flag);
    if (!vgmstream) goto fail;

	/* fill in the vital statistics */
	if (read_16bitBE(0x16,streamFile) == 1) {
		start_offset = 0x96;
        vgmstream->num_samples = (read_32bitBE(0x92,streamFile))*28/16/channel_count;
	}
	else {
		start_offset = 0xFE;
	    vgmstream->num_samples = (read_32bitBE(0xFA,streamFile))*28/16/channel_count;
	}
	vgmstream->channels = channel_count;
    vgmstream->sample_rate = read_32bitBE(0x18,streamFile);
    vgmstream->coding_type = coding_NGC_DSP;
    vgmstream->num_samples = (read_32bitBE(0xFA,streamFile))*28/16/channel_count;

    vgmstream->layout_type = layout_interleave; 
    vgmstream->interleave_block_size = 8;
    vgmstream->meta_type = meta_UBI_CKD;

    if (vgmstream->coding_type == coding_NGC_DSP) {
        int i;
        for (i=0;i<16;i++) {
            vgmstream->ch[0].adpcm_coef[i] = read_16bitBE(0x4A+i*2,streamFile);
        }
        if (vgmstream->channels) {
            for (i=0;i<16;i++) {
                vgmstream->ch[1].adpcm_coef[i] = read_16bitBE(0xB2+i*2,streamFile);
            }
        }
    }
    /* open the file for reading */
    {
        int i;
        STREAMFILE * file;
        file = streamFile->open(streamFile,filename,STREAMFILE_DEFAULT_BUFFER_SIZE);
        if (!file) goto fail;
        for (i=0;i<channel_count;i++) {
            vgmstream->ch[i].streamfile = file;

            vgmstream->ch[i].channel_start_offset=
                vgmstream->ch[i].offset=start_offset+
                vgmstream->interleave_block_size*i;

        }

    }

    return vgmstream;

fail:
    /* clean up anything we may have opened */
    if (vgmstream) close_vgmstream(vgmstream);
    return NULL;
}