diff options
author | gdkchan <gab.dark.100@gmail.com> | 2018-11-17 01:36:49 -0200 |
---|---|---|
committer | Ac_K <Acoustik666@gmail.com> | 2018-11-17 04:36:49 +0100 |
commit | b833183ef640934e82106cb91f7ced65d81e3b07 (patch) | |
tree | 9d0f7c8008e5d65d86550d66a11d1662e36a2e21 /Ryujinx.HLE/HOS/Services/Aud/IHardwareOpusDecoderManager.cs | |
parent | 5829e36a5cf5c1586dc8ebb5b52f99b7f61605b6 (diff) |
HwOpus service implementation (#201)
* Started to implement the hwopus service
* Write outputs on decode method, some basic error handling
* Fix buffer size read from header and check
* Fix order of values
Diffstat (limited to 'Ryujinx.HLE/HOS/Services/Aud/IHardwareOpusDecoderManager.cs')
-rw-r--r-- | Ryujinx.HLE/HOS/Services/Aud/IHardwareOpusDecoderManager.cs | 72 |
1 files changed, 72 insertions, 0 deletions
diff --git a/Ryujinx.HLE/HOS/Services/Aud/IHardwareOpusDecoderManager.cs b/Ryujinx.HLE/HOS/Services/Aud/IHardwareOpusDecoderManager.cs new file mode 100644 index 00000000..875dc74c --- /dev/null +++ b/Ryujinx.HLE/HOS/Services/Aud/IHardwareOpusDecoderManager.cs @@ -0,0 +1,72 @@ +using Ryujinx.HLE.HOS.Ipc; +using System.Collections.Generic; + +namespace Ryujinx.HLE.HOS.Services.Aud +{ + class IHardwareOpusDecoderManager : IpcService + { + private Dictionary<int, ServiceProcessRequest> m_Commands; + + public override IReadOnlyDictionary<int, ServiceProcessRequest> Commands => m_Commands; + + public IHardwareOpusDecoderManager() + { + m_Commands = new Dictionary<int, ServiceProcessRequest>() + { + { 0, Initialize }, + { 1, GetWorkBufferSize } + }; + } + + public long Initialize(ServiceCtx Context) + { + int SampleRate = Context.RequestData.ReadInt32(); + int ChannelsCount = Context.RequestData.ReadInt32(); + + MakeObject(Context, new IHardwareOpusDecoder(SampleRate, ChannelsCount)); + + return 0; + } + + public long GetWorkBufferSize(ServiceCtx Context) + { + //Note: The sample rate is ignored because it is fixed to 48KHz. + int SampleRate = Context.RequestData.ReadInt32(); + int ChannelsCount = Context.RequestData.ReadInt32(); + + Context.ResponseData.Write(GetOpusDecoderSize(ChannelsCount)); + + return 0; + } + + private static int GetOpusDecoderSize(int ChannelsCount) + { + const int SilkDecoderSize = 0x2198; + + if (ChannelsCount < 1 || ChannelsCount > 2) + { + return 0; + } + + int CeltDecoderSize = GetCeltDecoderSize(ChannelsCount); + + int OpusDecoderSize = (ChannelsCount * 0x800 + 0x4807) & -0x800 | 0x50; + + return OpusDecoderSize + SilkDecoderSize + CeltDecoderSize; + } + + private static int GetCeltDecoderSize(int ChannelsCount) + { + const int DecodeBufferSize = 0x2030; + const int CeltDecoderSize = 0x58; + const int CeltSigSize = 0x4; + const int Overlap = 120; + const int EBandsCount = 21; + + return (DecodeBufferSize + Overlap * 4) * ChannelsCount + + EBandsCount * 16 + + CeltDecoderSize + + CeltSigSize; + } + } +} |