Login
Username:

Password:

Remember me



Lost Password?

Register now!

Sections

Who's Online
113 user(s) are online (90 user(s) are browsing Forums)

Members: 0
Guests: 113

more...

Headlines

 
  Register To Post  

use mpega.library to load and uncompress MP3 file.
Quite a regular
Quite a regular


See User information
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.

All we have to decide is what to do with the time that is given to us.
Go to top
Re: use mpega.library to load and uncompress MP3 file.
Just can't stay away
Just can't stay away


See User information
@freddix

You have duration of MP3 stream in ms in mps->ms_duration. Knowing this information you should be able to calculate how large a buffer you will need.

Something like:
pcm_buffer_size = ((ms_duration * freq) / 1000 + 1) * channels * sizeof(int16);

As this calculation might not be completely accurate don't expect the buffer to be completely filled, also you should watch out for possibility of buffer overflow when filling it.

Go to top
Re: use mpega.library to load and uncompress MP3 file.
Quite a regular
Quite a regular


See User information
@salass00
Thank you for your explanation
I should be able to create a larger buffer and then when the MP3 is fully uncompressed, I see the size of buffer, create another one, copy the audio to it and delete from memory the larger one...
Otherwise, I can work with this calculation and if buffer overflow, I recalculate a larger buffer ... and continue convertion using larger buffer ...

Kindest Regards,
AmiDARK.

All we have to decide is what to do with the time that is given to us.
Go to top

  Register To Post

 




Currently Active Users Viewing This Thread: 1 ( 0 members and 1 Anonymous Users )




Powered by XOOPS 2.0 © 2001-2023 The XOOPS Project