aboutsummaryrefslogtreecommitdiff
path: root/lib/vgmstream/src/meta/ps2_mic.c
blob: 89a615d2000a0ff7667e3f7fe7bc34b0bae93f52 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
#include "meta.h"
#include "../util.h"

/* MIC

   PS2 MIC format is an interleaved format found in most of KOEI Games                
   The header always start the long value 0x800 which is the start
   of the BGM datas.

   2008-05-15 - Fastelbja : First version ...
*/

VGMSTREAM * init_vgmstream_ps2_mic(STREAMFILE *streamFile) {
    VGMSTREAM * vgmstream = NULL;
    char filename[260];

    int loop_flag=0;
    int channel_count;
    int i;

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

    /* check Header */
    if (read_32bitLE(0x00,streamFile) != 0x800)
        goto fail;

    /* check loop */
    loop_flag = (read_32bitLE(0x14,streamFile)!=1);

    channel_count=read_32bitLE(0x08,streamFile);

    /* 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_32bitLE(0x04,streamFile);

    /* Compression Scheme */
    vgmstream->coding_type = coding_PSX;
    vgmstream->num_samples = read_32bitLE(0x10,streamFile)*14*channel_count;

    /* Get loop point values */
    if(vgmstream->loop_flag) {
        vgmstream->loop_start_sample = read_32bitLE(0x14,streamFile)*14*channel_count;
        vgmstream->loop_end_sample = read_32bitLE(0x10,streamFile)*14*channel_count;
    }

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

    /* 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)(0x800+vgmstream->interleave_block_size*i);
        }
    }

    return vgmstream;

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