MP3 mono like light mp3

Discuss the development of new homebrew software, tools and libraries.

Moderators: cheriff, TyRaNiD

Post Reply
pspflashsystem
Posts: 31
Joined: Mon Mar 24, 2008 12:31 am

MP3 mono like light mp3

Post by pspflashsystem »

Hello everyone,
I want to know how I can play mono mp3 with mp3player.c: Light mp3 can do that so it's possible...
Here the mp3player.c:

Code: Select all

// mp3player.c: MP3 Player Implementation in C for Sony PSP
//
////////////////////////////////////////////////////////////////////////////

#include <pspiofilemgr.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <limits.h>
#include <errno.h>
#include <math.h>
#include <pspaudio.h>
#include "mp3player.h"



#define FALSE 0
#define TRUE !FALSE
#define min&#40;a,b&#41; &#40;&#40;&#40;a&#41;<&#40;b&#41;&#41;?&#40;a&#41;&#58;&#40;b&#41;&#41;
#define max&#40;a,b&#41; &#40;&#40;&#40;a&#41;>&#40;b&#41;&#41;?&#40;a&#41;&#58;&#40;b&#41;&#41;
#define MadErrorString&#40;x&#41; mad_stream_errorstr&#40;x&#41;
#define INPUT_BUFFER_SIZE	&#40;5*8192&#41;
#define OUTPUT_BUFFER_SIZE	2048	/* Must be an integer multiple of 4. */


/* This table represents the subband-domain filter characteristics. It
* is initialized by the ParseArgs&#40;&#41; function and is used as
* coefficients against each subband samples when DoFilter is non-nul.
*/
mad_fixed_t Filter&#91;32&#93;;

/* DoFilter is non-nul when the Filter table defines a filter bank to
* be applied to the decoded audio subbands.
*/
int DoFilter = 0;
/* Define printf, just to make typing easier */
#define printf	pspDebugScreenPrintf

#define NUMCHANNELS 2
u8 *ptr;
long size;
long samplesInOutput = 0;

//////////////////////////////////////////////////////////////////////
// Global local variables
//////////////////////////////////////////////////////////////////////

//libmad lowlevel stuff

// The following variables contain the music data, ie they don't change value until you load a new file
struct mad_stream Stream;
struct mad_frame Frame;
struct mad_synth Synth;
mad_timer_t Timer;
signed short OutputBuffer&#91;OUTPUT_BUFFER_SIZE&#93;;
unsigned char InputBuffer&#91;INPUT_BUFFER_SIZE + MAD_BUFFER_GUARD&#93;,
    *OutputPtr = &#40;unsigned char *&#41; OutputBuffer, *GuardPtr = NULL;
const unsigned char *OutputBufferEnd = &#40;unsigned char *&#41; OutputBuffer + OUTPUT_BUFFER_SIZE * 2;
int Status = 0, i;
unsigned long FrameCount = 0;

// The following variables are maintained and updated by the tracker during playback
static int isPlaying;		// Set to true when a mod is being played

//////////////////////////////////////////////////////////////////////
// These are the public functions
//////////////////////////////////////////////////////////////////////
static int myChannel;
static int eos;

/* Define printf, just to make typing easier */
#define printf	pspDebugScreenPrintf

/*void MP3setStubs&#40;codecStubs * stubs&#41;
&#123;
    stubs->init = MP3_Init;
    stubs->load = MP3_Load;
    stubs->play = MP3_Play;
    stubs->pause = MP3_Pause;
    stubs->stop = MP3_Stop;
    stubs->end = MP3_End;
    stubs->time = MP3_GetTimeString;
    stubs->tick = NULL;
    stubs->eos = MP3_EndOfStream;
    memcpy&#40;stubs->extension, "mp3\0" "\0\0\0\0", 2 * 4&#41;;
&#125;*/

static int PrintFrameInfo&#40;struct mad_header *Header&#41;
&#123;
    const char *Layer, *Mode, *Emphasis;

    /* Convert the layer number to it's printed representation. */
    switch &#40;Header->layer&#41; &#123;
    case MAD_LAYER_I&#58;
	Layer = "I";
	break;
    case MAD_LAYER_II&#58;
	Layer = "II";
	break;
    case MAD_LAYER_III&#58;
	Layer = "III";
	break;
    default&#58;
	Layer = "&#40;unexpected layer value&#41;";
	break;
    &#125;

    /* Convert the audio mode to it's printed representation. */
    switch &#40;Header->mode&#41; &#123;
    case MAD_MODE_SINGLE_CHANNEL&#58;
	Mode = "single channel";
	break;
    case MAD_MODE_DUAL_CHANNEL&#58;
	Mode = "dual channel";
	break;
    case MAD_MODE_JOINT_STEREO&#58;
	Mode = "joint &#40;MS/intensity&#41; stereo";
	break;
    case MAD_MODE_STEREO&#58;
	Mode = "normal LR stereo";
	break;
    default&#58;
	Mode = "&#40;unexpected mode value&#41;";
	break;
    &#125;

    /* Convert the emphasis to it's printed representation. Note that
     * the MAD_EMPHASIS_RESERVED enumeration value appeared in libmad
     * version 0.15.0b.
     */
    switch &#40;Header->emphasis&#41; &#123;
    case MAD_EMPHASIS_NONE&#58;
	Emphasis = "no";
	break;
    case MAD_EMPHASIS_50_15_US&#58;
	Emphasis = "50/15 us";
	break;
    case MAD_EMPHASIS_CCITT_J_17&#58;
	Emphasis = "CCITT J.17";
	break;
#if &#40;MAD_VERSION_MAJOR>=1&#41; || \
  &#40;&#40;MAD_VERSION_MAJOR==0&#41; && &#40;MAD_VERSION_MINOR>=15&#41;&#41;
    case MAD_EMPHASIS_RESERVED&#58;
	Emphasis = "reserved&#40;!&#41;";
	break;
#endif
    default&#58;
	Emphasis = "&#40;unexpected emphasis value&#41;";
	break;
    &#125;
    pspDebugScreenSetXY&#40;0, 29&#41;;
    //printf&#40;"%lu kb/s audio MPEG layer %s stream at %dHz\n", Header->bitrate / 1000, Layer, Header->samplerate&#41;;
    sceDisplayWaitVblankStart&#40;&#41;;
    return &#40;0&#41;;
&#125;

/****************************************************************************
* Applies a frequency-domain filter to audio data in the subband-domain.	*
****************************************************************************/
static void ApplyFilter&#40;struct mad_frame *Frame&#41;
&#123;
    int Channel, Sample, Samples, SubBand;

    /* There is two application loops, each optimized for the number
     * of audio channels to process. The first alternative is for
     * two-channel frames, the second is for mono-audio.
     */
    Samples = MAD_NSBSAMPLES&#40;&Frame->header&#41;;
    if &#40;Frame->header.mode != MAD_MODE_SINGLE_CHANNEL&#41;
	for &#40;Channel = 0; Channel < 2; Channel++&#41;
	    for &#40;Sample = 0; Sample < Samples; Sample++&#41;
		for &#40;SubBand = 0; SubBand < 32; SubBand++&#41;
		    Frame->sbsample&#91;Channel&#93;&#91;Sample&#93;&#91;SubBand&#93; =
			mad_f_mul&#40;Frame->sbsample&#91;Channel&#93;&#91;Sample&#93;&#91;SubBand&#93;, Filter&#91;SubBand&#93;&#41;;
    else
	for &#40;Sample = 0; Sample < Samples; Sample++&#41;
	    for &#40;SubBand = 0; SubBand < 32; SubBand++&#41;
		Frame->sbsample&#91;0&#93;&#91;Sample&#93;&#91;SubBand&#93; = mad_f_mul&#40;Frame->sbsample&#91;0&#93;&#91;Sample&#93;&#91;SubBand&#93;, Filter&#91;SubBand&#93;&#41;;
&#125;

/****************************************************************************
* Converts a sample from libmad's fixed point number format to a signed	*
* short &#40;16 bits&#41;.															*
****************************************************************************/
static signed short MadFixedToSshort&#40;mad_fixed_t Fixed&#41;
&#123;
    /* A fixed point number is formed of the following bit pattern&#58;
     *
     * SWWWFFFFFFFFFFFFFFFFFFFFFFFFFFFF
     * MSB                          LSB
     * S ==> Sign &#40;0 is positive, 1 is negative&#41;
     * W ==> Whole part bits
     * F ==> Fractional part bits
     *
     * This pattern contains MAD_F_FRACBITS fractional bits, one
     * should alway use this macro when working on the bits of a fixed
     * point number. It is not guaranteed to be constant over the
     * different platforms supported by libmad.
     *
     * The signed short value is formed, after clipping, by the least
     * significant whole part bit, followed by the 15 most significant
     * fractional part bits. Warning&#58; this is a quick and dirty way to
     * compute the 16-bit number, madplay includes much better
     * algorithms.
     */

    /* Clipping */
    if &#40;Fixed >= MAD_F_ONE&#41;
	return &#40;SHRT_MAX&#41;;
    if &#40;Fixed <= -MAD_F_ONE&#41;
	return &#40;-SHRT_MAX&#41;;

    /* Conversion. */
    Fixed = Fixed >> &#40;MAD_F_FRACBITS - 15&#41;;
    return &#40;&#40;signed short&#41; Fixed&#41;;
&#125;

static void MP3Callback&#40;void *_buf2, unsigned int numSamples, void *pdata&#41;
&#123;
  short *_buf = &#40;short *&#41;_buf2;
    unsigned long samplesOut = 0;
    //      u8 justStarted = 1;

    if &#40;isPlaying == TRUE&#41; &#123;	//  Playing , so mix up a buffer
	if &#40;samplesInOutput > 0&#41; &#123;
	    //printf&#40;"%d samples in buffer\n", samplesInOutput&#41;;
	    if &#40;samplesInOutput > numSamples&#41; &#123;
		memcpy&#40;&#40;char *&#41; _buf, &#40;char *&#41; OutputBuffer, numSamples * 2 * 2&#41;;
		samplesOut = numSamples;
		samplesInOutput -= numSamples;
	    &#125; else &#123;
		memcpy&#40;&#40;char *&#41; _buf, &#40;char *&#41; OutputBuffer, samplesInOutput * 2 * 2&#41;;
		samplesOut = samplesInOutput;
		samplesInOutput = 0;
	    &#125;
	&#125;
	while &#40;samplesOut < numSamples&#41; &#123;
	    if &#40;Stream.buffer == NULL || Stream.error == MAD_ERROR_BUFLEN&#41; &#123;
		//size_t ReadSize, Remaining;
		//unsigned char *ReadStart;

		/* &#123;2&#125; libmad may not consume all bytes of the input
		 * buffer. If the last frame in the buffer is not wholly
		 * contained by it, then that frame's start is pointed by
		 * the next_frame member of the Stream structure. This
		 * common situation occurs when mad_frame_decode&#40;&#41; fails,
		 * sets the stream error code to MAD_ERROR_BUFLEN, and
		 * sets the next_frame pointer to a non NULL value. &#40;See
		 * also the comment marked &#123;4&#125; bellow.&#41;
		 *
		 * When this occurs, the remaining unused bytes must be
		 * put back at the beginning of the buffer and taken in
		 * account before refilling the buffer. This means that
		 * the input buffer must be large enough to hold a whole
		 * frame at the highest observable bit-rate &#40;currently 448
		 * kb/s&#41;. XXX=XXX Is 2016 bytes the size of the largest
		 * frame? &#40;448000*&#40;1152/32000&#41;&#41;/8
		 */
		/*if&#40;Stream.next_frame!=NULL&#41;
		   &#123;
		   Remaining=Stream.bufend-Stream.next_frame;
		   memmove&#40;InputBuffer,Stream.next_frame,Remaining&#41;;
		   ReadStart=InputBuffer+Remaining;
		   ReadSize=INPUT_BUFFER_SIZE-Remaining;
		   &#125;
		   else
		   ReadSize=INPUT_BUFFER_SIZE,
		   ReadStart=InputBuffer,
		   Remaining=0;
		 */
		/* Fill-in the buffer. If an error occurs print a message
		 * and leave the decoding loop. If the end of stream is
		 * reached we also leave the loop but the return status is
		 * left untouched.
		 */
		//ReadSize=BstdRead&#40;ReadStart,1,ReadSize,BstdFile&#41;;
		//printf&#40;"readsize&#58; %d\n", ReadSize&#41;;
		//sceDisplayWaitVblankStart&#40;&#41;;
		/*if&#40;ReadSize<=0&#41;
		   &#123;
		   //printf&#40;"read error on bit-stream &#40;%s - %d&#41;\n", error_to_string&#40;errno&#41;, errno&#41;;
		   //   Status=1;

		   if&#40;BstdFile->eof&#41; &#123;
		   printf&#40;"end of input stream\n"&#41;;
		   sceDisplayWaitVblankStart&#40;&#41;;
		   &#125;
		   //break;
		   printf&#40;"Readsize was <=0 in player callback\n"&#41;;
		   sceDisplayWaitVblankStart&#40;&#41;;
		   &#125; */

		/* &#123;3&#125; When decoding the last frame of a file, it must be
		 * followed by MAD_BUFFER_GUARD zero bytes if one wants to
		 * decode that last frame. When the end of file is
		 * detected we append that quantity of bytes at the end of
		 * the available data. Note that the buffer can't overflow
		 * as the guard size was allocated but not used the the
		 * buffer management code. &#40;See also the comment marked
		 * &#123;1&#125;.&#41;
		 *
		 * In a message to the mad-dev mailing list on May 29th,
		 * 2001, Rob Leslie explains the guard zone as follows&#58;
		 *
		 *    "The reason for MAD_BUFFER_GUARD has to do with the
		 *    way decoding is performed. In Layer III, Huffman
		 *    decoding may inadvertently read a few bytes beyond
		 *    the end of the buffer in the case of certain invalid
		 *    input. This is not detected until after the fact. To
		 *    prevent this from causing problems, and also to
		 *    ensure the next frame's main_data_begin pointer is
		 *    always accessible, MAD requires MAD_BUFFER_GUARD
		 *    &#40;currently 8&#41; bytes to be present in the buffer past
		 *    the end of the current frame in order to decode the
		 *    frame."
		 */
		/*if&#40;BstdFileEofP&#40;BstdFile&#41;&#41;
		   &#123;
		   GuardPtr=ReadStart+ReadSize;
		   memset&#40;GuardPtr,0,MAD_BUFFER_GUARD&#41;;
		   ReadSize+=MAD_BUFFER_GUARD;
		   &#125; */

		/* Pipe the new buffer content to libmad's stream decoder
		 * facility.
		 */
		mad_stream_buffer&#40;&Stream, ptr, size&#41;;
		Stream.error = 0;
	    &#125;

	    /* Decode the next MPEG frame. The streams is read from the
	     * buffer, its constituents are break down and stored the the
	     * Frame structure, ready for examination/alteration or PCM
	     * synthesis. Decoding options are carried in the Frame
	     * structure from the Stream structure.
	     *
	     * Error handling&#58; mad_frame_decode&#40;&#41; returns a non zero value
	     * when an error occurs. The error condition can be checked in
	     * the error member of the Stream structure. A mad error is
	     * recoverable or fatal, the error status is checked with the
	     * MAD_RECOVERABLE macro.
	     *
	     * &#123;4&#125; When a fatal error is encountered all decoding
	     * activities shall be stopped, except when a MAD_ERROR_BUFLEN
	     * is signaled. This condition means that the
	     * mad_frame_decode&#40;&#41; function needs more input to complete
	     * its work. One shall refill the buffer and repeat the
	     * mad_frame_decode&#40;&#41; call. Some bytes may be left unused at
	     * the end of the buffer if those bytes forms an incomplete
	     * frame. Before refilling, the remaining bytes must be moved
	     * to the beginning of the buffer and used for input for the
	     * next mad_frame_decode&#40;&#41; invocation. &#40;See the comments
	     * marked &#123;2&#125; earlier for more details.&#41;
	     *
	     * Recoverable errors are caused by malformed bit-streams, in
	     * this case one can call again mad_frame_decode&#40;&#41; in order to
	     * skip the faulty part and re-sync to the next frame.
	     */
	    if &#40;mad_frame_decode&#40;&Frame, &Stream&#41;&#41; &#123;
		if &#40;MAD_RECOVERABLE&#40;Stream.error&#41;&#41; &#123;
		    /* Do not print a message if the error is a loss of
		     * synchronization and this loss is due to the end of
		     * stream guard bytes. &#40;See the comments marked &#123;3&#125;
		     * supra for more informations about guard bytes.&#41;
		     */
		    if &#40;Stream.error != MAD_ERROR_LOSTSYNC || Stream.this_frame != GuardPtr&#41; &#123;
			//printf&#40;"recoverable frame level error &#40;%s&#41;\n", MadErrorString&#40;&Stream&#41;&#41;;
			sceDisplayWaitVblankStart&#40;&#41;;
		    &#125;
		    return;	//continue;
		&#125; else if &#40;Stream.error == MAD_ERROR_BUFLEN&#41; &#123;
		    eos = 1;
		    return;	//continue;
		&#125; else &#123;
		    //printf&#40;"unrecoverable frame level error &#40;%s&#41;.\n", MadErrorString&#40;&Stream&#41;&#41;;
		    sceDisplayWaitVblankStart&#40;&#41;;
		    Status = 1;
		    MP3_Stop&#40;&#41;;	//break;
		&#125;
	    &#125;

	    /* The characteristics of the stream's first frame is printed
	     * on stderr. The first frame is representative of the entire
	     * stream.
	     */
	    if &#40;FrameCount == 0&#41;
		if &#40;PrintFrameInfo&#40;&Frame.header&#41;&#41; &#123;
		    Status = 1;
		    //break;
		&#125;

	    /* Accounting. The computed frame duration is in the frame
	     * header structure. It is expressed as a fixed point number
	     * whole data type is mad_timer_t. It is different from the
	     * samples fixed point format and unlike it, it can't directly
	     * be added or subtracted. The timer module provides several
	     * functions to operate on such numbers. Be careful there, as
	     * some functions of libmad's timer module receive some of
	     * their mad_timer_t arguments by value!
	     */
	    FrameCount++;
	    mad_timer_add&#40;&Timer, Frame.header.duration&#41;;

	    /* Between the frame decoding and samples synthesis we can
	     * perform some operations on the audio data. We do this only
	     * if some processing was required. Detailed explanations are
	     * given in the ApplyFilter&#40;&#41; function.
	     */
	    if &#40;DoFilter&#41;
		ApplyFilter&#40;&Frame&#41;;

	    /* Once decoded the frame is synthesized to PCM samples. No errors
	     * are reported by mad_synth_frame&#40;&#41;;
	     */
	    mad_synth_frame&#40;&Synth, &Frame&#41;;

	    /* Synthesized samples must be converted from libmad's fixed
	     * point number to the consumer format. Here we use unsigned
	     * 16 bit big endian integers on two channels. Integer samples
	     * are temporarily stored in a buffer that is flushed when
	     * full.
	     */

	    for &#40;i = 0; i < Synth.pcm.length; i++&#41; &#123;
		signed short Sample;
		//printf&#40;"%d < %d\n", samplesOut, numSamples&#41;;
		if &#40;samplesOut < numSamples&#41; &#123;
		    //printf&#40;"I really get here\n"&#41;;
		    /* Left channel */
		    Sample = MadFixedToSshort&#40;Synth.pcm.samples&#91;0&#93;&#91;i&#93;&#41;;
		    // *&#40;OutputPtr++&#41;=Sample>>8;
		    // *&#40;OutputPtr++&#41;=Sample&0xff;
		    _buf&#91;samplesOut * 2&#93; = Sample;

		    /* Right channel. If the decoded stream is monophonic then
		     * the right output channel is the same as the left one.
		     */
		    if &#40;MAD_NCHANNELS&#40;&Frame.header&#41; == 2&#41;
			Sample = MadFixedToSshort&#40;Synth.pcm.samples&#91;1&#93;&#91;i&#93;&#41;;
		    // *&#40;OutputPtr++&#41;=Sample>>8;
		    // *&#40;OutputPtr++&#41;=Sample&0xff;
		    //_buf&#91;samplesOut*2&#93;=0;//Sample;
		    _buf&#91;samplesOut * 2 + 1&#93; = Sample;
		    samplesOut++;
		&#125; else &#123;
		    //printf&#40;"%d < %d of %d\n", samplesOut, numSamples, Synth.pcm.length&#41;;
		    Sample = MadFixedToSshort&#40;Synth.pcm.samples&#91;0&#93;&#91;i&#93;&#41;;
		    OutputBuffer&#91;samplesInOutput * 2&#93; = Sample;
		    //OutputBuffer&#91;samplesInOutput*4+1&#93;=0;//Sample>>8;
		    //OutputBuffer&#91;samplesInOutput*4+2&#93;=0;//Sample&0xff;
		    if &#40;MAD_NCHANNELS&#40;&Frame.header&#41; == 2&#41;
			Sample = MadFixedToSshort&#40;Synth.pcm.samples&#91;1&#93;&#91;i&#93;&#41;;
		    OutputBuffer&#91;samplesInOutput * 2 + 1&#93; = Sample;
		    //OutputBuffer&#91;samplesInOutput*4+3&#93;=0;//Sample>>8;
		    //OutputBuffer&#91;samplesInOutput*4+4&#93;=0;//Sample&0xff;
		    samplesInOutput++;
		&#125;

	    &#125;
	&#125;
    &#125; else &#123;			//  Not Playing , so clear buffer
	&#123;
	    int count;
	    for &#40;count = 0; count < numSamples * 2; count++&#41;
		*&#40;_buf + count&#41; = 0;
	&#125;
    &#125;
&#125;

void MP3_Init&#40;int channel&#41;
&#123;
    myChannel = channel;
    isPlaying = FALSE;
    pspAudioSetChannelCallback&#40;myChannel, MP3Callback,0&#41;;
    /* First the structures used by libmad must be initialized. */
    mad_stream_init&#40;&Stream&#41;;
    mad_frame_init&#40;&Frame&#41;;
    mad_synth_init&#40;&Synth&#41;;
    mad_timer_reset&#40;&Timer&#41;;
    //ModPlay_Load&#40;"",data&#41;;
&#125;


void MP3_FreeTune&#40;&#41;
&#123;
    /* The input file was completely read; the memory allocated by our
     * reading module must be reclaimed.
     */
    if &#40;ptr&#41;
	free&#40;ptr&#41;;
    //sceIoClose&#40;BstdFile->fd&#41;;
    //BstdFileDestroy&#40;BstdFile&#41;;

    /* Mad is no longer used, the structures that were initialized must
     * now be cleared.
     */
    mad_synth_finish&#40;&Synth&#41;;
    mad_frame_finish&#40;&Frame&#41;;
    mad_stream_finish&#40;&Stream&#41;;

    /* If the output buffer is not empty and no error occurred during
     * the last write, then flush it.
     */
    /*if&#40;OutputPtr!=OutputBuffer && Status!=2&#41;
       &#123;
       size_t       BufferSize=OutputPtr-OutputBuffer;

       if&#40;fwrite&#40;OutputBuffer,1,BufferSize,OutputFp&#41;!=BufferSize&#41;
       &#123;
       fprintf&#40;stderr,"%s&#58; PCM write error &#40;%s&#41;.\n",
       ProgName,strerror&#40;errno&#41;&#41;;
       Status=2;
       &#125;
       &#125; */

    /* Accounting report if no error occurred. */
    if &#40;!Status&#41; &#123;
	char Buffer&#91;80&#93;;

	/* The duration timer is converted to a human readable string
	 * with the versatile, but still constrained mad_timer_string&#40;&#41;
	 * function, in a fashion not unlike strftime&#40;&#41;. The main
	 * difference is that the timer is broken into several
	 * values according some of it's arguments. The units and
	 * fracunits arguments specify the intended conversion to be
	 * executed.
	 *
	 * The conversion unit &#40;MAD_UNIT_MINUTES in our example&#41; also
	 * specify the order and kind of conversion specifications
	 * that can be used in the format string.
	 *
	 * It is best to examine libmad's timer.c source-code for details
	 * of the available units, fraction of units, their meanings,
	 * the format arguments, etc.
	 */
	mad_timer_string&#40;Timer, Buffer, "%lu&#58;%02lu.%03u", MAD_UNITS_MINUTES, MAD_UNITS_MILLISECONDS, 0&#41;;
	//printf&#40;"%lu frames decoded &#40;%s&#41;.\n", FrameCount, Buffer&#41;;
	sceDisplayWaitVblankStart&#40;&#41;;
	sceKernelDelayThread&#40;500000&#41;;
    &#125;
&#125;


void MP3_End&#40;&#41;
&#123;
    MP3_Stop&#40;&#41;;
    pspAudioSetChannelCallback&#40;myChannel, 0,0&#41;;
    MP3_FreeTune&#40;&#41;;
&#125;

//////////////////////////////////////////////////////////////////////
// Functions - Local and not public
//////////////////////////////////////////////////////////////////////

//  This is the initialiser and module loader
//  This is a general call, which loads the module from the 
//  given address into the modplayer
//
//  It basically loads into an internal format, so once this function
//  has returned the buffer at 'data' will not be needed again.
int MP3_Load&#40;char *filename&#41;
&#123;
    int fd;
    eos = 0;
    //psp_stats pstat;
    //sceIoGetstat&#40;filename, &pstat&#41;;
    if &#40;&#40;fd = sceIoOpen&#40;filename, PSP_O_RDONLY, 0777&#41;&#41; > 0&#41; &#123;
	//  opened file, so get size now
	size = sceIoLseek&#40;fd, 0, PSP_SEEK_END&#41;;
	sceIoLseek&#40;fd, 0, PSP_SEEK_SET&#41;;
	ptr = &#40;unsigned char *&#41; malloc&#40;size + 8&#41;;
	memset&#40;ptr, 0, size + 8&#41;;
	if &#40;ptr != 0&#41; &#123;		// Read file in
	    sceIoRead&#40;fd, ptr, size&#41;;
	&#125; else &#123;
	    printf&#40;"Error allocing\n"&#41;;
	    sceIoClose&#40;fd&#41;;
	    return 0;
	&#125;
	// Close file
	sceIoClose&#40;fd&#41;;
    &#125; else &#123;
	return 0;
    &#125;
    //  Set volume to full ready to play
    //SetMasterVolume&#40;64&#41;;
	//valeur modifiée normalement sur FALSE^^ mais utile si on veut pas utiliser MP3_Play^^
    isPlaying = TRUE;
    return 1;
&#125;

// This function initialises for playing, and starts
int MP3_Play&#40;&#41;
&#123;
    // See if I'm already playing
    if &#40;isPlaying&#41;
	return TRUE;

    isPlaying = TRUE;
    return TRUE;
&#125;

void MP3_Pause&#40;&#41;
&#123;
    isPlaying = !isPlaying;
&#125;

int MP3_Stop&#40;&#41;
&#123;
    //stop playing
    isPlaying = FALSE;

    //clear buffer
    memset&#40;OutputBuffer, 0, OUTPUT_BUFFER_SIZE&#41;;
    OutputPtr = &#40;unsigned char *&#41; OutputBuffer;

    //seek to beginning of file
    //sceIoLseek&#40;BstdFile->fd, 0, SEEK_SET&#41;;
	
	//réinitialisation des mp3 pour faire la fonction réelle de stop^^
	mad_stream_init&#40;&Stream&#41;;
    mad_frame_init&#40;&Frame&#41;;
    mad_synth_init&#40;&Synth&#41;;
    mad_timer_reset&#40;&Timer&#41;;

    return TRUE;
&#125;

void MP3_GetTimeString&#40;char *dest&#41;
&#123;
    mad_timer_string&#40;Timer, dest, "%02lu&#58;%02u&#58;%02u", MAD_UNITS_HOURS, MAD_UNITS_MILLISECONDS, 0&#41;;
&#125;

int MP3_EndOfStream&#40;&#41;
&#123;
    if &#40;eos == 1&#41;
	return 1;
    return 0;
&#125;
And here mp3player.h:

Code: Select all

// mp3player.h&#58; headers for psp mp3player code
//
// All public functions for mp3player
//
//////////////////////////////////////////////////////////////////////
#ifndef _MP3PLAYER_H_
#define _MP3PLAYER_H_

#include <mad.h>
//#include "../../codec.h"

#ifdef __cplusplus
extern "C" &#123;
#endif

//  Function prototypes for public functions
//    void MP3setStubs&#40;codecStubs * stubs&#41;;

//private functions
    void MP3_Init&#40;int channel&#41;;
    int MP3_Play&#40;&#41;;
    void MP3_Pause&#40;&#41;;
    int MP3_Stop&#40;&#41;;
    void MP3_End&#40;&#41;;
    void MP3_FreeTune&#40;&#41;;
    int MP3_Load&#40;char *filename&#41;;
    void MP3_GetTimeString&#40;char *dest&#41;;
    int MP3_EndOfStream&#40;&#41;;

#ifdef __cplusplus
&#125;
#endif
#endif
If Sakya read my post: can you help me??


Many thanks to everyone who help me^^
I'm apologize for my bad English because I am French :)

.::pspflashsystem::.
pegasus2000
Posts: 160
Joined: Wed Jul 12, 2006 7:09 am

Re: MP3 mono like light mp3

Post by pegasus2000 »

Code: Select all

include <nanodesktop.h>

struct ndMediaObj_Type ndMediaObj; 
int ErrRep;

int ndMain &#40;&#41;
&#123;
     ndInitSystem &#40;&#41;;

     ErrRep=ndHAL_MEDIA_LoadFile &#40;"MyFile.Mp3", -1, &ndMediaObj, 0, 0&#41;; 

    if &#40;!ErrRep&#41;
    &#123;
    ndHAL_MEDIA_Play &#40;&ndMediaObj, ND_LOCK_UNTIL_SONG_FINISH&#41;; 
    ndHAL_MEDIA_UnLoad &#40;&ndMediaObj&#41;; 
    &#125;
&#125;
pspflashsystem
Posts: 31
Joined: Mon Mar 24, 2008 12:31 am

Post by pspflashsystem »

Nanodesktop is very good I see what it can do: it's fantastic so thank you pegasus2000...
But I want to use the mp3player.c not nanodesktop^^
If an other person have an idea about my problem with the mp3player.c...
I'm apologize for my bad English because I am French :)

.::pspflashsystem::.
pspflashsystem
Posts: 31
Joined: Mon Mar 24, 2008 12:31 am

Post by pspflashsystem »

Any idea plase??
I'm apologize for my bad English because I am French :)

.::pspflashsystem::.
J.F.
Posts: 2906
Joined: Sun Feb 22, 2004 11:41 am

Post by J.F. »

Bumping threads is a sure way to make people NOT answer. Also, playing mono mp3 files is NOT a PSP issue. If you can't figure it out from existing code, you should probably check out more examples before asking about it again.
Post Reply