/// <summary> /// Initialize <see cref="SplitterContext"/>. /// </summary> /// <param name="behaviourContext">The behaviour context.</param> /// <param name="parameter">The audio renderer configuration.</param> /// <param name="workBufferAllocator">The <see cref="WorkBufferAllocator"/>.</param> /// <returns>Return true if the initialization was successful.</returns> public bool Initialize(ref BehaviourContext behaviourContext, ref AudioRendererConfiguration parameter, WorkBufferAllocator workBufferAllocator) { if (!behaviourContext.IsSplitterSupported() || parameter.SplitterCount <= 0 || parameter.SplitterDestinationCount <= 0) { Setup(Memory <SplitterState> .Empty, Memory <SplitterDestination> .Empty, false); return(true); } Memory <SplitterState> splitters = workBufferAllocator.Allocate <SplitterState>(parameter.SplitterCount, SplitterState.Alignment); if (splitters.IsEmpty) { return(false); } int splitterId = 0; foreach (ref SplitterState splitter in splitters.Span) { splitter = new SplitterState(splitterId++); } Memory <SplitterDestination> splitterDestinations = workBufferAllocator.Allocate <SplitterDestination>(parameter.SplitterDestinationCount, SplitterDestination.Alignment); if (splitterDestinations.IsEmpty) { return(false); } int splitterDestinationId = 0; foreach (ref SplitterDestination data in splitterDestinations.Span) { data = new SplitterDestination(splitterDestinationId++); } SplitterState.InitializeSplitters(splitters.Span); Setup(splitters, splitterDestinations, behaviourContext.IsSplitterBugFixed()); return(true); }
/// <summary> /// Get the work buffer size while adding the size needed for splitter to operate. /// </summary> /// <param name="size">The current size.</param> /// <param name="behaviourContext">The behaviour context.</param> /// <param name="parameter">The renderer configuration.</param> /// <returns>Return the new size taking splitter into account.</returns> public static ulong GetWorkBufferSize(ulong size, ref BehaviourContext behaviourContext, ref AudioRendererConfiguration parameter) { if (behaviourContext.IsSplitterSupported()) { size = WorkBufferAllocator.GetTargetSize <SplitterState>(size, parameter.SplitterCount, SplitterState.Alignment); size = WorkBufferAllocator.GetTargetSize <SplitterDestination>(size, parameter.SplitterDestinationCount, SplitterDestination.Alignment); if (behaviourContext.IsSplitterBugFixed()) { size = WorkBufferAllocator.GetTargetSize <int>(size, parameter.SplitterDestinationCount, 0x10); } return(size); } else { return(size); } }
public void TestRevision3() { BehaviourContext behaviourContext = new BehaviourContext(); behaviourContext.SetUserRevision(BehaviourContext.BaseRevisionMagic + BehaviourContext.Revision3); Assert.IsTrue(behaviourContext.IsAdpcmLoopContextBugFixed()); Assert.IsTrue(behaviourContext.IsSplitterSupported()); Assert.IsTrue(behaviourContext.IsLongSizePreDelaySupported()); Assert.IsFalse(behaviourContext.IsAudioUsbDeviceOutputSupported()); Assert.IsFalse(behaviourContext.IsFlushVoiceWaveBuffersSupported()); Assert.IsFalse(behaviourContext.IsSplitterBugFixed()); Assert.IsFalse(behaviourContext.IsElapsedFrameCountSupported()); Assert.IsFalse(behaviourContext.IsDecodingBehaviourFlagSupported()); Assert.IsFalse(behaviourContext.IsBiquadFilterEffectStateClearBugFixed()); Assert.IsFalse(behaviourContext.IsMixInParameterDirtyOnlyUpdateSupported()); Assert.IsFalse(behaviourContext.IsWaveBufferVersion2Supported()); Assert.AreEqual(0.70f, behaviourContext.GetAudioRendererProcessingTimeLimit()); Assert.AreEqual(1, behaviourContext.GetCommandProcessingTimeEstimatorVersion()); Assert.AreEqual(1, behaviourContext.GetPerformanceMetricsDataFormat()); }
/// <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(); } }