Compare commits

...

3 Commits

Author SHA1 Message Date
FearlessTobi
272c102e0f audio_renderer: Add support for 6 channel mixing and correct the default case 2020-04-20 18:04:52 +02:00
bunnei
36ddf72f47 audio_renderer: mixing: Fix single-channel mixing and cleanups. 2020-04-20 18:02:40 +02:00
FearlessTobi
3177e22dd1 audio_renderer: Add voice mixing system 2020-04-20 18:02:40 +02:00
2 changed files with 54 additions and 2 deletions

View File

@@ -73,6 +73,20 @@ private:
EffectInStatus info{};
};
class AudioRenderer::ChannelState {
public:
const ChannelInfoIn& GetInfo() const {
return info;
}
ChannelInfoIn& GetInfo() {
return info;
}
private:
ChannelInfoIn info{};
};
AudioRenderer::AudioRenderer(Core::Timing::CoreTiming& core_timing, Core::Memory::Memory& memory_,
AudioRendererParameter params,
std::shared_ptr<Kernel::WritableEvent> buffer_event,
@@ -134,6 +148,15 @@ std::vector<u8> AudioRenderer::UpdateAudioRenderer(const std::vector<u8>& input_
voice_offset += sizeof(VoiceInfo);
}
std::size_t channel_offset{sizeof(UpdateDataHeader) + config.behavior_size +
config.memory_pools_size};
channels.resize((voice_offset - channel_offset) / sizeof(ChannelInfoIn));
for (auto& channel : channels) {
std::memcpy(&channel.GetInfo(), input_params.data() + channel_offset,
sizeof(ChannelInfoIn));
channel_offset += sizeof(ChannelInfoIn);
}
std::size_t effect_offset{sizeof(UpdateDataHeader) + config.behavior_size +
config.memory_pools_size + config.voice_resource_size +
config.voices_size};
@@ -332,6 +355,19 @@ static constexpr s16 ClampToS16(s32 value) {
return static_cast<s16>(std::clamp(value, -32768, 32767));
}
static std::size_t GetMixVolumeIndex(const VoiceInfo& voice_info, std::size_t offset) {
switch (voice_info.channel_count) {
case 1:
return 0;
case 2:
case 6:
return offset % 2;
default:
UNIMPLEMENTED_MSG("Unimplemented channel_count={}", voice_info.channel_count);
return 0;
}
}
void AudioRenderer::QueueMixedBuffer(Buffer::Tag tag) {
constexpr std::size_t BUFFER_SIZE{512};
std::vector<s16> buffer(BUFFER_SIZE * stream->GetNumChannels());
@@ -352,10 +388,16 @@ void AudioRenderer::QueueMixedBuffer(Buffer::Tag tag) {
samples_remaining -= samples.size() / stream->GetNumChannels();
// TODO(FearlessTobi): Implement Surround mixing
const auto& mix_volumes{channels[voice.GetInfo().id].GetInfo().mix_volume};
for (const auto& sample : samples) {
const s32 buffer_sample{buffer[offset]};
buffer[offset++] =
ClampToS16(buffer_sample + static_cast<s32>(sample * voice.GetInfo().volume));
// Index 0 is for the left channel, 1 is for the right channel
const float mix_volume{mix_volumes[GetMixVolumeIndex(voice.GetInfo(), offset)]};
buffer[offset++] = ClampToS16(
buffer_sample + static_cast<s32>(sample * voice.GetInfo().volume * mix_volume));
}
}
}

View File

@@ -148,6 +148,14 @@ struct VoiceOutStatus {
};
static_assert(sizeof(VoiceOutStatus) == 0x10, "VoiceOutStatus has wrong size");
struct ChannelInfoIn {
u32_le id;
std::array<float_le, 24> mix_volume;
bool is_used;
INSERT_PADDING_BYTES(11);
};
static_assert(sizeof(ChannelInfoIn) == 0x70, "ChannelInfoIn has wrong size");
struct AuxInfo {
std::array<u8, 24> input_mix_buffers;
std::array<u8, 24> output_mix_buffers;
@@ -235,11 +243,13 @@ public:
Stream::State GetStreamState() const;
private:
class ChannelState;
class EffectState;
class VoiceState;
AudioRendererParameter worker_params;
std::shared_ptr<Kernel::WritableEvent> buffer_event;
std::vector<ChannelState> channels;
std::vector<VoiceState> voices;
std::vector<EffectState> effects;
std::unique_ptr<AudioOut> audio_out;