Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Update to use the new ZMusic_GetStreamInfoEx #1971

Open
wants to merge 3 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
42 changes: 21 additions & 21 deletions src/common/audio/music/music.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -119,10 +119,16 @@ 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;
const SampleType stype{(sampletype == MusicSamplesFloat) ? SampleType_Float32 : SampleType_Int16};

auto stream = GSnd->CreateStream(cb, int(size), stype, chans, samplerate, userdata);
if (stream)
{
stream->Play(true, 1);
Expand Down Expand Up @@ -194,17 +200,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);
}
}
Expand Down Expand Up @@ -548,25 +551,22 @@ 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;
while (ZMusic_FillStream(handle, readbuffer.Data(), fmt.mBufferSize))
{
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;
Expand All @@ -579,7 +579,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;
Expand All @@ -590,7 +590,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;
Expand All @@ -600,7 +600,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;
Expand Down
5 changes: 3 additions & 2 deletions src/common/audio/sound/i_sound.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -169,7 +169,7 @@ class NullSoundRenderer : public SoundRenderer
}

// 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;
}
Expand Down Expand Up @@ -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)";
}
Expand Down
13 changes: 1 addition & 12 deletions src/common/audio/sound/i_sound.h
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -114,7 +103,7 @@ class SoundRenderer
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;
Expand Down
117 changes: 53 additions & 64 deletions src/common/audio/sound/oalsound.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -117,6 +117,47 @@ 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 constexpr ALenum GetFormat(SampleType stype, ChannelConfig chans)
{
if(stype == SampleType_UInt8)
{
if(chans == ChannelConfig_Mono) return AL_FORMAT_MONO8;
if(chans == ChannelConfig_Stereo) return AL_FORMAT_STEREO8;
}
if(stype == SampleType_Int16)
{
if(chans == ChannelConfig_Mono) return AL_FORMAT_MONO16;
if(chans == ChannelConfig_Stereo) return AL_FORMAT_STEREO16;
}
if(stype == SampleType_Float32)
{
if(chans == ChannelConfig_Mono) return AL_FORMAT_MONO_FLOAT32;
if(chans == ChannelConfig_Stereo) return AL_FORMAT_STEREO_FLOAT32;
}
return AL_NONE;
}

static ALenum checkALError(const char *fn, unsigned int ln)
{
ALenum err = alGetError();
Expand Down Expand Up @@ -461,7 +502,7 @@ class OpenALSoundStream : public SoundStream
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;
Expand All @@ -470,47 +511,15 @@ class OpenALSoundStream : public SoundStream
UserData = userdata;
SampleRate = samplerate;

Format = AL_NONE;
if((flags&Bits8)) /* Signed or unsigned? We assume unsigned 8-bit... */
{
if((flags&Mono)) Format = AL_FORMAT_MONO8;
else Format = AL_FORMAT_STEREO8;
}
else if((flags&Float))
{
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;
}

Format = GetFormat(stype, chans);
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;
Expand All @@ -526,16 +535,6 @@ class OpenALSoundStream : public SoundStream

#define PITCH_MULT (0.7937005f) /* Approx. 4 semitones lower; what Nash suggested */

static size_t GetChannelCount(ChannelConfig chans)
{
switch(chans)
{
case ChannelConfig_Mono: return 1;
case ChannelConfig_Stereo: return 2;
}
return 0;
}

static float GetRolloff(const FRolloffInfo *rolloff, float distance)
{
return soundEngine->GetRolloff(rolloff, distance);
Expand Down Expand Up @@ -1099,10 +1098,6 @@ SoundHandle OpenALSoundRenderer::LoadSoundRaw(uint8_t *sfxdata, int length, int
SoundHandle OpenALSoundRenderer::LoadSound(uint8_t *sfxdata, int length)
{
SoundHandle retval = { NULL };
ALenum format = AL_NONE;
ChannelConfig chans;
SampleType type;
int srate;
uint32_t loop_start = 0, loop_end = ~0u;
zmusic_bool startass = false, endass = false;

Expand All @@ -1111,26 +1106,20 @@ SoundHandle OpenALSoundRenderer::LoadSound(uint8_t *sfxdata, int length)
if (!decoder)
return retval;

ChannelConfig chans;
SampleType type;
int srate;
SoundDecoder_GetInfo(decoder, &srate, &chans, &type);
int samplesize = 1;
if (chans == ChannelConfig_Mono)
{
if (type == SampleType_UInt8) format = AL_FORMAT_MONO8, samplesize = 1;
if (type == SampleType_Int16) format = AL_FORMAT_MONO16, samplesize = 2;
}
else if (chans == ChannelConfig_Stereo)
{
if (type == SampleType_UInt8) format = AL_FORMAT_STEREO8, samplesize = 2;
if (type == SampleType_Int16) format = AL_FORMAT_STEREO16, samplesize = 4;
}

ALenum format = GetFormat(type, chans);
if (format == AL_NONE)
{
SoundDecoder_Close(decoder);
Printf("Unsupported audio format: %s, %s\n", GetChannelConfigName(chans),
GetSampleTypeName(type));
return retval;
}
int samplesize = SampleTypeSize(type) * ChannelCount(chans);

std::vector<uint8_t> data;
unsigned total = 0;
Expand Down Expand Up @@ -1208,12 +1197,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;
Expand Down
2 changes: 1 addition & 1 deletion src/common/audio/sound/oalsound.h
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ class OpenALSoundRenderer : public SoundRenderer
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;
Expand Down