SoundPlayerAction.cs source code in C# .NET

Source code for the .NET framework in C#

                        

Code:

/ 4.0 / 4.0 / untmp / DEVDIV_TFS / Dev10 / Releases / RTMRel / wpf / src / Framework / System / Windows / Controls / SoundPlayerAction.cs / 1305600 / SoundPlayerAction.cs

                             
/****************************************************************************\
*
* File: SoundPlayerAction.cs
* 
* A SoundPlayerAction causes a sound to be played in response to a trigger.
* 
* Copyright (C) by Microsoft Corporation.  All rights reserved. 
*
\***************************************************************************/ 

using MS.Internal;
using MS.Internal.PresentationFramework;
using MS.Utility; 
using System;
using System.Collections; 
using System.ComponentModel;            // DefaultValueAttribute 
using System.IO;
using System.IO.Packaging; 
using System.Media;
using System.Net;
using System.Windows;
using System.Windows.Documents; 
using System.Windows.Markup;
using System.Windows.Media; 
using System.Windows.Navigation; 
using System.Windows.Threading;
using System.Diagnostics; 
using System.Runtime.InteropServices;
using System.Runtime.Remoting;
using System.Security;
using System.Security.Permissions; 

namespace System.Windows.Controls 
{ 
    /// 
    ///   A class that describes a sound playback action to perform for a trigger 
    /// 
    public class SoundPlayerAction : TriggerAction, IDisposable
    {
 
       /// 
       ///     Creates an instance of the SoundPlayerAction object. 
       ///  
       public SoundPlayerAction()
           : base() 
       {
       }

       ///  
       /// Dispose.
       ///  
       public void Dispose() 
       {
           if (m_player != null) 
           {
               m_player.Dispose();
           }
       } 

 
       ///  
       /// DependencyProperty for Source
       ///  
       public static readonly DependencyProperty SourceProperty =
               DependencyProperty.Register(
                       "Source",
                       typeof(Uri), 
                       typeof(SoundPlayerAction),
                       new FrameworkPropertyMetadata( 
                           new PropertyChangedCallback(OnSourceChanged))); 

       ///  
       ///   A class that describes a sound playback action to perform for a trigger
       /// 
       public Uri Source
       { 
           get { return (Uri)GetValue(SourceProperty); }
           set { SetValue(SourceProperty, value); } 
       } 

       private static void OnSourceChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) 
       {
           SoundPlayerAction soundPlayerAction = (SoundPlayerAction)d;

           soundPlayerAction.OnSourceChangedHelper((Uri)e.NewValue); 
       }
 
       // To avoid blocking the UI thread, SoundPlayerAction performs an asynchronous 
       // download of the WebResponse and later, the response Stream.  However,
       // PackWebRequest does not support the asynchonous Begin/EndGetResponse pattern. 
       // To work around this, we use our own asynchronous worker pool thread,
       // and then use the regular synchronous WebRequest.GetResponse() method.
       // Once we obtain the WebResponse, we will use SoundPlayer's async API
       // to download the content of the stream. 
       private void OnSourceChangedHelper(Uri newValue)
       { 
           if (newValue == null || newValue.IsAbsoluteUri) 
           {
               m_lastRequestedAbsoluteUri = newValue; 
           }
           else
           {
               // When we are given a relative Uri path, expand to an absolute Uri by resolving 
               // it against the Application's base Uri.  This would typically return a Pack Uri.
               m_lastRequestedAbsoluteUri = 
                   BaseUriHelper.GetResolvedUri(BaseUriHelper.BaseUri, newValue); 
           }
 
           // Invalidate items that depend on the Source uri
           m_player = null;
           m_playRequested = false;  // Suppress earlier requests to Play the sound
 
           if (m_streamLoadInProgress)
           { 
               // There is already a worker thread downloading the previous URI stream, 
               // or the SoundPlayer is copying the stream into its buffer.  Make a note
               // that the URI has been changed and we will have to reload everything. 
               m_uriChangedWhileLoadingStream = true;
           }
           else
           { 
               BeginLoadStream();
           } 
       } 

       ///  
       /// Invoke the SoundPlayer action.
       /// 
       internal sealed override void Invoke(FrameworkElement el,
                                            FrameworkContentElement ctntEl, 
                                            Style targetStyle,
                                            FrameworkTemplate targetTemplate, 
                                            Int64 layer) 
       {
           PlayWhenLoaded(); 
       }

       /// 
       /// invoke the SoundPlayer action. 
       /// 
       internal sealed override void Invoke(FrameworkElement el) 
       { 
           PlayWhenLoaded();
       } 

       /// 
       /// Plays the
       ///  
       private void PlayWhenLoaded()
       { 
           if (m_streamLoadInProgress) 
           {
               m_playRequested = true; 
           }
           else if (m_player != null)
           {
               // If the Player has not yet loaded, m_streamLoadInProgress must be true 
               Debug.Assert(m_player.IsLoadCompleted);
 
               m_player.Play(); 
           }
       } 


       private void BeginLoadStream()
       { 
           if (m_lastRequestedAbsoluteUri != null)  // Only reload if the new source is non-null
           { 
               m_streamLoadInProgress = true; 

               // Step 1: Perform an asynchronous load of the WebResponse and its associated Stream 
               LoadStreamCaller downloadStreamCaller = new LoadStreamCaller(LoadStreamAsync);

               IAsyncResult asyncResult = downloadStreamCaller.BeginInvoke(m_lastRequestedAbsoluteUri,
                                                                           new AsyncCallback(LoadStreamCallback), 
                                                                           downloadStreamCaller);
           } 
       } 

       private delegate Stream LoadStreamCaller(Uri uri); 

       /// 
       /// This is the actual code that runs in our worker thread.
       ///  
       private Stream LoadStreamAsync(Uri uri)
       { 
           return WpfWebRequestHelper.CreateRequestAndGetResponseStream(uri); 
       }
 
       /// 
       /// This code runs in the worker thread when LoadStreamAsync() finishes.
       /// 
       ///  
       private void LoadStreamCallback(IAsyncResult asyncResult)
       { 
           // Now have the UI thread regain control and initialize the SoundPlayer 
           DispatcherOperationCallback loadStreamCompletedCaller = new DispatcherOperationCallback(OnLoadStreamCompleted);
 
           Dispatcher.BeginInvoke(DispatcherPriority.Normal, loadStreamCompletedCaller, asyncResult);
       }

       ///  
       /// Called on the UI thread when the Stream object is initialized.
       /// Begins asynchronous download of the Stream content into SoundPlayer's local buffer. 
       ///  
       private Object OnLoadStreamCompleted(Object asyncResultArg)
       { 
           // Necessary for proper cleanup of async resources
           IAsyncResult asyncResult = (IAsyncResult)asyncResultArg;
           LoadStreamCaller caller = (LoadStreamCaller)asyncResult.AsyncState;
 
           Stream newStream = caller.EndInvoke(asyncResult);
 
           if (m_uriChangedWhileLoadingStream)  // The source URI was changed, redo Stream loading 
           {
               m_uriChangedWhileLoadingStream = false; 
               if (newStream != null)  // Don't hold on to the new stream - it's not needed anymore
               {
                   newStream.Dispose();
               } 
               BeginLoadStream();
           } 
           else if (newStream != null)  // We loaded the Stream, begin buffering it 
           {
               if (m_player == null) 
               {
                   m_player = new SoundPlayer((Stream)newStream);
               }
               else 
               {
                   m_player.Stream = (Stream)newStream; 
               } 
               m_player.LoadCompleted += new AsyncCompletedEventHandler(OnSoundPlayerLoadCompleted);
               m_player.LoadAsync();  // Begin preloading the stream into SoundPlayer's local buffer 
           }
           return null;
       }
 
        private void OnSoundPlayerLoadCompleted(Object sender, AsyncCompletedEventArgs e)
        { 
            if (Object.ReferenceEquals(m_player, sender)) 
            {
                Debug.Assert(m_player.IsLoadCompleted); 

                if (m_uriChangedWhileLoadingStream)  // The source URI was changed, redo Stream loading again
                {
                    m_player = null; 
                    m_uriChangedWhileLoadingStream = false;
                    BeginLoadStream(); 
                } 
                else
                { 
                    m_streamLoadInProgress = false;

                    if (m_playRequested)  // URI is correct, m_player is ready, play it if requested
                    { 
                        m_playRequested = false;
                        m_player.Play(); 
                    } 
                }
            } 
        }


        private SoundPlayer m_player; 
        private Uri m_lastRequestedAbsoluteUri;
 
        private bool m_streamLoadInProgress; 
        private bool m_playRequested;
        private bool m_uriChangedWhileLoadingStream; 
    }
}

// File provided for Reference Use Only by Microsoft Corporation (c) 2007.
// Copyright (c) Microsoft Corporation. All rights reserved.


                        

Link Menu

Network programming in C#, Network Programming in VB.NET, Network Programming in .NET
This book is available now!
Buy at Amazon US or
Buy at Amazon UK