aboutsummaryrefslogtreecommitdiff
path: root/Ryujinx.HLE/HOS/Services/Audio/HardwareOpusDecoderManager/IHardwareOpusDecoder.cs
diff options
context:
space:
mode:
authorAc_K <Acoustik666@gmail.com>2019-09-19 02:45:11 +0200
committerjduncanator <1518948+jduncanator@users.noreply.github.com>2019-09-19 10:45:11 +1000
commita0720b5681852f3d786d77bd3793b0359dea321c (patch)
tree9d8f61e540d1d1d827999902dad95e5c0c1e076e /Ryujinx.HLE/HOS/Services/Audio/HardwareOpusDecoderManager/IHardwareOpusDecoder.cs
parent4af3101b22e6957d6aa48a2768566d658699f4ed (diff)
Refactoring HOS folder structure (#771)
* Refactoring HOS folder structure Refactoring HOS folder structure: - Added some subfolders when needed (Following structure decided in private). - Added some `Types` folders when needed. - Little cleanup here and there. - Add services placeholders for every HOS services (close #766 and #753). * Remove Types namespaces
Diffstat (limited to 'Ryujinx.HLE/HOS/Services/Audio/HardwareOpusDecoderManager/IHardwareOpusDecoder.cs')
-rw-r--r--Ryujinx.HLE/HOS/Services/Audio/HardwareOpusDecoderManager/IHardwareOpusDecoder.cs81
1 files changed, 81 insertions, 0 deletions
diff --git a/Ryujinx.HLE/HOS/Services/Audio/HardwareOpusDecoderManager/IHardwareOpusDecoder.cs b/Ryujinx.HLE/HOS/Services/Audio/HardwareOpusDecoderManager/IHardwareOpusDecoder.cs
new file mode 100644
index 00000000..e23398df
--- /dev/null
+++ b/Ryujinx.HLE/HOS/Services/Audio/HardwareOpusDecoderManager/IHardwareOpusDecoder.cs
@@ -0,0 +1,81 @@
+using Concentus.Structs;
+
+namespace Ryujinx.HLE.HOS.Services.Audio.HardwareOpusDecoderManager
+{
+ class IHardwareOpusDecoder : IpcService
+ {
+ private const int FixedSampleRate = 48000;
+
+ private int _sampleRate;
+ private int _channelsCount;
+
+ private OpusDecoder _decoder;
+
+ public IHardwareOpusDecoder(int sampleRate, int channelsCount)
+ {
+ _sampleRate = sampleRate;
+ _channelsCount = channelsCount;
+
+ _decoder = new OpusDecoder(FixedSampleRate, channelsCount);
+ }
+
+ [Command(0)]
+ // DecodeInterleaved(buffer<unknown, 5>) -> (u32, u32, buffer<unknown, 6>)
+ public ResultCode DecodeInterleaved(ServiceCtx context)
+ {
+ long inPosition = context.Request.SendBuff[0].Position;
+ long inSize = context.Request.SendBuff[0].Size;
+
+ if (inSize < 8)
+ {
+ return ResultCode.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] << 24) |
+ (opusData[1] << 16) |
+ (opusData[2] << 8) |
+ (opusData[3] << 0)) + 8;
+
+ if ((uint)processed > (ulong)inSize)
+ {
+ return ResultCode.OpusInvalidInput;
+ }
+
+ short[] pcm = new short[outSize / 2];
+
+ int frameSize = pcm.Length / (_channelsCount * 2);
+
+ int samples = _decoder.Decode(opusData, 0, opusData.Length, pcm, 0, frameSize);
+
+ foreach (short sample in pcm)
+ {
+ context.Memory.WriteInt16(outPosition, sample);
+
+ outPosition += 2;
+ }
+
+ context.ResponseData.Write(processed);
+ context.ResponseData.Write(samples);
+
+ return ResultCode.Success;
+ }
+
+ [Command(4)]
+ // DecodeInterleavedWithPerf(buffer<unknown, 5>) -> (u32, u32, u64, buffer<unknown, 0x46>)
+ public ResultCode DecodeInterleavedWithPerf(ServiceCtx context)
+ {
+ ResultCode result = DecodeInterleaved(context);
+
+ // TODO: Figure out what this value is.
+ // According to switchbrew, it is now used.
+ context.ResponseData.Write(0L);
+
+ return result;
+ }
+ }
+} \ No newline at end of file