mirror of
https://github.com/ZDoom/gzdoom-gles.git
synced 2024-11-13 07:57:51 +00:00
- fixed a few issues with libmpg123 not correctly reporting the sound's length and issues with repeatedly rewinding the song.
This commit is contained in:
parent
f866e0f02f
commit
99579efd0d
7 changed files with 65 additions and 27 deletions
|
@ -132,7 +132,7 @@ struct SoundDecoder
|
||||||
|
|
||||||
virtual size_t read(char *buffer, size_t bytes) = 0;
|
virtual size_t read(char *buffer, size_t bytes) = 0;
|
||||||
virtual TArray<char> readAll();
|
virtual TArray<char> readAll();
|
||||||
virtual bool seek(size_t ms_offset, bool ms) = 0;
|
virtual bool seek(size_t ms_offset, bool ms, bool mayrestart) = 0;
|
||||||
virtual size_t getSampleOffset() = 0;
|
virtual size_t getSampleOffset() = 0;
|
||||||
virtual size_t getSampleLength() { return 0; }
|
virtual size_t getSampleLength() { return 0; }
|
||||||
|
|
||||||
|
|
|
@ -190,11 +190,13 @@ size_t MPG123Decoder::read(char *buffer, size_t bytes)
|
||||||
return amt;
|
return amt;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool MPG123Decoder::seek(size_t ms_offset, bool ms)
|
bool MPG123Decoder::seek(size_t ms_offset, bool ms, bool mayrestart)
|
||||||
{
|
{
|
||||||
int enc, channels;
|
int enc, channels;
|
||||||
long srate;
|
long srate;
|
||||||
|
|
||||||
|
if (!mayrestart || ms_offset > 0)
|
||||||
|
{
|
||||||
if (mpg123_getformat(MPG123, &srate, &channels, &enc) == MPG123_OK)
|
if (mpg123_getformat(MPG123, &srate, &channels, &enc) == MPG123_OK)
|
||||||
{
|
{
|
||||||
size_t smp_offset = ms ? (size_t)((double)ms_offset / 1000. * srate) : ms_offset;
|
size_t smp_offset = ms ? (size_t)((double)ms_offset / 1000. * srate) : ms_offset;
|
||||||
|
@ -206,7 +208,20 @@ bool MPG123Decoder::seek(size_t ms_offset, bool ms)
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Restart the song instead of rewinding. A rewind seems to cause distortion when done repeatedly.
|
||||||
|
// offset is intentionally ignored here.
|
||||||
|
if (MPG123)
|
||||||
|
{
|
||||||
|
mpg123_close(MPG123);
|
||||||
|
mpg123_delete(MPG123);
|
||||||
|
MPG123 = 0;
|
||||||
|
}
|
||||||
|
Reader->Seek(0, SEEK_SET);
|
||||||
|
return open(Reader);
|
||||||
|
}
|
||||||
|
}
|
||||||
size_t MPG123Decoder::getSampleOffset()
|
size_t MPG123Decoder::getSampleOffset()
|
||||||
{
|
{
|
||||||
return mpg123_tell(MPG123);
|
return mpg123_tell(MPG123);
|
||||||
|
|
|
@ -21,7 +21,7 @@ struct MPG123Decoder : public SoundDecoder
|
||||||
virtual void getInfo(int *samplerate, ChannelConfig *chans, SampleType *type);
|
virtual void getInfo(int *samplerate, ChannelConfig *chans, SampleType *type);
|
||||||
|
|
||||||
virtual size_t read(char *buffer, size_t bytes);
|
virtual size_t read(char *buffer, size_t bytes);
|
||||||
virtual bool seek(size_t ms_offset, bool ms);
|
virtual bool seek(size_t ms_offset, bool ms, bool mayrestart);
|
||||||
virtual size_t getSampleOffset();
|
virtual size_t getSampleOffset();
|
||||||
virtual size_t getSampleLength();
|
virtual size_t getSampleLength();
|
||||||
|
|
||||||
|
|
|
@ -326,16 +326,39 @@ bool SndFileSong::Read(SoundStream *stream, void *vbuff, int ilen, void *userdat
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
// This looks a bit more complicated than necessary because libmpg123 will not read the full requested length for the last block in the file.
|
||||||
if (currentpos + framestoread > song->Loop_End)
|
if (currentpos + framestoread > song->Loop_End)
|
||||||
{
|
{
|
||||||
size_t endblock = (song->Loop_End - currentpos) * song->Channels * 2;
|
size_t endblock = (song->Loop_End - currentpos) * song->Channels * 2;
|
||||||
err = (song->Decoder->read(buff, endblock) != endblock);
|
size_t endlen = song->Decoder->read(buff, endblock);
|
||||||
|
if (endlen != 0)
|
||||||
|
{
|
||||||
buff = buff + endblock;
|
buff = buff + endblock;
|
||||||
len -= endblock;
|
len -= endblock;
|
||||||
song->Decoder->seek(song->Loop_Start, false);
|
song->Decoder->seek(song->Loop_Start, false, true);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
song->CritSec.Leave();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
while (len > 0)
|
||||||
|
{
|
||||||
|
size_t readlen = song->Decoder->read(buff, len);
|
||||||
|
if (readlen == 0)
|
||||||
|
{
|
||||||
|
song->CritSec.Leave();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
buff += readlen;
|
||||||
|
len -= readlen;
|
||||||
|
if (len > 0)
|
||||||
|
{
|
||||||
|
song->Decoder->seek(song->Loop_Start, false, true);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
err |= song->Decoder->read(buff, len) != len;
|
|
||||||
}
|
}
|
||||||
song->CritSec.Leave();
|
song->CritSec.Leave();
|
||||||
return !err;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
|
@ -215,7 +215,7 @@ class OpenALSoundStream : public SoundStream
|
||||||
size_t got = self->Decoder->read((char*)ptr, length);
|
size_t got = self->Decoder->read((char*)ptr, length);
|
||||||
if(got < (unsigned int)length)
|
if(got < (unsigned int)length)
|
||||||
{
|
{
|
||||||
if(!self->Looping || !self->Decoder->seek(0, false))
|
if(!self->Looping || !self->Decoder->seek(0, false, true))
|
||||||
return false;
|
return false;
|
||||||
got += self->Decoder->read((char*)ptr+got, length-got);
|
got += self->Decoder->read((char*)ptr+got, length-got);
|
||||||
}
|
}
|
||||||
|
@ -364,7 +364,7 @@ public:
|
||||||
virtual bool SetPosition(unsigned int ms_pos)
|
virtual bool SetPosition(unsigned int ms_pos)
|
||||||
{
|
{
|
||||||
std::unique_lock<std::mutex> lock(Renderer->StreamLock);
|
std::unique_lock<std::mutex> lock(Renderer->StreamLock);
|
||||||
if(!Decoder->seek(ms_pos, true))
|
if(!Decoder->seek(ms_pos, true, false))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
if(!Playing.load())
|
if(!Playing.load())
|
||||||
|
|
|
@ -190,7 +190,7 @@ TArray<char> SndFileDecoder::readAll()
|
||||||
return output;
|
return output;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool SndFileDecoder::seek(size_t ms_offset, bool ms)
|
bool SndFileDecoder::seek(size_t ms_offset, bool ms, bool /*mayrestart*/)
|
||||||
{
|
{
|
||||||
size_t smp_offset = ms? (size_t)((double)ms_offset / 1000. * SndInfo.samplerate) : ms_offset;
|
size_t smp_offset = ms? (size_t)((double)ms_offset / 1000. * SndInfo.samplerate) : ms_offset;
|
||||||
if(sf_seek(SndFile, smp_offset, SEEK_SET) < 0)
|
if(sf_seek(SndFile, smp_offset, SEEK_SET) < 0)
|
||||||
|
|
|
@ -17,7 +17,7 @@ struct SndFileDecoder : public SoundDecoder
|
||||||
|
|
||||||
virtual size_t read(char *buffer, size_t bytes);
|
virtual size_t read(char *buffer, size_t bytes);
|
||||||
virtual TArray<char> readAll();
|
virtual TArray<char> readAll();
|
||||||
virtual bool seek(size_t ms_offset, bool ms);
|
virtual bool seek(size_t ms_offset, bool ms, bool mayrestart);
|
||||||
virtual size_t getSampleOffset();
|
virtual size_t getSampleOffset();
|
||||||
virtual size_t getSampleLength();
|
virtual size_t getSampleLength();
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue