Implemented MP4 AAC support for iOS AKB format

This commit is contained in:
Chris Moeller 2012-08-30 05:35:12 -07:00
parent ad3277214e
commit 21bedb985a
12 changed files with 348 additions and 5 deletions

View File

@ -62,7 +62,7 @@
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<ClCompile>
<Optimization>Disabled</Optimization>
<AdditionalIncludeDirectories>../ext_includes;..\..\foobar\foobar2000\SDK;..\..\foobar\foobar2000\helpers;..\..\foobar\foobar2000\ATLHelpers;..\..\foobar\foobar2000\shared;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<AdditionalIncludeDirectories>../ext_includes;..\..\foobar\foobar2000\SDK;..\..\foobar\foobar2000\helpers;..\..\foobar\foobar2000\ATLHelpers;..\..\foobar\foobar2000\shared;../../qaac/mp4v2/include;../../fdk-aac/libSYS/include;../../fdk-aac/libAACdec/include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>WIN32;VGM_USE_G7221;_DEBUG;_WINDOWS;_USRDLL;IN_VGMSTREAM_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<MinimalRebuild>true</MinimalRebuild>
<BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
@ -81,7 +81,7 @@
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<ClCompile>
<AdditionalIncludeDirectories>../ext_includes;..\..\foobar\foobar2000\SDK;..\..\foobar\foobar2000\helpers;..\..\foobar\foobar2000\ATLHelpers;..\..\foobar\foobar2000\shared;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<AdditionalIncludeDirectories>../ext_includes;..\..\foobar\foobar2000\SDK;..\..\foobar\foobar2000\helpers;..\..\foobar\foobar2000\ATLHelpers;..\..\foobar\foobar2000\shared;../../qaac/mp4v2/include;../../fdk-aac/libSYS/include;../../fdk-aac/libAACdec/include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>WIN32;VGM_USE_G7221;NDEBUG;_WINDOWS;_USRDLL;IN_VGMSTREAM_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
<PrecompiledHeader>
@ -114,6 +114,9 @@
<ClCompile Include="in_vgmstream.cpp" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\..\fdk-aac\msvc\fdk-aac.vcxproj">
<Project>{308e2ad5-be31-4770-9441-a8d50f56895c}</Project>
</ProjectReference>
<ProjectReference Include="..\..\foobar\foobar2000\ATLHelpers\foobar2000_ATL_helpers.vcxproj">
<Project>{622e8b19-8109-4717-bd4d-9657aa78363e}</Project>
</ProjectReference>
@ -129,6 +132,9 @@
<ProjectReference Include="..\..\foobar\pfc\pfc.vcxproj">
<Project>{ebfffb4e-261d-44d3-b89c-957b31a0bf9c}</Project>
</ProjectReference>
<ProjectReference Include="..\..\qaac\vcproject\mp4v2\mp4v2.vcxproj">
<Project>{86a064e2-c81b-4eee-8be0-a39a2e7c7c76}</Project>
</ProjectReference>
<ProjectReference Include="..\ext_libs\ext_libs.vcxproj">
<Project>{10e6bfc6-1e5b-46e4-ba42-f04dfbd0abff}</Project>
</ProjectReference>

View File

@ -281,6 +281,7 @@ bool input_vgmstream::g_is_our_path(const char * p_path,const char * p_extension
if(!stricmp_utf8(p_extension,"ahx")) return 1;
if(!stricmp_utf8(p_extension,"aic")) return 1;
if(!stricmp_utf8(p_extension,"aix")) return 1;
if(!stricmp_utf8(p_extension,"akb")) return 1;
if(!stricmp_utf8(p_extension,"amts")) return 1;
if(!stricmp_utf8(p_extension,"as4")) return 1;
if(!stricmp_utf8(p_extension,"asd")) return 1;
@ -599,6 +600,7 @@ DECLARE_MULTIPLE_FILE_TYPE("AGSC Audio File (*.AGSC)", agsc);
DECLARE_MULTIPLE_FILE_TYPE("AHX Audio File (*.AHX)", ahx);
DECLARE_MULTIPLE_FILE_TYPE("AIFC Audio File (*.AIFC)", aifc);
DECLARE_MULTIPLE_FILE_TYPE("AIX Audio File (*.AIX)", aix);
DECLARE_MULTIPLE_FILE_TYPE("AKB Audio File (*.AKB)", akb);
DECLARE_MULTIPLE_FILE_TYPE("AMTS Audio File (*.AMTS)", amts);
DECLARE_MULTIPLE_FILE_TYPE("AS4 Audio File (*.AS4)", as4);
DECLARE_MULTIPLE_FILE_TYPE("ASD Audio File (*.ASD)", asd);

View File

@ -1 +1 @@
#define VERSION "r995"
#define VERSION "r995-1"

View File

@ -71,6 +71,8 @@ void decode_maxis_adpcm(VGMSTREAM * vgmstream, sample * outbuf, int channelspaci
void decode_ogg_vorbis(ogg_vorbis_codec_data * data, sample * outbuf, int32_t samples_to_do, int channels);
#endif
void decode_mp4_aac(mp4_aac_codec_data * data, sample * outbuf, int32_t samples_to_do, int channels);
void decode_sdx2(VGMSTREAMCHANNEL * stream, sample * outbuf, int channelspacing, int32_t first_sample, int32_t samples_to_do);
void decode_sdx2_int(VGMSTREAMCHANNEL * stream, sample * outbuf, int channelspacing, int32_t first_sample, int32_t samples_to_do);
void decode_cbd2(VGMSTREAMCHANNEL * stream, sample * outbuf, int channelspacing, int32_t first_sample, int32_t samples_to_do);

View File

@ -0,0 +1,69 @@
#include "../vgmstream.h"
void decode_mp4_aac(mp4_aac_codec_data * data, sample * outbuf, int32_t samples_to_do, int channels) {
int samples_done = 0;
uint8_t * buffer = NULL;
uint32_t buffer_size;
UINT ubuffer_size, bytes_valid;
CStreamInfo * stream_info = aacDecoder_GetStreamInfo( data->h_aacdecoder );
int32_t samples_remain = data->samples_per_frame - data->sample_ptr;
if ( data->samples_discard ) {
if ( samples_remain <= data->samples_discard ) {
data->samples_discard -= samples_remain;
samples_remain = 0;
}
else {
samples_remain -= data->samples_discard;
data->sample_ptr += data->samples_discard;
data->samples_discard = 0;
}
}
if ( samples_remain > samples_to_do ) samples_remain = samples_to_do;
memcpy( outbuf, data->sample_buffer + data->sample_ptr * stream_info->numChannels, samples_remain * stream_info->numChannels * sizeof(short) );
outbuf += samples_remain * stream_info->numChannels;
data->sample_ptr += samples_remain;
samples_done += samples_remain;
while ( samples_done < samples_to_do ) {
if (!MP4ReadSample( data->h_mp4file, data->track_id, ++data->sampleId, (uint8_t**)(&buffer), (uint32_t*)(&buffer_size), 0, 0, 0, 0)) return;
ubuffer_size = buffer_size;
bytes_valid = buffer_size;
if ( aacDecoder_Fill( data->h_aacdecoder, &buffer, &ubuffer_size, &bytes_valid ) || bytes_valid ) {
free( buffer );
return;
}
if ( aacDecoder_DecodeFrame( data->h_aacdecoder, data->sample_buffer, ( (6) * (2048)*4 ), 0 ) ) {
free( buffer );
return;
}
free( buffer ); buffer = NULL;
stream_info = aacDecoder_GetStreamInfo( data->h_aacdecoder );
samples_remain = data->samples_per_frame = stream_info->frameSize;
data->sample_ptr = 0;
if ( data->samples_discard ) {
if ( samples_remain <= data->samples_discard ) {
data->samples_discard -= samples_remain;
samples_remain = 0;
}
else {
samples_remain -= data->samples_discard;
data->sample_ptr = data->samples_discard;
data->samples_discard = 0;
}
}
if ( samples_remain > samples_to_do - samples_done ) samples_remain = samples_to_do - samples_done;
memcpy( outbuf, data->sample_buffer + data->sample_ptr * stream_info->numChannels, samples_remain * stream_info->numChannels * sizeof(short) );
samples_done += samples_remain;
outbuf += samples_remain * stream_info->numChannels;
data->sample_ptr = samples_remain;
}
}

View File

@ -53,7 +53,7 @@
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<ClCompile>
<Optimization>Disabled</Optimization>
<AdditionalIncludeDirectories>../ext_includes;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<AdditionalIncludeDirectories>../ext_includes;../../qaac/mp4v2/include;../../fdk-aac/libSYS/include;../../fdk-aac/libAACdec/include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>WIN32;VGM_USE_G7221;_DEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<MinimalRebuild>true</MinimalRebuild>
<BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
@ -67,7 +67,7 @@
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<ClCompile>
<AdditionalIncludeDirectories>../ext_includes;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<AdditionalIncludeDirectories>../ext_includes;../../qaac/mp4v2/include;../../fdk-aac/libSYS/include;../../fdk-aac/libAACdec/include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>WIN32;VGM_USE_G7221;NDEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
<PrecompiledHeader>
@ -90,16 +90,19 @@
</ItemGroup>
<ItemGroup>
<ClCompile Include="coding\lsf_decoder.c" />
<ClCompile Include="coding\mp4_aac_decoder.c" />
<ClCompile Include="coding\mtaf_decoder.c" />
<ClCompile Include="layout\ps2_iab_blocked.c" />
<ClCompile Include="layout\ps2_strlr_blocked.c" />
<ClCompile Include="layout\scd_int_layout.c" />
<ClCompile Include="layout\tra_blocked.c" />
<ClCompile Include="meta\akb.c" />
<ClCompile Include="meta\excitebots.c" />
<ClCompile Include="meta\ios_psnd.c" />
<ClCompile Include="meta\lsf.c" />
<ClCompile Include="meta\mattel_hyperscan.c" />
<ClCompile Include="meta\mn_str.c" />
<ClCompile Include="meta\mp4.c" />
<ClCompile Include="meta\ngca.c" />
<ClCompile Include="meta\nub.c" />
<ClCompile Include="meta\pc_adp.c" />

View File

@ -937,5 +937,14 @@
<ClCompile Include="meta\ps3_ivag.c">
<Filter>meta\Source Files</Filter>
</ClCompile>
<ClCompile Include="meta\mp4.c">
<Filter>meta\Source Files</Filter>
</ClCompile>
<ClCompile Include="coding\mp4_aac_decoder.c">
<Filter>coding\Source Files</Filter>
</ClCompile>
<ClCompile Include="meta\akb.c">
<Filter>meta\Source Files</Filter>
</ClCompile>
</ItemGroup>
</Project>

30
src/meta/akb.c Normal file
View File

@ -0,0 +1,30 @@
#include "../vgmstream.h"
#include "meta.h"
VGMSTREAM * init_vgmstream_akb(STREAMFILE *streamFile) {
VGMSTREAM * vgmstream = NULL;
size_t filesize;
uint32_t loop_start, loop_end;
if ((uint32_t)read_32bitBE(0, streamFile) != 0x414b4220) goto fail;
loop_start = read_32bitLE(0x14, streamFile);
loop_end = read_32bitLE(0x18, streamFile);
filesize = get_streamfile_size( streamFile );
vgmstream = init_vgmstream_mp4_aac_offset( streamFile, 0x20, filesize - 0x20 );
if ( !vgmstream ) goto fail;
if ( loop_start || loop_end ) {
vgmstream->loop_flag = 1;
vgmstream->loop_start_sample = loop_start;
vgmstream->loop_end_sample = loop_end;
}
return vgmstream;
fail:
return NULL;
}

View File

@ -107,6 +107,12 @@ VGMSTREAM * init_vgmstream_ogg_vorbis_callbacks(STREAMFILE *streamFile, const ch
VGMSTREAM * init_vgmstream_sli_ogg(STREAMFILE * streamFile);
VGMSTREAM * init_vgmstream_mp4_aac(STREAMFILE * streamFile);
VGMSTREAM * init_vgmstream_mp4_aac_offset(STREAMFILE *streamFile, uint64_t start, uint64_t size);
VGMSTREAM * init_vgmstream_akb(STREAMFILE *streamFile);
VGMSTREAM * init_vgmstream_sfl(STREAMFILE * streamFile);
#endif

149
src/meta/mp4.c Normal file
View File

@ -0,0 +1,149 @@
#include "../vgmstream.h"
#include "meta.h"
#include "../util.h"
void* mp4_file_open( const char* name, MP4FileMode mode )
{
char * endptr;
#ifdef _MSC_VER
unsigned __int64 ptr = _strtoui64( name, &endptr, 16 );
#else
unsigned long ptr = strtoul( name, &endptr, 16 );
#endif
return (void*) ptr;
}
int mp4_file_seek( void* handle, int64_t pos )
{
mp4_streamfile * file = ( mp4_streamfile * ) handle;
if ( pos > file->size ) pos = file->size;
pos += file->start;
file->offset = pos;
return 0;
}
int mp4_file_get_size( void* handle, int64_t* size )
{
mp4_streamfile * file = ( mp4_streamfile * ) handle;
*size = file->size;
return 0;
}
int mp4_file_read( void* handle, void* buffer, int64_t size, int64_t* nin, int64_t maxChunkSize )
{
mp4_streamfile * file = ( mp4_streamfile * ) handle;
int64_t max_size = file->size - file->offset - file->start;
if ( size > max_size ) size = max_size;
*nin = read_streamfile( (uint8_t *) buffer, file->offset, size, file->streamfile );
file->offset += *nin;
return 0;
}
int mp4_file_write( void* handle, const void* buffer, int64_t size, int64_t* nout, int64_t maxChunkSize )
{
return 1;
}
int mp4_file_close( void* handle )
{
return 0;
}
MP4FileProvider mp4_file_provider = { mp4_file_open, mp4_file_seek, mp4_file_get_size, mp4_file_read, mp4_file_write, mp4_file_close };
VGMSTREAM * init_vgmstream_mp4_aac_offset(STREAMFILE *streamFile, uint64_t start, uint64_t size);
VGMSTREAM * init_vgmstream_mp4_aac(STREAMFILE *streamFile) {
return init_vgmstream_mp4_aac_offset( streamFile, 0, streamFile->get_size(streamFile) );
}
VGMSTREAM * init_vgmstream_mp4_aac_offset(STREAMFILE *streamFile, uint64_t start, uint64_t size) {
VGMSTREAM * vgmstream = NULL;
char filename[260];
mp4_aac_codec_data * aac_file = ( mp4_aac_codec_data * ) calloc(1, sizeof(mp4_aac_codec_data));
CStreamInfo * stream_info;
uint8_t * buffer = NULL;
uint32_t buffer_size;
UINT ubuffer_size, bytes_valid;
if ( !aac_file ) goto fail;
aac_file->if_file.streamfile = streamFile;
aac_file->if_file.start = start;
aac_file->if_file.offset = start;
aac_file->if_file.size = size;
/* Big ol' kludge! */
sprintf( filename, "%p", &aac_file->if_file );
aac_file->h_mp4file = MP4ReadProvider( filename, &mp4_file_provider );
if ( !aac_file->h_mp4file ) goto fail;
if ( MP4GetNumberOfTracks(aac_file->h_mp4file, MP4_AUDIO_TRACK_TYPE, '\000') != 1 ) goto fail;
aac_file->track_id = MP4FindTrackId( aac_file->h_mp4file, 0, MP4_AUDIO_TRACK_TYPE, '\000' );
aac_file->h_aacdecoder = aacDecoder_Open( TT_MP4_RAW, 1 );
if ( !aac_file->h_aacdecoder ) goto fail;
aacDecoder_SetParam( aac_file->h_aacdecoder, AAC_PCM_OUTPUT_CHANNELS, 2 );
MP4GetTrackESConfiguration( aac_file->h_mp4file, aac_file->track_id, (uint8_t**)(&aac_file->codec_init_data), (uint32_t*)(&aac_file->codec_init_data_size));
if ( aacDecoder_ConfigRaw( aac_file->h_aacdecoder, &aac_file->codec_init_data, &aac_file->codec_init_data_size ) ) goto fail;
aac_file->sampleId = 1;
aac_file->numSamples = MP4GetTrackNumberOfSamples( aac_file->h_mp4file, aac_file->track_id );
if (!MP4ReadSample(aac_file->h_mp4file, aac_file->track_id, aac_file->sampleId, (uint8_t**)(&buffer), (uint32_t*)(&buffer_size), 0, 0, 0, 0)) goto fail;
ubuffer_size = buffer_size;
bytes_valid = buffer_size;
if ( aacDecoder_Fill( aac_file->h_aacdecoder, &buffer, &ubuffer_size, &bytes_valid ) || bytes_valid ) goto fail;
if ( aacDecoder_DecodeFrame( aac_file->h_aacdecoder, aac_file->sample_buffer, ( (6) * (2048)*4 ), 0 ) ) goto fail;
free( buffer ); buffer = NULL;
aac_file->sample_ptr = 0;
stream_info = aacDecoder_GetStreamInfo( aac_file->h_aacdecoder );
aac_file->samples_per_frame = stream_info->frameSize;
aac_file->samples_discard = 0;
streamFile->get_name( streamFile, filename, sizeof(filename) );
aac_file->if_file.streamfile = streamFile->open(streamFile, filename, STREAMFILE_DEFAULT_BUFFER_SIZE);
if (!aac_file->if_file.streamfile) goto fail;
vgmstream = allocate_vgmstream( stream_info->numChannels, 1 );
if (!vgmstream) goto fail;
vgmstream->loop_flag = 0;
vgmstream->codec_data = aac_file;
vgmstream->channels = stream_info->numChannels;
vgmstream->sample_rate = stream_info->sampleRate;
vgmstream->num_samples = stream_info->frameSize * aac_file->numSamples;
vgmstream->coding_type = coding_MP4_AAC;
vgmstream->layout_type = layout_none;
vgmstream->meta_type = meta_MP4;
return vgmstream;
fail:
if ( buffer ) free( buffer );
if ( aac_file ) {
if ( aac_file->h_aacdecoder ) aacDecoder_Close( aac_file->h_aacdecoder );
if ( aac_file->h_mp4file ) MP4Close( aac_file->h_mp4file, 0 );
if ( aac_file->codec_init_data ) free( aac_file->codec_init_data );
free( aac_file );
}
return NULL;
}

View File

@ -59,6 +59,10 @@ VGMSTREAM * (*init_vgmstream_fcns[])(STREAMFILE *streamFile) = {
init_vgmstream_sli_ogg,
init_vgmstream_sfl,
#endif
#if 0
init_vgmstream_mp4_aac,
#endif
init_vgmstream_akb,
init_vgmstream_sadb,
init_vgmstream_ps2_bmdx,
init_vgmstream_wsi,
@ -414,6 +418,12 @@ void reset_vgmstream(VGMSTREAM * vgmstream) {
ov_pcm_seek(ogg_vorbis_file, 0);
}
#endif
if (vgmstream->coding_type==coding_MP4_AAC) {
mp4_aac_codec_data *data = vgmstream->codec_data;
data->sampleId = 1;
data->sample_ptr = data->samples_per_frame;
data->samples_discard = 0;
}
#ifdef VGM_USE_MPEG
if (vgmstream->layout_type==layout_mpeg ||
vgmstream->layout_type==layout_fake_mpeg) {
@ -576,6 +586,18 @@ void close_vgmstream(VGMSTREAM * vgmstream) {
}
#endif
if (vgmstream->coding_type==coding_MP4_AAC) {
mp4_aac_codec_data *data = vgmstream->codec_data;
if (vgmstream->codec_data) {
if (data->h_aacdecoder) aacDecoder_Close(data->h_aacdecoder);
if (data->h_mp4file) MP4Close(data->h_mp4file, 0);
if (data->if_file.streamfile) close_streamfile(data->if_file.streamfile);
if (data->codec_init_data) free(data->codec_init_data);
free(vgmstream->codec_data);
vgmstream->codec_data = NULL;
}
}
#ifdef VGM_USE_MPEG
if (vgmstream->layout_type==layout_fake_mpeg||
vgmstream->layout_type==layout_mpeg) {
@ -922,6 +944,8 @@ int get_vgmstream_samples_per_frame(VGMSTREAM * vgmstream) {
return 54;
case coding_MTAF:
return 0x80*2;
case coding_MP4_AAC:
return ((mp4_aac_codec_data*)vgmstream->codec_data)->samples_per_frame;
default:
return 0;
}
@ -1289,6 +1313,11 @@ void decode_vgmstream(VGMSTREAM * vgmstream, int samples_written, int samples_to
vgmstream->channels);
break;
#endif
case coding_MP4_AAC:
decode_mp4_aac(vgmstream->codec_data,
buffer+samples_written*vgmstream->channels,samples_to_do,
vgmstream->channels);
break;
case coding_SDX2:
for (chan=0;chan<vgmstream->channels;chan++) {
decode_sdx2(&vgmstream->ch[chan],buffer+samples_written*vgmstream->channels+chan,
@ -1546,6 +1575,16 @@ int vgmstream_do_loop(VGMSTREAM * vgmstream) {
ov_pcm_seek_lap(ogg_vorbis_file, vgmstream->loop_sample);
}
#endif
if (vgmstream->coding_type==coding_MP4_AAC) {
mp4_aac_codec_data *data = (mp4_aac_codec_data *)(vgmstream->codec_data);
data->sampleId = 0;
data->sample_ptr = data->samples_per_frame;
data->samples_discard = vgmstream->loop_sample;
aacDecoder_Close(data->h_aacdecoder);
data->h_aacdecoder = aacDecoder_Open( TT_MP4_RAW, 1 );
aacDecoder_SetParam( data->h_aacdecoder, AAC_PCM_OUTPUT_CHANNELS, 2 );
aacDecoder_ConfigRaw( data->h_aacdecoder, &data->codec_init_data, &data->codec_init_data_size );
}
#ifdef VGM_USE_MPEG
/* won't work for fake MPEG */
if (vgmstream->layout_type==layout_mpeg) {

View File

@ -26,6 +26,12 @@
#ifdef VGM_USE_G7221
#include "g7221.h"
#endif
#define MP4V2_NO_STDINT_DEFS
#include <mp4v2/mp4v2.h>
#include <aacdecoder_lib.h>
#include "coding/acm_decoder.h"
#include "coding/nwa_decoder.h"
@ -126,6 +132,8 @@ typedef enum {
coding_PCM16LE_XOR_int, /* sample-level xor */
coding_LSF, /* lsf ADPCM */
coding_MTAF, /* Konami IMA-derived MTAF ADPCM */
coding_MP4_AAC,
} coding_t;
/* The layout type specifies how the sound data is laid out in the file */
@ -537,6 +545,7 @@ typedef enum {
meta_PS2_HSF, // Lowrider (PS2)
meta_PS3_IVAG, // Interleaved VAG files (PS3)
meta_PS2_2PFS, // Mahoromatic: Moetto - KiraKira Maid-San (PS2)
meta_MP4,
} meta_t;
typedef struct {
@ -751,6 +760,25 @@ typedef struct {
STREAMFILE **intfiles;
} scd_int_codec_data;
typedef struct {
STREAMFILE *streamfile;
uint64_t start;
uint64_t offset;
uint64_t size;
} mp4_streamfile;
typedef struct {
mp4_streamfile if_file;
MP4FileHandle h_mp4file;
MP4TrackId track_id;
unsigned long sampleId, numSamples;
uint8_t * codec_init_data;
UINT codec_init_data_size;
HANDLE_AACDECODER h_aacdecoder;
unsigned int sample_ptr, samples_per_frame, samples_discard;
INT_PCM sample_buffer[( (6) * (2048)*4 )];
} mp4_aac_codec_data;
/* do format detection, return pointer to a usable VGMSTREAM, or NULL on failure */
VGMSTREAM * init_vgmstream(const char * const filename);