diff options
Diffstat (limited to '')
-rw-r--r-- | src/audio_core/audio_renderer.cpp | 24 | ||||
-rw-r--r-- | src/audio_core/audio_renderer.h | 28 | ||||
-rw-r--r-- | src/audio_core/stream.cpp | 12 | ||||
-rw-r--r-- | src/audio_core/stream.h | 7 |
4 files changed, 50 insertions, 21 deletions
diff --git a/src/audio_core/audio_renderer.cpp b/src/audio_core/audio_renderer.cpp index 9a0939883..e6f38d600 100644 --- a/src/audio_core/audio_renderer.cpp +++ b/src/audio_core/audio_renderer.cpp @@ -73,13 +73,15 @@ private: EffectInStatus info{}; }; AudioRenderer::AudioRenderer(Core::Timing::CoreTiming& core_timing, AudioRendererParameter params, - Kernel::SharedPtr<Kernel::WritableEvent> buffer_event) + Kernel::SharedPtr<Kernel::WritableEvent> buffer_event, + std::size_t instance_number) : worker_params{params}, buffer_event{buffer_event}, voices(params.voice_count), effects(params.effect_count) { audio_out = std::make_unique<AudioCore::AudioOut>(); stream = audio_out->OpenStream(core_timing, STREAM_SAMPLE_RATE, STREAM_NUM_CHANNELS, - "AudioRenderer", [=]() { buffer_event->Signal(); }); + fmt::format("AudioRenderer-Instance{}", instance_number), + [=]() { buffer_event->Signal(); }); audio_out->StartStream(stream); QueueMixedBuffer(0); @@ -105,6 +107,11 @@ Stream::State AudioRenderer::GetStreamState() const { return stream->GetState(); } +static constexpr u32 VersionFromRevision(u32_le rev) { + // "REV7" -> 7 + return ((rev >> 24) & 0xff) - 0x30; +} + std::vector<u8> AudioRenderer::UpdateAudioRenderer(const std::vector<u8>& input_params) { // Copy UpdateDataHeader struct UpdateDataHeader config{}; @@ -164,6 +171,11 @@ std::vector<u8> AudioRenderer::UpdateAudioRenderer(const std::vector<u8>& input_ // Copy output header UpdateDataHeader response_data{worker_params}; std::vector<u8> output_params(response_data.total_size); + const auto audren_revision = VersionFromRevision(config.revision); + if (audren_revision >= 5) { + response_data.frame_count = 0x10; + response_data.total_size += 0x10; + } std::memcpy(output_params.data(), &response_data, sizeof(UpdateDataHeader)); // Copy output memory pool entries @@ -217,13 +229,15 @@ std::vector<s16> AudioRenderer::VoiceState::DequeueSamples(std::size_t sample_co if (offset == samples.size()) { offset = 0; - if (!wave_buffer.is_looping) { + if (!wave_buffer.is_looping && wave_buffer.buffer_sz) { SetWaveIndex(wave_index + 1); } - out_status.wave_buffer_consumed++; + if (wave_buffer.buffer_sz) { + out_status.wave_buffer_consumed++; + } - if (wave_buffer.end_of_stream) { + if (wave_buffer.end_of_stream || wave_buffer.buffer_sz == 0) { info.play_state = PlayState::Paused; } } diff --git a/src/audio_core/audio_renderer.h b/src/audio_core/audio_renderer.h index b2e5d336c..4f14b91cd 100644 --- a/src/audio_core/audio_renderer.h +++ b/src/audio_core/audio_renderer.h @@ -194,28 +194,32 @@ struct UpdateDataHeader { mixes_size = 0x0; sinks_size = config.sink_count * 0x20; performance_manager_size = 0x10; + frame_count = 0; total_size = sizeof(UpdateDataHeader) + behavior_size + memory_pools_size + voices_size + effects_size + sinks_size + performance_manager_size; } - u32_le revision; - u32_le behavior_size; - u32_le memory_pools_size; - u32_le voices_size; - u32_le voice_resource_size; - u32_le effects_size; - u32_le mixes_size; - u32_le sinks_size; - u32_le performance_manager_size; - INSERT_PADDING_WORDS(6); - u32_le total_size; + u32_le revision{}; + u32_le behavior_size{}; + u32_le memory_pools_size{}; + u32_le voices_size{}; + u32_le voice_resource_size{}; + u32_le effects_size{}; + u32_le mixes_size{}; + u32_le sinks_size{}; + u32_le performance_manager_size{}; + INSERT_PADDING_WORDS(1); + u32_le frame_count{}; + INSERT_PADDING_WORDS(4); + u32_le total_size{}; }; static_assert(sizeof(UpdateDataHeader) == 0x40, "UpdateDataHeader has wrong size"); class AudioRenderer { public: AudioRenderer(Core::Timing::CoreTiming& core_timing, AudioRendererParameter params, - Kernel::SharedPtr<Kernel::WritableEvent> buffer_event); + Kernel::SharedPtr<Kernel::WritableEvent> buffer_event, + std::size_t instance_number); ~AudioRenderer(); std::vector<u8> UpdateAudioRenderer(const std::vector<u8>& input_params); diff --git a/src/audio_core/stream.cpp b/src/audio_core/stream.cpp index 11481a776..6a5f53a57 100644 --- a/src/audio_core/stream.cpp +++ b/src/audio_core/stream.cpp @@ -51,6 +51,10 @@ void Stream::Stop() { UNIMPLEMENTED(); } +void Stream::SetVolume(float volume) { + game_volume = volume; +} + Stream::State Stream::GetState() const { return state; } @@ -62,8 +66,8 @@ s64 Stream::GetBufferReleaseCycles(const Buffer& buffer) const { return Core::Timing::usToCycles(us); } -static void VolumeAdjustSamples(std::vector<s16>& samples) { - const float volume{std::clamp(Settings::values.volume, 0.0f, 1.0f)}; +static void VolumeAdjustSamples(std::vector<s16>& samples, float game_volume) { + const float volume{std::clamp(Settings::values.volume - (1.0f - game_volume), 0.0f, 1.0f)}; if (volume == 1.0f) { return; @@ -97,11 +101,11 @@ void Stream::PlayNextBuffer() { active_buffer = queued_buffers.front(); queued_buffers.pop(); - VolumeAdjustSamples(active_buffer->GetSamples()); + VolumeAdjustSamples(active_buffer->GetSamples(), game_volume); sink_stream.EnqueueSamples(GetNumChannels(), active_buffer->GetSamples()); - core_timing.ScheduleEventThreadsafe(GetBufferReleaseCycles(*active_buffer), release_event, {}); + core_timing.ScheduleEvent(GetBufferReleaseCycles(*active_buffer), release_event, {}); } void Stream::ReleaseActiveBuffer() { diff --git a/src/audio_core/stream.h b/src/audio_core/stream.h index 05071243b..8106cea43 100644 --- a/src/audio_core/stream.h +++ b/src/audio_core/stream.h @@ -61,6 +61,12 @@ public: /// Returns a vector of recently released buffers specified by tag std::vector<Buffer::Tag> GetTagsAndReleaseBuffers(std::size_t max_count); + void SetVolume(float volume); + + float GetVolume() const { + return game_volume; + } + /// Returns true if the stream is currently playing bool IsPlaying() const { return state == State::Playing; @@ -94,6 +100,7 @@ private: u32 sample_rate; ///< Sample rate of the stream Format format; ///< Format of the stream + float game_volume = 1.0f; ///< The volume the game currently has set ReleaseCallback release_callback; ///< Buffer release callback for the stream State state{State::Stopped}; ///< Playback state of the stream Core::Timing::EventType* release_event{}; ///< Core timing release event for the stream |