Beispiel #1
0
        public IAudioRenderer(
            Horizon system,
            MemoryManager memory,
            IAalOutput audioOut,
            AudioRendererParameter Params)
        {
            _updateEvent = new KEvent(system);

            _memory   = memory;
            _audioOut = audioOut;
            _params   = Params;

            _track = audioOut.OpenTrack(
                AudioConsts.HostSampleRate,
                AudioConsts.HostChannelsCount,
                AudioCallback);

            _memoryPools = CreateArray <MemoryPoolContext>(Params.EffectCount + Params.VoiceCount * 4);

            _voices = CreateArray <VoiceContext>(Params.VoiceCount);

            InitializeAudioOut();

            _playState = PlayState.Stopped;
        }
Beispiel #2
0
        public IAudioRenderer(AMemory Memory, IAalOutput AudioOut, AudioRendererParameter Params)
        {
            m_Commands = new Dictionary <int, ServiceProcessRequest>()
            {
                { 4, RequestUpdateAudioRenderer },
                { 5, StartAudioRenderer },
                { 6, StopAudioRenderer },
                { 7, QuerySystemEvent }
            };

            UpdateEvent = new KEvent();

            this.Memory   = Memory;
            this.AudioOut = AudioOut;
            this.Params   = Params;

            Track = AudioOut.OpenTrack(
                AudioConsts.HostSampleRate,
                AudioConsts.HostChannelsCount,
                AudioCallback);

            MemoryPools = CreateArray <MemoryPoolContext>(Params.EffectCount + Params.VoiceCount * 4);

            Voices = CreateArray <VoiceContext>(Params.VoiceCount);

            InitializeAudioOut();
        }
Beispiel #3
0
 public static long CalculateCommandBufferSize(AudioRendererParameter parameters)
 {
     return(parameters.EffectCount * 0x840 +
            parameters.SubMixCount * 0x5A38 +
            parameters.SinkCount * 0x148 +
            parameters.SplitterDestinationDataCount * 0x540 +
            (parameters.SplitterCount * 0x68 + 0x2E0) * parameters.VoiceCount +
            ((parameters.VoiceCount + parameters.SubMixCount + parameters.EffectCount + parameters.SinkCount + 0x65) << 6) +
            0x3F8);
 }
        // OpenAudioRenderer(nn::audio::detail::AudioRendererParameterInternal, u64, nn::applet::AppletResourceUserId, pid, handle<copy>, handle<copy>)
        // -> object<nn::audio::detail::IAudioRenderer>
        public ResultCode OpenAudioRenderer(ServiceCtx context)
        {
            IAalOutput audioOut = context.Device.AudioOut;

            AudioRendererParameter Params = GetAudioRendererParameter(context);

            MakeObject(context, new IAudioRenderer(
                           context.Device.System,
                           context.Memory,
                           audioOut,
                           Params));

            return(ResultCode.Success);
        }
        private AudioRendererParameter GetAudioRendererParameter(ServiceCtx context)
        {
            AudioRendererParameter Params = new AudioRendererParameter
            {
                SampleRate                   = context.RequestData.ReadInt32(),
                SampleCount                  = context.RequestData.ReadInt32(),
                MixBufferCount               = context.RequestData.ReadInt32(),
                SubMixCount                  = context.RequestData.ReadInt32(),
                VoiceCount                   = context.RequestData.ReadInt32(),
                SinkCount                    = context.RequestData.ReadInt32(),
                EffectCount                  = context.RequestData.ReadInt32(),
                PerformanceManagerCount      = context.RequestData.ReadInt32(),
                VoiceDropEnable              = context.RequestData.ReadInt32(),
                SplitterCount                = context.RequestData.ReadInt32(),
                SplitterDestinationDataCount = context.RequestData.ReadInt32(),
                Unknown2C                    = context.RequestData.ReadInt32(),
                Revision = context.RequestData.ReadInt32()
            };

            return(Params);
        }
Beispiel #6
0
        public IAudioRenderer(
            Horizon system,
            MemoryManager memory,
            IAalOutput audioOut,
            AudioRendererParameter Params)
        {
            _commands = new Dictionary <int, ServiceProcessRequest>
            {
                { 0, GetSampleRate },
                { 1, GetSampleCount },
                { 2, GetMixBufferCount },
                { 3, GetState },
                { 4, RequestUpdateAudioRenderer },
                { 5, StartAudioRenderer },
                { 6, StopAudioRenderer },
                { 7, QuerySystemEvent }
            };

            _updateEvent = new KEvent(system);

            _memory   = memory;
            _audioOut = audioOut;
            _params   = Params;

            _track = audioOut.OpenTrack(
                AudioConsts.HostSampleRate,
                AudioConsts.HostChannelsCount,
                AudioCallback);

            _memoryPools = CreateArray <MemoryPoolContext>(Params.EffectCount + Params.VoiceCount * 4);

            _voices = CreateArray <VoiceContext>(Params.VoiceCount);

            InitializeAudioOut();

            _playState = PlayState.Stopped;
        }
        // GetWorkBufferSize(nn::audio::detail::AudioRendererParameterInternal) -> u64
        public ResultCode GetAudioRendererWorkBufferSize(ServiceCtx context)
        {
            AudioRendererParameter parameters = GetAudioRendererParameter(context);

            if (AudioRendererCommon.CheckValidRevision(parameters))
            {
                BehaviorInfo behaviorInfo = new BehaviorInfo();

                behaviorInfo.SetUserLibRevision(parameters.Revision);

                long size;

                int totalMixCount = parameters.SubMixCount + 1;

                size = BitUtils.AlignUp(parameters.MixBufferCount * 4, AudioRendererConsts.BufferAlignment) +
                       parameters.SubMixCount * 0x400 +
                       totalMixCount * 0x940 +
                       parameters.VoiceCount * 0x3F0 +
                       BitUtils.AlignUp(totalMixCount * 8, 16) +
                       BitUtils.AlignUp(parameters.VoiceCount * 8, 16) +
                       BitUtils.AlignUp(((parameters.SinkCount + parameters.SubMixCount) * 0x3C0 + parameters.SampleCount * 4) *
                                        (parameters.MixBufferCount + 6), AudioRendererConsts.BufferAlignment) +
                       (parameters.SinkCount + parameters.SubMixCount) * 0x2C0 +
                       (parameters.EffectCount + parameters.VoiceCount * 4) * 0x30 +
                       0x50;

                if (behaviorInfo.IsSplitterSupported())
                {
                    size += BitUtils.AlignUp(NodeStates.GetWorkBufferSize(totalMixCount) + EdgeMatrix.GetWorkBufferSize(totalMixCount), 16);
                }

                size = parameters.SinkCount * 0x170 +
                       (parameters.SinkCount + parameters.SubMixCount) * 0x280 +
                       parameters.EffectCount * 0x4C0 +
                       ((size + SplitterContext.CalcWorkBufferSize(behaviorInfo, parameters) + 0x30 * parameters.EffectCount + (4 * parameters.VoiceCount) + 0x8F) & ~0x3FL) +
                       ((parameters.VoiceCount << 8) | 0x40);

                if (parameters.PerformanceManagerCount >= 1)
                {
                    size += (PerformanceManager.GetRequiredBufferSizeForPerformanceMetricsPerFrame(behaviorInfo, parameters) *
                             (parameters.PerformanceManagerCount + 1) + 0xFF) & ~0x3FL;
                }

                if (behaviorInfo.IsVariadicCommandBufferSizeSupported())
                {
                    size += CommandGenerator.CalculateCommandBufferSize(parameters) + 0x7E;
                }
                else
                {
                    size += 0x1807E;
                }

                size = BitUtils.AlignUp(size, 0x1000);

                context.ResponseData.Write(size);

                Logger.PrintDebug(LogClass.ServiceAudio, $"WorkBufferSize is 0x{size:x16}.");

                return(ResultCode.Success);
            }
            else
            {
                context.ResponseData.Write(0L);

                Logger.PrintWarning(LogClass.ServiceAudio, $"Library Revision REV{AudioRendererCommon.GetRevisionVersion(parameters.Revision)} is not supported!");

                return(ResultCode.UnsupportedRevision);
            }
        }
Beispiel #8
0
 public static bool CheckValidRevision(AudioRendererParameter parameters) => GetRevisionVersion(parameters.Revision) <= AudioRendererConsts.Revision;