Пример #1
0
        private void output_NewFrameRequested(object sender, NewFrameRequestedEventArgs e)
        {
            e.FrameIndex = decoder.Position;

            Signal s = decoder.Decode(e.Frames);

            if (s == null)
            {
                e.Stop = true;
            }
            else
            {
                // Inform the number of frames
                // actually read from source
                e.Frames = s.Length;

                // Copy the signal to the buffer
                s.CopyTo(e.Buffer);
            }
        }
Пример #2
0
        private void AudioOutputDeviceNewFrameRequested(object sender, NewFrameRequestedEventArgs e)
        {
            if (decoder == null)
            {
                return;
            }

            e.FrameIndex = decoder.Position;

            Signal signal = decoder.Decode(e.Frames);

            if (signal == null)
            {
                e.Stop = true;
                return;
            }

            e.Frames = signal.Length;

            signal.CopyTo(e.Buffer);
        }
Пример #3
0
        /// <summary>
        ///   This event is triggered when the sound card needs more samples to be
        ///   played. When this happens, we have to feed it additional frames so it
        ///   can continue playing.
        /// </summary>
        ///
        private void output_NewFrameRequested(object sender, NewFrameRequestedEventArgs e)
        {
            // This is the next frame index
            e.FrameIndex = decoder.Position;

            // Attempt to decode the requested number of frames from the stream
            Signal signal = decoder.Decode(e.Frames);

            if (signal == null)
            {
                // We could not get the requested number of frames. When
                // this happens, this is an indication we need to stop.
                e.Stop = true;
                return;
            }

            // Inform the number of frames
            // actually read from source
            e.Frames = signal.Length;

            // Copy the signal to the buffer
            signal.CopyTo(e.Buffer);
        }
Пример #4
0
        public void FillNewFrame(NewFrameRequestedEventArgs frameRequestArgs)
        {
            // This is the next frame index
            frameRequestArgs.FrameIndex = this.decoder.Position;

            // Attempt to decode the requested number of frames from the stream
            Signal signal = this.decoder.Decode(frameRequestArgs.Frames);

            if (signal == null)
            {
                // We could not get the requested number of frames. When
                // this happens, this is an indication we need to stop.
                frameRequestArgs.Stop = true;
                return;
            }

            // Inform the number of frames
            // actually read from source
            frameRequestArgs.Frames = signal.Length;

            // Copy the signal to the buffer
            signal.CopyTo(frameRequestArgs.Buffer);
        }
        /// <summary>
        ///   Worker thread.
        /// </summary>
        ///
        private void WorkerThread()
        {
            int samples = bufferSize / sizeof(float);

            try
            {
                // The first write should fill the entire buffer.
                var request = new NewFrameRequestedEventArgs(samples);
                NewFrameRequested.Invoke(this, request);

                buffer.Write(request.Buffer, 0, LockFlags.None);

                // The buffer starts playing.
                buffer.Play(0, PlayFlags.Looping);

                int  framesPlayed             = request.FrameIndex;
                int  lastNotificationLocation = 0;
                bool requestedToStop          = false;

                while (!stop)
                {
                    int positionIndex = WaitHandle.WaitAny(waitHandles);

                    if (stop)
                    {
                        break;
                    }


                    if (positionIndex == firstHalfBufferIndex ||
                        positionIndex == secondHalfBufferIndex)
                    {
                        if (requestedToStop)
                        {
                            break;
                        }

                        // When the first half of the buffer has finished
                        //  playing and we have just started playing the
                        //  second half, we will write the next samples in
                        //  the first half of the buffer again.

                        // When the second half of the buffer has finished
                        //  playing, the first half of the buffer will
                        //  start playing again (since this is a circular
                        //  buffer). At this time, we can write the next
                        //  samples in the second half of the buffer.

                        request.Frames = samples / 2;
                        NewFrameRequested(this, request);
                        requestedToStop = request.Stop;

                        int offset = (positionIndex == firstHalfBufferIndex) ? 0 : bufferSize / 2;

                        buffer.Write(request.Buffer, 0, request.Frames, offset, LockFlags.None);
                    }

                    if (positionIndex != secondHalfBufferIndex)
                    {
                        // Notify progress
                        int currentBufferLocation = notifications[positionIndex].Offset;

                        if (lastNotificationLocation >= currentBufferLocation)
                        {
                            lastNotificationLocation = -(bufferSize - lastNotificationLocation);
                        }

                        int delta = (currentBufferLocation - lastNotificationLocation);

                        framesPlayed += delta / sizeof(float);

                        lastNotificationLocation = currentBufferLocation;

                        OnFramePlayingStarted(new PlayFrameEventArgs(framesPlayed, delta));
                    }
                }
            }
            catch (Exception ex)
            {
                if (AudioOutputError != null)
                {
                    AudioOutputError(this, new AudioOutputErrorEventArgs(ex.Message));
                }
                else
                {
                    throw;
                }
            }
            finally
            {
                buffer.Stop();

                OnStopped(EventArgs.Empty);
            }
        }
Пример #6
0
        //========================================================================================================================================//

        /// <summary>
        ///   This event is triggered when the sound card needs more samples to be
        ///   played. When this happens, we have to feed it additional frames so it
        ///   can continue playing.
        /// </summary>
        ///
        private void output_NewFrameRequested(object sender, NewFrameRequestedEventArgs e)
        {
            this.decoder.FillNewFrame(e);
        }