예제 #1
0
        private void OnInputDataAvailable(IntPtr handle, uint length)
        {
            if (length == 0U)
            {
                return;
            }

            IntPtr ptr = IntPtr.Zero;

            try
            {
                AudioIOUtil.ThrowIfError(AudioInput.Peek(_handle, out ptr, ref length));

                byte[] buffer = new byte[length];
                Marshal.Copy(ptr, buffer, 0, (int)length);

                AudioInput.Drop(_handle);

                DataAvailable?.Invoke(this, new AudioDataAvailableEventArgs(buffer));
            }
            catch (Exception e)
            {
                Log.Error(nameof(AsyncAudioCapture), e.Message);
            }
        }
예제 #2
0
        /// <summary>
        /// Prepares the AudioCapture for reading audio data by starting buffering of audio data from the device.
        /// </summary>
        /// <exception cref="InvalidOperationException">
        ///     Operation failed due to an internal error.<br/>
        ///     -or-<br/>
        ///     The current state is not <see cref="AudioIOState.Idle"/>.
        /// </exception>
        /// <exception cref="ObjectDisposedException">The AudioCaptureBase has already been disposed of.</exception>
        /// <seealso cref="Unprepare"/>
        /// <since_tizen> 3 </since_tizen>
        public void Prepare()
        {
            ValidateState(AudioIOState.Idle);

            AudioIOUtil.ThrowIfError(AudioInput.Prepare(_handle),
                                     "Failed to prepare the AudioCapture");
        }
예제 #3
0
        /// <summary>
        /// Unprepares the AudioCapture.
        /// </summary>
        /// <exception cref="InvalidOperationException">
        ///     Operation failed due to an internal error.<br/>
        ///     -or-<br/>
        ///     The current state is <see cref="AudioIOState.Idle"/>.
        /// </exception>
        /// <exception cref="ObjectDisposedException">The AudioCaptureBase has already been disposed of.</exception>
        /// <seealso cref="Prepare"/>
        /// <since_tizen> 3 </since_tizen>
        public void Unprepare()
        {
            ValidateState(AudioIOState.Running, AudioIOState.Paused);

            AudioIOUtil.ThrowIfError(AudioInput.Unprepare(_handle),
                                     "Failed to unprepare the AudioCapture");
        }
예제 #4
0
        /// <summary>
        /// Unprepares the AudioPlayback.
        /// </summary>
        /// <exception cref="InvalidOperationException">
        ///     Operation failed due to an internal error.<br/>
        ///     -or-<br/>
        ///     The current state is <see cref="AudioIOState.Idle"/>.
        /// </exception>
        /// <exception cref="ObjectDisposedException">The AudioPlayback has already been disposed of.</exception>
        /// <seealso cref="Prepare"/>
        /// <since_tizen> 3 </since_tizen>
        public void Unprepare()
        {
            ValidateState(AudioIOState.Running, AudioIOState.Paused);

            AudioIOUtil.ThrowIfError(AudioOutput.Unprepare(_handle),
                                     $"Failed to unprepare the {nameof(AudioPlayback)}");
        }
예제 #5
0
        /// <summary>
        /// Prepares the AudioPlayback.
        /// </summary>
        /// <remarks>
        /// This must be called before <see cref="Write(byte[])"/>.
        /// </remarks>
        /// <exception cref="InvalidOperationException">
        ///     Operation failed due to an internal error.<br/>
        ///     -or-<br/>
        ///     The current state is not <see cref="AudioIOState.Idle"/>.
        /// </exception>
        /// <exception cref="ObjectDisposedException">The AudioPlayback has already been disposed of.</exception>
        /// <seealso cref="Unprepare"/>
        /// <since_tizen> 3 </since_tizen>
        public void Prepare()
        {
            ValidateState(AudioIOState.Idle);

            AudioIOUtil.ThrowIfError(AudioOutput.Prepare(_handle),
                                     $"Failed to prepare the {nameof(AudioPlayback)}");
        }
예제 #6
0
        /// <summary>
        /// Initializes a new instance of the AsyncAudioCapture class with the specified sample rate, channel and sampleType.
        /// </summary>
        /// <param name="sampleRate">The audio sample rate (8000 ~ 48000Hz).</param>
        /// <param name="channel">The audio channel type.</param>
        /// <param name="sampleType">The audio sample type.</param>
        /// <exception cref="ArgumentOutOfRangeException">
        ///     <paramref name="sampleRate"/> is less than <see cref="AudioCaptureBase.MinSampleRate"/>.<br/>
        ///     -or-<br/>
        ///     <paramref name="sampleRate"/> is greater than <see cref="AudioCaptureBase.MaxSampleRate"/>.
        /// </exception>
        /// <exception cref="ArgumentException">
        ///     <paramref name="channel"/> is invalid.<br/>
        ///     -or-<br/>
        ///     <paramref name="sampleType"/> is invalid.
        /// </exception>
        /// <exception cref="UnauthorizedAccessException">The required privilege is not specified.</exception>
        /// <exception cref="NotSupportedException">The system does not support microphone.</exception>
        /// <since_tizen> 3 </since_tizen>
        public AsyncAudioCapture(int sampleRate, AudioChannel channel, AudioSampleType sampleType)
            : base(sampleRate, channel, sampleType)
        {
            _streamCallback = (IntPtr handle, uint length, IntPtr _) => { OnInputDataAvailable(handle, length); };

            AudioIOUtil.ThrowIfError(
                AudioInput.SetStreamCallback(_handle, _streamCallback, IntPtr.Zero),
                $"Failed to initialize a { nameof(AsyncAudioCapture) }");
        }
예제 #7
0
        /// <summary>
        /// Resumes buffering audio data from the device.
        /// </summary>
        /// <exception cref="InvalidOperationException">
        ///     The current state is <see cref="AudioIOState.Idle"/>.<br/>
        ///     -or-<br/>
        ///     The method is called in the <see cref="AsyncAudioCapture.DataAvailable"/> event handler.
        /// </exception>
        /// <exception cref="ObjectDisposedException">The AudioCaptureBase has already been disposed of.</exception>
        /// <seealso cref="Pause"/>
        /// <since_tizen> 3 </since_tizen>
        public void Resume()
        {
            if (_state == AudioIOState.Running)
            {
                return;
            }
            ValidateState(AudioIOState.Paused);

            AudioIOUtil.ThrowIfError(AudioInput.Resume(_handle));
        }
예제 #8
0
        /// <summary>
        /// Sets the sound stream information to the audio input.
        /// </summary>
        /// <param name="streamPolicy">The <see cref="AudioStreamPolicy"/> to apply for the AudioCapture.</param>
        /// <exception cref="ArgumentNullException"><paramref name="streamPolicy"/> is null.</exception>
        /// <exception cref="ObjectDisposedException">
        ///     <paramref name="streamPolicy"/> has already been disposed of.<br/>
        ///     -or-<br/>
        ///     The AudioCaptureBase has already been disposed of.
        /// </exception>
        /// <exception cref="NotSupportedException"><paramref name="streamPolicy"/> is not supported.</exception>
        /// <exception cref="ArgumentException">Not able to retrieve information from <paramref name="streamPolicy"/>.</exception>
        /// <since_tizen> 3 </since_tizen>
        public void ApplyStreamPolicy(AudioStreamPolicy streamPolicy)
        {
            if (streamPolicy == null)
            {
                throw new ArgumentNullException(nameof(streamPolicy));
            }

            ValidateNotDisposed();

            AudioIOUtil.ThrowIfError(AudioInput.SetStreamInfo(_handle, streamPolicy.Handle));
        }
예제 #9
0
        private void RegisterStreamCallback()
        {
            _streamCallback = (IntPtr handle, uint bytes, IntPtr _) =>
            {
                BufferAvailable?.Invoke(this, new AudioPlaybackBufferAvailableEventArgs((int)bytes));
            };

            AudioIOUtil.ThrowIfError(
                AudioOutput.SetStreamChangedCallback(_handle, _streamCallback, IntPtr.Zero),
                $"Failed to create {nameof(AudioPlayback)}");
        }
예제 #10
0
        private void RegisterStateChangedCallback()
        {
            _stateChangedCallback = (IntPtr handle, int previous, int current, bool byPolicy, IntPtr _) =>
            {
                _state = (AudioIOState)current;

                StateChanged?.Invoke(this,
                                     new AudioIOStateChangedEventArgs((AudioIOState)previous, _state, byPolicy));
            };

            AudioIOUtil.ThrowIfError(
                AudioInput.SetStateChangedCallback(_handle, _stateChangedCallback, IntPtr.Zero));
        }
예제 #11
0
        /// <summary>
        /// Reads audio data from the audio input buffer.
        /// </summary>
        /// <param name="count">The number of bytes to be read.</param>
        /// <returns>The buffer of audio data captured.</returns>
        /// <exception cref="InvalidOperationException">The current state is not <see cref="AudioIOState.Running"/>.</exception>
        /// <exception cref="ArgumentOutOfRangeException"><paramref name="count"/> is equal to or less than zero.</exception>
        /// <exception cref="ObjectDisposedException">The AudioCapture has already been disposed of.</exception>
        /// <since_tizen> 3 </since_tizen>
        public byte[] Read(int count)
        {
            if (count <= 0)
            {
                throw new ArgumentOutOfRangeException(nameof(count), count,
                                                      $"{ nameof(count) } can't be equal to or less than zero.");
            }
            ValidateState(AudioIOState.Running);

            byte[] buffer = new byte[count];

            AudioIOUtil.ThrowIfError(AudioInput.Read(_handle, buffer, count),
                                     "Failed to read");

            return(buffer);
        }
예제 #12
0
        internal AudioCaptureBase(int sampleRate, AudioChannel channel, AudioSampleType sampleType)
        {
            if (sampleRate < MinSampleRate || MaxSampleRate < sampleRate)
            {
                throw new ArgumentOutOfRangeException(nameof(sampleRate), sampleRate,
                                                      $"Valid sampleRate range is { MinSampleRate } <= x <= { MaxSampleRate }.");
            }

            ValidationUtil.ValidateEnum(typeof(AudioChannel), channel, nameof(channel));
            ValidationUtil.ValidateEnum(typeof(AudioSampleType), sampleType, nameof(sampleType));

            SampleRate = sampleRate;
            Channel    = channel;
            SampleType = sampleType;

            AudioIOUtil.ThrowIfError(
                AudioInput.Create(SampleRate, (int)Channel, (int)SampleType, out _handle));

            RegisterStateChangedCallback();
        }
예제 #13
0
        /// <summary>
        /// Starts writing the audio data to the device.
        /// </summary>
        /// <param name="buffer">The buffer to write.</param>
        /// <returns>The written size.</returns>
        /// <exception cref="ArgumentNullException"><paramref name="buffer"/> is null.</exception>
        /// <exception cref="ArgumentException">The length of <paramref name="buffer"/> is zero.</exception>
        /// <exception cref="InvalidOperationException">The current state is not <see cref="AudioIOState.Running"/>.</exception>
        /// <exception cref="ObjectDisposedException">The AudioPlayback has already been disposed of.</exception>
        /// <since_tizen> 3 </since_tizen>
        public int Write(byte[] buffer)
        {
            ValidateState(AudioIOState.Running);

            if (buffer == null)
            {
                throw new ArgumentNullException(nameof(buffer));
            }

            if (buffer.Length == 0)
            {
                throw new ArgumentException("buffer has no data.(the Length is zero.)", nameof(buffer));
            }

            int ret = AudioOutput.Write(_handle, buffer, (uint)buffer.Length);

            AudioIOUtil.ThrowIfError(ret, "Failed to write buffer");

            return(ret);
        }
예제 #14
0
        internal void ValidateState(params AudioIOState[] desiredStates)
        {
            ValidateNotDisposed();

            AudioIOUtil.ValidateState(_state, desiredStates);
        }