示例#1
0
文件: sthd.c 项目: kode54/vgmstream
/* STHD - Dream Factory .stx [Kakuto Chojin (Xbox)] */
VGMSTREAM * init_vgmstream_sthd(STREAMFILE *streamFile) {
    VGMSTREAM * vgmstream = NULL;
    off_t start_offset;
    int loop_flag, channel_count;


    /* checks */
    if (!check_extensions(streamFile, "stx"))
        goto fail;
    if (read_32bitBE(0x00,streamFile) != 0x53544844) /* "STHD" */
        goto fail;
    /* first block has special values */
    if (read_32bitLE(0x04,streamFile) != 0x0800 &&
        read_32bitLE(0x0c,streamFile) != 0x0001 &&
        read_32bitLE(0x14,streamFile) != 0x0000)
        goto fail;

    channel_count = read_16bitLE(0x06,streamFile);
    loop_flag = read_16bitLE(0x18,streamFile) != -1;
    start_offset = 0x800;

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

    vgmstream->meta_type = meta_STHD;
    vgmstream->sample_rate = read_32bitLE(0x20, streamFile); /* repeated ~8 times? */

    vgmstream->coding_type = coding_XBOX_IMA_int;
    vgmstream->layout_type = layout_blocked_sthd;

    if (!vgmstream_open_stream(vgmstream,streamFile,start_offset))
        goto fail;

    /* calc num_samples manually (blocks data varies in size) */
    {
        /* loop values may change to +1 in first actual block, but this works ok enough */
        int loop_start_block = (uint16_t)read_16bitLE(0x1a,streamFile);
        int loop_end_block   = (uint16_t)read_16bitLE(0x1c,streamFile);
        int block_count = 1; /* header block = 0 */

        vgmstream->next_block_offset = start_offset;
        do {
            block_update(vgmstream->next_block_offset,vgmstream);
            if (block_count == loop_start_block)
                vgmstream->loop_start_sample = vgmstream->num_samples;
            if (block_count == loop_end_block)
                vgmstream->loop_end_sample = vgmstream->num_samples;

            vgmstream->num_samples += xbox_ima_bytes_to_samples(vgmstream->current_block_size, 1);
            block_count++;
        }
        while (vgmstream->next_block_offset < get_streamfile_size(streamFile));
        block_update(start_offset, vgmstream);
    }

    return vgmstream;

fail:
    close_vgmstream(vgmstream);
    return NULL;
}
示例#2
0
/* NGCA (from GoldenEye 007) */
VGMSTREAM * init_vgmstream_ngca(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("ngca",filename_extension(filename))) goto fail;

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

    loop_flag = 0;
    channel_count = 1;

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

   /* fill in the vital statistics */
    start_offset = 0x40;
    vgmstream->channels = channel_count;
    vgmstream->sample_rate = 32000;
    vgmstream->coding_type = coding_NGC_DSP;
    vgmstream->num_samples = (((read_32bitBE(0x4,streamFile))/2) - 1) / 8 * 14;

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

	 if (vgmstream->coding_type == coding_NGC_DSP) {
         int i;
         for (i=0;i<16;i++) {
            vgmstream->ch[0].adpcm_coef[i] = read_16bitBE(0xC+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;
}
示例#3
0
/* AUS (found in various Capcom games) */
VGMSTREAM * init_vgmstream_aus(STREAMFILE *streamFile) {
    VGMSTREAM * vgmstream = NULL;
    char filename[1024];
    off_t start_offset;
    int loop_flag = 0;
	int channel_count;

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

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

    loop_flag = (read_32bitLE(0x0c,streamFile)!=0);
    channel_count = read_32bitLE(0xC,streamFile);
    
	/* 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_32bitLE(0x10,streamFile);
	vgmstream->num_samples = read_32bitLE(0x08,streamFile);

	if(read_16bitLE(0x06,streamFile)==0x02) {
		vgmstream->coding_type = coding_XBOX;
		vgmstream->layout_type=layout_none;
	} else {
		vgmstream->coding_type = coding_PSX;
		vgmstream->layout_type = layout_interleave;
		vgmstream->interleave_block_size = 0x800;
	}

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

	vgmstream->meta_type = meta_AUS;

    /* 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;
}
示例#4
0
/* ivaud (from GTA IV (PC)) */
VGMSTREAM * init_vgmstream_ivaud(STREAMFILE *streamFile) {
    VGMSTREAM * vgmstream = NULL;

	char filename[PATH_LIMIT];
    off_t start_offset;
	off_t block_table_offset;
    int loop_flag = 0;
	int channel_count;
    int i;


    /* at this time, i only check for extension */
	/* i'll make further checks later */
    streamFile->get_name(streamFile,filename,sizeof(filename));
    if (strcasecmp("ivaud",filename_extension(filename))) goto fail;

	/* multiple sounds .ivaud files are not implemented */
	/* only used for voices & sfx */
	if(read_32bitLE(0x10,streamFile)!=0)
		goto fail;

	/* never looped and allways 2 channels */
    loop_flag = 0;
    channel_count = 2;
    
	/* build the VGMSTREAM */
    vgmstream = allocate_vgmstream(channel_count,loop_flag);
    if (!vgmstream) goto fail;

	/* fill in the vital statistics */
    block_table_offset = read_32bitLE(0,streamFile);
	vgmstream->channels = channel_count;
    vgmstream->sample_rate = read_32bitLE(block_table_offset + 0x04,streamFile);
    vgmstream->coding_type = coding_INT_IMA;

	vgmstream->layout_type = layout_ivaud_blocked;
	vgmstream->meta_type = meta_PC_IVAUD;

	/* open the file for reading */
	{
        for (i=0;i<channel_count;i++) {
            vgmstream->ch[i].streamfile = streamFile->open(streamFile,filename,0x2000);
            if (!vgmstream->ch[i].streamfile) goto fail;
        }
    }
	
	/* Calc num_samples */
	start_offset = read_32bitLE(0x2C,streamFile);
	//block_count = read_32bitLE(0x08,streamFile);
	vgmstream->next_block_offset = read_32bitLE(0x2C,streamFile);

	// to avoid troubles with "extra" samples
	vgmstream->num_samples=((read_32bitLE(0x60,streamFile)/2)*2);

	ivaud_block_update(start_offset,vgmstream);

    return vgmstream;

    /* clean up anything we may have opened */
fail:
    if (vgmstream) close_vgmstream(vgmstream);
    return NULL;
}
示例#5
0
VGMSTREAM * init_vgmstream_ps2_vpk(STREAMFILE *streamFile) {
    VGMSTREAM * vgmstream = NULL;
    char filename[1024];

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

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

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

	/* check loop */
	loop_flag = (read_32bitLE(0x7FC,streamFile)!=0);
    channel_count=read_32bitLE(0x14,streamFile);
    
	/* build the VGMSTREAM */
    vgmstream = allocate_vgmstream(channel_count,loop_flag);
    if (!vgmstream) goto fail;

	/* fill in the vital statistics */
	vgmstream->channels = read_32bitLE(0x14,streamFile);
    vgmstream->sample_rate = read_32bitLE(0x10,streamFile);

	/* Check for Compression Scheme */
	vgmstream->coding_type = coding_PSX;
    vgmstream->num_samples = read_32bitLE(0x04,streamFile)/16*28;

	/* Get loop point values */
	if(vgmstream->loop_flag) {
		vgmstream->loop_start_sample = read_32bitLE(0x7FC,streamFile);
		vgmstream->loop_end_sample = vgmstream->num_samples;
	}

	vgmstream->interleave_block_size = read_32bitLE(0x0C,streamFile)/2;
    vgmstream->layout_type = layout_interleave;
    vgmstream->meta_type = meta_PS2_VPK;

	start_offset = (off_t)read_32bitLE(0x08,streamFile);

    /* 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=
                (off_t)(start_offset+vgmstream->interleave_block_size*i);
        }
    }

    return vgmstream;

    /* clean up anything we may have opened */
fail:
    if (vgmstream) close_vgmstream(vgmstream);
    return NULL;
}
示例#6
0
VGMSTREAM * init_vgmstream_gh3_bar(STREAMFILE *streamFile) {
    VGMSTREAM * vgmstream = NULL;
    // don't close, this is just the source streamFile wrapped
    STREAMFILE* streamFileBAR = NULL;
    char filename[260];
    off_t start_offset;
    off_t ch2_start_offset;
    int loop_flag;
	int channel_count;
    long file_size;


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

    /* decryption wrapper for header reading */
    streamFileBAR = wrap_bar_STREAMFILE(streamFile);
    if (!streamFileBAR) goto fail;

    file_size = get_streamfile_size(streamFileBAR);

    /* check header */
    if (read_32bitBE(0x00,streamFileBAR) != 0x11000100 ||
        read_32bitBE(0x04,streamFileBAR) != 0x01000200) goto fail;
    if (read_32bitLE(0x50,streamFileBAR) != file_size) goto fail;

    start_offset = read_32bitLE(0x18,streamFileBAR);
    if (0x54 != start_offset) goto fail;
    ch2_start_offset = read_32bitLE(0x48,streamFileBAR);
    if (ch2_start_offset >= file_size) goto fail;

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

    /* fill in the vital statistics */
    vgmstream->channels = channel_count;
    vgmstream->sample_rate = 11025;
    vgmstream->coding_type = coding_IMA;
    vgmstream->num_samples = (file_size-ch2_start_offset)*2;
    vgmstream->layout_type = layout_none;
    vgmstream->meta_type = meta_GH3_BAR;

    {
        STREAMFILE *file1, *file2;
        file1 = streamFileBAR->open(streamFileBAR,filename,STREAMFILE_DEFAULT_BUFFER_SIZE);
        if (!file1) goto fail;
        file2 = streamFileBAR->open(streamFileBAR,filename,STREAMFILE_DEFAULT_BUFFER_SIZE);
        if (!file2)
        {
            close_streamfile(file1);
            goto fail;
        }
        vgmstream->ch[0].streamfile = file1;
        vgmstream->ch[1].streamfile = file2;
        vgmstream->ch[0].channel_start_offset=
            vgmstream->ch[0].offset=start_offset;
        vgmstream->ch[1].channel_start_offset=
            vgmstream->ch[1].offset=ch2_start_offset;
    }

    // discard our decrypt wrapper, without closing the original streamfile
    free(streamFileBAR);

    return vgmstream;
fail:
    if (streamFileBAR)
        free(streamFileBAR);
    if (vgmstream) close_vgmstream(vgmstream);
    return NULL;
}
示例#7
0
文件: xps.c 项目: kode54/vgmstream
/* .XPS - From Software games banks [Metal Wolf Chaos (Xbox), Otogi (Xbox)] */
VGMSTREAM * init_vgmstream_xps(STREAMFILE *streamFile) {
    VGMSTREAM * vgmstream = NULL;
    STREAMFILE * streamData = NULL;
    int i, entries;
    off_t entry_offset = 0x10;
    int total_subsongs, target_subsong = streamFile->stream_index;


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

    if (read_32bitLE(0x00,streamFile) != get_streamfile_size(streamFile))
        goto fail;
    if (read_32bitBE(0x0c,streamFile) != 0x64696666)  /* "diff" */
        goto fail;

    /* handle .xps alone (stream .xps+data are done above) */
    streamData = open_streamfile_by_ext(streamFile, "dat");
    if (streamData) goto fail;

    /* main section + bank sections (usually same number but not always) */
    entries = read_32bitLE(0x04,streamFile);

    total_subsongs = 0;
    if (target_subsong == 0) target_subsong = 1;
    if (target_subsong < 0 /*|| target_subsong > total_subsongs || total_subsongs < 1*/) goto fail;


    /* parse entries: skip (there is probably a stream/bank flag here) */
    for (i = 0; i < entries; i++) {
        off_t entry_base  = entry_offset;
        size_t entry_size = read_32bitLE(entry_base+0x00,streamFile);
        uint32_t entry_id = read_32bitBE(entry_base+0x04,streamFile);
        size_t entry_pad  = read_32bitLE(entry_base+0x08,streamFile);
        /* 0x0c: always null, rest: entry (format varies) */

        entry_offset += entry_size + entry_pad + 0x10;

        /* sound info entry */
        if (entry_id == 0x73696400) { /* "sid\0" */
            /* keep looking for sound banks */
            continue;
        }

        /* sound bank entry, otherwise no good */
        if (entry_id != 0x75647362) { /* "udsb" */
            goto fail;
        }

        total_subsongs++;

        /* open internal RIFF */
        if (target_subsong == total_subsongs && vgmstream == NULL) {
            STREAMFILE* temp_streamFile;
            off_t subsong_offset = entry_base+0x18;
            size_t subsong_size  = read_32bitLE(entry_base+0x14,streamFile);

            temp_streamFile = setup_subfile_streamfile(streamFile, subsong_offset,subsong_size, "wav");
            if (!temp_streamFile) goto fail;

            vgmstream = init_vgmstream_riff(temp_streamFile);
            close_streamfile(temp_streamFile);
            if (!vgmstream) goto fail;

        }
    }

    /* subsong not found */
    if (!vgmstream)
        goto fail;

    vgmstream->num_streams = total_subsongs;
    return vgmstream;

fail:
    close_streamfile(streamData);
    close_vgmstream(vgmstream);
    return NULL;
}
示例#8
0
VGMSTREAM * init_vgmstream_str_snds(STREAMFILE *streamFile) {
    VGMSTREAM * vgmstream = NULL;
    char filename[PATH_LIMIT];

    int channel_count;
    int loop_flag = 0;
    off_t SHDR_offset = -1;
    int FoundSHDR = 0;
    int CTRL_size = -1;

    size_t file_size;

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

    /* check for opening CTRL or SNDS chunk */
    if (read_32bitBE(0x0,streamFile) != 0x4354524c &&   /* CTRL */
        read_32bitBE(0x0,streamFile) != 0x534e4453 &&   // SNDS
		read_32bitBE(0x0,streamFile) != 0x53484452)     // SHDR    
        goto fail;

    file_size = get_streamfile_size(streamFile);

    /* scan chunks until we find a SNDS containing a SHDR */
    {
        off_t current_chunk;

        current_chunk = 0;

        while (!FoundSHDR && current_chunk < file_size) {
            if (current_chunk < 0) goto fail;

            if (current_chunk+read_32bitBE(current_chunk+4,streamFile) >=
                    file_size) goto fail;

            switch (read_32bitBE(current_chunk,streamFile)) 
			{
                case 0x4354524C: /* CTRL */
                    /* to distinguish between styles */
                    CTRL_size = read_32bitBE(current_chunk+4,streamFile);					
					break;
                case 0x534e4453: /* SNDS */
                    switch (read_32bitBE(current_chunk+16,streamFile)) 
					{
						case 0x53484452: /* SHDR */
							FoundSHDR = 1;
							SHDR_offset = current_chunk+16;
						break;
						
						default:
							break;
                    }
                    break;
                case 0x53484452: /* SHDR */
                    switch (read_32bitBE(current_chunk+0x7C, streamFile)) 
					{
						case 0x4354524C: /* CTRL */
							// to distinguish between styles 
							CTRL_size = read_32bitBE(current_chunk + 0x80, streamFile);							
							break;
						
						default:
							break;
                    }
					break;
				default:
                    /* ignore others for now */
                    break;
            }

            current_chunk += read_32bitBE(current_chunk+4,streamFile);
        }
    }

    if (!FoundSHDR) goto fail;

    /* details */
    channel_count = read_32bitBE(SHDR_offset+0x20,streamFile);
    loop_flag = 0;

    /* build the VGMSTREAM */

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

    /* fill in the vital statistics */
    if ((CTRL_size == 0x1C) ||
		(CTRL_size == 0x0B) ||
		(CTRL_size == -1))
	{
        vgmstream->num_samples =
            read_32bitBE(SHDR_offset+0x2c,streamFile)-1; /* sample count? */
    } 
	else {
        vgmstream->num_samples =
            read_32bitBE(SHDR_offset+0x2c,streamFile)   /* frame count? */
            * 0x10;
    }

	vgmstream->num_samples/=vgmstream->channels;

    vgmstream->sample_rate = read_32bitBE(SHDR_offset+0x1c,streamFile);
    switch (read_32bitBE(SHDR_offset+0x24,streamFile)) {
        case 0x53445832:    /* SDX2 */
            if (channel_count > 1) {
                vgmstream->coding_type = coding_SDX2_int;
                vgmstream->interleave_block_size = 1;
            } else
                vgmstream->coding_type = coding_SDX2;
            break;
        default:
            goto fail;
    }
    vgmstream->layout_type = layout_blocked_str_snds;
    vgmstream->meta_type = meta_STR_SNDS;

    /* channels and loop flag are set by allocate_vgmstream */
    if (loop_flag) {
        /* just guessin', no way to set loop flag anyway */
        vgmstream->loop_start_sample = 0;
        vgmstream->loop_end_sample = vgmstream->num_samples;
    }

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

    /* start me up */
    block_update_str_snds(0,vgmstream);

    return vgmstream;

    /* clean up anything we may have opened */
fail:
    if (vgmstream) close_vgmstream(vgmstream);
    return NULL;
}
示例#9
0
VGMSTREAM * init_vgmstream_mn_str(STREAMFILE *streamFile) {
    VGMSTREAM * vgmstream = NULL;
    char filename[PATH_LIMIT];
    off_t start_offset;
    int loop_flag = 0;
	int channel_count;
	int bitspersample;

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

    loop_flag = 0;
    channel_count = read_32bitLE(0x50,streamFile);
    bitspersample = read_32bitLE(0x58,streamFile);
	
	/* build the VGMSTREAM */
    vgmstream = allocate_vgmstream(channel_count,loop_flag);
    if (!vgmstream) goto fail;

	/* fill in the vital statistics */
    start_offset = read_32bitLE(0x20,streamFile)+0x48;
	vgmstream->channels = channel_count;
    vgmstream->sample_rate = read_32bitLE(0x54,streamFile);

	switch (bitspersample) {
		case 0x10:
			vgmstream->coding_type = coding_PCM16LE;
			if (channel_count == 1)
			{
				vgmstream->layout_type = layout_none;
			}
			else
			{
				vgmstream->interleave_block_size = 0x2;
				vgmstream->layout_type = layout_interleave;
			}
		break;
		case 0x4:
			if (read_32bitLE(0x20,streamFile) == 0x24)
			{
				vgmstream->interleave_block_size = 0x800;
				vgmstream->layout_type = layout_none;
			}
	}

    vgmstream->num_samples = read_32bitLE(0x4C,streamFile);

    //vgmstream->layout_type = layout_interleave;
    //vgmstream->interleave_block_size = 0x2;
    vgmstream->meta_type = meta_MN_STR;

    /* 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;
}
示例#10
0
/* IDSP (Defender NGC) */
VGMSTREAM * init_vgmstream_idsp4(STREAMFILE *streamFile) {
    VGMSTREAM * vgmstream = NULL;
    char filename[260];
    int loop_flag = 0;
  	int channel_count;
    off_t start_offset;

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

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

    channel_count = read_32bitBE(0x0C,streamFile);
    
    if (channel_count > 2) // Refuse everything else for now
    {
      goto fail;
    }

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

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

    if (channel_count == 1)
    {
      vgmstream->layout_type = layout_none;
    }
    else
    {
      vgmstream->layout_type = layout_interleave;
      vgmstream->interleave_block_size = read_32bitBE(0x10,streamFile);
    }
    
    vgmstream->meta_type = meta_IDSP;

			{
				int i;
				for (i=0;i<16;i++)
					vgmstream->ch[0].adpcm_coef[i] = read_16bitBE(0x14+i*2,streamFile);
				if (channel_count == 2) {
				for (i=0;i<16;i++)
					vgmstream->ch[1].adpcm_coef[i] = read_16bitBE(0x42+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;
}
示例#11
0
/*	"idsp/IDSP"
	Soul Calibur Legends (Wii)
	Sky Crawlers: Innocent Aces (Wii)
*/
VGMSTREAM * init_vgmstream_idsp2(STREAMFILE *streamFile) {
    VGMSTREAM * vgmstream = NULL;
    char filename[260];
    int loop_flag;
  	int channel_count;
	  int i, j;
    off_t start_offset;

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

    /* check header */
    if (read_32bitBE(0x00,streamFile) != 0x69647370 || /* "idsp" */
        read_32bitBE(0xBC,streamFile) != 0x49445350) /* IDSP */
    goto fail;

    loop_flag = read_32bitBE(0x20,streamFile);
    channel_count = read_32bitBE(0xC4,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 */
		start_offset = (channel_count * 0x60) + 0x100;
		vgmstream->channels = channel_count;
		vgmstream->sample_rate = read_32bitBE(0xC8,streamFile);
		vgmstream->coding_type = coding_NGC_DSP;
		vgmstream->num_samples = (read_32bitBE(0x14,streamFile))*14/8/channel_count;
    if (loop_flag) {
        vgmstream->loop_start_sample = (read_32bitBE(0xD0,streamFile));
        vgmstream->loop_end_sample = (read_32bitBE(0xD4,streamFile));
    }
	    
	  if (channel_count == 1)
    {
			vgmstream->layout_type = layout_none;
    }
    else if (channel_count > 1)
    {
    		if (read_32bitBE(0xD8,streamFile) == 0)
        {
	    	  	vgmstream->layout_type = layout_none;
		    	  vgmstream->interleave_block_size = (get_streamfile_size(streamFile)-start_offset)/2;
        }
        else if (read_32bitBE(0xD8,streamFile) > 0)
        {
			      vgmstream->layout_type = layout_interleave;
			      vgmstream->interleave_block_size = read_32bitBE(0xD8,streamFile);
        }
    }

		vgmstream->meta_type = meta_IDSP;

	  {
		  if (vgmstream->coding_type == coding_NGC_DSP) {
			  off_t coef_table[8] = {0x118,0x178,0x1D8,0x238,0x298,0x2F8,0x358,0x3B8};
			  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);
          }
        }
      }
    }

    /* 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;
}
示例#12
0
VGMSTREAM * init_vgmstream_ngc_sck_dsp(STREAMFILE *streamFile) {

	VGMSTREAM * vgmstream = NULL;
    STREAMFILE * streamFileDSP = NULL;
    char filename[PATH_LIMIT];
	char filenameDSP[PATH_LIMIT];
	
	int i;
	int channel_count;
	int loop_flag;

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


	strcpy(filenameDSP,filename);
	strcpy(filenameDSP+strlen(filenameDSP)-3,"dsp");

	streamFileDSP = streamFile->open(streamFile,filenameDSP,STREAMFILE_DEFAULT_BUFFER_SIZE);
	
    if (read_32bitBE(0x5C,streamFile) != 0x60A94000)
        goto fail;

	if (!streamFile) goto fail;
	
	channel_count = 2;
	loop_flag = 0;

    /* 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(0x18,streamFile);
	vgmstream->num_samples=read_32bitBE(0x14,streamFile)/8/channel_count*14;
	vgmstream->coding_type = coding_NGC_DSP;
	
	if(loop_flag) {
		vgmstream->loop_start_sample = 0;
		vgmstream->loop_end_sample = read_32bitBE(0x10,streamFile)/8/channel_count*14;
	}	

	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(0xC,streamFile);
	}



    vgmstream->meta_type = meta_NGC_SCK_DSP;
	
    /* open the file for reading */
    {
        for (i=0;i<channel_count;i++) {
			/* Not sure, i'll put a fake value here for now */
            vgmstream->ch[i].streamfile = streamFile->open(streamFileDSP,filenameDSP,0x8000);
            vgmstream->ch[i].offset = 0;

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


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


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

    /* clean up anything we may have opened */
fail:
    if (streamFileDSP) close_streamfile(streamFileDSP);
    if (vgmstream) close_vgmstream(vgmstream);
    return NULL;
}
示例#13
0
/* VAS (from Pro Baseball Spirits 5) */
VGMSTREAM * init_vgmstream_ps2_vas(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("vas",filename_extension(filename))) goto fail;

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

    loop_flag = (read_32bitLE(0x10,streamFile)!=0);
    channel_count = 2;
    
	/* 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_32bitLE(0x04,streamFile);
    vgmstream->coding_type = coding_PSX;
    vgmstream->num_samples = read_32bitLE(0x00,streamFile)*28/16/channel_count;
    if (loop_flag) {
        vgmstream->loop_start_sample = read_32bitLE(0x14,streamFile)*28/16/channel_count;
        vgmstream->loop_end_sample = read_32bitLE(0x00,streamFile)*28/16/channel_count;
    }

    vgmstream->layout_type = layout_interleave;
    vgmstream->interleave_block_size = 0x200;
    vgmstream->meta_type = meta_PS2_VAS;

    /* 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;
}
示例#14
0
/* VAGp - Sony SDK format, created by various tools */
VGMSTREAM * init_vgmstream_vag(STREAMFILE *streamFile) {
    VGMSTREAM * vgmstream = NULL;
    off_t start_offset;
    size_t file_size, channel_size, interleave;
    meta_t meta_type;
    int channel_count = 0, loop_flag, sample_rate;
    uint32_t vag_id, version;
    int32_t loop_start_sample = 0, loop_end_sample = 0;
    int allow_dual_stereo = 0;


    /* checks */
    /* .vag: standard
     * .swag: Frantix (PSP)
     * .str: Ben10 Galactic Racing
     * .vig: MX vs. ATV Untamed (PS2)
     * .l/r: Crash Nitro Kart (PS2), Gradius V (PS2) */
    if ( !check_extensions(streamFile,"vag,swag,str,vig,l,r") )
        goto fail;

    /* check VAG Header */
    if (((read_32bitBE(0x00,streamFile) & 0xFFFFFF00) != 0x56414700) && /* "VAG" */
        ((read_32bitLE(0x00,streamFile) & 0xFFFFFF00) != 0x56414700))
        goto fail;

    file_size = get_streamfile_size(streamFile);

    /* version used to create the file:
     * - 00000000 = v1.8 PC,
     * - 00000002 = v1.3 Mac (used?)
     * - 00000003 = v1.6+ Mac
     * - 00000020 = v2.0 PC (most common)
     * - 00000004 = ? (later games)
     * - 00000006 = ? (vagconv)
     * - 00020001 = v2.1 (vagconv2)
     * - 00030000 = v3.0 (vagconv2) */
    version = (uint32_t)read_32bitBE(0x04,streamFile);
    /* 0x08-0c: reserved */
    channel_size = read_32bitBE(0x0c,streamFile);
    sample_rate = read_32bitBE(0x10,streamFile);
    /* 0x14-20 reserved */
    /* 0x20-30: name (optional) */
    /* 0x30: data start (first 0x10 usually 0s to init SPU) */


    /* check variation */
    vag_id = read_32bitBE(0x00,streamFile);
    switch(vag_id) {

        case 0x56414731: /* "VAG1" (1 channel) [Metal Gear Solid 3 (PS2)] */
            meta_type = meta_PS2_VAG1;
            start_offset = 0x40; /* 0x30 is extra data in VAG1 */
            channel_count = 1;
            interleave = 0;
            loop_flag = 0;
            break;

        case 0x56414732: /* "VAG2" (2 channels) [Metal Gear Solid 3 (PS2)] */
            meta_type = meta_PS2_VAG2;
            start_offset = 0x40; /* 0x30 is extra data in VAG2 */
            channel_count = 2;
            interleave = 0x800;
            loop_flag = 0;
            break;

        case 0x56414769: /* "VAGi" (interleaved) */
            meta_type = meta_PS2_VAGi;
            start_offset = 0x800;
            channel_count = 2;
            interleave = read_32bitLE(0x08,streamFile);
            loop_flag = 0;
            break;

        case 0x70474156: /* pGAV (little endian / stereo) [Jak 3 (PS2), Jak X (PS2)] */
            meta_type = meta_PS2_pGAV;
            start_offset = 0x00; //todo 0x30, requires interleave_first

            if (read_32bitBE(0x20,streamFile) == 0x53746572) { /* "Ster" */
                channel_count = 2;

                if (read_32bitLE(0x2000,streamFile) == 0x56414770) /* "pGAV" */
                    interleave = 0x2000; /* Jak 3 interleave, includes header */
                else if (read_32bitLE(0x1000,streamFile) == 0x56414770) /* "pGAV" */
                    interleave = 0x1000; /* Jak X interleave, includes header */
                else
                    goto fail;
                //todo interleave_first = interleave - start_offset; /* interleave includes header */
            }
            else {
                channel_count = 1;
                interleave = 0;
            }

            channel_size = read_32bitLE(0x0C,streamFile) / channel_count;
            sample_rate = read_32bitLE(0x10,streamFile);
            //todo adjust channel_size, includes part of header?
            loop_flag = 0;
            break;

        case 0x56414770: /* "VAGp" (standard and variations) */
            meta_type = meta_PS2_VAGp;

            if (check_extensions(streamFile,"vig")) {
                /* MX vs. ATV Untamed (PS2) */
                start_offset = 0x800 - 0x20;
                channel_count = 2;
                interleave = 0x10;
                loop_flag = 0;
            }
            else if (check_extensions(streamFile,"swag")) { /* algo "VAGp" at (file_size / channels) */
                /* Frantix (PSP) */
                start_offset = 0x40; /* channel_size ignores empty frame */
                channel_count = 2;
                interleave = file_size / channel_count;

                channel_size = read_32bitLE(0x0c,streamFile);
                sample_rate = read_32bitLE(0x10,streamFile);

                loop_flag = ps_find_loop_offsets(streamFile, start_offset, channel_size*channel_count, channel_count, interleave, &loop_start_sample, &loop_end_sample);
            }
            else if (read_32bitBE(0x6000,streamFile) == 0x56414770) { /* "VAGp" */
                /* The Simpsons Wrestling (PS1) */
                start_offset = 0x00; //todo 0x30, requires interleave_first
                channel_count = 2;
                interleave = 0x6000;
                //todo interleave_first = interleave - start_offset; /* includes header */
                channel_size += 0x30;

                loop_flag = 0;
            }
            else if (read_32bitBE(0x1000,streamFile) == 0x56414770) { /* "VAGp" */
                /* Shikigami no Shiro (PS2) */
                start_offset = 0x00; //todo 0x30, requires interleave_first
                channel_count = 2;
                interleave = 0x1000;
                //todo interleave_first = interleave - start_offset; /* includes header */
                channel_size += 0x30;

                loop_flag = ps_find_loop_offsets(streamFile, start_offset, channel_size*channel_count, channel_count, interleave, &loop_start_sample, &loop_end_sample);
            }
            else if (read_32bitBE(0x30,streamFile) == 0x56414770) { /* "VAGp" */
                /* The Red Star (PS2) */
                start_offset = 0x60; /* two VAGp headers */
                channel_count = 2;

                if ((file_size - start_offset) % 0x4000 == 0)
                    interleave = 0x4000;
                else if ((file_size - start_offset) % 0x4180 == 0)
                    interleave = 0x4180;
                else
                    goto fail;

                loop_flag = 0; /* loop segments */
            }
            else if (version == 0x40000000) {
                /* Killzone (PS2) */
                start_offset = 0x30;
                channel_count = 1;
                interleave = 0;

                channel_size = read_32bitLE(0x0C,streamFile) / channel_count;
                sample_rate = read_32bitLE(0x10,streamFile);
                loop_flag = 0;
            }
            else if (version == 0x00020001 || version == 0x00030000) {
                /* standard Vita/PS4 .vag [Chronovolt (Vita), Grand Kingdom (PS4)] */
                start_offset = 0x30;
                interleave = 0x10;

                /* channels are at 0x1e, except Ukiyo no Roushi (Vita), which has
                 * loop start/end frame (but also uses PS-ADPCM flags) */
                if (read_32bitBE(0x18,streamFile) == 0
                        && (read_32bitBE(0x1c,streamFile) & 0xFFFF00FF) == 0
                        && read_8bit(0x1e,streamFile) < 16) {
                    channel_count = read_8bit(0x1e,streamFile);
                    if (channel_count == 0)
                        channel_count = 1;  /* ex. early games [Lumines (Vita)] */
                }
                else {
                    channel_count = 1;
                }

                channel_size = channel_size / channel_count;
                loop_flag = ps_find_loop_offsets(streamFile, start_offset, channel_size*channel_count, channel_count, interleave, &loop_start_sample, &loop_end_sample);
            }
            else {
                /* standard PS1/PS2/PS3 .vag [Ecco the Dolphin (PS2), Legasista (PS3)] */
                start_offset = 0x30;
                interleave = 0;

                channel_count = 1;
                loop_flag = ps_find_loop_offsets_full(streamFile, start_offset, channel_size*channel_count, channel_count, interleave, &loop_start_sample, &loop_end_sample);
                allow_dual_stereo = 1; /* often found with external L/R files */
            }
            break;

        default:
            goto fail;
    }


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

    vgmstream->meta_type = meta_type;
    vgmstream->allow_dual_stereo = allow_dual_stereo;

    vgmstream->sample_rate = sample_rate;
    vgmstream->num_samples = ps_bytes_to_samples(channel_size,1);
    vgmstream->loop_start_sample = loop_start_sample;
    vgmstream->loop_end_sample = loop_end_sample;
    vgmstream->coding_type = coding_PSX;
    if (version == 0x00020001 || version == 0x00030000)
        vgmstream->coding_type = coding_HEVAG;
    vgmstream->layout_type = (channel_count == 1) ? layout_none : layout_interleave;
    vgmstream->interleave_block_size = interleave;

    read_string(vgmstream->stream_name,0x10+1, 0x20,streamFile); /* always, can be null */

    if ( !vgmstream_open_stream(vgmstream, streamFile, start_offset) )
        goto fail;
    return vgmstream;

fail:
    close_vgmstream(vgmstream);
    return NULL;
}
示例#15
0
/* MSF header */
VGMSTREAM * init_vgmstream_ps3_msf(STREAMFILE *streamFile) {
    VGMSTREAM * vgmstream = NULL;
    char filename[260];
    off_t start_offset;
    int32_t loop_start, loop_end;
    int loop_flag = 0;
  	int channel_count;
    int codec_id;
	size_t	fileLength;

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


    if (read_8bit(0x0,streamFile) != 0x4D) goto fail;	/* M */
    if (read_8bit(0x1,streamFile) != 0x53) goto fail;	/* S */
    if (read_8bit(0x2,streamFile) != 0x46) goto fail; /* F */

    fileLength = get_streamfile_size(streamFile);

	loop_flag = (read_32bitBE(0x18,streamFile) != 0xFFFFFFFF);
    if (loop_flag)
    {
      loop_start = read_32bitBE(0x18,streamFile);
      loop_end = read_32bitBE(0x0C,streamFile);
    }

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

    /* fill in the vital statistics */
	  vgmstream->channels = channel_count;

   /* Sample rate hack for strange files that don't have a specified frequency */
	if (read_32bitBE(0x10,streamFile)==0x00000000)
		vgmstream->sample_rate = 48000;
	else
		vgmstream->sample_rate = read_32bitBE(0x10,streamFile);

    start_offset = 0x40;

    switch (codec_id) {
        case 0x0: /* PCM (Big Endian) */
            {
                vgmstream->coding_type = coding_PCM16BE;
                vgmstream->num_samples = read_32bitBE(0x0C,streamFile)/2/channel_count;
                
				if (loop_flag){
                    vgmstream->loop_start_sample = loop_start/2/channel_count;
                    vgmstream->loop_end_sample = loop_end/2/channel_count;
                }
                
                if (channel_count == 1)
                {
                  vgmstream->layout_type = layout_none;
                }
                else if (channel_count > 1)
                {
                  vgmstream->layout_type = layout_interleave;
                  vgmstream->interleave_block_size = 2;
                }
            }
            break;
        case 0x3: /* PSx ADPCM */
            {
                vgmstream->coding_type = coding_PSX;
                vgmstream->num_samples = read_32bitBE(0x0C,streamFile)*28/16/channel_count;

				if (vgmstream->num_samples == 0xFFFFFFFF)
				{
					vgmstream->num_samples = (fileLength - start_offset)*28/16/channel_count;
				}

				if (loop_flag)
				{
                    vgmstream->loop_start_sample = loop_start*28/16/channel_count;
                    vgmstream->loop_end_sample = loop_end*28/16/channel_count;
                }
                
                if (channel_count == 1)
                {
                  vgmstream->layout_type = layout_none;
                }
                else if (channel_count > 1)
                {
                  vgmstream->layout_type = layout_interleave;
                  vgmstream->interleave_block_size = 0x10; // read_32bitBE(0x14,streamFile);
                }
            }
            break;
#ifdef VGM_USE_MPEG
        case 0x7: /* MPEG */
            {
                mpeg_codec_data *mpeg_data = NULL;
                struct mpg123_frameinfo mi;
                coding_t ct;

                mpeg_data = init_mpeg_codec_data(streamFile, start_offset, vgmstream->sample_rate, vgmstream->channels, &ct, NULL, NULL);
                if (!mpeg_data) goto fail;
                vgmstream->codec_data = mpeg_data;

                if (MPG123_OK != mpg123_info(mpeg_data->m, &mi)) goto fail;

                vgmstream->coding_type = ct;
                vgmstream->layout_type = layout_mpeg;
                if (mi.vbr != MPG123_CBR) goto fail;
                vgmstream->num_samples = mpeg_bytes_to_samples(read_32bitBE(0xC,streamFile), &mi);
                vgmstream->num_samples -= vgmstream->num_samples%576;
                if (loop_flag) {
                    vgmstream->loop_start_sample = mpeg_bytes_to_samples(loop_start, &mi);
                    vgmstream->loop_start_sample -= vgmstream->loop_start_sample%576;
                    vgmstream->loop_end_sample = mpeg_bytes_to_samples(loop_end, &mi);
                    vgmstream->loop_end_sample -= vgmstream->loop_end_sample%576;
                }
                vgmstream->interleave_block_size = 0;
            }
            break;
#endif
        default:
            goto fail;
    }

    vgmstream->meta_type = meta_PS3_MSF;

    /* 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;
}
示例#16
0
文件: pcm.c 项目: flyingtime/boxee
/* PCM (from Ephemeral Fantasia) */
VGMSTREAM * init_vgmstream_pcm(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("pcm",filename_extension(filename))) goto fail;

	/* check header */
    if (read_32bitBE(0x0C,streamFile) ==0x0AA00AA0) {

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

		/* fill in the vital statistics */
		start_offset = 0x200;
		vgmstream->channels = channel_count;
		vgmstream->sample_rate = 44100;
		vgmstream->coding_type = coding_PCM8_SB_int;
		vgmstream->num_samples = read_32bitBE(0x06,streamFile)*2;

		if(loop_flag) {
			vgmstream->loop_start_sample = read_32bitBE(0x02,streamFile)*2;
			vgmstream->loop_end_sample = read_32bitBE(0x06,streamFile)*2;
		}
		vgmstream->layout_type = layout_interleave;
		vgmstream->interleave_block_size = 0x2;
		vgmstream->meta_type = meta_PCM;

	} else if (read_32bitBE(0x410,streamFile) ==0x9CDB0740) {

		loop_flag = (read_32bitLE(0x0C,streamFile)!=0);
		channel_count = 2;
 
		/* 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 = 22050;
		vgmstream->coding_type = coding_PCM16LE;
		vgmstream->num_samples = read_32bitLE(0x4,streamFile);

        if(loop_flag == 1) {
			vgmstream->loop_start_sample = read_32bitLE(0x08,streamFile);
			vgmstream->loop_end_sample = read_32bitLE(0x0C,streamFile);
		}

		vgmstream->layout_type = layout_interleave;
		vgmstream->interleave_block_size = 0x2;
		vgmstream->meta_type = meta_PCM;
	} else if ((read_32bitBE(0x0,streamFile) ==0x786D6402) || 
				(read_32bitBE(0x0,streamFile) ==0x786D6401)) {
		loop_flag = 0;
		channel_count = read_8bit(0x03,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;
		vgmstream->sample_rate = (int32_t)(read_16bitLE(0x4,streamFile) & 0x0000ffff);
		vgmstream->coding_type = coding_PCM8_int;
		vgmstream->num_samples = read_32bitLE(0x6,streamFile);

        if(loop_flag == 1) {
			vgmstream->loop_start_sample = read_32bitLE(0x08,streamFile);
			vgmstream->loop_end_sample = read_32bitLE(0x0C,streamFile);
		}

		vgmstream->layout_type = layout_interleave;
		vgmstream->interleave_block_size = 0x8;
		vgmstream->meta_type = meta_PCM;
	} else
		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;
			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;
}
示例#17
0
VGMSTREAM * init_vgmstream_adx(STREAMFILE *streamFile) {
    VGMSTREAM * vgmstream = NULL;
    off_t stream_offset;
    size_t filesize;
    uint16_t version_signature;
    int loop_flag=0;
    int channel_count;
    int32_t loop_start_offset=0;
    int32_t loop_end_offset=0;
    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[260];
    int coding_type = coding_CRI_ADX;
    uint16_t xor_start=0,xor_mult=0,xor_add=0;

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

    filesize = get_streamfile_size(streamFile);

    /* check first 2 bytes */
    if ((uint16_t)read_16bitBE(0,streamFile)!=0x8000) goto fail;

    /* 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 */
    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;
}
示例#18
0
文件: flx.c 项目: benladen/vgmstream
/* FLX - from Ultima IX (.FLX is actually an archive format with sometimes sound data, let's support both anyway) */
VGMSTREAM * init_vgmstream_flx(STREAMFILE *streamFile) {
    VGMSTREAM * vgmstream = NULL;
    off_t start_offset, stream_offset = 0;
    size_t data_size;
    int loop_flag, channel_count, codec;
    int total_subsongs = 0, target_subsong = streamFile->stream_index;
    size_t stream_size = 0;


    /* check extensions (.flx: name of archive, files inside don't have extensions) */
    if (!check_extensions(streamFile,"flx"))
        goto fail;

    /* all spaces up to 0x50 = archive FLX */
    if (read_32bitBE(0x00,streamFile) == 0x20202020 && read_32bitBE(0x40,streamFile) == 0x20202020) {
        int i;
        int entries = read_32bitLE(0x50,streamFile);
        off_t offset = 0x80;

        if (read_32bitLE(0x54,streamFile) != 0x02
                || read_32bitLE(0x58,streamFile) != get_streamfile_size(streamFile))
            goto fail;

        if (target_subsong == 0) target_subsong = 1;

        for (i = 0; i < entries; i++) {
            off_t entry_offset = read_32bitLE(offset + 0x00, streamFile);
            size_t entry_size = read_32bitLE(offset + 0x04, streamFile);
            offset += 0x08;

            if (entry_offset != 0x00)
                total_subsongs++; /* many entries are empty */
            if (total_subsongs == target_subsong && stream_offset == 0) {
                stream_offset = entry_offset; /* found but let's keep adding total_streams */
                stream_size = entry_size;
            }
        }
        if (target_subsong < 0 || target_subsong > total_subsongs || total_subsongs < 1) goto fail;
        if (stream_offset == 0x00) goto fail;
    }
    else {
        stream_offset = 0x00;
        stream_size = get_streamfile_size(streamFile);
    }

    if (read_32bitLE(stream_offset + 0x30,streamFile) != 0x10)
        goto fail;
    data_size = read_32bitLE(stream_offset + 0x28,streamFile);
    channel_count = read_32bitLE(stream_offset + 0x34,streamFile);
    codec = read_32bitLE(stream_offset + 0x38,streamFile);
    loop_flag = (channel_count > 1); /* full seamless repeats in music */
    start_offset = stream_offset + 0x3c;
    /* 0x00: id */

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

    vgmstream->sample_rate = read_32bitLE(stream_offset + 0x2c,streamFile);
    vgmstream->num_streams = total_subsongs;
    vgmstream->stream_size = stream_size;
    vgmstream->meta_type = meta_PC_FLX;

    switch(codec) {
        case 0x00:  /* PCM (sfx) */
            vgmstream->coding_type = coding_PCM16LE;
            vgmstream->layout_type = layout_interleave;
            vgmstream->interleave_block_size = 0x02;

            vgmstream->num_samples = pcm_bytes_to_samples(data_size, channel_count, 16);
            break;

        case 0x01:  /* EA-XA (music, sfx) */
            vgmstream->coding_type = channel_count > 1 ? coding_EA_XA : coding_EA_XA_int;
            vgmstream->layout_type = layout_none;

            vgmstream->num_samples = read_32bitLE(stream_offset + 0x28,streamFile) / 0x0f*channel_count * 28; /* ea_xa_bytes_to_samples */
            vgmstream->loop_start_sample = 0;
            vgmstream->loop_end_sample = vgmstream->num_samples;
            break;

        case 0x02:  /* EA-MT (voices) */
            vgmstream->coding_type = coding_EA_MT;
            vgmstream->codec_data = init_ea_mt(vgmstream->channels, 0);
            if (!vgmstream->codec_data) goto fail;

            vgmstream->num_samples = read_32bitLE(start_offset,streamFile);
            start_offset += 0x04;
            break;

        default:
            VGM_LOG("FLX: unknown codec 0x%x\n", codec);
            goto fail;
    }

    read_string(vgmstream->stream_name,0x20+1, stream_offset + 0x04,streamFile);


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

    return vgmstream;

fail:
    close_vgmstream(vgmstream);
    return NULL;
}
示例#19
0
/* PDT - Custom Generated File (Mario Party) */
VGMSTREAM * init_vgmstream_ngc_pdt(STREAMFILE *streamFile) {
    VGMSTREAM * vgmstream = NULL;
    char filename[260];
    int loop_flag;
    int channel_count;
    off_t start_offset;
    int second_channel_start = -1;
    
    /* check extension, case insensitive */
    streamFile->get_name(streamFile,filename,sizeof(filename));
    if (strcasecmp("pdt",filename_extension(filename))) goto fail;

    /* check header */
    if (read_32bitBE(0x00,streamFile) != 0x50445420) /* "PDT " */
        goto fail;
    if (read_32bitBE(0x04,streamFile) != 0x44535020) /* "DSP " */
        goto fail;
    if (read_32bitBE(0x08,streamFile) != 0x48454144) /* "HEAD " */
        goto fail;
    if (read_16bitBE(0x0C,streamFile) != 0x4552) /* "ER " */
        goto fail;

    loop_flag = (read_32bitBE(0x1C,streamFile)!=2);
    channel_count = (uint16_t)(read_16bitLE(0x0E,streamFile));

	  /* 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(0x14,streamFile);
    vgmstream->coding_type = coding_NGC_DSP;

    if (channel_count == 1)
    {
      vgmstream->num_samples = read_32bitBE(0x18,streamFile)*14/8/channel_count/2;
        if (loop_flag) {
            vgmstream->loop_start_sample = read_32bitBE(0x1C,streamFile)*14/8/channel_count/2;
            vgmstream->loop_end_sample = read_32bitBE(0x18,streamFile)*14/8/channel_count/2;
        }
    }
    else if (channel_count == 2)
    {
      vgmstream->num_samples = read_32bitBE(0x18,streamFile)*14/8/channel_count;
        if (loop_flag) {
            vgmstream->loop_start_sample = read_32bitBE(0x1C,streamFile)*14/8/channel_count;
            vgmstream->loop_end_sample = read_32bitBE(0x18,streamFile)*14/8/channel_count;
        }
        second_channel_start = (get_streamfile_size(streamFile)+start_offset)/2;
    }
    else
    {
      goto fail;
    }

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

    if (vgmstream->coding_type == coding_NGC_DSP) {
        int i;
        for (i=0;i<16;i++) {
            vgmstream->ch[0].adpcm_coef[i] = read_16bitBE(0x50+i*2,streamFile);
        }
        if (vgmstream->channels == 2) {
            for (i=0;i<16;i++) {
                vgmstream->ch[1].adpcm_coef[i] = read_16bitBE(0x70+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[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;
}
示例#20
0
VGMSTREAM * init_vgmstream_dsp_ygo(STREAMFILE *streamFile) {
    VGMSTREAM * vgmstream = NULL;
    char filename[PATH_LIMIT];
	int loop_flag;
	int channel_count;
    off_t start_offset;
    int i;

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

    /* check file size with size given in header */
    if ((read_32bitBE(0x0,streamFile)+0xE0) != (get_streamfile_size(streamFile)))
        goto fail;

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

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

	// read coef stuff
	{
		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;

fail:
    /* clean up anything we may have opened */
    if (vgmstream) close_vgmstream(vgmstream);
    return NULL;
}
示例#21
0
文件: xps.c 项目: kode54/vgmstream
/* .XPS+DAT - From Software games streams [Metal Wolf Chaos (Xbox), Otogi (Xbox)] */
VGMSTREAM * init_vgmstream_xps_dat(STREAMFILE *streamFile) {
    VGMSTREAM * vgmstream = NULL;
    STREAMFILE * streamData = NULL;
    off_t start_offset, header_offset;
    size_t stream_size;
    int loop_flag, channel_count, sample_rate, codec, loop_start_sample, loop_end_sample, file_id;
    int total_subsongs, target_subsong = streamFile->stream_index;


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

    if (read_32bitLE(0x00,streamFile) != get_streamfile_size(streamFile))
        goto fail;
    if (read_32bitBE(0x0c,streamFile) != 0x64696666)  /* "diff" */
        goto fail;

    /* handle .xps+dat (bank .xps are done below) */
    streamData = open_streamfile_by_ext(streamFile, "dat");
    if (!streamData) goto fail;

    /* 0x00: approximate file size */

    total_subsongs = read_32bitLE(0x04,streamData);
    if (target_subsong == 0) target_subsong = 1;
    if (target_subsong < 0 || target_subsong > total_subsongs || total_subsongs < 1) goto fail;

    header_offset = 0x20 + 0x94*(target_subsong-1); /* could start at 0x0c too */

    file_id             = read_32bitLE(header_offset+0x00,streamData);
    start_offset        = read_32bitLE(header_offset+0x04,streamData);
    stream_size         = read_32bitLE(header_offset+0x08,streamData);
    /* 0x0c: loop start offset? */
    /* 0x10: loop end offset? */
    /* 0x14: always null? */
    codec               = read_16bitLE(header_offset+0x18,streamData);
    channel_count       = read_16bitLE(header_offset+0x1a,streamData);
    sample_rate         = read_32bitLE(header_offset+0x1c,streamData);
    /* 0x20: average bitrate */
    /* 0x24: block size, bps */
    loop_flag           = read_32bitLE(header_offset+0x5c,streamData);
    loop_start_sample   = read_32bitLE(header_offset+0x6c,streamData);
    loop_end_sample     = read_32bitLE(header_offset+0x70,streamData) + 1; /* a "smpl" chunk basically */


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

    vgmstream->sample_rate = sample_rate;
    vgmstream->meta_type = meta_XPS_DAT;
    vgmstream->loop_start_sample = loop_start_sample;
    vgmstream->loop_end_sample = loop_end_sample;
    vgmstream->num_streams = total_subsongs;
    vgmstream->stream_size = stream_size;

    switch(codec) {
        case 0x01:
            vgmstream->coding_type = coding_PCM16LE;
            vgmstream->layout_type = layout_interleave;
            vgmstream->interleave_block_size = 0x02;
            vgmstream->num_samples = pcm_bytes_to_samples(stream_size, channel_count, 16);
            break;

        case 0x69:
            vgmstream->coding_type = coding_XBOX_IMA;
            vgmstream->layout_type = layout_none;
            vgmstream->num_samples = xbox_ima_bytes_to_samples(stream_size, channel_count);
            break;

        default:
            goto fail;
    }

    read_xps_name(vgmstream, streamFile, file_id);

    if (!vgmstream_open_stream(vgmstream,streamData,start_offset))
        goto fail;

    close_streamfile(streamData);
    return vgmstream;

fail:
    close_streamfile(streamData);
    close_vgmstream(vgmstream);
    return NULL;
}
示例#22
0
VGMSTREAM * init_vgmstream_ps2_svag_snk(STREAMFILE* streamFile) {
    VGMSTREAM * vgmstream = NULL;
    char filename[PATH_LIMIT];

    off_t start_offset = 0x20;

    int loop_flag;
    int channel_count;
    int loop_start_block;
    int loop_end_block;

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

    /* check SNK SVAG Header ("VAGm") */
    if (read_32bitBE(0x00,streamFile) != 0x5641476D)
        goto fail;


    channel_count = read_32bitLE(0x0c,streamFile);

    loop_start_block = read_32bitLE(0x18,streamFile);
    loop_end_block = read_32bitLE(0x1c,streamFile);

    loop_flag = loop_end_block > 0; /* loop_start_block can be 0 */


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

    /* header data */
    vgmstream->coding_type = coding_PSX;
    vgmstream->meta_type = meta_PS2_SVAG_SNK;

    vgmstream->channels = channel_count;
    vgmstream->sample_rate = read_32bitLE(0x08,streamFile);
    vgmstream->num_samples = read_32bitLE(0x10,streamFile) * 28; /* size in blocks */
    if( vgmstream->loop_flag ) {
        vgmstream->loop_start_sample = loop_start_block * 28;
        vgmstream->loop_end_sample = loop_end_block * 28;
    }
    vgmstream->layout_type = layout_interleave;
    vgmstream->interleave_block_size = 0x10;


    /* 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;
}
示例#23
0
文件: his.c 项目: 9a3eedi/Droidsound
VGMSTREAM * init_vgmstream_his(STREAMFILE *streamFile) {
    VGMSTREAM * vgmstream = NULL;
    char filename[260];
    int channel_count;
    int loop_flag = 0;
    int bps = 0;
    off_t start_offset;
    const uint8_t header_magic_expected[0x16] = "Her Interactive Sound\x1a";
    uint8_t header_magic[0x16];

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

    /* check header magic */
    if (0x16 != streamFile->read(streamFile, header_magic, 0, 0x16)) goto fail;
    if (memcmp(header_magic_expected, header_magic, 0x16)) goto fail;

    /* data chunk label */
    if (0x64617461 != read_32bitBE(0x24,streamFile)) goto fail;

    start_offset = 0x2c;

    channel_count = read_16bitLE(0x16,streamFile);

    /* 8-bit or 16-bit expected */
    switch (read_16bitLE(0x22,streamFile))
    {
        case 8:
            bps = 1;
            break;
        case 16:
            bps = 2;
            break;
        default:
            goto fail;
    }

    /* check bytes per frame */
    if (read_16bitLE(0x20,streamFile) != channel_count*bps) goto fail;

    /* check size */
    /* file size -8 */
	if ((read_32bitLE(0x1c,streamFile)+8) != get_streamfile_size(streamFile))
		goto fail;
    /* data chunk size, assume it occupies the rest of the file */
    //if ((read_32bitLE(0x28,streamFile)+start_offset) != get_streamfile_size(streamFile))
    //    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_32bitLE(0x28,streamFile) / channel_count / bps;
    vgmstream->sample_rate = read_32bitLE(0x18,streamFile);

    vgmstream->meta_type = meta_HIS;
    vgmstream->layout_type = layout_none;
    if (bps == 2)
    {
        vgmstream->coding_type = coding_PCM16LE;
        if (channel_count == 2)
        {
            vgmstream->coding_type = coding_PCM16LE_int;
            vgmstream->interleave_block_size = 2;
        }
    }
    else // bps == 1
    {
        vgmstream->coding_type = coding_PCM8_U;
        if (channel_count == 2)
        {
            vgmstream->coding_type = coding_PCM8_U_int;
            vgmstream->interleave_block_size = 1;
        }
    }

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

        vgmstream->ch[0].channel_start_offset=
            vgmstream->ch[0].offset=start_offset;

        if (channel_count == 2)
        {
            file = streamFile->open(streamFile,filename,STREAMFILE_DEFAULT_BUFFER_SIZE);
            if (!file) goto fail;
            vgmstream->ch[1].streamfile = file;
        
            vgmstream->ch[0].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;
}
示例#24
0
VGMSTREAM * init_vgmstream_riff(STREAMFILE *streamFile) {
    VGMSTREAM * vgmstream = NULL;
    char filename[260];

    struct riff_fmt_chunk fmt;

    off_t file_size = -1;
    int sample_count = 0;
    int fact_sample_count = -1;
    off_t start_offset = -1;

    int loop_flag = 0;
    long loop_start_ms = -1;
    long loop_end_ms = -1;
    off_t loop_start_offset = -1;
    off_t loop_end_offset = -1;
    uint32_t riff_size;
    uint32_t data_size = 0;

    int FormatChunkFound = 0;
    int DataChunkFound = 0;

    /* Level-5 mwv */
    int mwv = 0;
    off_t mwv_pflt_offset = -1;
    off_t mwv_ctrl_offset = -1;

    /* Ubisoft sns */
    int sns = 0;

    /* check extension, case insensitive */
    streamFile->get_name(streamFile,filename,sizeof(filename));
    if (strcasecmp("wav",filename_extension(filename)) &&
        strcasecmp("lwav",filename_extension(filename)))
    {
        if (!strcasecmp("mwv",filename_extension(filename)))
            mwv = 1;
        else if (!strcasecmp("sns",filename_extension(filename)))
            sns = 1;
        else
            goto fail;
    }

    /* check header */
    if ((uint32_t)read_32bitBE(0,streamFile)!=0x52494646) /* "RIFF" */
        goto fail;
    /* check for WAVE form */
    if ((uint32_t)read_32bitBE(8,streamFile)!=0x57415645) /* "WAVE" */
        goto fail;

    riff_size = read_32bitLE(4,streamFile);
    file_size = get_streamfile_size(streamFile);

    /* check for tructated RIFF */
    if (file_size < riff_size+8) goto fail;

    /* read through chunks to verify format and find metadata */
    {
        off_t current_chunk = 0xc; /* start with first chunk */

        while (current_chunk < file_size && current_chunk < riff_size+8) {
            uint32_t chunk_type = read_32bitBE(current_chunk,streamFile);
            off_t chunk_size = read_32bitLE(current_chunk+4,streamFile);

            if (current_chunk+8+chunk_size > file_size) goto fail;

            switch(chunk_type) {
                case 0x666d7420:    /* "fmt " */
                    /* only one per file */
                    if (FormatChunkFound) goto fail;
                    FormatChunkFound = 1;

                    if (-1 == read_fmt(0, /* big endian == false*/
                        streamFile,
                        current_chunk,
                        &fmt,
                        sns,
                        mwv))
                        goto fail;

                    break;
                case 0x64617461:    /* data */
                    /* at most one per file */
                    if (DataChunkFound) goto fail;
                    DataChunkFound = 1;

                    start_offset = current_chunk + 8;
                    data_size = chunk_size;
                    break;
                case 0x4C495354:    /* LIST */
                    /* what lurks within?? */
                    switch (read_32bitBE(current_chunk + 8, streamFile)) {
                        case 0x6164746C:    /* adtl */
                            /* yay, atdl is its own little world */
                            parse_adtl(current_chunk + 8, chunk_size,
                                    streamFile,
                                    &loop_start_ms,&loop_end_ms,&loop_flag);
                            break;
                        default:
                            break;
                    }
                    break;
                case 0x736D706C:    /* smpl */
                    /* check loop count */
                    if (read_32bitLE(current_chunk+0x24, streamFile)==1)
                    {
                        /* check loop info */
                        if (read_32bitLE(current_chunk+0x2c+4, streamFile)==0)
                        {
                            loop_flag = 1;
                            loop_start_offset =
                                read_32bitLE(current_chunk+0x2c+8, streamFile);
                            loop_end_offset =
                                read_32bitLE(current_chunk+0x2c+0xc,streamFile);
                        }
                    }
                    break;
                case 0x70666c74:    /* pflt */
                    if (!mwv) break;    /* ignore if not in an mwv */
                    /* predictor filters */
                    mwv_pflt_offset = current_chunk;
                    break;
                case 0x6374726c:    /* ctrl */
                    if (!mwv) break;    /* ignore if not in an mwv */
                    /* loops! */
                    if (read_32bitLE(current_chunk+8, streamFile))
                    {
                        loop_flag = 1;
                    }
                    mwv_ctrl_offset = current_chunk;
                    break;
                case 0x66616374:    /* fact */
                    if (chunk_size != 4
                        && (!(sns && chunk_size == 0x10))) break;
                    fact_sample_count = read_32bitLE(current_chunk+8, streamFile);
                    break;
                default:
                    /* ignorance is bliss */
                    break;
            }

            current_chunk += 8+chunk_size;
        }
    }

    if (!FormatChunkFound || !DataChunkFound) goto fail;

    switch (fmt.coding_type) {
        case coding_PCM16LE:
            sample_count = data_size/2/fmt.channel_count;
            break;
        case coding_PCM8_U_int:
            sample_count = data_size/fmt.channel_count;
            break;
        case coding_L5_555:
            sample_count = data_size/0x12/fmt.channel_count*32;
            break;
        case coding_MSADPCM:
            sample_count = msadpcm_bytes_to_samples(data_size, fmt.block_size, fmt.channel_count);
            break;
        case coding_MS_IMA:
            sample_count = (data_size / fmt.block_size) * (fmt.block_size - 4 * fmt.channel_count) * 2 / fmt.channel_count +
                ((data_size % fmt.block_size) ? (data_size % fmt.block_size - 4 * fmt.channel_count) * 2 / fmt.channel_count : 0);
            break;
        case coding_NGC_DSP:
            break;
        default:
            goto fail;
    }

    /* .sns uses fact chunk */
    if (sns)
    {
        if (-1 == fact_sample_count) goto fail;
        sample_count = fact_sample_count;
    }

    /* build the VGMSTREAM */

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

    /* fill in the vital statistics */
    vgmstream->num_samples = sample_count;
    vgmstream->sample_rate = fmt.sample_rate;

    vgmstream->coding_type = fmt.coding_type;

    vgmstream->layout_type = layout_none;
    if (fmt.channel_count > 1) {
        switch (fmt.coding_type) {
            case coding_PCM8_U_int:
            case coding_MS_IMA:
            case coding_MSADPCM:
                // use layout_none from above
                break;
            default:
                vgmstream->layout_type = layout_interleave;
                break;
        }
    }

    vgmstream->interleave_block_size = fmt.interleave;
    switch (fmt.coding_type) {
        case coding_MSADPCM:
        case coding_MS_IMA:
            // override interleave_block_size with frame size
            vgmstream->interleave_block_size = fmt.block_size;
            break;
        default:
            // use interleave from above
            break;
    }

    if (loop_flag) {
        if (loop_start_ms >= 0)
        {
            vgmstream->loop_start_sample =
                (long long)loop_start_ms*fmt.sample_rate/1000;
            vgmstream->loop_end_sample =
                (long long)loop_end_ms*fmt.sample_rate/1000;
            vgmstream->meta_type = meta_RIFF_WAVE_labl_Marker;
        }
        else if (loop_start_offset >= 0)
        {
            vgmstream->loop_start_sample = loop_start_offset;
            vgmstream->loop_end_sample = loop_end_offset;
            vgmstream->meta_type = meta_RIFF_WAVE_smpl;
        }
        else if (mwv && mwv_ctrl_offset != -1)
        {
            vgmstream->loop_start_sample = read_32bitLE(mwv_ctrl_offset+12,
                    streamFile);
            vgmstream->loop_end_sample = sample_count;
        }
    }
    else
    {
        vgmstream->meta_type = meta_RIFF_WAVE;
    }

    if (mwv)
    {
        int i, c;
        if (fmt.coding_type == coding_L5_555)
        {
            const int filter_order = 3;
            int filter_count = read_32bitLE(mwv_pflt_offset+12, streamFile);

            if (mwv_pflt_offset == -1 ||
                    read_32bitLE(mwv_pflt_offset+8, streamFile) != filter_order ||
                    read_32bitLE(mwv_pflt_offset+4, streamFile) < 8 + filter_count * 4 * filter_order)
                goto fail;
            if (filter_count > 0x20) goto fail;
            for (c = 0; c < fmt.channel_count; c++)
            {
                for (i = 0; i < filter_count * filter_order; i++)
                {
                    vgmstream->ch[c].adpcm_coef_3by32[i] = read_32bitLE(
                            mwv_pflt_offset+16+i*4, streamFile
                            );
                }
            }
        }
        vgmstream->meta_type = meta_RIFF_WAVE_MWV;
    }

    if (sns)
    {
        int c;
        /* common codebook? */
        static const int16_t coef[16] =
        {0x04ab,0xfced,0x0789,0xfedf,0x09a2,0xfae5,0x0c90,0xfac1,
         0x084d,0xfaa4,0x0982,0xfdf7,0x0af6,0xfafa,0x0be6,0xfbf5};

        for (c = 0; c < fmt.channel_count; c++)
        {
            int i;
            for (i = 0; i < 16; i++)
            {
                vgmstream->ch[c].adpcm_coef[i] = coef[i];
            }
        }
        vgmstream->meta_type = meta_RIFF_WAVE_SNS;
    }

    /* open the file, set up each channel */
    {
        int i;

        vgmstream->ch[0].streamfile = streamFile->open(streamFile,filename,
                STREAMFILE_DEFAULT_BUFFER_SIZE);
        if (!vgmstream->ch[0].streamfile) goto fail;

        for (i=0;i<fmt.channel_count;i++) {
            vgmstream->ch[i].streamfile = vgmstream->ch[0].streamfile;
            vgmstream->ch[i].offset = vgmstream->ch[i].channel_start_offset =
                start_offset+i*fmt.interleave;
        }
    }

    return vgmstream;

    /* clean up anything we may have opened */
fail:
    if (vgmstream) close_vgmstream(vgmstream);
    return NULL;
}
示例#25
0
文件: XBMCVGM.cpp 项目: 1c0n/xbmc
 void __declspec(dllexport) DLL_FreeVGM(long vgm)
 {
   close_vgmstream((VGMSTREAM*)vgm);
 }
示例#26
0
VGMSTREAM * init_vgmstream_rifx(STREAMFILE *streamFile) {
    VGMSTREAM * vgmstream = NULL;
    char filename[260];

    struct riff_fmt_chunk fmt;

    off_t file_size = -1;
    int sample_count = 0;
    int fact_sample_count = -1;
    off_t start_offset = -1;
    off_t wiih_offset = -1;
    uint32_t wiih_size = 0;

    int loop_flag = 0;
    off_t loop_start_offset = -1;
    off_t loop_end_offset = -1;
    uint32_t riff_size;
    uint32_t data_size = 0;

    int FormatChunkFound = 0;
    int DataChunkFound = 0;

    /* check extension, case insensitive */
    streamFile->get_name(streamFile,filename,sizeof(filename));
    if (strcasecmp("wav",filename_extension(filename)) &&
        strcasecmp("lwav",filename_extension(filename)))
    {
        goto fail;
    }

    /* check header */
    if ((uint32_t)read_32bitBE(0,streamFile)!=0x52494658) /* "RIFX" */
        goto fail;
    /* check for WAVE form */
    if ((uint32_t)read_32bitBE(8,streamFile)!=0x57415645) /* "WAVE" */
        goto fail;

    riff_size = read_32bitBE(4,streamFile);
    file_size = get_streamfile_size(streamFile);

    /* check for tructated RIFF */
    if (file_size < riff_size+8) goto fail;

    /* read through chunks to verify format and find metadata */
    {
        off_t current_chunk = 0xc; /* start with first chunk */

        while (current_chunk < file_size && current_chunk < riff_size+8) {
            uint32_t chunk_type = read_32bitBE(current_chunk,streamFile);
            off_t chunk_size = read_32bitBE(current_chunk+4,streamFile);

            if (current_chunk+8+chunk_size > file_size) goto fail;

            switch(chunk_type) {
                case 0x666d7420:    /* "fmt " */
                    /* only one per file */
                    if (FormatChunkFound) goto fail;
                    FormatChunkFound = 1;

                    if (-1 == read_fmt(1, /* big endian == true */
                        streamFile,
                        current_chunk,
                        &fmt,
                        0,  /* sns == false */
                        0)) /* mwv == false */
                        goto fail;

                    break;
                case 0x64617461:    /* data */
                    /* at most one per file */
                    if (DataChunkFound) goto fail;
                    DataChunkFound = 1;

                    start_offset = current_chunk + 8;
                    data_size = chunk_size;
                    break;
                case 0x736D706C:    /* smpl */
                    /* check loop count */
                    if (read_32bitBE(current_chunk+0x24, streamFile)==1)
                    {
                        /* check loop info */
                        if (read_32bitBE(current_chunk+0x2c+4, streamFile)==0)
                        {
                            loop_flag = 1;
                            loop_start_offset =
                                read_32bitBE(current_chunk+0x2c+8, streamFile);
                            loop_end_offset =
                                read_32bitBE(current_chunk+0x2c+0xc,streamFile);
                        }
                    }
                    break;
                case 0x66616374:    /* fact */
                    if (chunk_size != 4) break;
                    fact_sample_count = read_32bitBE(current_chunk+8, streamFile);
                    break;
                case 0x57696948:    /* WiiH */
                    wiih_size = read_32bitBE(current_chunk+4, streamFile);
                    wiih_offset = current_chunk+8;
                    break;
                default:
                    /* ignorance is bliss */
                    break;
            }

            current_chunk += 8+chunk_size;
        }
    }

    if (!FormatChunkFound || !DataChunkFound) goto fail;

    switch (fmt.coding_type) {
        case coding_PCM16BE:
            sample_count = data_size/2/fmt.channel_count;
            break;
        case coding_PCM8_U_int:
            sample_count = data_size/fmt.channel_count;
            break;
        case coding_NGC_DSP:
            /* the only way of getting DSP info right now */
            if (wiih_offset < 0 || wiih_size != 0x2e*fmt.channel_count) goto fail;
            sample_count = data_size/8/fmt.channel_count*14;
            break;
#if 0
        /* found in RE:ORC, looks like it should be MS_IMA instead */
        case coding_MSADPCM:
            sample_count = msadpcm_bytes_to_samples(data_size, fmt.block_size, fmt.channel_count);
            break;
#endif
        default:
            goto fail;
    }

    /* build the VGMSTREAM */

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

    /* fill in the vital statistics */
    vgmstream->num_samples = sample_count;
    vgmstream->sample_rate = fmt.sample_rate;

    vgmstream->coding_type = fmt.coding_type;

    vgmstream->layout_type = layout_none;
    if (fmt.channel_count > 1) {
        switch (fmt.coding_type) {
            case coding_PCM8_U_int:
            case coding_MS_IMA:
            case coding_MSADPCM:
                // use layout_none from above
                break;
            default:
                vgmstream->layout_type = layout_interleave;
                break;
        }
    }

    vgmstream->interleave_block_size = fmt.interleave;
    switch (fmt.coding_type) {
        case coding_MSADPCM:
        case coding_MS_IMA:
            // override interleave_block_size with frame size
            vgmstream->interleave_block_size = fmt.block_size;
            break;
        default:
            // use interleave from above
            break;
    }

    if (fmt.coding_type == coding_MS_IMA)
        vgmstream->interleave_block_size = fmt.block_size;

    if (loop_flag) {
        if (loop_start_offset >= 0)
        {
            vgmstream->loop_start_sample = loop_start_offset;
            vgmstream->loop_end_sample = loop_end_offset;
            vgmstream->meta_type = meta_RIFX_WAVE_smpl;
        }
    }
    else
    {
        vgmstream->meta_type = meta_RIFX_WAVE;
    }

    /* read from WiiH */
    if (wiih_offset >= 0) {
        int i,j;
        for (i=0;i<fmt.channel_count;i++) {
            for (j=0;j<16;j++)
                vgmstream->ch[i].adpcm_coef[j] = read_16bitBE(wiih_offset + i * 0x2e + j * 2,streamFile);
            vgmstream->ch[i].adpcm_history1_16 = read_16bitBE(wiih_offset + i * 0x2e + 0x24,streamFile);
            vgmstream->ch[i].adpcm_history2_16 = read_16bitBE(wiih_offset + i * 0x2e + 0x26,streamFile);
        }
    }

    /* open the file, set up each channel */
    {
        int i;

        vgmstream->ch[0].streamfile = streamFile->open(streamFile,filename,
                STREAMFILE_DEFAULT_BUFFER_SIZE);
        if (!vgmstream->ch[0].streamfile) goto fail;

        for (i=0;i<fmt.channel_count;i++) {
            vgmstream->ch[i].streamfile = vgmstream->ch[0].streamfile;
            vgmstream->ch[i].offset = vgmstream->ch[i].channel_start_offset =
                start_offset+i*fmt.interleave;
        }
    }

    return vgmstream;

    /* clean up anything we may have opened */
fail:
    if (vgmstream) close_vgmstream(vgmstream);
    return NULL;
}
示例#27
0
文件: aix.c 项目: 9a3eedi/Droidsound
VGMSTREAM * init_vgmstream_aix(STREAMFILE *streamFile) {
    
	VGMSTREAM * vgmstream = NULL;
    STREAMFILE * streamFileAIX = NULL;
    STREAMFILE * streamFileADX = NULL;
    char filename[260];
    off_t *segment_offset = NULL;
    int32_t *samples_in_segment = NULL;
    int32_t sample_count;

    int loop_flag = 0;
    int32_t loop_start_sample=0;
    int32_t loop_end_sample=0;

    aix_codec_data *data = NULL;

    off_t first_AIXP;
    off_t stream_list_offset;
    off_t stream_list_end;
    const int segment_list_entry_size = 0x10;
    const off_t segment_list_offset = 0x20;

    int stream_count,channel_count,segment_count;
    int sample_rate;

	int i;

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

    if (read_32bitBE(0x0,streamFile) != 0x41495846 ||   /* "AIXF" */
            read_32bitBE(0x08,streamFile) != 0x01000014 ||
            read_32bitBE(0x0c,streamFile) != 0x00000800)
        goto fail;

    first_AIXP = read_32bitBE(0x4,streamFile)+8;
    segment_count = (uint16_t)read_16bitBE(0x18,streamFile);
    stream_list_offset = segment_list_offset+segment_list_entry_size*segment_count+0x10;

    if (stream_list_offset >= first_AIXP)
        goto fail;
    if (segment_count < 1)
        goto fail;

    sample_rate = read_32bitBE(stream_list_offset+8,streamFile);
    if (!check_sample_rate(sample_rate))
        goto fail;

    samples_in_segment = calloc(segment_count,sizeof(int32_t));
    if (!samples_in_segment)
        goto fail;
    segment_offset = calloc(segment_count,sizeof(off_t));
    if (!segment_offset)
        goto fail;

    for (i = 0; i < segment_count; i++)
    {
        segment_offset[i] = read_32bitBE(segment_list_offset+segment_list_entry_size*i+0,streamFile);
        samples_in_segment[i] = read_32bitBE(segment_list_offset+segment_list_entry_size*i+0x08,streamFile);
        /*printf("samples_in_segment[%d]=%d\n",i,samples_in_segment[i]);*/
        /* all segments must have equal sample rate */
        if (read_32bitBE(segment_list_offset+segment_list_entry_size*i+0x0c,streamFile) != sample_rate)
        {
            /* segments > 0 can have 0 sample rate (Ryu ga gotoku: Kenzan! tenkei_sng1.aix),
               seems to indicate same sample rate as first */
            if (!(i > 0 && read_32bitBE(segment_list_offset+segment_list_entry_size*i+0x0c,streamFile) == 0))
                goto fail;
        }
    }

    if (segment_offset[0] != first_AIXP)
        goto fail;

    stream_count = (uint8_t)read_8bit(stream_list_offset,streamFile);
    if (stream_count < 1)
        goto fail;
    stream_list_end = stream_list_offset + 0x8 + stream_count * 8;

    if (stream_list_end >= first_AIXP)
        goto fail;

    channel_count = 0;
    for (i = 0; i < stream_count; i++)
    {
        /* all streams must have same samplerate as segments */
        if (read_32bitBE(stream_list_offset+8+i*8,streamFile)!=sample_rate)
            goto fail;
        channel_count += read_8bit(stream_list_offset+8+i*8+4,streamFile);
    }

    /* check for existence of segments */
    for (i = 0; i < segment_count; i++)
    {
        int j;
        off_t AIXP_offset = segment_offset[i];
        for (j = 0; j < stream_count; j++)
        {
            if (read_32bitBE(AIXP_offset,streamFile)!=0x41495850) /* "AIXP" */
                goto fail;
            if (read_8bit(AIXP_offset+8,streamFile)!=j)
                goto fail;
            AIXP_offset += read_32bitBE(AIXP_offset+4,streamFile)+8;
        }
    }

    /*streamFileAIX = streamFile->open(streamFile,filename,sample_rate*0.0375*2/32*18segment_count);*/
    streamFileAIX = streamFile->open(streamFile,filename,sample_rate*0.1*segment_count);
    if (!streamFileAIX) goto fail;

    data = malloc(sizeof(aix_codec_data));
    if (!data) goto fail;
    data->segment_count = segment_count;
    data->stream_count = stream_count;
    data->adxs = malloc(sizeof(STREAMFILE *)*segment_count*stream_count);
    if (!data->adxs) goto fail;
    for (i=0;i<segment_count*stream_count;i++) {
        data->adxs[i] = NULL;
    }
    data->sample_counts = calloc(segment_count,sizeof(int32_t));
    if (!data->sample_counts) goto fail;
    memcpy(data->sample_counts,samples_in_segment,segment_count*sizeof(int32_t));

    /* for each segment */
    for (i = 0; i < segment_count; i++)
    {
        int j;
        /* for each stream */
        for (j = 0; j < stream_count; j++)
        {
            VGMSTREAM *adx;
            /*printf("try opening segment %d/%d stream %d/%d %x\n",i,segment_count,j,stream_count,segment_offset[i]);*/
            streamFileADX = open_aix_with_STREAMFILE(streamFileAIX,segment_offset[i],j);
            if (!streamFileADX) goto fail;
            adx = data->adxs[i*stream_count+j] = init_vgmstream_adx(streamFileADX);
            if (!adx)
                goto fail;
            close_streamfile(streamFileADX); streamFileADX = NULL;

            if (adx->num_samples != data->sample_counts[i] ||
                    adx->loop_flag != 0)
                goto fail;

            /* save start things so we can restart for seeking/looping */
            /* copy the channels */
            memcpy(adx->start_ch,adx->ch,sizeof(VGMSTREAMCHANNEL)*adx->channels);
            /* copy the whole VGMSTREAM */
            memcpy(adx->start_vgmstream,adx,sizeof(VGMSTREAM));

        }
    }

    if (segment_count > 1)
    {
        loop_flag = 1;
    }

    sample_count = 0;
    for (i = 0; i < segment_count; i++)
    {
        sample_count += data->sample_counts[i];

        if (i == 0)
            loop_start_sample = sample_count;
        if (i == 1)
            loop_end_sample = sample_count;
    }

    vgmstream = allocate_vgmstream(channel_count,loop_flag);

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

    vgmstream->loop_start_sample = loop_start_sample;
    vgmstream->loop_end_sample = loop_end_sample;

    vgmstream->coding_type = data->adxs[0]->coding_type;
    vgmstream->layout_type = layout_aix;
    vgmstream->meta_type = meta_AIX;

    vgmstream->ch[0].streamfile = streamFileAIX;
    data->current_segment = 0;

    vgmstream->codec_data = data;
    free(segment_offset);
    free(samples_in_segment);

    return vgmstream;

    /* clean up anything we may have opened */
fail:
    if (streamFileAIX) close_streamfile(streamFileAIX);
    if (streamFileADX) close_streamfile(streamFileADX);
    if (vgmstream) close_vgmstream(vgmstream);
    if (samples_in_segment) free(samples_in_segment);
    if (segment_offset) free(segment_offset);
    if (data) {
        if (data->adxs)
        {
            int i;
            for (i=0;i<data->segment_count*data->stream_count;i++)
                if (data->adxs)
                    close_vgmstream(data->adxs[i]);
            free(data->adxs);
        }
        if (data->sample_counts)
        {
            free(data->sample_counts);
        }
        free(data);
    }
    return NULL;
}
示例#28
0
/* XNBm (Windows 7 Phone) */
VGMSTREAM * init_vgmstream_xnbm(STREAMFILE *streamFile) {
    VGMSTREAM * vgmstream = NULL;
    char filename[260];

    struct riff_fmt_chunk fmt;

    off_t file_size = -1;
    int sample_count = 0;
    off_t start_offset = -1;

    int loop_flag = 0;
#if 0
    long loop_start_ms = -1;
    long loop_end_ms = -1;
    off_t loop_start_offset = -1;
    off_t loop_end_offset = -1;
#endif

    uint32_t xnbm_size;
    uint32_t data_size = 0;

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

    /* check header */
    if ((uint32_t)read_32bitBE(0,streamFile)!=0x584E426d) /* "XNBm" */
        goto fail;
    /* check version? */
    if ((uint32_t)read_16bitLE(4,streamFile)!=5)
        goto fail;

    xnbm_size = read_32bitLE(6,streamFile);
    file_size = get_streamfile_size(streamFile);

    /* check for tructated XNBm */
    if (file_size < xnbm_size) goto fail;

    /* read through chunks to verify format and find metadata */
    {
        off_t current_chunk = 0xa; /* start with first chunk */
        int id_string_len;
        uint32_t fmt_chunk_size;

        /* flag? count of strings? */
        if (read_8bit(current_chunk ++, streamFile) != 1)
            goto fail;

        /* string length */
        id_string_len = read_8bit(current_chunk ++, streamFile);

        /* skip string */
        /* may want to check this ID "Microsoft.Xna.Framework.Content.SoundEffectReader" */
        current_chunk += id_string_len;

        /* ???? */
        if (read_32bitLE(current_chunk, streamFile) != 0)
            goto fail;
        current_chunk += 4;

        /* ???? */
        if (read_8bit(current_chunk ++, streamFile) != 0)
            goto fail;

        /* flag? count of chunks? */
        if (read_8bit(current_chunk++, streamFile) != 1)
            goto fail;

        /* fmt size */
        fmt_chunk_size = read_32bitLE(current_chunk, streamFile);
        current_chunk += 4;

        if (-1 == read_fmt(0, /* big endian == false */
                  streamFile,
                  current_chunk-8,  /* read_fmt() expects to skip "fmt "+size */
                  &fmt,
                  0,    /* sns == false */
                  0))   /* mwv == false */
                  goto fail;

        current_chunk += fmt_chunk_size;

        /* data size! */
        data_size = read_32bitLE(current_chunk, streamFile);
        current_chunk += 4;

        start_offset = current_chunk;
    }

    switch (fmt.coding_type) {
        case coding_PCM16LE:
            sample_count = data_size/2/fmt.channel_count;
            break;
        case coding_PCM8_U_int:
            sample_count = data_size/fmt.channel_count;
            break;
        case coding_MSADPCM:
            sample_count = msadpcm_bytes_to_samples(data_size, fmt.block_size, fmt.channel_count);
            break;
        case coding_MS_IMA:
            sample_count = (data_size / fmt.block_size) * (fmt.block_size - 4 * fmt.channel_count) * 2 / fmt.channel_count +
                ((data_size % fmt.block_size) ? (data_size % fmt.block_size - 4 * fmt.channel_count) * 2 / fmt.channel_count : 0);
            break;
        default:
            goto fail;
    }

    /* build the VGMSTREAM */

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

    /* fill in the vital statistics */
    vgmstream->num_samples = sample_count;
    vgmstream->sample_rate = fmt.sample_rate;

    vgmstream->coding_type = fmt.coding_type;

    vgmstream->layout_type = layout_none;
    if (fmt.channel_count > 1) {
        switch (fmt.coding_type) {
            case coding_PCM8_U_int:
            case coding_MS_IMA:
            case coding_MSADPCM:
                // use layout_none from above
                break;
            default:
                vgmstream->layout_type = layout_interleave;
                break;
        }
    }

    vgmstream->interleave_block_size = fmt.interleave;
    switch (fmt.coding_type) {
        case coding_MSADPCM:
        case coding_MS_IMA:
            // override interleave_block_size with frame size
            vgmstream->interleave_block_size = fmt.block_size;
            break;
        default:
            // use interleave from above
            break;
    }

    vgmstream->meta_type = meta_XNBm;

    /* open the file, set up each channel */
    {
        int i;

        vgmstream->ch[0].streamfile = streamFile->open(streamFile,filename,
                STREAMFILE_DEFAULT_BUFFER_SIZE);
        if (!vgmstream->ch[0].streamfile) goto fail;

        for (i=0;i<fmt.channel_count;i++) {
            vgmstream->ch[i].streamfile = vgmstream->ch[0].streamfile;
            vgmstream->ch[i].offset = vgmstream->ch[i].channel_start_offset =
                start_offset+i*fmt.interleave;
        }
    }

    return vgmstream;

    /* clean up anything we may have opened */
fail:
    if (vgmstream) close_vgmstream(vgmstream);
    return NULL;
}
示例#29
0
/* GCUB - found in 'Sega Soccer Slam' */
VGMSTREAM * init_vgmstream_ngc_gcub(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("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;
}
示例#30
0
VGMSTREAM * init_vgmstream_dsp_bdsp(STREAMFILE *streamFile) {

    VGMSTREAM * vgmstream = NULL;
    char filename[260];
    int channel_count;
    int loop_flag;
    int i;
    off_t start_offset;
    
    /* check extension, case insensitive */
    streamFile->get_name(streamFile,filename,sizeof(filename));
    if (strcasecmp("bdsp",filename_extension(filename))) goto fail;

    channel_count = 2;
    loop_flag = 0;

    /* 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(0x8,streamFile);
    vgmstream->coding_type = coding_NGC_DSP;

#if 0
    if(loop_flag) {
        vgmstream->loop_start_sample = read_32bitBE(0x64,streamFile);
        vgmstream->loop_end_sample = read_32bitBE(0x68,streamFile);
    }	
#endif


        vgmstream->layout_type = layout_dsp_bdsp_blocked;
        vgmstream->interleave_block_size = 0x8;
        vgmstream->meta_type = meta_DSP_BDSP;
    
    /* 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(0x1C+i*2,streamFile);
        }
        if (vgmstream->channels == 2) {
            for (i=0;i<16;i++) {
                vgmstream->ch[1].adpcm_coef[i] = read_16bitBE(0x7C+i*2,streamFile);
            }
        }
    }

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

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

    dsp_bdsp_block_update(start_offset,vgmstream);


    return vgmstream;


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