?? main.cpp
字號(hào):
// sample mp3 player to demonstrate the usage of the [software] mp3 // decoder.// you can use this code as a base when implementing your own audio// software decoder - this samples sends PCM to the mpeg engine#include <stdio.h>#include <stdlib.h>#include <sys/time.h>#include "mpegdec/mpegdec.h"#include "mpegdec/em85xx.h"#include "mp3/mp3.h"#include "dac/dac.h"#include "mpegdec/myfont.c"#if 0static void debug_break (void){}#define ASSERT(exp) ((void)((exp)?1:(printf ("***ASSERT failed: line %d, file %s\n", __LINE__,__FILE__), debug_break(), 0)))#define DEBUGMSG(cond,printf_exp) ((void)((cond)?(printf printf_exp),1:0))#else#define ASSERT(exp)#define DEBUGMSG(cond,printf_exp)#endif//////////////////////////////////////////////////////////////////////// global datastatic MP3Decoder *pMP3Decoder;static RMuint32 databuffers[1024*1024/4];static BufferPool BPmp3;static BufferPool BPpcm;static RMuint32 *mp3_buffer = (databuffers);static RMuint32 *pcm_buffer = (databuffers+(1024*1024/8));static MpegDecoder *pMpegDecoder;static RMuint32 NumberOfBitsPerSample = 0;static RMuint32 NumberOfChannels = 0;static RMuint32 SamplesPerSecond = 0;static RMuint32 BytesPerSecond = 0;static RMuint32 prebuffering = 0;// end global data////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// file system callbacks required by the mp3 decoderstatic RMuint32 fs_fopen (RMint8 *filename, void *context){ return (RMuint32)fopen (filename, "rb");}static RMuint32 fs_fread (RMuint32 handle, void *buf, RMuint32 length, void *context){ return fread (buf, 1, length, (FILE *)handle);}static RMuint32 fs_fseek (RMuint32 handle, RMuint32 pos, RMuint32 whence, void *context){ return (RMuint32)fseek ((FILE *)handle, pos, whence);}static RMuint32 fs_ftell (RMuint32 handle, void *context){ return (RMuint32)ftell ((FILE *)handle);}static RMuint32 fs_feof (RMuint32 handle, void *context){ return (RMuint32)feof ((FILE *)handle);}static RMuint32 fs_fclose (RMuint32 handle, void *context){ return (RMuint32)fclose ((FILE *)handle);}// end file system callbacks required by mp3 decoder//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// callbacks required by the mp3 decoderRMuint32 my_addref (RMuint8 *pBuffer, void *context){ BufferPool *BP; if ((RMuint32)pBuffer < (RMuint32)pcm_buffer) BP = &BPmp3; else BP = &BPpcm; RMint32 idx = ((RMint32)pBuffer - (RMint32)BP->start_address) / BP->buffers_size; ASSERT (idx >= 0); addref_buffer (&(BP->B[idx])); return 0;}RMuint32 my_release (RMuint8 *pBuffer, void *context){ BufferPool *BP; if ((RMuint32)pBuffer < (RMuint32)pcm_buffer) BP = &BPmp3; else BP = &BPpcm; RMint32 idx = ((RMint32)pBuffer - (RMint32)BP->start_address) / BP->buffers_size; ASSERT (idx >= 0); release_buffer (&(BP->B[idx])); return 0;}// mp3 callback - the mp3 decoder is informing teh application of // some useful mp3 informationstatic RMuint32 mp3_info (RMint32 msg, void *info, void *context){ DEBUGMSG (0, ("mp3_info:\n")); if (msg == MP3_MSG_MP3_DECODE_INFO) { MP3_DECODE_INFO *pInfo = (MP3_DECODE_INFO *)info; if ((pInfo->NumberOfBitsPerSample != NumberOfBitsPerSample) || (pInfo->NumberOfChannels != NumberOfChannels) || (pInfo->SamplesPerSecond != SamplesPerSecond)) { PCM_PARAMETERS pcmparams; pcmparams.NumberOfBitsPerSample = pInfo->NumberOfBitsPerSample; pcmparams.NumberOfChannels = pInfo->NumberOfChannels; pcmparams.SamplesPerSecond = pInfo->SamplesPerSecond; DEBUGMSG (1, ("PCM update:\n")); DEBUGMSG (1, (" NumberOfBitsPerSample: %lu\n", pcmparams.NumberOfBitsPerSample)); DEBUGMSG (1, (" NumberOfChannels: %lu\n", pcmparams.NumberOfChannels)); DEBUGMSG (1, (" SamplesPerSecond: %lu\n", pcmparams.SamplesPerSecond)); pMpegDecoder->SetPCMParameters (&pcmparams); NumberOfBitsPerSample = pInfo->NumberOfBitsPerSample; NumberOfChannels = pInfo->NumberOfChannels; SamplesPerSecond = pInfo->SamplesPerSecond; BytesPerSecond = (NumberOfBitsPerSample / 8) * NumberOfChannels * SamplesPerSecond; if (prebuffering) pMpegDecoder->Pause (); } } return 0;}// mp3 callback - the mp3 decoding object is requesting// the application render some pcm samplesstatic RMuint32 mp3_putPCM (RMuint8 *pBuffer, RMuint32 length, void *context){ BufferPool *BP; BP = &BPpcm; ASSERT ((RMuint32)pBuffer >= (RMuint32)pcm_buffer); ASSERT ((RMuint32)pBuffer >= (RMuint32)BP->start_address); RMint32 idx = ((RMuint32)pBuffer - (RMuint32)BP->start_address) / BP->buffers_size; addref_buffer (&(BP->B[idx])); DEBUGMSG (1, ("mp3_putPCM (%d)\n", idx)); DEBUGMSG (1, ("mp3_putPCM: address = 0x%08lx, length = %d, idx = %d\n", (RMuint32)pBuffer, (RMint32)length, idx)); // no need to send a timestamp when dealing with only PCM samples if (pMpegDecoder->WritePCM (pBuffer, length, &(BP->B[idx]), 0, 0, 0) == MPEG_DECODER_ERROR_NO_ERROR) { ASSERT (BytesPerSecond); return 0; } if (prebuffering) { prebuffering = 0; pMpegDecoder->Play (); } release_buffer (&(BP->B[idx])); return 1;}// mp3 callback - the mp3 decoding object is requesting// the application to provide a buffer to place the decoded// pcm samples intostatic RMuint32 mp3_getPCM (RMuint8 **pBuffer, RMuint32 *plength, void *context){ DEBUGMSG (0, ("mp3wma_getPCM\n")); int idx = find_free_buffer (&BPpcm, 0); if (idx < 0) { if (prebuffering) { prebuffering = 0; pMpegDecoder->Play (); } return 1; } DEBUGMSG (1, ("mp3_getPCM (%d)\n", idx)); *plength = (RMuint32)BPpcm.buffers_size; *pBuffer = (RMuint8 *)get_buffer_address (&BPpcm, idx); ASSERT ((RMuint32)*pBuffer >= (RMuint32)pcm_buffer); return 0;}// mp3 decode callback - the mp3 decoding object is requesting the// application to provide a buffer to read mp3 data intostatic RMuint32 mp3_getMP3 (RMuint8 **pBuffer, RMuint32 *plength, void *context){ DEBUGMSG (1, ("mp3_getMP3\n")); int idx = find_free_buffer (&BPmp3, 0); if (idx < 0) { if (prebuffering) { prebuffering = 0; pMpegDecoder->Play (); } return 1; } *plength = (RMuint32)BPmp3.buffers_size; *pBuffer = (RMuint8 *)get_buffer_address (&BPmp3, idx); return 0;}// end decoding callbacks required by mp3 decoder//////////////////////////////////////////////////////////////////////static int gettime (){ struct timeval tv1, tv2; struct timezone tz; gettimeofday (&tv1, &tz); return (tv1.tv_sec * 1000 + tv1.tv_usec/1000);}// entry pointint main (int argc, char *argv[]){ int seconds = 0, t0; if (argc < 2) { printf ("usage: mp3play.bin <filename> <seek to seconds>\n"); return -1; } if (argc > 2) { seconds = atoi (argv[2]); printf ("seek to %d seconds after 5 seconds of playback\n", seconds); } // create an instance of the mpeg decoder pMpegDecoder = (MpegDecoder *) new MpegDecoder; ASSERT (pMpegDecoder); pMpegDecoder->Init (); // ntsc pMpegDecoder->SetupDisplay (1); // create an instance of the mp3 decoder pMP3Decoder = (MP3Decoder *) new MP3Decoder; MP3_CALLBACK_TABLE callback_table; callback_table.context = &BPmp3; // saved context information for application callback_table.fopen = fs_fopen; // fopen for file decoding callback_table.fseek = fs_fseek; // fseek for file decoding callback_table.ftell = fs_ftell; // tell for file decoding callback_table.fread = fs_fread; // fread for file decoding callback_table.fclose = fs_fclose; // fclose for file decoding callback_table.addref = my_addref; // addref a buffer callback_table.release = my_release; // release a buffer callback_table.info = mp3_info; // inform app of some mp3 information callback_table.putPCM = mp3_putPCM; // output PCM bytes callback_table.getPCM = mp3_getPCM; // get a buffer for PCM data callback_table.getMP3 = mp3_getMP3; // get a buffer for reading MP3 data init_buffer_pool (&BPmp3, mp3_buffer, 256*1024, 2); init_buffer_pool (&BPpcm, pcm_buffer, 1152*4, 64); pMP3Decoder->Init (); pMP3Decoder->InitCallbackTable (&callback_table); prebuffering = 1; if (pMP3Decoder->DecodeFile (argv[1]) != MP3_DECODER_ERROR_NO_ERROR) { DEBUGMSG (1, ("pMP3Decoder->DecodeFile (%s) failed\n", argv[1])); delete pMP3Decoder; pMP3Decoder = 0; deinit_buffer_pool (&BPmp3); deinit_buffer_pool (&BPpcm); return -1; } // initialize the dac dac_init (); t0 = gettime (); // play the stream while (1) { if (pMP3Decoder->Schedule () == MP3_DECODER_ERROR_FILE_DONE) { if (prebuffering) { prebuffering = 0; pMpegDecoder->Play (); } if (pMpegDecoder->EndOfStream (-1, 0) == MPEG_DECODER_ERROR_EOF) { sleep (1); delete pMP3Decoder; pMP3Decoder = 0; deinit_buffer_pool (&BPmp3); deinit_buffer_pool (&BPpcm); pMpegDecoder->Stop (); break; } } if (seconds && ((gettime () - t0) > 5000)) { printf ("seeking to %d seconds\n"); if (pMP3Decoder->Seek (seconds) == 0) { prebuffering = 1; pMpegDecoder->Stop (); pMpegDecoder->Pause (); } seconds = 0; } } delete pMpegDecoder; return 0;}
?? 快捷鍵說(shuō)明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號(hào)
Ctrl + =
減小字號(hào)
Ctrl + -