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.
This commit is contained in:
Daniel Önnerby 2009-01-24 23:49:14 +00:00
parent cabb7e171a
commit 34d2d196be
4 changed files with 79 additions and 101 deletions

View File

@ -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->pcBufferSize<this->pcBufferMaxSize && !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 = pcBufferLeft<availableBuffer?pcBufferLeft:availableBuffer;
readMax = rotationSizeLeft<readMax?rotationSizeLeft:readMax;
boost::system::error_code error;
std::size_t addedToPrecache = this->socket.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(bytesRead<getLength && this->pcBufferSize){
std::size_t rotationSizeLeft = this->pcBufferMaxSize-this->pcBufferPosition;
std::size_t requestedLeft = getLength-bytesRead;
std::size_t readMax = rotationSizeLeft<this->pcBufferSize?rotationSizeLeft:this->pcBufferSize;
readMax = requestedLeft<readMax?requestedLeft:readMax;
memcpy((char*)buffer+bytesRead,this->pcBuffer+this->pcBufferPosition,readMax);
bytesRead += readMax;
this->pcBufferSize -= readMax;
this->pcBufferPosition = (this->pcBufferPosition+readMax)%this->pcBufferMaxSize;
}
}
return bytesRead;
}

View File

@ -20,5 +20,9 @@ private:
boost::asio::io_service IOService;
boost::asio::ip::tcp::socket socket;
long pcBufferMaxSize;
long pcBufferSize;
long pcBufferPosition;
char *pcBuffer;
};

View File

@ -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;
}
}

View File

@ -34,7 +34,7 @@
WaveOut::WaveOut()
:waveHandle(NULL)
,maxBuffers(16)
,maxBuffers(32)
,currentVolume(1.0)
,addToRemovedBuffers(false)
{