Use the new ZMusic_GetStreamInfoEx function

This commit is contained in:
Chris Robinson 2023-01-25 04:25:41 -08:00 committed by Ricardo Luís Vaz Silva
commit c5910976d2
5 changed files with 62 additions and 68 deletions

View file

@ -176,10 +176,15 @@ static TArray<SoundStream*> customStreams;
SoundStream *S_CreateCustomStream(size_t size, int samplerate, int numchannels, MusicCustomStreamType sampletype, StreamCallback cb, void *userdata)
{
int flags = 0;
if (numchannels < 2) flags |= SoundStream::Mono;
if (sampletype == MusicSamplesFloat) flags |= SoundStream::Float;
auto stream = GSnd->CreateStream(cb, int(size), flags, samplerate, userdata);
ChannelConfig chans;
if(numchannels == 1)
chans = ChannelConfig_Mono;
else if(numchannels == 2)
chans = ChannelConfig_Stereo;
else
return nullptr;
auto stream = GSnd->CreateStream(cb, int(size), SampleType_Int16, chans, samplerate, userdata);
if (stream)
{
stream->Play(true, 1);
@ -251,17 +256,14 @@ static bool FillStream(SoundStream* stream, void* buff, int len, void* userdata)
void S_CreateStream()
{
if (!mus_playing.handle) return;
SoundStreamInfo fmt;
ZMusic_GetStreamInfo(mus_playing.handle, &fmt);
// always create a floating point streaming buffer so we can apply replay gain without risk of integer overflows.
mus_playing.isfloat = fmt.mNumChannels > 0;
SoundStreamInfoEx fmt;
ZMusic_GetStreamInfoEx(mus_playing.handle, &fmt);
mus_playing.isfloat = fmt.mSampleType == SampleType_Float32;
if (!mus_playing.isfloat) fmt.mBufferSize *= 2;
if (fmt.mBufferSize > 0) // if buffer size is 0 the library will play the song itself (e.g. Windows system synth.)
{
int flags = SoundStream::Float;
if (abs(fmt.mNumChannels) < 2) flags |= SoundStream::Mono;
musicStream.reset(GSnd->CreateStream(FillStream, fmt.mBufferSize, flags, fmt.mSampleRate, nullptr));
// always create a floating point streaming buffer so we can apply replay gain without risk of integer overflows.
musicStream.reset(GSnd->CreateStream(FillStream, fmt.mBufferSize, SampleType_Float32, fmt.mChannelConfig, fmt.mSampleRate, nullptr));
if (musicStream) musicStream->Play(true, 1);
}
}
@ -603,17 +605,14 @@ static void CheckReplayGain(const char *musicname, EMidiDevice playertype, const
return; // unable to open
}
SoundStreamInfo fmt;
ZMusic_GetStreamInfo(handle, &fmt);
SoundStreamInfoEx fmt;
ZMusic_GetStreamInfoEx(handle, &fmt);
if (fmt.mBufferSize == 0)
{
ZMusic_Close(handle);
return; // external player.
}
int flags = SoundStream::Float;
if (abs(fmt.mNumChannels) < 2) flags |= SoundStream::Mono;
TArray<uint8_t> readbuffer(fmt.mBufferSize, true);
TArray<float> lbuffer;
TArray<float> rbuffer;
@ -621,7 +620,7 @@ static void CheckReplayGain(const char *musicname, EMidiDevice playertype, const
{
unsigned index;
// 4 cases, all with different preparation needs.
if (fmt.mNumChannels == -2) // 16 bit stereo
if (fmt.mSampleType == SampleType_Int16 && fmt.mChannelConfig == ChannelConfig_Stereo) // 16 bit stereo
{
int16_t* sbuf = (int16_t*)readbuffer.Data();
int numsamples = fmt.mBufferSize / 4;
@ -634,7 +633,7 @@ static void CheckReplayGain(const char *musicname, EMidiDevice playertype, const
rbuffer[index + i] = sbuf[i * 2 + 1];
}
}
else if (fmt.mNumChannels == -1) // 16 bit mono
else if (fmt.mSampleType == SampleType_Int16 && fmt.mChannelConfig == ChannelConfig_Mono) // 16 bit mono
{
int16_t* sbuf = (int16_t*)readbuffer.Data();
int numsamples = fmt.mBufferSize / 2;
@ -645,7 +644,7 @@ static void CheckReplayGain(const char *musicname, EMidiDevice playertype, const
lbuffer[index + i] = sbuf[i];
}
}
else if (fmt.mNumChannels == 1) // float mono
else if (fmt.mSampleType == SampleType_Float32 && fmt.mChannelConfig == ChannelConfig_Mono) // float mono
{
float* sbuf = (float*)readbuffer.Data();
int numsamples = fmt.mBufferSize / 4;
@ -655,7 +654,7 @@ static void CheckReplayGain(const char *musicname, EMidiDevice playertype, const
lbuffer[index + i] = sbuf[i] * 32768.f;
}
}
else if (fmt.mNumChannels == 2) // float stereo
else if (fmt.mSampleType == SampleType_Float32 && fmt.mChannelConfig == ChannelConfig_Stereo) // float stereo
{
float* sbuf = (float*)readbuffer.Data();
int numsamples = fmt.mBufferSize / 8;

View file

@ -169,7 +169,7 @@ public:
}
// Streaming sounds.
SoundStream *CreateStream (SoundStreamCallback callback, int buffbytes, int flags, int samplerate, void *userdata)
SoundStream *CreateStream (SoundStreamCallback callback, int buffbytes, SampleType stype, ChannelConfig chans, int samplerate, void *userdata)
{
return NULL;
}
@ -299,7 +299,8 @@ const char *GetSampleTypeName(SampleType type)
{
case SampleType_UInt8: return "Unsigned 8-bit";
case SampleType_Int16: return "Signed 16-bit";
default: break;
case SampleType_Float32: return "32-bit float";
default: break;
}
return "(invalid sample type)";
}

View file

@ -65,17 +65,6 @@ class SoundStream
public:
virtual ~SoundStream() = default;
enum
{ // For CreateStream
Mono = 1,
Bits8 = 2,
Bits32 = 4,
Float = 8,
// For OpenStream
Loop = 16
};
struct Position {
uint64_t samplesplayed;
std::chrono::nanoseconds latency;
@ -114,7 +103,7 @@ public:
virtual float GetOutputRate() = 0;
// Streaming sounds.
virtual SoundStream *CreateStream (SoundStreamCallback callback, int buffbytes, int flags, int samplerate, void *userdata) = 0;
virtual SoundStream *CreateStream (SoundStreamCallback callback, int buffbytes, SampleType stype, ChannelConfig chans, int samplerate, void *userdata) = 0;
// Starts a sound.
virtual FISoundChannel *StartSound (SoundHandle sfx, float vol, float pitch, int chanflags, FISoundChannel *reuse_chan, float startTime = 0.f) = 0;

View file

@ -117,6 +117,27 @@ EXTERN_CVAR (Int, snd_hrtf)
#define GET_PTRID(x) ((uint32_t)(uintptr_t)(x))
static constexpr uint8_t SampleTypeSize(SampleType stype)
{
switch(stype)
{
case SampleType_UInt8: return sizeof(uint8_t);
case SampleType_Int16: return sizeof(int16_t);
case SampleType_Float32: return sizeof(float);
}
return 0;
}
static constexpr uint8_t ChannelCount(ChannelConfig chans)
{
switch(chans)
{
case ChannelConfig_Mono: return 1;
case ChannelConfig_Stereo: return 2;
}
return 0;
}
static ALenum checkALError(const char *fn, unsigned int ln)
{
ALenum err = alGetError();
@ -461,7 +482,7 @@ public:
return ok;
}
bool Init(SoundStreamCallback callback, int buffbytes, int flags, int samplerate, void *userdata)
bool Init(SoundStreamCallback callback, int buffbytes, SampleType stype, ChannelConfig chans, int samplerate, void *userdata)
{
if(!SetupSource())
return false;
@ -471,46 +492,30 @@ public:
SampleRate = samplerate;
Format = AL_NONE;
if((flags&Bits8)) /* Signed or unsigned? We assume unsigned 8-bit... */
if(stype == SampleType_UInt8)
{
if((flags&Mono)) Format = AL_FORMAT_MONO8;
else Format = AL_FORMAT_STEREO8;
if(chans == ChannelConfig_Mono) Format = AL_FORMAT_MONO8;
else if(chans == ChannelConfig_Stereo) Format = AL_FORMAT_STEREO8;
}
else if(stype == SampleType_Int16)
{
if(chans == ChannelConfig_Mono) Format = AL_FORMAT_MONO16;
else if(chans == ChannelConfig_Stereo) Format = AL_FORMAT_STEREO16;
}
else if((flags&Float))
else if(stype == SampleType_Float32 && alIsExtensionPresent("AL_EXT_FLOAT32"))
{
if(alIsExtensionPresent("AL_EXT_FLOAT32"))
{
if((flags&Mono)) Format = AL_FORMAT_MONO_FLOAT32;
else Format = AL_FORMAT_STEREO_FLOAT32;
}
}
else if((flags&Bits32))
{
}
else
{
if((flags&Mono)) Format = AL_FORMAT_MONO16;
else Format = AL_FORMAT_STEREO16;
if(chans == ChannelConfig_Mono) Format = AL_FORMAT_MONO_FLOAT32;
else if(chans == ChannelConfig_Stereo) Format = AL_FORMAT_STEREO_FLOAT32;
}
if(Format == AL_NONE)
{
Printf("Unsupported format: 0x%x\n", flags);
Printf("Unhandled audio format: %s, %s\n", GetChannelConfigName(chans),
GetSampleTypeName(stype));
return false;
}
FrameSize = 1;
if((flags&Bits8))
FrameSize *= 1;
else if((flags&(Bits32|Float)))
FrameSize *= 4;
else
FrameSize *= 2;
if((flags&Mono))
FrameSize *= 1;
else
FrameSize *= 2;
FrameSize = SampleTypeSize(stype) * ChannelCount(chans);
buffbytes += FrameSize-1;
buffbytes -= buffbytes%FrameSize;
@ -1223,12 +1228,12 @@ void OpenALSoundRenderer::UnloadSound(SoundHandle sfx)
}
SoundStream *OpenALSoundRenderer::CreateStream(SoundStreamCallback callback, int buffbytes, int flags, int samplerate, void *userdata)
SoundStream *OpenALSoundRenderer::CreateStream(SoundStreamCallback callback, int buffbytes, SampleType stype, ChannelConfig chans, int samplerate, void *userdata)
{
if(StreamThread.get_id() == std::thread::id())
StreamThread = std::thread(std::mem_fn(&OpenALSoundRenderer::BackgroundProc), this);
OpenALSoundStream *stream = new OpenALSoundStream(this);
if (!stream->Init(callback, buffbytes, flags, samplerate, userdata))
if (!stream->Init(callback, buffbytes, stype, chans, samplerate, userdata))
{
delete stream;
return NULL;

View file

@ -42,7 +42,7 @@ public:
virtual float GetOutputRate();
// Streaming sounds.
virtual SoundStream *CreateStream(SoundStreamCallback callback, int buffbytes, int flags, int samplerate, void *userdata);
SoundStream *CreateStream(SoundStreamCallback callback, int buffbytes, SampleType stype, ChannelConfig chans, int samplerate, void *userdata) override;
// Starts a sound.
FISoundChannel *StartSound(SoundHandle sfx, float vol, float pitch, int chanflags, FISoundChannel *reuse_chan, float startTime) override;