diff --git a/Ryujinx.HLE/OsHle/Services/Aud/AudErr.cs b/Ryujinx.HLE/OsHle/Services/Aud/AudErr.cs new file mode 100644 index 0000000000..ec5d054ebf --- /dev/null +++ b/Ryujinx.HLE/OsHle/Services/Aud/AudErr.cs @@ -0,0 +1,7 @@ +namespace Ryujinx.HLE.OsHle.Services.Aud +{ + static class AudErr + { + public const int OpusInvalidInput = 6; + } +} \ No newline at end of file diff --git a/Ryujinx.HLE/OsHle/Services/Aud/IHardwareOpusDecoder.cs b/Ryujinx.HLE/OsHle/Services/Aud/IHardwareOpusDecoder.cs index 7212e776c7..8ed560fd5b 100644 --- a/Ryujinx.HLE/OsHle/Services/Aud/IHardwareOpusDecoder.cs +++ b/Ryujinx.HLE/OsHle/Services/Aud/IHardwareOpusDecoder.cs @@ -2,6 +2,8 @@ using Concentus.Structs; using Ryujinx.HLE.OsHle.Ipc; using System.Collections.Generic; +using static Ryujinx.HLE.OsHle.ErrorCode; + namespace Ryujinx.HLE.OsHle.Services.Aud { class IHardwareOpusDecoder : IpcService @@ -35,16 +37,31 @@ namespace Ryujinx.HLE.OsHle.Services.Aud long InPosition = Context.Request.SendBuff[0].Position; long InSize = Context.Request.SendBuff[0].Size; + if (InSize < 8) + { + return MakeError(ErrorModule.Audio, AudErr.OpusInvalidInput); + } + long OutPosition = Context.Request.ReceiveBuff[0].Position; long OutSize = Context.Request.ReceiveBuff[0].Size; byte[] OpusData = Context.Memory.ReadBytes(InPosition, InSize); + int Processed = ((OpusData[0] << 0) | + (OpusData[1] << 8) | + (OpusData[2] << 16) | + (OpusData[3] << 24)) + 8; + + if (Processed > InSize) + { + return MakeError(ErrorModule.Audio, AudErr.OpusInvalidInput); + } + short[] Pcm = new short[OutSize / 2]; int FrameSize = Pcm.Length / (ChannelsCount * 2); - int Result = Decoder.Decode(OpusData, 0, OpusData.Length, Pcm, 0, FrameSize); + int Samples = Decoder.Decode(OpusData, 0, OpusData.Length, Pcm, 0, FrameSize); foreach (short Sample in Pcm) { @@ -53,6 +70,9 @@ namespace Ryujinx.HLE.OsHle.Services.Aud OutPosition += 2; } + Context.ResponseData.Write(Samples); + Context.ResponseData.Write(Processed); + return 0; } }