Implemented MP4 AAC support for iOS AKB format

This commit is contained in:
Chris Moeller 2012-08-30 05:35:12 -07:00
parent 5f7f61ace8
commit 0e52bf94d2
5 changed files with 15 additions and 33 deletions

View File

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

View File

@ -1,15 +1,5 @@
#include "../vgmstream.h" #include "../vgmstream.h"
static void convert_samples(INT_PCM * src, sample * dest, int32_t count) {
int32_t i;
for ( i = 0; i < count; i++ ) {
INT_PCM sample = *src++;
sample >>= SAMPLE_BITS - 16;
if ( ( sample + 0x8000 ) & 0xFFFF0000 ) sample = 0x7FFF ^ ( sample >> 31 );
*dest++ = sample;
}
}
void decode_mp4_aac(mp4_aac_codec_data * data, sample * outbuf, int32_t samples_to_do, int channels) { void decode_mp4_aac(mp4_aac_codec_data * data, sample * outbuf, int32_t samples_to_do, int channels) {
int samples_done = 0; int samples_done = 0;
@ -35,7 +25,7 @@ void decode_mp4_aac(mp4_aac_codec_data * data, sample * outbuf, int32_t samples_
if ( samples_remain > samples_to_do ) samples_remain = samples_to_do; if ( samples_remain > samples_to_do ) samples_remain = samples_to_do;
convert_samples( data->sample_buffer + data->sample_ptr * stream_info->numChannels, outbuf, samples_remain * stream_info->numChannels ); memcpy( outbuf, data->sample_buffer + data->sample_ptr * stream_info->numChannels, samples_remain * stream_info->numChannels * sizeof(short) );
outbuf += samples_remain * stream_info->numChannels; outbuf += samples_remain * stream_info->numChannels;
@ -44,10 +34,6 @@ void decode_mp4_aac(mp4_aac_codec_data * data, sample * outbuf, int32_t samples_
samples_done += samples_remain; samples_done += samples_remain;
while ( samples_done < samples_to_do ) { while ( samples_done < samples_to_do ) {
if (data->sampleId >= data->numSamples) {
memset(outbuf, 0, (samples_to_do - samples_done) * stream_info->numChannels * sizeof(sample));
break;
}
if (!MP4ReadSample( data->h_mp4file, data->track_id, ++data->sampleId, (uint8_t**)(&buffer), (uint32_t*)(&buffer_size), 0, 0, 0, 0)) return; 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; ubuffer_size = buffer_size;
bytes_valid = buffer_size; bytes_valid = buffer_size;
@ -75,7 +61,7 @@ void decode_mp4_aac(mp4_aac_codec_data * data, sample * outbuf, int32_t samples_
} }
} }
if ( samples_remain > samples_to_do - samples_done ) samples_remain = samples_to_do - samples_done; if ( samples_remain > samples_to_do - samples_done ) samples_remain = samples_to_do - samples_done;
convert_samples( data->sample_buffer + data->sample_ptr * stream_info->numChannels, outbuf, samples_remain * stream_info->numChannels ); memcpy( outbuf, data->sample_buffer + data->sample_ptr * stream_info->numChannels, samples_remain * stream_info->numChannels * sizeof(short) );
samples_done += samples_remain; samples_done += samples_remain;
outbuf += samples_remain * stream_info->numChannels; outbuf += samples_remain * stream_info->numChannels;
data->sample_ptr = samples_remain; data->sample_ptr = samples_remain;

View File

@ -34,16 +34,8 @@ int mp4_file_read( void* handle, void* buffer, int64_t size, int64_t* nin, int64
mp4_streamfile * file = ( mp4_streamfile * ) handle; mp4_streamfile * file = ( mp4_streamfile * ) handle;
int64_t max_size = file->size - file->offset - file->start; int64_t max_size = file->size - file->offset - file->start;
if ( size > max_size ) size = max_size; if ( size > max_size ) size = max_size;
if ( size > 0 ) *nin = read_streamfile( (uint8_t *) buffer, file->offset, size, file->streamfile );
{ file->offset += *nin;
*nin = read_streamfile( (uint8_t *) buffer, file->offset, size, file->streamfile );
file->offset += *nin;
}
else
{
*nin = 0;
return 1;
}
return 0; return 0;
} }
@ -99,12 +91,9 @@ VGMSTREAM * init_vgmstream_mp4_aac_offset(STREAMFILE *streamFile, uint64_t start
aacDecoder_SetParam( aac_file->h_aacdecoder, AAC_PCM_OUTPUT_CHANNELS, 2 ); aacDecoder_SetParam( aac_file->h_aacdecoder, AAC_PCM_OUTPUT_CHANNELS, 2 );
MP4GetTrackESConfiguration( aac_file->h_mp4file, aac_file->track_id, (uint8_t**)(&buffer), (uint32_t*)(&buffer_size)); MP4GetTrackESConfiguration( aac_file->h_mp4file, aac_file->track_id, (uint8_t**)(&aac_file->codec_init_data), (uint32_t*)(&aac_file->codec_init_data_size));
ubuffer_size = buffer_size; if ( aacDecoder_ConfigRaw( aac_file->h_aacdecoder, &aac_file->codec_init_data, &aac_file->codec_init_data_size ) ) goto fail;
if ( aacDecoder_ConfigRaw( aac_file->h_aacdecoder, &buffer, &ubuffer_size ) ) goto fail;
free( buffer ); buffer = NULL;
aac_file->sampleId = 1; aac_file->sampleId = 1;
aac_file->numSamples = MP4GetTrackNumberOfSamples( aac_file->h_mp4file, aac_file->track_id ); aac_file->numSamples = MP4GetTrackNumberOfSamples( aac_file->h_mp4file, aac_file->track_id );
@ -153,6 +142,7 @@ fail:
if ( aac_file ) { if ( aac_file ) {
if ( aac_file->h_aacdecoder ) aacDecoder_Close( aac_file->h_aacdecoder ); 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->h_mp4file ) MP4Close( aac_file->h_mp4file, 0 );
if ( aac_file->codec_init_data ) free( aac_file->codec_init_data );
free( aac_file ); free( aac_file );
} }
return NULL; return NULL;

View File

@ -420,7 +420,7 @@ void reset_vgmstream(VGMSTREAM * vgmstream) {
#endif #endif
if (vgmstream->coding_type==coding_MP4_AAC) { if (vgmstream->coding_type==coding_MP4_AAC) {
mp4_aac_codec_data *data = vgmstream->codec_data; mp4_aac_codec_data *data = vgmstream->codec_data;
data->sampleId = 0; data->sampleId = 1;
data->sample_ptr = data->samples_per_frame; data->sample_ptr = data->samples_per_frame;
data->samples_discard = 0; data->samples_discard = 0;
} }
@ -592,6 +592,7 @@ void close_vgmstream(VGMSTREAM * vgmstream) {
if (data->h_aacdecoder) aacDecoder_Close(data->h_aacdecoder); if (data->h_aacdecoder) aacDecoder_Close(data->h_aacdecoder);
if (data->h_mp4file) MP4Close(data->h_mp4file, 0); if (data->h_mp4file) MP4Close(data->h_mp4file, 0);
if (data->if_file.streamfile) close_streamfile(data->if_file.streamfile); 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); free(vgmstream->codec_data);
vgmstream->codec_data = NULL; vgmstream->codec_data = NULL;
} }
@ -1579,6 +1580,10 @@ int vgmstream_do_loop(VGMSTREAM * vgmstream) {
data->sampleId = 0; data->sampleId = 0;
data->sample_ptr = data->samples_per_frame; data->sample_ptr = data->samples_per_frame;
data->samples_discard = vgmstream->loop_sample; 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 */

View File

@ -772,6 +772,7 @@ typedef struct {
MP4FileHandle h_mp4file; MP4FileHandle h_mp4file;
MP4TrackId track_id; MP4TrackId track_id;
unsigned long sampleId, numSamples; unsigned long sampleId, numSamples;
uint8_t * codec_init_data;
UINT codec_init_data_size; UINT codec_init_data_size;
HANDLE_AACDECODER h_aacdecoder; HANDLE_AACDECODER h_aacdecoder;
unsigned int sample_ptr, samples_per_frame, samples_discard; unsigned int sample_ptr, samples_per_frame, samples_discard;