// RequestUpdateAudioRenderer(buffer<nn::audio::detail::AudioRendererUpdateDataHeader, 5>) // -> (buffer<nn::audio::detail::AudioRendererUpdateDataHeader, 6>, buffer<nn::audio::detail::AudioRendererUpdateDataHeader, 6>) public ResultCode RequestUpdateAudioRenderer(ServiceCtx context) { long outputPosition = context.Request.ReceiveBuff[0].Position; long outputSize = context.Request.ReceiveBuff[0].Size; MemoryHelper.FillWithZeros(context.Memory, outputPosition, (int)outputSize); long inputPosition = context.Request.SendBuff[0].Position; StructReader reader = new StructReader(context.Memory, inputPosition); StructWriter writer = new StructWriter(context.Memory, outputPosition); UpdateDataHeader inputHeader = reader.Read <UpdateDataHeader>(); BehaviorInfo behaviorInfo = new BehaviorInfo(); behaviorInfo.SetUserLibRevision(inputHeader.Revision); reader.Read <BehaviorIn>(inputHeader.BehaviorSize); MemoryPoolIn[] memoryPoolsIn = reader.Read <MemoryPoolIn>(inputHeader.MemoryPoolSize); for (int index = 0; index < memoryPoolsIn.Length; index++) { MemoryPoolIn memoryPool = memoryPoolsIn[index]; if (memoryPool.State == MemoryPoolState.RequestAttach) { _memoryPools[index].OutStatus.State = MemoryPoolState.Attached; } else if (memoryPool.State == MemoryPoolState.RequestDetach) { _memoryPools[index].OutStatus.State = MemoryPoolState.Detached; } } reader.Read <VoiceChannelResourceIn>(inputHeader.VoiceResourceSize); VoiceIn[] voicesIn = reader.Read <VoiceIn>(inputHeader.VoiceSize); for (int index = 0; index < voicesIn.Length; index++) { VoiceIn voice = voicesIn[index]; VoiceContext voiceCtx = _voices[index]; voiceCtx.SetAcquireState(voice.Acquired != 0); if (voice.Acquired == 0) { continue; } if (voice.FirstUpdate != 0) { voiceCtx.AdpcmCtx = GetAdpcmDecoderContext( voice.AdpcmCoeffsPosition, voice.AdpcmCoeffsSize); voiceCtx.SampleFormat = voice.SampleFormat; voiceCtx.SampleRate = voice.SampleRate; voiceCtx.ChannelsCount = voice.ChannelsCount; voiceCtx.SetBufferIndex(voice.BaseWaveBufferIndex); } voiceCtx.WaveBuffers[0] = voice.WaveBuffer0; voiceCtx.WaveBuffers[1] = voice.WaveBuffer1; voiceCtx.WaveBuffers[2] = voice.WaveBuffer2; voiceCtx.WaveBuffers[3] = voice.WaveBuffer3; voiceCtx.Volume = voice.Volume; voiceCtx.PlayState = voice.PlayState; } EffectIn[] effectsIn = reader.Read <EffectIn>(inputHeader.EffectSize); for (int index = 0; index < effectsIn.Length; index++) { if (effectsIn[index].IsNew != 0) { _effects[index].OutStatus.State = EffectState.New; } } UpdateAudio(); UpdateDataHeader outputHeader = new UpdateDataHeader(); int updateHeaderSize = Marshal.SizeOf <UpdateDataHeader>(); outputHeader.Revision = AudioRendererConsts.RevMagic; outputHeader.BehaviorSize = 0xb0; outputHeader.MemoryPoolSize = (_params.EffectCount + _params.VoiceCount * 4) * 0x10; outputHeader.VoiceSize = _params.VoiceCount * 0x10; outputHeader.EffectSize = _params.EffectCount * 0x10; outputHeader.SinkSize = _params.SinkCount * 0x20; outputHeader.PerformanceManagerSize = 0x10; if (behaviorInfo.IsElapsedFrameCountSupported()) { outputHeader.ElapsedFrameCountInfoSize = 0x10; } outputHeader.TotalSize = updateHeaderSize + outputHeader.BehaviorSize + outputHeader.MemoryPoolSize + outputHeader.VoiceSize + outputHeader.EffectSize + outputHeader.SinkSize + outputHeader.PerformanceManagerSize + outputHeader.ElapsedFrameCountInfoSize; writer.Write(outputHeader); foreach (MemoryPoolContext memoryPool in _memoryPools) { writer.Write(memoryPool.OutStatus); } foreach (VoiceContext voice in _voices) { writer.Write(voice.OutStatus); } foreach (EffectContext effect in _effects) { writer.Write(effect.OutStatus); } writer.SkipBytes(_params.SinkCount * 0x20); writer.SkipBytes(outputHeader.PerformanceManagerSize); writer.SkipBytes(outputHeader.BehaviorSize); if (behaviorInfo.IsElapsedFrameCountSupported()) { writer.Write(new RendererInfoOut { ElapsedFrameCount = _elapsedFrameCount }); } return(ResultCode.Success); }