c# Service Play Sound with NAudio example by Moshe
windows server 2008 or vista 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)
{
// we know it is stereo
//w aveformPainter1.AddMax(e.MaxSampleValues[0]);
//waveformPainter2.AddMax(e.MaxSampleValues[1]);
}
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)
{
// we know it is stereo
//volumeMeter1.Amplitude = e.MaxSampleValues[0];
//volumeMeter2.Amplitude = e.MaxSampleValues[1];
}
public WASAPI(string fileName)
{
ISampleProvider sampleProvider = null;
sampleProvider = CreateInputStream(fileName);
waveOut.Init(new SampleToWaveProvider(sampleProvider));
waveOut.Play();
return;
}
}
}
and what u need to do in ur app is simply this:
WASAPI Player = new WASAPI(path);
(advised to do sleep for it to finish and maybe player = null if ur the saving resources type)
ENJOY!
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)
{
// we know it is stereo
//w aveformPainter1.AddMax(e.MaxSampleValues[0]);
//waveformPainter2.AddMax(e.MaxSampleValues[1]);
}
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)
{
// we know it is stereo
//volumeMeter1.Amplitude = e.MaxSampleValues[0];
//volumeMeter2.Amplitude = e.MaxSampleValues[1];
}
public WASAPI(string fileName)
{
ISampleProvider sampleProvider = null;
sampleProvider = CreateInputStream(fileName);
waveOut.Init(new SampleToWaveProvider(sampleProvider));
waveOut.Play();
return;
}
}
}
and what u need to do in ur app is simply this:
WASAPI Player = new WASAPI(path);
(advised to do sleep for it to finish and maybe player = null if ur the saving resources type)
ENJOY!
does not worth to write this much of code to simply play a sound
ReplyDeleteHello
ReplyDeletei am looking for someone for a small developing/programming project with IVR
please contact me i pay for it
asherdan@gmail.com
Excellent!
ReplyDeleteI needed a way to play a sound in a windows service and this resolve that :D
Good code! Thank you!!!
ReplyDeleteIt solved my problem! Thanks!
ReplyDelete