/// <summary>
 /// Register a new <see cref="AudioInputSystem"/>.
 /// </summary>
 /// <param name="input">The <see cref="AudioInputSystem"/> to register.</param>
 private void Register(AudioInputSystem input)
 {
     lock (_sessionLock)
     {
         _sessions[input.GetSessionId()] = input;
     }
 }
        /// <summary>
        /// Unregister a new <see cref="AudioInputSystem"/>.
        /// </summary>
        /// <param name="input">The <see cref="AudioInputSystem"/> to unregister.</param>
        internal void Unregister(AudioInputSystem input)
        {
            lock (_sessionLock)
            {
                int sessionId = input.GetSessionId();

                _sessions[input.GetSessionId()] = null;

                ReleaseSessionId(sessionId);
            }
        }
        /// <summary>
        /// Open a new <see cref="AudioInputSystem"/>.
        /// </summary>
        /// <param name="outputDeviceName">The output device name selected by the <see cref="AudioInputSystem"/></param>
        /// <param name="outputConfiguration">The output audio configuration selected by the <see cref="AudioInputSystem"/></param>
        /// <param name="obj">The new <see cref="AudioInputSystem"/></param>
        /// <param name="memoryManager">The memory manager that will be used for all guest memory operations</param>
        /// <param name="inputDeviceName">The input device name wanted by the user</param>
        /// <param name="sampleFormat">The sample format to use</param>
        /// <param name="parameter">The user configuration</param>
        /// <param name="appletResourceUserId">The applet resource user id of the application</param>
        /// <param name="processHandle">The process handle of the application</param>
        /// <returns>A <see cref="ResultCode"/> reporting an error or a success</returns>
        public ResultCode OpenAudioIn(out string outputDeviceName,
                                      out AudioOutputConfiguration outputConfiguration,
                                      out AudioInputSystem obj,
                                      IVirtualMemoryManager memoryManager,
                                      string inputDeviceName,
                                      SampleFormat sampleFormat,
                                      ref AudioInputConfiguration parameter,
                                      ulong appletResourceUserId,
                                      uint processHandle)
        {
            int sessionId = AcquireSessionId();

            _sessionsBufferEvents[sessionId].Clear();

            IHardwareDeviceSession deviceSession = _deviceDriver.OpenDeviceSession(IHardwareDeviceDriver.Direction.Input, memoryManager, sampleFormat, parameter.SampleRate, parameter.ChannelCount);

            AudioInputSystem audioIn = new AudioInputSystem(this, _lock, deviceSession, _sessionsBufferEvents[sessionId]);

            ResultCode result = audioIn.Initialize(inputDeviceName, sampleFormat, ref parameter, sessionId);

            if (result == ResultCode.Success)
            {
                outputDeviceName    = audioIn.DeviceName;
                outputConfiguration = new AudioOutputConfiguration
                {
                    ChannelCount  = audioIn.ChannelCount,
                    SampleFormat  = audioIn.SampleFormat,
                    SampleRate    = audioIn.SampleRate,
                    AudioOutState = audioIn.GetState(),
                };

                obj = audioIn;

                Register(audioIn);
            }
            else
            {
                ReleaseSessionId(sessionId);

                obj = null;
                outputDeviceName    = null;
                outputConfiguration = default;
            }

            return(result);
        }