mirror of
https://github.com/ZDoom/ZMusic.git
synced 2025-03-21 01:50:53 +00:00
Better handle various formats in SndFileSong
This commit is contained in:
parent
db05f4a8ef
commit
ae70ea40f2
2 changed files with 33 additions and 20 deletions
|
@ -55,9 +55,8 @@ public:
|
|||
|
||||
protected:
|
||||
SoundDecoder *Decoder;
|
||||
int Channels;
|
||||
int SampleRate;
|
||||
|
||||
unsigned int FrameSize;
|
||||
|
||||
uint32_t Loop_Start;
|
||||
uint32_t Loop_End;
|
||||
|
||||
|
@ -434,29 +433,30 @@ static int32_t Scale(int32_t a, int32_t b, int32_t c)
|
|||
|
||||
SndFileSong::SndFileSong(SoundDecoder *decoder, uint32_t loop_start, uint32_t loop_end, bool startass, bool endass)
|
||||
{
|
||||
ChannelConfig iChannels;
|
||||
SampleType Type;
|
||||
|
||||
decoder->getInfo(&SampleRate, &iChannels, &Type);
|
||||
ChannelConfig chanconf;
|
||||
SampleType stype;
|
||||
int srate;
|
||||
|
||||
if (!startass) loop_start = Scale(loop_start, SampleRate, 1000);
|
||||
if (!endass) loop_end = Scale(loop_end, SampleRate, 1000);
|
||||
decoder->getInfo(&srate, &chanconf, &stype);
|
||||
|
||||
if (!startass) loop_start = Scale(loop_start, srate, 1000);
|
||||
if (!endass) loop_end = Scale(loop_end, srate, 1000);
|
||||
|
||||
const uint32_t sampleLength = (uint32_t)decoder->getSampleLength();
|
||||
Loop_Start = loop_start;
|
||||
Loop_End = sampleLength == 0 ? loop_end : std::min<uint32_t>(loop_end, sampleLength);
|
||||
Decoder = decoder;
|
||||
Channels = iChannels == ChannelConfig_Stereo? 2:1;
|
||||
FrameSize = ZMusic_ChannelCount(chanconf) * ZMusic_SampleTypeSize(stype);
|
||||
}
|
||||
|
||||
SoundStreamInfoEx SndFileSong::GetFormatEx()
|
||||
{
|
||||
ChannelConfig chans;
|
||||
ChannelConfig chanconf;
|
||||
SampleType stype;
|
||||
int srate;
|
||||
|
||||
Decoder->getInfo(&srate, &chans, &stype);
|
||||
return { 64/*snd_streambuffersize*/ * 1024, srate, stype, chans };
|
||||
Decoder->getInfo(&srate, &chanconf, &stype);
|
||||
return { 64/*snd_streambuffersize*/ * 1024, srate, stype, chanconf };
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
|
@ -483,14 +483,17 @@ std::string SndFileSong::GetStats()
|
|||
{
|
||||
char out[80];
|
||||
|
||||
size_t SamplePos;
|
||||
ChannelConfig chanconf;
|
||||
SampleType stype;
|
||||
int srate;
|
||||
Decoder->getInfo(&srate, &chanconf, &stype);
|
||||
|
||||
SamplePos = Decoder->getSampleOffset();
|
||||
int time = int (SamplePos / SampleRate);
|
||||
size_t SamplePos = Decoder->getSampleOffset();
|
||||
int time = int (SamplePos / srate);
|
||||
|
||||
snprintf(out, 80,
|
||||
"Track: %s, %dHz Time: %02d:%02d",
|
||||
Channels == 2? "Stereo" : "Mono", SampleRate,
|
||||
ZMusic_ChannelConfigName(chanconf), srate,
|
||||
time/60,
|
||||
time % 60);
|
||||
return out;
|
||||
|
@ -507,7 +510,7 @@ bool SndFileSong::GetData(void *vbuff, size_t len)
|
|||
char *buff = (char*)vbuff;
|
||||
|
||||
size_t currentpos = Decoder->getSampleOffset();
|
||||
size_t framestoread = len / (Channels*2);
|
||||
size_t framestoread = len / FrameSize;
|
||||
bool err = false;
|
||||
if (!m_Looping)
|
||||
{
|
||||
|
@ -519,7 +522,7 @@ bool SndFileSong::GetData(void *vbuff, size_t len)
|
|||
}
|
||||
if (currentpos + framestoread > maxpos)
|
||||
{
|
||||
size_t got = Decoder->read(buff, (maxpos - currentpos) * Channels * 2);
|
||||
size_t got = Decoder->read(buff, (maxpos - currentpos) * FrameSize);
|
||||
memset(buff + got, 0, len - got);
|
||||
}
|
||||
else
|
||||
|
@ -536,7 +539,7 @@ bool SndFileSong::GetData(void *vbuff, size_t len)
|
|||
// Loop can be very short, make sure the current position doesn't exceed it
|
||||
if (currentpos < Loop_End)
|
||||
{
|
||||
size_t endblock = (Loop_End - currentpos) * Channels * 2;
|
||||
size_t endblock = (Loop_End - currentpos) * FrameSize;
|
||||
size_t endlen = Decoder->read(buff, endblock);
|
||||
|
||||
// Even if zero bytes was read give it a chance to start from the beginning
|
||||
|
|
|
@ -70,3 +70,13 @@ inline uint8_t ZMusic_ChannelCount(ChannelConfig chans)
|
|||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
inline const char *ZMusic_ChannelConfigName(ChannelConfig chans)
|
||||
{
|
||||
switch(chans)
|
||||
{
|
||||
case ChannelConfig_Mono: return "Mono";
|
||||
case ChannelConfig_Stereo: return "Stereo";
|
||||
}
|
||||
return "(unknown)";
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue