From 34d2d196be983789aa66f07181a4770b960bdd19 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20=C3=96nnerby?= Date: Sat, 24 Jan 2009 23:49:14 +0000 Subject: [PATCH] Fixed: mpg123_decoder that wouldn't read some files. Added: precaching of up to 256kb in the httpstream_plugin. Tuned the waveout to have more internal buffers, making the "almost done" signal called earlier for precaching next track. --- src/contrib/httpstream/HTTPRequest.cpp | 61 ++++++++++-- src/contrib/httpstream/HTTPRequest.h | 4 + src/contrib/mpg123decoder/MP3Decoder.cpp | 113 ++++------------------- src/contrib/waveout/WaveOut.cpp | 2 +- 4 files changed, 79 insertions(+), 101 deletions(-) diff --git a/src/contrib/httpstream/HTTPRequest.cpp b/src/contrib/httpstream/HTTPRequest.cpp index 0202f4390..e7f5cac5e 100644 --- a/src/contrib/httpstream/HTTPRequest.cpp +++ b/src/contrib/httpstream/HTTPRequest.cpp @@ -10,11 +10,17 @@ HTTPRequest::HTTPRequest(void) :socket(IOService) + ,pcBuffer(NULL) + ,pcBufferMaxSize(256*1024) + ,pcBufferSize(0) + ,pcBufferPosition(0) { + this->pcBuffer = new char[256*1024]; } HTTPRequest::~HTTPRequest(void) { + delete this->pcBuffer; this->socket.close(); } @@ -126,13 +132,56 @@ bool HTTPRequest::Request(const char *url){ } long HTTPRequest::GetContent(void *buffer,long getLength){ - // First just try to read_some so that we do not hold if not nessesary - boost::system::error_code error; - std::size_t bytesRead = this->socket.read_some(boost::asio::buffer(buffer,getLength),error); - - if(error){ - return 0; + std::size_t bytesRead(0); + // lets check if ther is more that we can precache + if(this->pcBufferSize==0){ + // if there is no available buffer, lets read directly to the buffer once there is something to read + boost::system::error_code error; + bytesRead = this->socket.read_some(boost::asio::buffer(buffer,getLength),error); + if(error){ + return 0; + } } + + // lets try to precache whatever is left + size_t availableBuffer = this->socket.available(); + bool readError(false); + while(availableBuffer && this->pcBufferSizepcBufferMaxSize && !readError){ + // read to the internal precache buffer + std::size_t pcEndPosition = (this->pcBufferPosition+this->pcBufferSize)%this->pcBufferMaxSize; + + std::size_t rotationSizeLeft = this->pcBufferMaxSize-pcEndPosition; + std::size_t pcBufferLeft = this->pcBufferMaxSize-this->pcBufferSize; + std::size_t readMax = pcBufferLeftsocket.read_some(boost::asio::buffer(&this->pcBuffer[pcEndPosition],readMax),error); + if(error){ + readError = true; + } + this->pcBufferSize += addedToPrecache; + + availableBuffer = this->socket.available(); + } + + // if we havn't read anything yet and we have some cached buffer, lets copy from the precache buffer + if(!bytesRead && this->pcBufferSize){ + while(bytesReadpcBufferSize){ + std::size_t rotationSizeLeft = this->pcBufferMaxSize-this->pcBufferPosition; + std::size_t requestedLeft = getLength-bytesRead; + std::size_t readMax = rotationSizeLeftpcBufferSize?rotationSizeLeft:this->pcBufferSize; + readMax = requestedLeftpcBuffer+this->pcBufferPosition,readMax); + + bytesRead += readMax; + this->pcBufferSize -= readMax; + this->pcBufferPosition = (this->pcBufferPosition+readMax)%this->pcBufferMaxSize; + + } + } + return bytesRead; + } diff --git a/src/contrib/httpstream/HTTPRequest.h b/src/contrib/httpstream/HTTPRequest.h index 3d32b1517..ff2697243 100644 --- a/src/contrib/httpstream/HTTPRequest.h +++ b/src/contrib/httpstream/HTTPRequest.h @@ -20,5 +20,9 @@ private: boost::asio::io_service IOService; boost::asio::ip::tcp::socket socket; + long pcBufferMaxSize; + long pcBufferSize; + long pcBufferPosition; + char *pcBuffer; }; diff --git a/src/contrib/mpg123decoder/MP3Decoder.cpp b/src/contrib/mpg123decoder/MP3Decoder.cpp index 5bbb5d0d7..8b6b4a103 100644 --- a/src/contrib/mpg123decoder/MP3Decoder.cpp +++ b/src/contrib/mpg123decoder/MP3Decoder.cpp @@ -41,8 +41,8 @@ MP3Decoder::MP3Decoder(void) :cachedLength(0) ,decoder(NULL) - ,cachedRate(0) - ,cachedChannels(0) + ,cachedRate(44100) + ,cachedChannels(2) ,fileStream(NULL) ,lastMpg123Status(MPG123_NEED_MORE) { @@ -62,40 +62,10 @@ MP3Decoder::~MP3Decoder(void){ } } - void MP3Decoder::Destroy(){ delete this; } - -/* -double MP3Decoder::Length(){ - - this->GuessLength(); - - if( this->cachedLength>0 && this->cachedRate>0){ - return ((double)this->cachedLength)/((double)this->cachedRate); - } - - return 0; -} - -bool MP3Decoder::GuessLength(){ -// if(this->cachedLength<=0){ - unsigned long newCachedLength = mpg123_length(this->decoder); - if(newCachedLength>0){ - this->cachedLength = newCachedLength; - return true; - }else{ - if(this->cachedLength>0){ - return true; - } - } -// } - return false; -} -*/ - double MP3Decoder::SetPosition(double second,double totalLength){ off_t seekToFileOffset(0); @@ -122,26 +92,9 @@ double MP3Decoder::SetPosition(double second,double totalLength){ } } - // Try the fuzzy way -/* if(this->GuessLength()){ - unsigned long filePosition = ((double)this->fileStream->Filesize() * second )/this->Length(); - if(this->fileStream->SetPosition(filePosition)){ - return second; - } - } -*/ - return -1; } -/* -bool MP3Decoder::GetFormat(unsigned long * SampleRate, unsigned long * Channels){ - *SampleRate = this->cachedRate; - *Channels = this->cachedChannels; - return true; -} -*/ - bool MP3Decoder::GetBuffer(IBuffer *buffer){ long nofSamplesMax = 1024*2; @@ -150,12 +103,7 @@ bool MP3Decoder::GetBuffer(IBuffer *buffer){ buffer->SetSampleRate(this->cachedRate); buffer->SetSamples(nofSamplesMax); -// static float buffer[7680]; -// int nofSamplesMax(7680/this->cachedChannels); -// *ppBuffer = buffer; - unsigned char* currentBuffer = (unsigned char*)(buffer->BufferPointer()); -// unsigned long bytesLeft(nofSamplesMax*this->sampleSize); bool done(false); @@ -175,6 +123,23 @@ bool MP3Decoder::GetBuffer(IBuffer *buffer){ break; case MPG123_ERR: return false; + break; + case MPG123_NEW_FORMAT: + int encoding(0); + int gfCode = mpg123_getformat(this->decoder,&this->cachedRate,&this->cachedChannels,&encoding); + if( gfCode==MPG123_OK ){ + this->sampleSize = this->cachedChannels*sizeof(float); + + // Format should not change + mpg123_format_none(this->decoder); + // Force the encoding to float32 + int e=mpg123_format(this->decoder,this->cachedRate,this->cachedChannels,MPG123_ENC_FLOAT_32); + + buffer->SetChannels(this->cachedChannels); + buffer->SetSampleRate(this->cachedRate); + buffer->SetSamples(nofSamplesMax); + } + break; } @@ -210,46 +175,6 @@ bool MP3Decoder::Open(musik::core::filestreams::IFileStream *fileStream){ // Set filelength to decoder for better seeking mpg123_set_filesize(this->decoder,this->fileStream->Filesize()); - - // Set the format - int encoding(0); - bool continueFeed(true); - - // Loop until we have a format - int maxLoops(0); // - while(continueFeed){ - continueFeed = continueFeed && this->Feed() && !this->fileStream->Eof(); - ++maxLoops; - if(continueFeed){ - - continueFeed = false; - int gfCode = mpg123_getformat(this->decoder,&this->cachedRate,&this->cachedChannels,&encoding); - if(gfCode!=MPG123_OK){ - continueFeed = true; - }else{ - if(maxLoops<512){ - continueFeed = true; - } - } - } - } - - if(this->cachedRate==0){ - return false; - } - - this->sampleSize = this->cachedChannels*sizeof(float); - - // Loop until we have a length -// while(!this->GuessLength() && this->Feed()){ -// } - - - // Format should not change - mpg123_format_none(this->decoder); - // Force the encoding to float32 - int e=mpg123_format(this->decoder,this->cachedRate,this->cachedChannels,MPG123_ENC_FLOAT_32); - return true; } } diff --git a/src/contrib/waveout/WaveOut.cpp b/src/contrib/waveout/WaveOut.cpp index dfeddec93..e6232dc44 100644 --- a/src/contrib/waveout/WaveOut.cpp +++ b/src/contrib/waveout/WaveOut.cpp @@ -34,7 +34,7 @@ WaveOut::WaveOut() :waveHandle(NULL) - ,maxBuffers(16) + ,maxBuffers(32) ,currentVolume(1.0) ,addToRemovedBuffers(false) {