Hi All,
I have found a sample showing how to use AHI to load an MP3 using mpega.library and replay it using AHI but.
This sample is really interesting but I need something smally different.
I need to :
1. Load MP3 and uncompress it in memory.
2. uncompressed MP3 sound can be played at any time.
So it must be 2 separate things.
if I'm not wrong, using the sample, I've made this small function to load the mp3 and uncompress it in memory :
Quote:
// MP3loader using mpega.library.
//
// Include mpega.Library files.
#include "libraries/mpega.h"
#include "Interfaces/mpega.h"
// #include "Proto/mpega.h"
struct Library * MPEGABase = NULL;
struct MpegaIFace * IMpega = NULL;
signed short *outbuf = NULL, *dubbuf = NULL;
MPEGA_STREAM *mps = NULL;
// Ram Buffer
#define PCM_BUFFER_SIZE ( MPEGA_MAX_CHANNELS * MPEGA_PCM_SIZE ) // from mpega.h
#define AHIBUFFERSIZE MPEGA_PCM_SIZE * sizeof( WORD )
#define AHI_BUFFERS 24 // N? of PCM_BUFFER_SIZE to write to AHI
BYTE *mpega_buffer = NULL;
ULONG mpega_buffer_offset = 0;
ULONG mpega_buffer_size = 0;
struct MyMP3Struct{
int IntERROR;
int frame; // global frame counter
WORD i; // global loop counter
LONG pcm_count, total_pcm; // Count current pcm frames and total pcm frames
WORD *pcma[ 2 ]; // Allocate an array of buffers for audio (most likely 2 of them)
WORD *AHIpcmbuf, *AHIpcmdbuf; // pointers to AHI PCM audio buffers.
WORD *pcm0, *pcm1, *pcmLR; // pointers to use to copy to PCM buffers SHOULD HAVE register AT START
long br_sum;
int iCount; // SHOULD HAVE register AT START
MPEGA_CTRL mpa_ctrl;
BOOL terminated;
};
typedef struct MyMP3Struct * NewMP3Struct;
int AmigaSYS_OpenMPEGALibrary( void ){
int Success = 0;
MPEGABase = IExec->OpenLibrary( "mpega.library", 0L );
if ( MPEGABase ){
IMpega = ( struct MpegaIFace *)IExec->GetInterface( MPEGABase, "main", 1, NULL );
if ( IMpega != 0){
Success = 1;
}
}
return Success;
}
void AmigaSYS_CloseMPEGALibrary( void ){
if ( IMpega != 0 ){
IExec->DropInterface( ( struct Interface * )IMpega );
}
if( MPEGABase != 0 ){
IExec->CloseLibrary( MPEGABase );
MPEGABase = NULL;
}
}
void IntSetMPEGOutput( MPEGA_OUTPUT * moutput ){
moutput->freq_div = 1;
moutput->quality = 2;
moutput->freq_max = 48000;
}
void * Internal_LoadMPEGAFile( char * FileName ){
int IntERROR = 0;
NewMP3Struct NewMP3 = malloc( sizeof( NewMP3Struct ) );
NewMP3->frame = 0; // global frame counter
NewMP3->i = 0; // global loop counter
NewMP3->pcm_count = 1;
NewMP3->total_pcm = 0; // Count current pcm frames and total pcm frames
NewMP3->pcma[ 1 ] = NULL;
NewMP3->pcma[ 2 ] = NULL; // Allocate an array of buffers for audio (most likely 2 of them)
NewMP3->AHIpcmbuf = NULL;
NewMP3->AHIpcmdbuf = NULL; // pointers to AHI PCM audio buffers.
NewMP3->pcm0 = NULL;
NewMP3->pcm1 = NULL;
NewMP3->pcmLR = NULL; // pointers to use to copy to PCM buffers
NewMP3->br_sum = 0;
NewMP3->iCount = 0;
NewMP3->terminated = FALSE;
// We define default MPEGA replay parameters.
MPEGA_CTRL * mpa_ctrl = &NewMP3->mpa_ctrl;
mpa_ctrl->bs_access = NULL;
mpa_ctrl->check_mpeg = 0; // Don't check MPEG validity at start (needed for mux stream )
mpa_ctrl->stream_buffer_size = 32768; // Stream buffer size
// We define default MP1/2 replay parameters
MPEGA_LAYER * mpeglayer = &mpa_ctrl->layer_1_2;
mpeglayer->force_mono = FALSE;
IntSetMPEGOutput( &mpeglayer->mono );
IntSetMPEGOutput( &mpeglayer->stereo );
// We define default MP3 replay parameters;
mpeglayer = &mpa_ctrl->layer_3;
mpeglayer->force_mono = FALSE;
IntSetMPEGOutput( &mpeglayer->mono );
IntSetMPEGOutput( &mpeglayer->stereo );
//
if ( MPEGABase == NULL ){
AmigaSYS_OpenMPEGALibrary();
}
if ( MPEGABase != NULL ){
// Allocate PCM BUFFERS
for ( NewMP3->i=0; NewMP3->i < MPEGA_MAX_CHANNELS; NewMP3->i++ ){
NewMP3->pcma[ NewMP3->i ] = malloc( MPEGA_PCM_SIZE * sizeof( WORD ) );
if ( !NewMP3->pcma[ NewMP3->i ] ){
printf( "MP3Loader - Error 2 : Couldn't allocate PCM buffers\n" );
IntERROR = 2;
}
}
NewMP3->AHIpcmbuf = malloc( PCM_BUFFER_SIZE * sizeof( WORD ) * AHI_BUFFERS ) ; // buffer
NewMP3->AHIpcmdbuf = malloc( PCM_BUFFER_SIZE * sizeof( WORD ) * AHI_BUFFERS ) ; // space double buffer
mps = IMpega->MPEGA_open( FileName, &NewMP3->mpa_ctrl );
if ( !mps ){
printf( "MP3Loader - Error 6 : Couldn't find audio stream (file exist ?)\n" );
IntERROR = 6;
}
// Inside the MP3Loader we do not setup AHI. We only load the files and uncompress it in memory.
// Output format in memory is merged LR audio output.
while( !NewMP3->terminated ){
NewMP3->pcmLR = NewMP3->AHIpcmbuf; // We write the uncompressed audiodata in the AHIpcmbuffer.
for ( NewMP3->i = 0 ; NewMP3->i < AHI_BUFFERS; NewMP3->i++){
NewMP3->pcm_count = IMpega->MPEGA_decode_frame( mps, NewMP3->pcma );
// MPEGA_decode_frame returns a number of samples decoded or -1 on error ( or termination )
if ( NewMP3->pcm_count == -1 ){
NewMP3->terminated = TRUE;
break;
}
NewMP3->br_sum += mps->bitrate;
NewMP3->total_pcm += NewMP3->pcm_count;
NewMP3->frame++;
NewMP3->pcm0 = NewMP3->pcma[ 0 ];
NewMP3->pcm1 = NewMP3->pcma[ 1 ];
if ( mps->dec_channels == 2 ){
// Sort audio into proper PCM byte order ( WORD ) L/R/L/R/L/R....
for ( NewMP3->iCount = NewMP3->pcm_count; NewMP3->iCount > 0; NewMP3->iCount-- ){
*NewMP3->pcmLR++ = *NewMP3->pcm0++; // Left channel
*NewMP3->pcmLR++ = *NewMP3->pcm1++; // Right channel
}
}else{
for ( NewMP3->iCount = NewMP3->pcm_count; NewMP3->iCount > 0; NewMP3->iCount-- ){
*NewMP3->pcmLR++ = *NewMP3->pcm0++;
}
}
}
}
// Now that we have copied the decoded PCM audio to buffers, we can send it to AHI when user 'll request it.
}else{
printf( "cannot load .MP3 audio file. Mpega.library not found\n" );
}
return NewMP3;
}
I understand mainly everything in the original sample and my functions but there is something I found illogic. This :
Quote:
NewMP3->AHIpcmbuf = malloc( PCM_BUFFER_SIZE * sizeof( WORD ) * AHI_BUFFERS ) ; // buffer
NewMP3->AHIpcmdbuf = malloc( PCM_BUFFER_SIZE * sizeof( WORD ) * AHI_BUFFERS ) ; // space double buffer
As we don't know the size of the MP3 files and more to this, we don't know the size of uncompressed MP3 audio. How can we setup a static value for pcm buffer ?
Is there a way to know the final size for audio data when uncompressed and then use MPEGA_decode_frame to decode entirely the MP3 file in memory ?
Kindest Regards,
AmiDARK.