Shabat Closer

Tuesday, February 5, 2013

C# : Play Sound in system service

windows server 2008/vista/windows 7 forword if u host a service W/O a user loggon the system wont start the audio devices.
to solve this u can use the dear NAudio Dll from http://naudio.codeplex.com/ - its open source.
but its a damn long (and helpful) code while u wont a simple service with only 1 CS page, so my Dear Team Chief and IT man Moshe reduced that to a single CS page just to play the sounds and here u go:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using NAudio.Wave;
using NAudio.CoreAudioApi;
using System.ComponentModel.Composition;
using NAudio.Wave.SampleProviders;

namespace CallAndRead
{
   
public interface IInputFileFormatPlugin
   {
      
string Name { get; }
       string Extension { get; }
       WaveStream CreateWaveStream(string fileName);
   }
   

   [Export(typeof(IInputFileFormatPlugin))]
   class WaveInputFilePlugin : IInputFileFormatPlugin
   {       public string Name
      { get { return "WAV file"; } }
       public string Extension
      { get { return ".wav"; } }

       public WaveStream CreateWaveStream(string fileName)
       {             WaveStream readerStream = new WaveFileReader(fileName);
             if (readerStream.WaveFormat.Encoding != WaveFormatEncoding.Pcm
                   && readerStream.WaveFormat.Encoding != WaveFormatEncoding.IeeeFloat)
            {
                  readerStream =
WaveFormatConversionStream.CreatePcmStream(readerStream);
                  readerStream = new BlockAlignReductionStream(readerStream);
            }            return readerStream;
      }
   }
   

   class WASAPI
   {        public static void Concatenate(string outputFile, IEnumerable<string> sourceFiles)
        {             byte[] buffer = new byte[1024];
             WaveFileWriter waveFileWriter = null;
             try
            {                 foreach (string sourceFile in sourceFiles)
                 {                        using (WaveFileReader reader = new WaveFileReader(sourceFile))
                        {                               if (waveFileWriter == null)
                                   waveFileWriter = new WaveFileWriter(outputFile, reader.WaveFormat);
                               else
                              {                                     if (!reader.WaveFormat.Equals(waveFileWriter.WaveFormat))
                                     throw new InvalidOperationException(
                                              "Can't concatenate WAV Files that don't share the same format");
                              }                              int read;
                              while ((read = reader.Read(buffer, 0, buffer.Length)) > 0)
                             {
                                   waveFileWriter.WriteData(buffer, 0, read);
                             }
                      }
                }
            }
           
finally
           {                if (waveFileWriter != null)
                     waveFileWriter.Dispose();
           }
      }
      private IWavePlayer waveOut = new WasapiOut(NAudio.CoreAudioApi.AudioClientShareMode.Shared, 300);
      WaveStream fileWaveStream;
      Action<float> setVolumeDelegate;

     [ImportMany(typeof(IInputFileFormatPlugin))]
     public IEnumerable<IInputFileFormatPlugin> InputFileFormats { get; set; }

     void OnPreVolumeMeter(object sender, NAudio.Wave.SampleProviders.StreamVolumeEventArgs e)    {     }

      public ISampleProvider CreateInputStream(string fileName)
     {
  
        var plugin = new WaveInputFilePlugin();
           if (plugin == null)
                  throw new InvalidOperationException("Unsupported file extension");
           fileWaveStream = plugin.CreateWaveStream(fileName);           var waveChannel = new NAudio.Wave.SampleProviders.SampleChannel(fileWaveStream);
           setVolumeDelegate = (vol) => waveChannel.Volume = vol;
           waveChannel.PreVolumeMeter += OnPreVolumeMeter;
           var postVolumeMeter = new MeteringSampleProvider(waveChannel);
           postVolumeMeter.StreamVolume += OnPostVolumeMeter;           return postVolumeMeter;
     }

     
void OnPostVolumeMeter(object sender, StreamVolumeEventArgs e){      }      public WASAPI(string fileName)
     {            ISampleProvider sampleProvider = null;
            sampleProvider = CreateInputStream(fileName);
            waveOut.Init(
new SampleToWaveProvider(sampleProvider));
            waveOut.Play();            return;
      }
   }
}


usage:
and what u need to do in ur app is simply this:
WASAPI Player = new WASAPI("filetoplay.wav");
(advised to do sleep for it to finish and maybe player = null if ur the saving resources type)

:

No comments:

Post a Comment