mirror of
https://github.com/vgmstream/vgmstream.git
synced 2024-11-28 00:20:47 +01:00
AIX.
git-svn-id: https://vgmstream.svn.sourceforge.net/svnroot/vgmstream@385 51a99a44-fe44-0410-b1ba-c3e57ba2b86b
This commit is contained in:
parent
30c2a4e033
commit
90f0dccd9c
@ -26,7 +26,8 @@ LAYOUT_OBJS=layout/ast_blocked.o \
|
||||
layout/str_snds_blocked.o \
|
||||
layout/ws_aud_blocked.o \
|
||||
layout/interleave_byte.o \
|
||||
layout/mus_acm_layout.o
|
||||
layout/mus_acm_layout.o \
|
||||
layout/aix_layout.o
|
||||
|
||||
META_OBJS=meta/adx_header.o \
|
||||
meta/afc_header.o \
|
||||
@ -108,7 +109,8 @@ META_OBJS=meta/adx_header.o \
|
||||
meta/ps2_vas.o \
|
||||
meta/ps2_tec.o \
|
||||
meta/ps2_enth.o \
|
||||
meta/sdt.o
|
||||
meta/sdt.o \
|
||||
meta/aix.o
|
||||
|
||||
OBJECTS=vgmstream.o streamfile.o util.o $(CODING_OBJS) $(LAYOUT_OBJS) $(META_OBJS)
|
||||
|
||||
|
@ -18,5 +18,6 @@ liblayout_la_SOURCES += str_snds_blocked.c
|
||||
liblayout_la_SOURCES += ws_aud_blocked.c
|
||||
liblayout_la_SOURCES += interleave_byte.c
|
||||
liblayout_la_SOURCES += mus_acm_layout.c
|
||||
liblayout_la_SOURCES += aix_layout.c
|
||||
|
||||
EXTRA_DIST = layout.h
|
||||
|
87
src/layout/aix_layout.c
Normal file
87
src/layout/aix_layout.c
Normal file
@ -0,0 +1,87 @@
|
||||
#include "layout.h"
|
||||
#include "../vgmstream.h"
|
||||
#include "../coding/coding.h"
|
||||
|
||||
void render_vgmstream_aix(sample * buffer, int32_t sample_count, VGMSTREAM * vgmstream) {
|
||||
int samples_written=0;
|
||||
aix_codec_data *data = vgmstream->codec_data;
|
||||
|
||||
while (samples_written<sample_count) {
|
||||
int samples_to_do;
|
||||
int samples_this_block = data->sample_counts[data->current_segment];
|
||||
int current_stream;
|
||||
|
||||
if (vgmstream->loop_flag && vgmstream_do_loop(vgmstream)) {
|
||||
data->current_segment = 1;
|
||||
for (current_stream = 0; current_stream < data->stream_count; current_stream++)
|
||||
{
|
||||
int i;
|
||||
reset_vgmstream(data->adxs[data->current_segment*data->stream_count+current_stream]);
|
||||
|
||||
/* carry over the history from the loop point */
|
||||
for (i=0;i<2;i++)
|
||||
{
|
||||
data->adxs[1*data->stream_count+current_stream]->ch[i].adpcm_history1_32 =
|
||||
data->adxs[0+current_stream]->ch[i].adpcm_history1_32;
|
||||
data->adxs[1*data->stream_count+current_stream]->ch[i].adpcm_history2_32 =
|
||||
data->adxs[0+current_stream]->ch[i].adpcm_history2_32;
|
||||
}
|
||||
}
|
||||
vgmstream->samples_into_block = 0;
|
||||
continue;
|
||||
}
|
||||
|
||||
samples_to_do = vgmstream_samples_to_do(samples_this_block, 1, vgmstream);
|
||||
|
||||
/*printf("samples_to_do=%d,samples_this_block=%d,samples_written=%d,sample_count=%d\n",samples_to_do,samples_this_block,samples_written,sample_count);*/
|
||||
|
||||
if (samples_written+samples_to_do > sample_count)
|
||||
samples_to_do=sample_count-samples_written;
|
||||
|
||||
if (samples_to_do == 0)
|
||||
{
|
||||
int i;
|
||||
data->current_segment++;
|
||||
/*printf("next %d, %d samples\n",data->current_file,data->files[data->current_file]->total_values/data->files[data->current_file]->info.channels);*/
|
||||
for (current_stream = 0; current_stream < data->stream_count; current_stream++)
|
||||
{
|
||||
reset_vgmstream(data->adxs[data->current_segment*data->stream_count+current_stream]);
|
||||
|
||||
/* carry over the history from the previous segment */
|
||||
for (i=0;i<2;i++)
|
||||
{
|
||||
data->adxs[data->current_segment*data->stream_count+current_stream]->ch[i].adpcm_history1_32 =
|
||||
data->adxs[(data->current_segment-1)*data->stream_count+current_stream]->ch[i].adpcm_history1_32;
|
||||
data->adxs[data->current_segment*data->stream_count+current_stream]->ch[i].adpcm_history2_32 =
|
||||
data->adxs[(data->current_segment-1)*data->stream_count+current_stream]->ch[i].adpcm_history2_32;
|
||||
}
|
||||
}
|
||||
vgmstream->samples_into_block = 0;
|
||||
continue;
|
||||
}
|
||||
|
||||
/*printf("decode %d samples file %d\n",samples_to_do,data->current_file);*/
|
||||
if (samples_to_do > AIX_BUFFER_SIZE/2)
|
||||
{
|
||||
samples_to_do = AIX_BUFFER_SIZE/2;
|
||||
}
|
||||
|
||||
for (current_stream = 0; current_stream < data->stream_count; current_stream++)
|
||||
{
|
||||
int i;
|
||||
VGMSTREAM *adx = data->adxs[data->current_segment*data->stream_count+current_stream];
|
||||
|
||||
render_vgmstream(data->buffer,samples_to_do,adx);
|
||||
|
||||
for (i = 0; i < samples_to_do; i++)
|
||||
{
|
||||
buffer[(i+samples_written)*vgmstream->channels+current_stream*2] = data->buffer[i*2];
|
||||
buffer[(i+samples_written)*vgmstream->channels+current_stream*2+1] = data->buffer[i*2+1];
|
||||
}
|
||||
}
|
||||
|
||||
samples_written += samples_to_do;
|
||||
vgmstream->current_sample += samples_to_do;
|
||||
vgmstream->samples_into_block+=samples_to_do;
|
||||
}
|
||||
}
|
@ -32,4 +32,6 @@ void render_vgmstream_interleave_byte(sample * buffer, int32_t sample_count, VGM
|
||||
|
||||
void render_vgmstream_mus_acm(sample * buffer, int32_t sample_count, VGMSTREAM * vgmstream);
|
||||
|
||||
void render_vgmstream_aix(sample * buffer, int32_t sample_count, VGMSTREAM * vgmstream);
|
||||
|
||||
#endif
|
||||
|
@ -218,6 +218,10 @@
|
||||
RelativePath=".\meta\aifc.c"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\meta\aix.c"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\meta\ast.c"
|
||||
>
|
||||
@ -618,6 +622,10 @@
|
||||
<Filter
|
||||
Name="Source Files"
|
||||
>
|
||||
<File
|
||||
RelativePath=".\layout\aix_layout.c"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\layout\ast_blocked.c"
|
||||
>
|
||||
|
@ -85,5 +85,6 @@ libmeta_la_SOURCES += ps2_vas.c
|
||||
libmeta_la_SOURCES += ps2_tec.c
|
||||
libmeta_la_SOURCES += ps2_enth.c
|
||||
libmeta_la_SOURCES += sdt.c
|
||||
libmeta_la_SOURCES += aix.c
|
||||
|
||||
EXTRA_DIST = meta.h
|
||||
|
239
src/meta/aix.c
239
src/meta/aix.c
@ -13,11 +13,29 @@ typedef struct _AIXSTREAMFILE
|
||||
int stream_id;
|
||||
} AIXSTREAMFILE;
|
||||
|
||||
static STREAMFILE *open_aix_with_STREAMFILE(STREAMFILE *file,off_t start_offset,int stream_id);
|
||||
|
||||
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,loop_end_sample;
|
||||
|
||||
aix_codec_data *data = NULL;
|
||||
|
||||
off_t first_AIXP;
|
||||
off_t stream_list_offset;
|
||||
off_t stream_list_end;
|
||||
|
||||
int stream_count,segment_count;
|
||||
int sample_rate;
|
||||
|
||||
int i;
|
||||
|
||||
@ -25,56 +43,193 @@ VGMSTREAM * init_vgmstream_aix(STREAMFILE *streamFile) {
|
||||
streamFile->get_name(streamFile,filename,sizeof(filename));
|
||||
if (strcasecmp("aix",filename_extension(filename))) goto fail;
|
||||
|
||||
streamFileADX = streamFile->open(streamFile,filenameWAV,STREAMFILE_DEFAULT_BUFFER_SIZE);
|
||||
if (!streamFileWAV) {
|
||||
/* try again, ucase */
|
||||
for (i=strlen(filenameWAV);i>=0&&filenameWAV[i]!=DIRSEP;i--)
|
||||
filenameWAV[i]=toupper(filenameWAV[i]);
|
||||
if (read_32bitBE(0x0,streamFile) != 0x41495846 || /* "AIXF" */
|
||||
read_32bitBE(0x08,streamFile) != 0x01000014 ||
|
||||
read_32bitBE(0x0c,streamFile) != 0x00000800)
|
||||
goto fail;
|
||||
|
||||
streamFileWAV = streamFile->open(streamFile,filenameWAV,STREAMFILE_DEFAULT_BUFFER_SIZE);
|
||||
if (!streamFileWAV) goto fail;
|
||||
first_AIXP = read_32bitBE(0x4,streamFile)+8;
|
||||
segment_count = (uint16_t)read_16bitBE(0x18,streamFile);
|
||||
stream_list_offset = 0x20+0x10*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(0x20+0x10*i+0,streamFile);
|
||||
samples_in_segment[i] = read_32bitBE(0x20+0x10*i+0x08,streamFile);
|
||||
/*printf("samples_in_segment[%d]=%d\n",i,samples_in_segment[i]);*/
|
||||
/* all segments must have equal samplerate */
|
||||
if (read_32bitBE(0x20+0x10*i+0x0c,streamFile) != sample_rate)
|
||||
goto fail;
|
||||
}
|
||||
|
||||
/* let the real initer do the parsing */
|
||||
vgmstream = init_vgmstream_riff(streamFileWAV);
|
||||
if (!vgmstream) goto fail;
|
||||
if (segment_offset[0] != first_AIXP)
|
||||
goto fail;
|
||||
|
||||
close_streamfile(streamFileWAV);
|
||||
streamFileWAV = NULL;
|
||||
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;
|
||||
|
||||
/* install loops */
|
||||
if (!vgmstream->loop_flag) {
|
||||
vgmstream->loop_flag = 1;
|
||||
vgmstream->loop_ch = calloc(vgmstream->channels,
|
||||
sizeof(VGMSTREAMCHANNEL));
|
||||
if (!vgmstream->loop_ch) goto fail;
|
||||
if (stream_list_end >= first_AIXP)
|
||||
goto fail;
|
||||
|
||||
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;
|
||||
/* all streams must be stereo */
|
||||
if (read_8bit(stream_list_offset+8+i*8+4,streamFile)!=2)
|
||||
goto fail;
|
||||
}
|
||||
|
||||
vgmstream->loop_start_sample = read_32bitLE(0,streamFile);
|
||||
vgmstream->loop_end_sample = read_32bitLE(4,streamFile);
|
||||
vgmstream->meta_type = meta_RIFF_WAVE_POS;
|
||||
/* 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->channels != 2 ||
|
||||
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(stream_count*2,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 = coding_CRI_ADX;
|
||||
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);
|
||||
|
||||
return vgmstream;
|
||||
|
||||
/* clean up anything we may have opened */
|
||||
fail:
|
||||
if (streamFileWAV) close_streamfile(streamFileWAV);
|
||||
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;
|
||||
}
|
||||
static size_t read_aix(AIXSTREAMFILE *streamfile,uint8_t *dest,off_t offset,size_t length)
|
||||
{
|
||||
size_t sz = 0;
|
||||
|
||||
/*printf("trying to read %x bytes from %x (str%d)\n",length,offset,streamfile->stream_id);*/
|
||||
while (length > 0)
|
||||
{
|
||||
int read_something = 0;
|
||||
|
||||
if (offset >= logical_file_size)
|
||||
{
|
||||
return sz;
|
||||
}
|
||||
|
||||
/* read the beginning of the requested block, if we can */
|
||||
if (offset >= streamfile->current_logical_offset)
|
||||
{
|
||||
@ -135,11 +290,12 @@ static size_t read_aix(AIXSTREAMFILE *streamfile,uint8_t *dest,off_t offset,size
|
||||
|
||||
/* seek ye forwards */
|
||||
while (!found_block) {
|
||||
/*printf("seek looks at %x\n",streamfile->current_physical_offset);*/
|
||||
switch (read_32bitBE(streamfile->current_physical_offset,
|
||||
streamfile->real_file))
|
||||
{
|
||||
case 0x41495850: /* AIXP */
|
||||
if (read_8bitBE(
|
||||
if (read_8bit(
|
||||
streamfile->current_physical_offset+8,
|
||||
streamfile->real_file) ==
|
||||
streamfile->stream_id)
|
||||
@ -154,12 +310,20 @@ static size_t read_aix(AIXSTREAMFILE *streamfile,uint8_t *dest,off_t offset,size
|
||||
{
|
||||
streamfile->current_logical_offset +=
|
||||
streamfile->current_block_size;
|
||||
streamfile->current_physical_offset +=
|
||||
read_32bitBE(
|
||||
streamfile->current_physical_offset+0x04,
|
||||
streamfile->real_file
|
||||
);
|
||||
}
|
||||
else
|
||||
{
|
||||
found_block = 1;
|
||||
}
|
||||
}
|
||||
|
||||
if (!found_block)
|
||||
{
|
||||
streamfile->current_physical_offset +=
|
||||
read_32bitBE(
|
||||
streamfile->current_physical_offset+0x04,
|
||||
streamfile->real_file
|
||||
) + 8;
|
||||
}
|
||||
|
||||
break;
|
||||
@ -196,7 +360,7 @@ static size_t get_offset_aix(AIXSTREAMFILE *streamfile)
|
||||
|
||||
static void get_name_aix(AIXSTREAMFILE *streamfile,char *buffer,size_t length)
|
||||
{
|
||||
strncpy(buffer,length,"ARBITRARY.ADX");
|
||||
strncpy(buffer,"ARBITRARY.ADX",length);
|
||||
buffer[length-1]='\0';
|
||||
}
|
||||
|
||||
@ -210,12 +374,13 @@ static STREAMFILE *open_aix_impl(AIXSTREAMFILE *streamfile,const char * const fi
|
||||
if (!newfile)
|
||||
return NULL;
|
||||
memcpy(newfile,streamfile,sizeof(AIXSTREAMFILE));
|
||||
return newfile;
|
||||
return &newfile->sf;
|
||||
}
|
||||
|
||||
static STREAMFILE *open_aix_with_STREAMFILE(STREAMFILE *file,off_t start_offset,int stream_id);
|
||||
static STREAMFILE *open_aix_with_STREAMFILE(STREAMFILE *file,off_t start_offset,int stream_id)
|
||||
{
|
||||
AIXSTREAMFILE *streamfile = malloc(sizeof(AIXSTREAMFILE));
|
||||
|
||||
if (!streamfile)
|
||||
return NULL;
|
||||
|
||||
@ -234,7 +399,7 @@ static STREAMFILE *open_aix_with_STREAMFILE(STREAMFILE *file,off_t start_offset,
|
||||
#endif
|
||||
|
||||
streamfile->real_file = file;
|
||||
streamfile->current_physicial_offset =
|
||||
streamfile->current_physical_offset =
|
||||
streamfile->start_physical_offset = start_offset;
|
||||
streamfile->current_logical_offset = 0;
|
||||
streamfile->current_block_size = 0;
|
||||
|
@ -183,4 +183,6 @@ VGMSTREAM * init_vgmstream_ps2_enth(STREAMFILE * streamFile);
|
||||
|
||||
VGMSTREAM * init_vgmstream_sdt(STREAMFILE * streamFile);
|
||||
|
||||
VGMSTREAM * init_vgmstream_aix(STREAMFILE * streamFile);
|
||||
|
||||
#endif
|
||||
|
@ -107,6 +107,7 @@ VGMSTREAM * (*init_vgmstream_fcns[])(STREAMFILE *streamFile) = {
|
||||
init_vgmstream_ps2_tec,
|
||||
init_vgmstream_ps2_enth,
|
||||
init_vgmstream_sdt,
|
||||
init_vgmstream_aix,
|
||||
};
|
||||
|
||||
#define INIT_VGMSTREAM_FCNS (sizeof(init_vgmstream_fcns)/sizeof(init_vgmstream_fcns[0]))
|
||||
@ -209,6 +210,17 @@ void reset_vgmstream(VGMSTREAM * vgmstream) {
|
||||
acm_reset(data->files[i]);
|
||||
}
|
||||
}
|
||||
|
||||
if (vgmstream->layout_type==layout_aix) {
|
||||
aix_codec_data *data = vgmstream->codec_data;
|
||||
int i;
|
||||
|
||||
data->current_segment = 0;
|
||||
for (i=0;i<data->segment_count*data->stream_count;i++)
|
||||
{
|
||||
reset_vgmstream(data->adxs[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* simply allocate memory for the VGMSTREAM and its channels */
|
||||
@ -271,28 +283,6 @@ void close_vgmstream(VGMSTREAM * vgmstream) {
|
||||
int i,j;
|
||||
if (!vgmstream) return;
|
||||
|
||||
for (i=0;i<vgmstream->channels;i++) {
|
||||
if (vgmstream->ch[i].streamfile) {
|
||||
close_streamfile(vgmstream->ch[i].streamfile);
|
||||
/* Multiple channels might have the same streamfile. Find the others
|
||||
* that are the same as this and clear them so they won't be closed
|
||||
* again. */
|
||||
for (j=0;j<vgmstream->channels;j++) {
|
||||
if (i!=j && vgmstream->ch[j].streamfile ==
|
||||
vgmstream->ch[i].streamfile) {
|
||||
vgmstream->ch[j].streamfile = NULL;
|
||||
}
|
||||
}
|
||||
vgmstream->ch[i].streamfile = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
if (vgmstream->loop_ch) free(vgmstream->loop_ch);
|
||||
if (vgmstream->start_ch) free(vgmstream->start_ch);
|
||||
if (vgmstream->ch) free(vgmstream->ch);
|
||||
/* the start_vgmstream is considered just data */
|
||||
if (vgmstream->start_vgmstream) free(vgmstream->start_vgmstream);
|
||||
|
||||
#ifdef VGM_USE_VORBIS
|
||||
if (vgmstream->coding_type==coding_ogg_vorbis) {
|
||||
ogg_vorbis_codec_data *data = vgmstream->codec_data;
|
||||
@ -348,6 +338,52 @@ void close_vgmstream(VGMSTREAM * vgmstream) {
|
||||
}
|
||||
}
|
||||
|
||||
if (vgmstream->layout_type==layout_aix) {
|
||||
aix_codec_data *data = vgmstream->codec_data;
|
||||
|
||||
if (data) {
|
||||
if (data->adxs) {
|
||||
int i;
|
||||
for (i=0;i<data->segment_count*data->stream_count;i++) {
|
||||
|
||||
/* note that the AIX close_streamfile won't do anything but
|
||||
* deallocate itself, there is only one open file and that
|
||||
* is in vgmstream->ch[0].streamfile */
|
||||
close_vgmstream(data->adxs[i]);
|
||||
}
|
||||
free(data->adxs);
|
||||
}
|
||||
if (data->sample_counts) {
|
||||
free(data->sample_counts);
|
||||
}
|
||||
|
||||
free(data);
|
||||
}
|
||||
}
|
||||
|
||||
/* now that the special cases have had their chance, clean up the standard items */
|
||||
for (i=0;i<vgmstream->channels;i++) {
|
||||
if (vgmstream->ch[i].streamfile) {
|
||||
close_streamfile(vgmstream->ch[i].streamfile);
|
||||
/* Multiple channels might have the same streamfile. Find the others
|
||||
* that are the same as this and clear them so they won't be closed
|
||||
* again. */
|
||||
for (j=0;j<vgmstream->channels;j++) {
|
||||
if (i!=j && vgmstream->ch[j].streamfile ==
|
||||
vgmstream->ch[i].streamfile) {
|
||||
vgmstream->ch[j].streamfile = NULL;
|
||||
}
|
||||
}
|
||||
vgmstream->ch[i].streamfile = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
if (vgmstream->loop_ch) free(vgmstream->loop_ch);
|
||||
if (vgmstream->start_ch) free(vgmstream->start_ch);
|
||||
if (vgmstream->ch) free(vgmstream->ch);
|
||||
/* the start_vgmstream is considered just data */
|
||||
if (vgmstream->start_vgmstream) free(vgmstream->start_vgmstream);
|
||||
|
||||
free(vgmstream);
|
||||
}
|
||||
|
||||
@ -392,6 +428,9 @@ void render_vgmstream(sample * buffer, int32_t sample_count, VGMSTREAM * vgmstre
|
||||
case layout_mus_acm:
|
||||
render_vgmstream_mus_acm(buffer,sample_count,vgmstream);
|
||||
break;
|
||||
case layout_aix:
|
||||
render_vgmstream_aix(buffer,sample_count,vgmstream);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@ -750,10 +789,10 @@ void decode_vgmstream(VGMSTREAM * vgmstream, int samples_written, int samples_to
|
||||
buffer+samples_written*vgmstream->channels,samples_to_do,
|
||||
vgmstream->channels);
|
||||
break;
|
||||
#endif
|
||||
case coding_ACM:
|
||||
/* handled in its own layout, here to quiet compiler */
|
||||
break;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
@ -1095,6 +1134,9 @@ void describe_vgmstream(VGMSTREAM * vgmstream, char * desc, int length) {
|
||||
case layout_mus_acm:
|
||||
snprintf(temp,TEMPSIZE,"multiple ACM files, ACM blocked");
|
||||
break;
|
||||
case layout_aix:
|
||||
snprintf(temp,TEMPSIZE,"AIX interleave, internally 18-byte interleaved");
|
||||
break;
|
||||
default:
|
||||
snprintf(temp,TEMPSIZE,"INCONCEIVABLE");
|
||||
}
|
||||
@ -1134,6 +1176,9 @@ void describe_vgmstream(VGMSTREAM * vgmstream, char * desc, int length) {
|
||||
case meta_ADX_05:
|
||||
snprintf(temp,TEMPSIZE,"CRI ADX header type 05");
|
||||
break;
|
||||
case meta_AIX:
|
||||
snprintf(temp,TEMPSIZE,"CRI AIX header");
|
||||
break;
|
||||
case meta_DSP_AGSC:
|
||||
snprintf(temp,TEMPSIZE,"Retro Studios AGSC header");
|
||||
break;
|
||||
|
@ -115,6 +115,7 @@ typedef enum {
|
||||
#endif
|
||||
layout_acm, /* dummy, let libacm handle layout */
|
||||
layout_mus_acm, /* mus has multi-files to deal with */
|
||||
layout_aix, /* CRI AIX's wheels within wheels */
|
||||
} layout_t;
|
||||
|
||||
/* The meta type specifies how we know what we know about the file. We may know because of a header we read, some of it may have been guessed from filenames, etc. */
|
||||
@ -147,6 +148,7 @@ typedef enum {
|
||||
meta_ADX_03, /* ADX "type 03" */
|
||||
meta_ADX_04, /* ADX "type 04" */
|
||||
meta_ADX_05, /* ADX "type 05" */
|
||||
meta_AIX, /* CRI AIX */
|
||||
|
||||
/* etc */
|
||||
meta_NGC_ADPDTK, /* NGC DTK/ADP, no header (.adp) */
|
||||
@ -390,6 +392,20 @@ typedef struct {
|
||||
ACMStream **files;
|
||||
} mus_acm_codec_data;
|
||||
|
||||
#define AIX_BUFFER_SIZE 0x1000
|
||||
/* AIXery */
|
||||
typedef struct {
|
||||
sample buffer[AIX_BUFFER_SIZE];
|
||||
int segment_count;
|
||||
int stream_count;
|
||||
int current_segment;
|
||||
/* one per segment */
|
||||
int32_t *sample_counts;
|
||||
/* organized like:
|
||||
* segment1_stream1, segment1_stream2, segment2_stream1, segment2_stream2*/
|
||||
VGMSTREAM **adxs;
|
||||
} aix_codec_data;
|
||||
|
||||
/* do format detection, return pointer to a usable VGMSTREAM, or NULL on failure */
|
||||
VGMSTREAM * init_vgmstream(const char * const filename);
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
export SHELL = /bin/sh
|
||||
export CFLAGS=-Wall -O3
|
||||
export CFLAGS=-Wall -ggdb
|
||||
export LDFLAGS=-lm -L../src -lvgmstream -lvorbisfile -lmpg123
|
||||
export STRIP=strip
|
||||
|
||||
@ -7,7 +7,6 @@ export STRIP=strip
|
||||
|
||||
test: libvgmstream.a test.o
|
||||
$(CC) test.o $(LDFLAGS) $(CFLAGS) -o test
|
||||
$(STRIP) test
|
||||
|
||||
test.o: test.c
|
||||
$(CC) $(CFLAGS) -c "-DVERSION=\"`../version.sh`\"" test.c -o test.o
|
||||
|
@ -102,6 +102,7 @@ gchar *vgmstream_exts [] = {
|
||||
"tec",
|
||||
"enth",
|
||||
"sdt",
|
||||
"aix",
|
||||
/* terminator */
|
||||
NULL
|
||||
};
|
||||
|
@ -166,6 +166,7 @@ char * extension_list[] = {
|
||||
"tec\0TEC Audio File (*.TEC)\0",
|
||||
"enth\0ENTH Audio File (*.ENTH)\0",
|
||||
"sdt\0SDT Audio File (*.SDT)\0",
|
||||
"aix\0AIX Audio File (*.AIX)\0",
|
||||
};
|
||||
|
||||
void about(HWND hwndParent) {
|
||||
|
Loading…
Reference in New Issue
Block a user