mirror of
https://github.com/vgmstream/vgmstream.git
synced 2024-11-24 15:00:11 +01:00
Implemented MP4 AAC support for iOS AKB format
This commit is contained in:
parent
ad3277214e
commit
21bedb985a
@ -62,7 +62,7 @@
|
|||||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||||
<ClCompile>
|
<ClCompile>
|
||||||
<Optimization>Disabled</Optimization>
|
<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>
|
<PreprocessorDefinitions>WIN32;VGM_USE_G7221;_DEBUG;_WINDOWS;_USRDLL;IN_VGMSTREAM_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||||
<MinimalRebuild>true</MinimalRebuild>
|
<MinimalRebuild>true</MinimalRebuild>
|
||||||
<BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
|
<BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
|
||||||
@ -81,7 +81,7 @@
|
|||||||
</ItemDefinitionGroup>
|
</ItemDefinitionGroup>
|
||||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||||
<ClCompile>
|
<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>
|
<PreprocessorDefinitions>WIN32;VGM_USE_G7221;NDEBUG;_WINDOWS;_USRDLL;IN_VGMSTREAM_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||||
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
|
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
|
||||||
<PrecompiledHeader>
|
<PrecompiledHeader>
|
||||||
@ -114,6 +114,9 @@
|
|||||||
<ClCompile Include="in_vgmstream.cpp" />
|
<ClCompile Include="in_vgmstream.cpp" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<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">
|
<ProjectReference Include="..\..\foobar\foobar2000\ATLHelpers\foobar2000_ATL_helpers.vcxproj">
|
||||||
<Project>{622e8b19-8109-4717-bd4d-9657aa78363e}</Project>
|
<Project>{622e8b19-8109-4717-bd4d-9657aa78363e}</Project>
|
||||||
</ProjectReference>
|
</ProjectReference>
|
||||||
@ -129,6 +132,9 @@
|
|||||||
<ProjectReference Include="..\..\foobar\pfc\pfc.vcxproj">
|
<ProjectReference Include="..\..\foobar\pfc\pfc.vcxproj">
|
||||||
<Project>{ebfffb4e-261d-44d3-b89c-957b31a0bf9c}</Project>
|
<Project>{ebfffb4e-261d-44d3-b89c-957b31a0bf9c}</Project>
|
||||||
</ProjectReference>
|
</ProjectReference>
|
||||||
|
<ProjectReference Include="..\..\qaac\vcproject\mp4v2\mp4v2.vcxproj">
|
||||||
|
<Project>{86a064e2-c81b-4eee-8be0-a39a2e7c7c76}</Project>
|
||||||
|
</ProjectReference>
|
||||||
<ProjectReference Include="..\ext_libs\ext_libs.vcxproj">
|
<ProjectReference Include="..\ext_libs\ext_libs.vcxproj">
|
||||||
<Project>{10e6bfc6-1e5b-46e4-ba42-f04dfbd0abff}</Project>
|
<Project>{10e6bfc6-1e5b-46e4-ba42-f04dfbd0abff}</Project>
|
||||||
</ProjectReference>
|
</ProjectReference>
|
||||||
|
@ -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,"ahx")) return 1;
|
||||||
if(!stricmp_utf8(p_extension,"aic")) return 1;
|
if(!stricmp_utf8(p_extension,"aic")) return 1;
|
||||||
if(!stricmp_utf8(p_extension,"aix")) 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,"amts")) return 1;
|
||||||
if(!stricmp_utf8(p_extension,"as4")) return 1;
|
if(!stricmp_utf8(p_extension,"as4")) return 1;
|
||||||
if(!stricmp_utf8(p_extension,"asd")) 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("AHX Audio File (*.AHX)", ahx);
|
||||||
DECLARE_MULTIPLE_FILE_TYPE("AIFC Audio File (*.AIFC)", aifc);
|
DECLARE_MULTIPLE_FILE_TYPE("AIFC Audio File (*.AIFC)", aifc);
|
||||||
DECLARE_MULTIPLE_FILE_TYPE("AIX Audio File (*.AIX)", aix);
|
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("AMTS Audio File (*.AMTS)", amts);
|
||||||
DECLARE_MULTIPLE_FILE_TYPE("AS4 Audio File (*.AS4)", as4);
|
DECLARE_MULTIPLE_FILE_TYPE("AS4 Audio File (*.AS4)", as4);
|
||||||
DECLARE_MULTIPLE_FILE_TYPE("ASD Audio File (*.ASD)", asd);
|
DECLARE_MULTIPLE_FILE_TYPE("ASD Audio File (*.ASD)", asd);
|
||||||
|
@ -1 +1 @@
|
|||||||
#define VERSION "r995"
|
#define VERSION "r995-1"
|
||||||
|
@ -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);
|
void decode_ogg_vorbis(ogg_vorbis_codec_data * data, sample * outbuf, int32_t samples_to_do, int channels);
|
||||||
#endif
|
#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(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_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);
|
void decode_cbd2(VGMSTREAMCHANNEL * stream, sample * outbuf, int channelspacing, int32_t first_sample, int32_t samples_to_do);
|
||||||
|
69
src/coding/mp4_aac_decoder.c
Normal file
69
src/coding/mp4_aac_decoder.c
Normal 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;
|
||||||
|
}
|
||||||
|
}
|
@ -53,7 +53,7 @@
|
|||||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||||
<ClCompile>
|
<ClCompile>
|
||||||
<Optimization>Disabled</Optimization>
|
<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>
|
<PreprocessorDefinitions>WIN32;VGM_USE_G7221;_DEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||||
<MinimalRebuild>true</MinimalRebuild>
|
<MinimalRebuild>true</MinimalRebuild>
|
||||||
<BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
|
<BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
|
||||||
@ -67,7 +67,7 @@
|
|||||||
</ItemDefinitionGroup>
|
</ItemDefinitionGroup>
|
||||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||||
<ClCompile>
|
<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>
|
<PreprocessorDefinitions>WIN32;VGM_USE_G7221;NDEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||||
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
|
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
|
||||||
<PrecompiledHeader>
|
<PrecompiledHeader>
|
||||||
@ -90,16 +90,19 @@
|
|||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ClCompile Include="coding\lsf_decoder.c" />
|
<ClCompile Include="coding\lsf_decoder.c" />
|
||||||
|
<ClCompile Include="coding\mp4_aac_decoder.c" />
|
||||||
<ClCompile Include="coding\mtaf_decoder.c" />
|
<ClCompile Include="coding\mtaf_decoder.c" />
|
||||||
<ClCompile Include="layout\ps2_iab_blocked.c" />
|
<ClCompile Include="layout\ps2_iab_blocked.c" />
|
||||||
<ClCompile Include="layout\ps2_strlr_blocked.c" />
|
<ClCompile Include="layout\ps2_strlr_blocked.c" />
|
||||||
<ClCompile Include="layout\scd_int_layout.c" />
|
<ClCompile Include="layout\scd_int_layout.c" />
|
||||||
<ClCompile Include="layout\tra_blocked.c" />
|
<ClCompile Include="layout\tra_blocked.c" />
|
||||||
|
<ClCompile Include="meta\akb.c" />
|
||||||
<ClCompile Include="meta\excitebots.c" />
|
<ClCompile Include="meta\excitebots.c" />
|
||||||
<ClCompile Include="meta\ios_psnd.c" />
|
<ClCompile Include="meta\ios_psnd.c" />
|
||||||
<ClCompile Include="meta\lsf.c" />
|
<ClCompile Include="meta\lsf.c" />
|
||||||
<ClCompile Include="meta\mattel_hyperscan.c" />
|
<ClCompile Include="meta\mattel_hyperscan.c" />
|
||||||
<ClCompile Include="meta\mn_str.c" />
|
<ClCompile Include="meta\mn_str.c" />
|
||||||
|
<ClCompile Include="meta\mp4.c" />
|
||||||
<ClCompile Include="meta\ngca.c" />
|
<ClCompile Include="meta\ngca.c" />
|
||||||
<ClCompile Include="meta\nub.c" />
|
<ClCompile Include="meta\nub.c" />
|
||||||
<ClCompile Include="meta\pc_adp.c" />
|
<ClCompile Include="meta\pc_adp.c" />
|
||||||
|
@ -937,5 +937,14 @@
|
|||||||
<ClCompile Include="meta\ps3_ivag.c">
|
<ClCompile Include="meta\ps3_ivag.c">
|
||||||
<Filter>meta\Source Files</Filter>
|
<Filter>meta\Source Files</Filter>
|
||||||
</ClCompile>
|
</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>
|
</ItemGroup>
|
||||||
</Project>
|
</Project>
|
30
src/meta/akb.c
Normal file
30
src/meta/akb.c
Normal 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;
|
||||||
|
}
|
@ -107,6 +107,12 @@ VGMSTREAM * init_vgmstream_ogg_vorbis_callbacks(STREAMFILE *streamFile, const ch
|
|||||||
|
|
||||||
VGMSTREAM * init_vgmstream_sli_ogg(STREAMFILE * streamFile);
|
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);
|
VGMSTREAM * init_vgmstream_sfl(STREAMFILE * streamFile);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
149
src/meta/mp4.c
Normal file
149
src/meta/mp4.c
Normal 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;
|
||||||
|
}
|
@ -59,6 +59,10 @@ VGMSTREAM * (*init_vgmstream_fcns[])(STREAMFILE *streamFile) = {
|
|||||||
init_vgmstream_sli_ogg,
|
init_vgmstream_sli_ogg,
|
||||||
init_vgmstream_sfl,
|
init_vgmstream_sfl,
|
||||||
#endif
|
#endif
|
||||||
|
#if 0
|
||||||
|
init_vgmstream_mp4_aac,
|
||||||
|
#endif
|
||||||
|
init_vgmstream_akb,
|
||||||
init_vgmstream_sadb,
|
init_vgmstream_sadb,
|
||||||
init_vgmstream_ps2_bmdx,
|
init_vgmstream_ps2_bmdx,
|
||||||
init_vgmstream_wsi,
|
init_vgmstream_wsi,
|
||||||
@ -414,6 +418,12 @@ void reset_vgmstream(VGMSTREAM * vgmstream) {
|
|||||||
ov_pcm_seek(ogg_vorbis_file, 0);
|
ov_pcm_seek(ogg_vorbis_file, 0);
|
||||||
}
|
}
|
||||||
#endif
|
#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
|
#ifdef VGM_USE_MPEG
|
||||||
if (vgmstream->layout_type==layout_mpeg ||
|
if (vgmstream->layout_type==layout_mpeg ||
|
||||||
vgmstream->layout_type==layout_fake_mpeg) {
|
vgmstream->layout_type==layout_fake_mpeg) {
|
||||||
@ -576,6 +586,18 @@ void close_vgmstream(VGMSTREAM * vgmstream) {
|
|||||||
}
|
}
|
||||||
#endif
|
#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
|
#ifdef VGM_USE_MPEG
|
||||||
if (vgmstream->layout_type==layout_fake_mpeg||
|
if (vgmstream->layout_type==layout_fake_mpeg||
|
||||||
vgmstream->layout_type==layout_mpeg) {
|
vgmstream->layout_type==layout_mpeg) {
|
||||||
@ -922,6 +944,8 @@ int get_vgmstream_samples_per_frame(VGMSTREAM * vgmstream) {
|
|||||||
return 54;
|
return 54;
|
||||||
case coding_MTAF:
|
case coding_MTAF:
|
||||||
return 0x80*2;
|
return 0x80*2;
|
||||||
|
case coding_MP4_AAC:
|
||||||
|
return ((mp4_aac_codec_data*)vgmstream->codec_data)->samples_per_frame;
|
||||||
default:
|
default:
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -1289,6 +1313,11 @@ void decode_vgmstream(VGMSTREAM * vgmstream, int samples_written, int samples_to
|
|||||||
vgmstream->channels);
|
vgmstream->channels);
|
||||||
break;
|
break;
|
||||||
#endif
|
#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:
|
case coding_SDX2:
|
||||||
for (chan=0;chan<vgmstream->channels;chan++) {
|
for (chan=0;chan<vgmstream->channels;chan++) {
|
||||||
decode_sdx2(&vgmstream->ch[chan],buffer+samples_written*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);
|
ov_pcm_seek_lap(ogg_vorbis_file, vgmstream->loop_sample);
|
||||||
}
|
}
|
||||||
#endif
|
#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
|
#ifdef VGM_USE_MPEG
|
||||||
/* won't work for fake MPEG */
|
/* won't work for fake MPEG */
|
||||||
if (vgmstream->layout_type==layout_mpeg) {
|
if (vgmstream->layout_type==layout_mpeg) {
|
||||||
|
@ -26,6 +26,12 @@
|
|||||||
#ifdef VGM_USE_G7221
|
#ifdef VGM_USE_G7221
|
||||||
#include "g7221.h"
|
#include "g7221.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#define MP4V2_NO_STDINT_DEFS
|
||||||
|
#include <mp4v2/mp4v2.h>
|
||||||
|
|
||||||
|
#include <aacdecoder_lib.h>
|
||||||
|
|
||||||
#include "coding/acm_decoder.h"
|
#include "coding/acm_decoder.h"
|
||||||
#include "coding/nwa_decoder.h"
|
#include "coding/nwa_decoder.h"
|
||||||
|
|
||||||
@ -126,6 +132,8 @@ typedef enum {
|
|||||||
coding_PCM16LE_XOR_int, /* sample-level xor */
|
coding_PCM16LE_XOR_int, /* sample-level xor */
|
||||||
coding_LSF, /* lsf ADPCM */
|
coding_LSF, /* lsf ADPCM */
|
||||||
coding_MTAF, /* Konami IMA-derived MTAF ADPCM */
|
coding_MTAF, /* Konami IMA-derived MTAF ADPCM */
|
||||||
|
|
||||||
|
coding_MP4_AAC,
|
||||||
} coding_t;
|
} coding_t;
|
||||||
|
|
||||||
/* The layout type specifies how the sound data is laid out in the file */
|
/* 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_PS2_HSF, // Lowrider (PS2)
|
||||||
meta_PS3_IVAG, // Interleaved VAG files (PS3)
|
meta_PS3_IVAG, // Interleaved VAG files (PS3)
|
||||||
meta_PS2_2PFS, // Mahoromatic: Moetto - KiraKira Maid-San (PS2)
|
meta_PS2_2PFS, // Mahoromatic: Moetto - KiraKira Maid-San (PS2)
|
||||||
|
meta_MP4,
|
||||||
} meta_t;
|
} meta_t;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
@ -751,6 +760,25 @@ typedef struct {
|
|||||||
STREAMFILE **intfiles;
|
STREAMFILE **intfiles;
|
||||||
} scd_int_codec_data;
|
} 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 */
|
/* do format detection, return pointer to a usable VGMSTREAM, or NULL on failure */
|
||||||
VGMSTREAM * init_vgmstream(const char * const filename);
|
VGMSTREAM * init_vgmstream(const char * const filename);
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user