Beispiel #1
0
 void ApplicationStreamedSound_BufferNotification(object sender, BufferNotificationEventArgs e)
 {
     if (e.SoundFinished)
     {
         IsPlaying = false;
     }
 }
Beispiel #2
0
 void ApplicationStreamedSound_BufferNotificationSendPostback(object sender, BufferNotificationEventArgs e)
 {
     if (e.SoundFinished)
     {
         IsPlaying = false;
         if (OnPlayEnd != null)
         {
             OnPlayEnd();
         }
     }
 }
Beispiel #3
0
        public void OnBufferNotification(object sender, BufferNotificationEventArgs e)
        {
            if (e.NewSoundByte == null || e.NewSoundByte.Length != e.NumBytesRequired)
            {
                e.NewSoundByte = new byte[e.NumBytesRequired];
            }

            int bytesRead = Stream.Read(e.NewSoundByte, 0, e.NumBytesRequired);

            if (bytesRead != e.NumBytesRequired)
            {
                byte[] trimmedBytes = new byte[bytesRead];
                Array.Copy(e.NewSoundByte, trimmedBytes, bytesRead);
                e.NewSoundByte = trimmedBytes;
            }
            e.SoundFinished = Stream.Length == Stream.Position;

            if (BufferNotification != null)
            {
                BufferNotification(sender, e);
            }
        }
Beispiel #4
0
        /// <summary>
        /// The stream control thread raises events every half the stream.
        /// When the BufferNotificationEventArgs contains a SoundFinished property set to true, the
        /// current buffer segment is padded with silence.  At the next notification, the next
        /// buffer segment is filled with silence, and no event is raised.
        /// At the next notification, which will come when the padded segment
        /// (not the completely silent segment) is finished, the SecondaryBuffer is stopped and
        /// the thread terminated.
        /// </summary>
        private void StreamControlThread(object o)
        {
            int nextPlaceForBytes     = 0;
            int wholeBufferSize       = SB.Caps.BufferBytes;
            int byteWindowSize        = wholeBufferSize / 2;
            NextNotificationTask task = NextNotificationTask.FillSectionWithNewSound;

            //BufferNotificationEventArgs ssea = new BufferNotificationEventArgs(SB.Caps.BufferBytes);
            BufferNotificationEventArgs firstNotificationEventArgs = new BufferNotificationEventArgs(wholeBufferSize);

            GetBytesByRaisingEvent(0, wholeBufferSize, firstNotificationEventArgs);
            task = HandleNewBytesInControlThread(nextPlaceForBytes, wholeBufferSize, firstNotificationEventArgs);


            bool terminate = false;

            while (!terminate)
            {
                NotificationEvent.Reset();
                NotificationEvent.WaitOne();

                if (SB.Disposed || (!Playing))
                {
                    break;
                }

                /// Very strange behavior from DirectSound!!
                /// SB.PlayPosition returns a value slightly less than the actual position.  Either that or the event is raised
                /// So you can use that to determine which section to fill.  Fill the half that you're currently "playing"
                /// according to the PlayPosition.
                /// If anyone knows how to do this properly, please e-mail me, [email protected].
                int playPosition = SB.PlayPosition;
                int distToBegin  = Math.Abs(playPosition - 0);
                int distToEnd    = Math.Abs(playPosition - wholeBufferSize);
                int distToMid    = Math.Abs(playPosition - byteWindowSize);

                if (distToMid < distToEnd && distToMid < distToBegin)
                {
                    nextPlaceForBytes = 0;
                }
                else
                {
                    nextPlaceForBytes = byteWindowSize;
                }
                //Console.WriteLine(DateTime.Now + ": Received request for bytes at " + nextPlaceForBytes + " and I'm now at " + SB.PlayPosition);
                switch (task)
                {
                case NextNotificationTask.FillSectionWithNewSound:
                    BufferNotificationEventArgs nextNotificationEventArgs = new BufferNotificationEventArgs(byteWindowSize);
                    GetBytesByRaisingEvent(nextPlaceForBytes, byteWindowSize, nextNotificationEventArgs);
                    task = HandleNewBytesInControlThread(nextPlaceForBytes, byteWindowSize, nextNotificationEventArgs);
                    break;

                case NextNotificationTask.FillSectionWithSilence:
                    task = NextNotificationTask.StopSecondaryBufferAndThread;
                    //Console.WriteLine("Filling section with silence at " + nextPlaceForBytes);
                    int currentPosition = 0; int writePos = 0;
                    SB.GetCurrentPosition(out currentPosition, out writePos);
                    //Console.WriteLine("Current pos " + currentPosition + " and writing " + byteWindowSize + " at " + nextPlaceForBytes);
                    SB.Write(nextPlaceForBytes, new byte[byteWindowSize], LockFlag.None);
                    break;

                default:     // NextNotificationTask.StopSecondaryBufferAndThread
                    SB.Stop();
                    //Console.WriteLine("stream control thread dies.");
                    return;
                }
                //nextPlaceForBytes += byteWindowSize; if (nextPlaceForBytes >= SB.Caps.BufferBytes) nextPlaceForBytes = 0;
            }
            //Console.WriteLine("stream control thread dies.");
        }
Beispiel #5
0
        private NextNotificationTask HandleNewBytesInControlThread(int nextPlaceForBytes, int byteWindowSize, BufferNotificationEventArgs ea)
        {
            LockFlag lockFlag      = LockFlag.None;
            int      bytesObtained = ea.NewSoundByte.Length;

            if (bytesObtained > byteWindowSize)
            {
                SB.Stop();
                throw new ApplicationException("An event handler provided the streaming buffer with " + bytesObtained + " bytes of sound, but it only requested " + byteWindowSize + " bytes.");
            }
            else if (bytesObtained == byteWindowSize)
            {
                SB.Write(nextPlaceForBytes, ea.NewSoundByte, lockFlag);
            }
            else
            {
                // Fill the remainder of the segment with silence.
                if (ea.NewSoundByte.Length > 0)
                {
                    SB.Write(nextPlaceForBytes, ea.NewSoundByte, lockFlag);
                }
                SB.Write(nextPlaceForBytes + ea.NewSoundByte.Length, new byte[byteWindowSize - ea.NewSoundByte.Length], lockFlag);

                if (ea.SoundFinished)
                {
                    return(NextNotificationTask.FillSectionWithSilence);
                }
            }
            return(NextNotificationTask.FillSectionWithNewSound);
        }
Beispiel #6
0
        private void GetBytesByRaisingEvent(int locationInSecondaryBuffer, int numBytesToAcquire, BufferNotificationEventArgs e)
        {
            e.NumBytesRequiredRep = numBytesToAcquire;
            if (BufferNotification != null)
            {
                BufferNotification(this, e);
            }

            if (e.NewSoundByte == null)
            {
                e.NewSoundByte = new byte[0];
            }

            //Console.WriteLine("Request issued for " + numBytesToAcquire + " bytes; " + e.NewSoundByte.Length + " obtained.");
        }