#include "MP3Player.h" #include namespace HSound { MP3Player::MP3Player(void) : Status(0), FrameCount(0), slackBufferContentLength(0), readPos(0), slackBuffer(), sampleBuffer(), resampleInputBufferLength(0), resampleInputBuffer(0), resampleSlackBuffer(), resampleOutputBuffer(0), resampleOutputBufferLength(0), noMoreSamples(false) { mad_stream_init(&Stream); mad_frame_init(&Frame); mad_synth_init(&Synth); mad_timer_reset(&Timer); resamplingState=src_new(SRC_SINC_MEDIUM_QUALITY, 2, 0); if(resamplingState==0) { throw "src_new failed!"; } }; MP3Player::~MP3Player(void) { mad_synth_finish(&Synth); mad_frame_finish(&Frame); mad_stream_finish(&Stream); resamplingState=src_delete(resamplingState); delete[] resampleInputBuffer; delete[] resampleOutputBuffer; }; unsigned int MP3Player::loadNextBuffer(SoundSample *outBuffer,unsigned int length) { sampleBuffer.reserve(length); unsigned int sampleBufferPos=0; //load any pre computed samples we have for(;sampleBufferPos20000) *((char*)1)=1;//dam, we are in an infinite loop continue; } else { /*fprintf(stderr,"%s: unrecoverable frame level error (%s).\n", ProgName,MadErrorString(&Stream));*/ Status=1; break; } }//end of if mad_frame_decode FrameCount++; mad_timer_add(&Timer,Frame.header.duration); //magic filtering is not implemented mad_synth_frame(&Synth,&Frame); unsigned int slackSize=resampleSlackBuffer.size(); unsigned int targetResampleInputBufferLength=Synth.pcm.length*MAD_NCHANNELS(&Frame.header)+slackSize; if(resampleInputBufferLength::const_iterator endItr=resampleSlackBuffer.end(); for(list::const_iterator itr=resampleSlackBuffer.begin();itr!=endItr;++itr) { float s=*itr; resampleInputBuffer[resampleInputBufferPos++]=s; } //load the just now synthed samples into the resample buffer for(unsigned int i=0;iresampleOutputBufferLength) { delete[] resampleOutputBuffer; resampleOutputBuffer=0; } if(!resampleOutputBuffer) { resampleOutputBuffer=new float[targetResampleOutputBufferLength]; resampleOutputBufferLength=targetResampleOutputBufferLength; } noMoreSamples=Stream.error==MAD_ERROR_LOSTSYNC && Stream.this_frame==GuardPtr && EOF; SRC_DATA resamplingData; resamplingData.input_frames = resampleInputBufferPos; resamplingData.input_frames_used = 0; resamplingData.output_frames_gen = 0; resamplingData.data_in = resampleInputBuffer; resamplingData.end_of_input = noMoreSamples; resamplingData.data_out = resampleOutputBuffer; resamplingData.output_frames = resampleOutputBufferLength; //recomputed because vbr will change the bitrate resamplingData.src_ratio = ((double)48000)/((double)Frame.header.samplerate); /* //this code will be removed, since it's not doing anything int randomCrapSum=0; for(int i=0;i::const_iterator itr=resampleSlackBuffer.begin();itr!=endItr;++itr) { } resampleSlackBuffer.clear(); for(int i=resamplingData.input_frames_used;i=length) { slackBufferContentLength=sampleBufferPos-length; slackBuffer.reserve(slackBufferContentLength); //save the slack that accidently got decoded unsigned int sampleBufferLength=sampleBuffer.size(); for(unsigned int i=0;sampleBufferPoslength?length:sampleBufferPos; };//end of member function loadNextBuffer signed short MP3Player::MadFixedToSshort(mad_fixed_t Fixed) { // A fixed point number is formed of the following bit pattern: // // SWWWFFFFFFFFFFFFFFFFFFFFFFFFFFFF // MSB LSB // S ==> Sign (0 is positive, 1 is negative) // 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: this is a quick and dirty way to // compute the 16-bit number, madplay includes much better // algorithms. // Clipping if(Fixed>=MAD_F_ONE) return(SHRT_MAX); if(Fixed<=-MAD_F_ONE) return(-SHRT_MAX); // Conversion. Fixed=Fixed>>(MAD_F_FRACBITS-15); return((signed short)Fixed); }; void MP3Player::seek(const unsigned int pos) { readPos=pos; soundComplete=false; noMoreSamples=false; src_reset(resamplingState); } };//end of namespace