diff --git a/src/xrSound/SoundRender_Emitter_FSM.cpp b/src/xrSound/SoundRender_Emitter_FSM.cpp index 24434bada57..82bbe2fe32e 100644 --- a/src/xrSound/SoundRender_Emitter_FSM.cpp +++ b/src/xrSound/SoundRender_Emitter_FSM.cpp @@ -8,7 +8,7 @@ XRSOUND_API extern float psSoundCull; -inline u32 calc_cursor(const float& fTimeStarted, float& fTime, const float& fTimeTotal, const float& fFreq, const WAVEFORMATEX& wfx) //--#SM+#-- +inline u32 calc_cursor(const float& fTimeStarted, float& fTime, const float& fTimeTotal, const float& fFreq, const SoundSourceInfo& info) //--#SM+#-- { if (fTime < fTimeStarted) fTime = fTimeStarted; // Андрюха посоветовал, ассерт что ниже вылетел из за паузы как то хитро @@ -17,8 +17,8 @@ inline u32 calc_cursor(const float& fTimeStarted, float& fTime, const float& fTi { fTime -= fTimeTotal / fFreq; } - u32 curr_sample_num = iFloor((fTime - fTimeStarted) * fFreq * wfx.nSamplesPerSec); - return curr_sample_num * (wfx.wBitsPerSample / 8) * wfx.nChannels; + const u32 curr_sample_num = iFloor((fTime - fTimeStarted) * fFreq * info.samplesPerSec); + return curr_sample_num * (info.bitsPerSample / 8) * info.channels; } void CSoundRender_Emitter::update(float fTime, float dt) @@ -151,7 +151,7 @@ void CSoundRender_Emitter::update(float fTime, float dt) } else { - const u32 ptr = calc_cursor(fTimeStarted, fTime, get_length_sec(), p_source.freq, source()->m_wformat); //--#SM+#-- + const u32 ptr = calc_cursor(fTimeStarted, fTime, get_length_sec(), p_source.freq, source()->m_info); //--#SM+#-- set_cursor(ptr); if (update_culling(dt)) @@ -162,7 +162,7 @@ void CSoundRender_Emitter::update(float fTime, float dt) u32 ptr = calc_cursor( fTimeStarted, fTime, get_length_sec(), - source()->m_wformat); + source()->m_info); set_cursor (ptr); */ SoundRender->i_start(this); @@ -204,7 +204,7 @@ void CSoundRender_Emitter::update(float fTime, float dt) { // switch to: PLAY m_current_state = stPlayingLooped; // switch state - const u32 ptr = calc_cursor(fTimeStarted, fTime, get_length_sec(), p_source.freq, source()->m_wformat); //--#SM+#-- + const u32 ptr = calc_cursor(fTimeStarted, fTime, get_length_sec(), p_source.freq, source()->m_info); //--#SM+#-- set_cursor(ptr); SoundRender->i_start(this); @@ -253,7 +253,7 @@ void CSoundRender_Emitter::update(float fTime, float dt) fTimeToStop = fTime + fRemainingTime; } - const u32 ptr = calc_cursor(fTimeStarted, fTime, fLength, p_source.freq, source()->m_wformat); + const u32 ptr = calc_cursor(fTimeStarted, fTime, fLength, p_source.freq, source()->m_info); set_cursor(ptr); fTimeToRewind = 0.0f; diff --git a/src/xrSound/SoundRender_Source.cpp b/src/xrSound/SoundRender_Source.cpp index e6238fba64a..482c74d18ee 100644 --- a/src/xrSound/SoundRender_Source.cpp +++ b/src/xrSound/SoundRender_Source.cpp @@ -57,13 +57,13 @@ void CSoundRender_Source::decompress(void* dest, u32 byte_offset, u32 size) std::lock_guard guard{ read_lock }; // seek - const auto sample_offset = ogg_int64_t(byte_offset / m_wformat.nBlockAlign); + const auto sample_offset = ogg_int64_t(byte_offset / m_info.blockAlign); const u32 cur_pos = u32(ov_pcm_tell(&ovf)); if (cur_pos != sample_offset) ov_pcm_seek(&ovf, sample_offset); // decompress - if (m_wformat.wFormatTag == WAVE_FORMAT_IEEE_FLOAT) + if (m_info.format == SoundFormat::Float32) i_decompress(static_cast(dest), size); else i_decompress(static_cast(dest), size); @@ -85,7 +85,7 @@ void CSoundRender_Source::i_decompress(char* _dest, u32 size) void CSoundRender_Source::i_decompress(float* _dest, u32 size) { - s32 left = s32(size / m_wformat.nBlockAlign); + s32 left = s32(size / m_info.blockAlign); while (left) { float** pcm; @@ -98,7 +98,7 @@ void CSoundRender_Source::i_decompress(float* _dest, u32 size) samples = left; for (long j = 0; j < samples; j++) - for (long i = 0; i < m_wformat.nChannels; i++) + for (long i = 0; i < m_info.channels; i++) *_dest++ = pcm[i][j]; left -= samples; @@ -184,28 +184,29 @@ bool CSoundRender_Source::LoadWave(pcstr pName, bool crashOnError) return false; }); - ZeroMemory(&m_wformat, sizeof(WAVEFORMATEX)); + m_info = {}; - m_wformat.nSamplesPerSec = ovi->rate; - m_wformat.nChannels = u16(ovi->channels); + m_info.samplesPerSec = ovi->rate; + m_info.channels = u16(ovi->channels); if (SoundRender->supports_float_pcm) { - m_wformat.wFormatTag = WAVE_FORMAT_IEEE_FLOAT; - m_wformat.wBitsPerSample = 32; + m_info.format = SoundFormat::Float32; + m_info.bitsPerSample = 32; } else { - m_wformat.wFormatTag = WAVE_FORMAT_PCM; - m_wformat.wBitsPerSample = 16; + m_info.format = SoundFormat::PCM; + m_info.bitsPerSample = 16; } - m_wformat.nBlockAlign = m_wformat.wBitsPerSample / 8 * m_wformat.nChannels; - m_wformat.nAvgBytesPerSec = m_wformat.nSamplesPerSec * m_wformat.nBlockAlign; + m_info.blockAlign = m_info.bitsPerSample / 8 * m_info.channels; + m_info.avgBytesPerSec = m_info.samplesPerSec * m_info.blockAlign; + m_info.bytesPerBuffer = sdef_target_block * m_info.avgBytesPerSec / 1000; const s64 pcm_total = ov_pcm_total(&ovf, -1); - dwBytesTotal = u32(pcm_total * m_wformat.nBlockAlign); - fTimeTotal = dwBytesTotal / float(m_wformat.nAvgBytesPerSec); + dwBytesTotal = u32(pcm_total * m_info.blockAlign); + fTimeTotal = dwBytesTotal / float(m_info.avgBytesPerSec); const vorbis_comment* ovm = ov_comment(&ovf, -1); if (ovm->comments) diff --git a/src/xrSound/SoundRender_Source.h b/src/xrSound/SoundRender_Source.h index c80b88e44f0..6592fdb57af 100644 --- a/src/xrSound/SoundRender_Source.h +++ b/src/xrSound/SoundRender_Source.h @@ -4,6 +4,24 @@ #include +enum class SoundFormat +{ + Unknown, + PCM, + Float32, +}; + +struct SoundSourceInfo +{ + SoundFormat format{}; + u16 channels{}; // number of channels (i.e. mono, stereo...) + u32 samplesPerSec{}; // sample rate + u32 avgBytesPerSec{}; // for buffer estimation + u16 blockAlign{}; // block size of data + u16 bitsPerSample{}; // number of bits per sample of mono data + u32 bytesPerBuffer{}; // target buffer size +}; + class XRSOUND_API CSoundRender_Source final : public CSound_source { public: @@ -18,7 +36,7 @@ class XRSOUND_API CSoundRender_Source final : public CSound_source float fTimeTotal; u32 dwBytesTotal; - WAVEFORMATEX m_wformat; + SoundSourceInfo m_info{}; float m_fBaseVolume; float m_fMinDist; @@ -48,6 +66,6 @@ class XRSOUND_API CSoundRender_Source final : public CSound_source [[nodiscard]] u32 game_type() const override { return m_uGameType; } [[nodiscard]] pcstr file_name() const override { return *fname; } [[nodiscard]] float base_volume() const { return m_fBaseVolume; } - [[nodiscard]] u16 channels_num() const override { return m_wformat.nChannels; } + [[nodiscard]] u16 channels_num() const override { return m_info.channels; } [[nodiscard]] u32 bytes_total() const override { return dwBytesTotal; } }; diff --git a/src/xrSound/SoundRender_Target.cpp b/src/xrSound/SoundRender_Target.cpp index 0eb009fc070..41a47480ebb 100644 --- a/src/xrSound/SoundRender_Target.cpp +++ b/src/xrSound/SoundRender_Target.cpp @@ -29,9 +29,8 @@ void CSoundRender_Target::start(CSoundRender_Emitter* E) //m_pEmitter->source()->attach(); // Calc storage - buf_block = sdef_target_block * E->source()->m_wformat.nAvgBytesPerSec / 1000; for (auto& buf : temp_buf) - buf.resize(buf_block); + buf.resize(E->source()->m_info.bytesPerBuffer); } void CSoundRender_Target::render() @@ -69,7 +68,7 @@ void CSoundRender_Target::fill_parameters() void CSoundRender_Target::fill_block(size_t idx) { R_ASSERT(m_pEmitter); - m_pEmitter->fill_block(temp_buf[idx].data(), buf_block); + m_pEmitter->fill_block(temp_buf[idx].data(), temp_buf[idx].size()); } void CSoundRender_Target::fill_all_blocks() diff --git a/src/xrSound/SoundRender_Target.h b/src/xrSound/SoundRender_Target.h index cd9cf9f4af8..ecfb0926e46 100644 --- a/src/xrSound/SoundRender_Target.h +++ b/src/xrSound/SoundRender_Target.h @@ -10,7 +10,6 @@ class CSoundRender_Target CSoundRender_Emitter* m_pEmitter{}; bool rendering{}; - u32 buf_block{}; xr_vector temp_buf[sdef_target_count]; void fill_block(size_t idx); void fill_all_blocks(); diff --git a/src/xrSound/SoundRender_TargetA.cpp b/src/xrSound/SoundRender_TargetA.cpp index 3d772134d2f..9ed2d05c0ab 100644 --- a/src/xrSound/SoundRender_TargetA.cpp +++ b/src/xrSound/SoundRender_TargetA.cpp @@ -110,7 +110,7 @@ void CSoundRender_TargetA::update() A_CHK(alSourceUnqueueBuffers(pSource, 1, &BufferID)); const auto id = get_block_id(BufferID); - submit_buffer(BufferID, temp_buf[id].data()); + submit_buffer(BufferID, temp_buf[id].data(), temp_buf[id].size()); A_CHK(alSourceQueueBuffers(pSource, 1, &BufferID)); processed--; @@ -201,26 +201,26 @@ size_t CSoundRender_TargetA::get_block_id(ALuint BufferID) const return it - std::begin(pBuffers); } -void CSoundRender_TargetA::submit_buffer(ALuint BufferID, const void* data) const +void CSoundRender_TargetA::submit_buffer(ALuint BufferID, const void* data, size_t dataSize) const { R_ASSERT(m_pEmitter); - const auto& wvf = m_pEmitter->source()->m_wformat; - const bool mono = wvf.nChannels == 1; + const auto& info = m_pEmitter->source()->m_info; + const bool mono = info.channels == 1; ALuint format; - if (wvf.wFormatTag == WAVE_FORMAT_IEEE_FLOAT) + if (info.format == SoundFormat::Float32) format = mono ? AL_FORMAT_MONO_FLOAT32 : AL_FORMAT_STEREO_FLOAT32; else { format = mono ? AL_FORMAT_MONO16 : AL_FORMAT_STEREO16; } - A_CHK(alBufferData(BufferID, format, data, buf_block, m_pEmitter->source()->m_wformat.nSamplesPerSec)); + A_CHK(alBufferData(BufferID, format, data, dataSize, info.samplesPerSec)); } void CSoundRender_TargetA::submit_all_buffers() const { for (size_t i = 0; i < sdef_target_count; ++i) - submit_buffer(pBuffers[i], temp_buf[i].data()); + submit_buffer(pBuffers[i], temp_buf[i].data(), temp_buf[i].size()); } diff --git a/src/xrSound/SoundRender_TargetA.h b/src/xrSound/SoundRender_TargetA.h index 12bf5d81f27..9ede60b3f97 100644 --- a/src/xrSound/SoundRender_TargetA.h +++ b/src/xrSound/SoundRender_TargetA.h @@ -16,7 +16,7 @@ class CSoundRender_TargetA : public CSoundRender_Target float cache_pitch{ 1.0f }; size_t get_block_id(ALuint BufferID) const; - void submit_buffer(ALuint BufferID, const void* data) const; + void submit_buffer(ALuint BufferID, const void* data, size_t dataSize) const; void submit_all_buffers() const; public: diff --git a/src/xrSound/stdafx.h b/src/xrSound/stdafx.h index 52b1529fc67..210532c408e 100644 --- a/src/xrSound/stdafx.h +++ b/src/xrSound/stdafx.h @@ -8,26 +8,3 @@ #include "xrCDB/xrCDB.h" #include "Sound.h" - -#if defined(XR_PLATFORM_WINDOWS) -// mmreg.h -#define NOMMIDS -#define NONEWRIFF -#define NOJPEGDIB -#define NONEWIC -#define NOBITMAP -#include -#else -#define WAVE_FORMAT_PCM 0x0001 -#define WAVE_FORMAT_IEEE_FLOAT 0x0003 - -typedef struct { - WORD wFormatTag; - WORD nChannels; - DWORD nSamplesPerSec; - DWORD nAvgBytesPerSec; - WORD nBlockAlign; - WORD wBitsPerSample; - WORD cbSize; -} WAVEFORMATEX, *LPWAVEFORMATEX; -#endif