Example #1
0
        public void Update <T>(out BehaviourParameter.ErrorInfo updateErrorInfo, ref T parameter, PoolMapper mapper) where T : unmanaged, IEffectInParameter
        {
            Debug.Assert(IsTypeValid(ref parameter));

            UpdateParameterBase(ref parameter);

            Parameter = MemoryMarshal.Cast <byte, AuxiliaryBufferParameter>(parameter.SpecificData)[0];
            IsEnabled = parameter.IsEnabled;

            updateErrorInfo = new BehaviourParameter.ErrorInfo();

            if (BufferUnmapped || parameter.IsNew)
            {
                ulong bufferSize = (ulong)Unsafe.SizeOf <int>() * Parameter.BufferStorageSize + (ulong)Unsafe.SizeOf <AuxiliaryBufferHeader>();

                bool sendBufferUnmapped   = !mapper.TryAttachBuffer(out updateErrorInfo, ref WorkBuffers[0], Parameter.SendBufferInfoAddress, bufferSize);
                bool returnBufferUnmapped = !mapper.TryAttachBuffer(out updateErrorInfo, ref WorkBuffers[1], Parameter.ReturnBufferInfoAddress, bufferSize);

                BufferUnmapped = sendBufferUnmapped && returnBufferUnmapped;

                if (!BufferUnmapped)
                {
                    DspAddress sendDspAddress   = WorkBuffers[0].GetReference(false);
                    DspAddress returnDspAddress = WorkBuffers[1].GetReference(false);

                    State.SendBufferInfo     = sendDspAddress + (uint)Unsafe.SizeOf <AuxiliaryBufferInfo>();
                    State.SendBufferInfoBase = sendDspAddress + (uint)Unsafe.SizeOf <AuxiliaryBufferHeader>();

                    State.ReturnBufferInfo     = returnDspAddress + (uint)Unsafe.SizeOf <AuxiliaryBufferInfo>();
                    State.ReturnBufferInfoBase = returnDspAddress + (uint)Unsafe.SizeOf <AuxiliaryBufferHeader>();
                }
            }
        }
Example #2
0
        public void Update <T>(out BehaviourParameter.ErrorInfo updateErrorInfo, ref T parameter, PoolMapper mapper) where T : unmanaged, IEffectInParameter
        {
            Debug.Assert(IsTypeValid(ref parameter));

            UpdateParameterBase(ref parameter);

            Parameter = MemoryMarshal.Cast <byte, AuxiliaryBufferParameter>(parameter.SpecificData)[0];
            IsEnabled = parameter.IsEnabled;

            updateErrorInfo = new BehaviourParameter.ErrorInfo();

            if (BufferUnmapped || parameter.IsNew)
            {
                ulong bufferSize = (ulong)Unsafe.SizeOf <int>() * Parameter.BufferStorageSize + (ulong)Unsafe.SizeOf <AuxiliaryBufferHeader>();

                bool sendBufferUnmapped = !mapper.TryAttachBuffer(out updateErrorInfo, ref WorkBuffers[0], Parameter.SendBufferInfoAddress, bufferSize);

                BufferUnmapped = sendBufferUnmapped;

                if (!BufferUnmapped)
                {
                    DspAddress sendDspAddress = WorkBuffers[0].GetReference(false);

                    // NOTE: Nintendo directly interact with the CPU side structure in the processing of the DSP command.
                    State.SendBufferInfo       = sendDspAddress;
                    State.SendBufferInfoBase   = sendDspAddress + (ulong)Unsafe.SizeOf <AuxiliaryBufferHeader>();
                    State.ReturnBufferInfo     = 0;
                    State.ReturnBufferInfoBase = 0;
                }
            }
        }
Example #3
0
        /// <summary>
        /// Update the internal state from a user parameter.
        /// </summary>
        /// <param name="outErrorInfo">The possible <see cref="ErrorInfo"/> that was generated.</param>
        /// <param name="parameter">The user parameter.</param>
        /// <param name="poolMapper">The mapper to use.</param>
        /// <param name="behaviourContext">The behaviour context.</param>
        public void UpdateParameters(out ErrorInfo outErrorInfo, ref VoiceInParameter parameter, ref PoolMapper poolMapper, ref BehaviourContext behaviourContext)
        {
            InUse  = parameter.InUse;
            Id     = parameter.Id;
            NodeId = parameter.NodeId;

            UpdatePlayState(parameter.PlayState);

            SrcQuality = parameter.SrcQuality;

            Priority      = parameter.Priority;
            SortingOrder  = parameter.SortingOrder;
            SampleRate    = parameter.SampleRate;
            SampleFormat  = parameter.SampleFormat;
            ChannelsCount = parameter.ChannelCount;
            Pitch         = parameter.Pitch;
            Volume        = parameter.Volume;
            parameter.BiquadFilters.ToSpan().CopyTo(BiquadFilters.ToSpan());
            WaveBuffersCount = parameter.WaveBuffersCount;
            WaveBuffersIndex = parameter.WaveBuffersIndex;

            if (behaviourContext.IsFlushVoiceWaveBuffersSupported())
            {
                FlushWaveBufferCount += parameter.FlushWaveBufferCount;
            }

            MixId = parameter.MixId;

            if (behaviourContext.IsSplitterSupported())
            {
                SplitterId = parameter.SplitterId;
            }
            else
            {
                SplitterId = RendererConstants.UnusedSplitterId;
            }

            parameter.ChannelResourceIds.ToSpan().CopyTo(ChannelResourceIds.ToSpan());

            DecodingBehaviour behaviour = DecodingBehaviour.Default;

            if (behaviourContext.IsDecodingBehaviourFlagSupported())
            {
                behaviour = parameter.DecodingBehaviourFlags;
            }

            DecodingBehaviour = behaviour;

            if (parameter.ResetVoiceDropFlag)
            {
                VoiceDropFlag = false;
            }

            if (ShouldUpdateParameters(ref parameter))
            {
                DataSourceStateUnmapped = !poolMapper.TryAttachBuffer(out outErrorInfo, ref DataSourceStateAddressInfo, parameter.DataSourceStateAddress, parameter.DataSourceStateSize);
            }
            else
            {
                outErrorInfo = new ErrorInfo();
            }
        }
Example #4
0
        public void TestTryAttachBuffer()
        {
            const CpuAddress CpuAddress = 0x20000;
            const DspAddress DspAddress = CpuAddress; // TODO: DSP LLE
            const ulong      CpuSize    = 0x1000;

            const int        MemoryPoolStateArraySize = 0x10;
            const CpuAddress CpuAddressRegionEnding   = CpuAddress * MemoryPoolStateArraySize;

            MemoryPoolState[] memoryPoolStateArray = new MemoryPoolState[MemoryPoolStateArraySize];

            for (int i = 0; i < memoryPoolStateArray.Length; i++)
            {
                memoryPoolStateArray[i] = MemoryPoolState.Create(MemoryPoolState.LocationType.Cpu);
                memoryPoolStateArray[i].SetCpuAddress(CpuAddress + (ulong)i * CpuSize, CpuSize);
            }

            ErrorInfo errorInfo;

            AddressInfo addressInfo = AddressInfo.Create();

            PoolMapper poolMapper = new PoolMapper(DummyProcessHandle, true);

            Assert.IsTrue(poolMapper.TryAttachBuffer(out errorInfo, ref addressInfo, 0, 0));

            Assert.AreEqual(ResultCode.InvalidAddressInfo, errorInfo.ErrorCode);
            Assert.AreEqual(0, errorInfo.ExtraErrorInfo);
            Assert.AreEqual(0, addressInfo.ForceMappedDspAddress);

            Assert.IsTrue(poolMapper.TryAttachBuffer(out errorInfo, ref addressInfo, CpuAddress, CpuSize));

            Assert.AreEqual(ResultCode.InvalidAddressInfo, errorInfo.ErrorCode);
            Assert.AreEqual(CpuAddress, errorInfo.ExtraErrorInfo);
            Assert.AreEqual(DspAddress, addressInfo.ForceMappedDspAddress);

            poolMapper = new PoolMapper(DummyProcessHandle, false);

            Assert.IsFalse(poolMapper.TryAttachBuffer(out errorInfo, ref addressInfo, 0, 0));

            addressInfo.ForceMappedDspAddress = 0;

            Assert.IsFalse(poolMapper.TryAttachBuffer(out errorInfo, ref addressInfo, CpuAddress, CpuSize));

            Assert.AreEqual(ResultCode.InvalidAddressInfo, errorInfo.ErrorCode);
            Assert.AreEqual(CpuAddress, errorInfo.ExtraErrorInfo);
            Assert.AreEqual(0, addressInfo.ForceMappedDspAddress);

            poolMapper = new PoolMapper(DummyProcessHandle, memoryPoolStateArray.AsMemory(), false);

            Assert.IsFalse(poolMapper.TryAttachBuffer(out errorInfo, ref addressInfo, CpuAddressRegionEnding, CpuSize));

            Assert.AreEqual(ResultCode.InvalidAddressInfo, errorInfo.ErrorCode);
            Assert.AreEqual(CpuAddressRegionEnding, errorInfo.ExtraErrorInfo);
            Assert.AreEqual(0, addressInfo.ForceMappedDspAddress);
            Assert.IsFalse(addressInfo.HasMemoryPoolState);

            Assert.IsTrue(poolMapper.TryAttachBuffer(out errorInfo, ref addressInfo, CpuAddress, CpuSize));

            Assert.AreEqual(ResultCode.Success, errorInfo.ErrorCode);
            Assert.AreEqual(0, errorInfo.ExtraErrorInfo);
            Assert.AreEqual(0, addressInfo.ForceMappedDspAddress);
            Assert.IsTrue(addressInfo.HasMemoryPoolState);
        }