Click here to Skip to main content
13,193,590 members (48,099 online)
Click here to Skip to main content
Add your own
alternative version


179 bookmarked
Posted 31 May 2012

Play or Capture Audio Sound. Send and Receive as Multicast (RTP)

, 22 Apr 2014
Rate this:
Please Sign up or sign in to vote.
Play, record and capture Audio sound. Read, write and stream Wav-Files. Send and receive Ulaw RTP-streams. Using the WaveIn WaveOut functions of the WMM API.

Download source



It is not comfortable to use the Sound API in .NET, because there is no support by the class library itself. So I decided to write my own small Audio Assembly WinSound.dll by using PInvoke and the native WMM API (Windows Multi Media). With help of this library you can play or capture audio sound in an easy way. In addition i wrote some Network Assemblies, to stream and play Audio Data over Network by Multicast.

Optional C++

In addition i implemented a similar C++ Version for the sound part of this project as a COM Server with name WinSoundServer. In the project is also included a little WinSoundServerTester.sln for VisualStudio 2012 that shows the recording and playing methods in an example. I did not intend to publish that, but maybe anybody will find it useful anyway. You must first compile the WinSoundServer project, so that the vc100.tlb and the WinSoundServer.dll will be created. Before starting the test app you have to register the COM Server with help of the reg.bat file including in the project directory. This will register the WinSoundServer.dll. After that the test application must refers to the typelibrary by an import statement, so you have access to all interfaces and classes (like adding a reference in C#)

#import "WinSoundServer\\vc100.tlb" no_namespace


The WaveOut and WaveIn functions of WMM are very tricky, because you have to know some special features of how to work with the internal buffers and handles. For example you can not stop a recording, without waiting for all buffers to finish. You are not allowed to stay too long in the Callback functions. You have to swap from managed to unmanaged code. The Repeater is the most sensitive one, because you have to balance the recording and playing buffers all the time.

Using the code

The assemblies which are to be used as DLLs are

For common sound operations

  • WinSound.dll

For network operations

  • TCPClient.dll
  • TCPServer.dll
  • MulticastReceiver.dll
  • MulticastSender.dll

Example Projects are

  • MulticastPlayer (Plays a RTP-Multicast to Soundcard)
  • MulticastStreamer (Sends a RTP-Multicast from Soundcard)
  • Player Tester (Plays or records a wav-File)
  • RepeaterTester (Plays from Soundcard to Soundcard)

The heart of all this is WinSound.dll. All example projects need this DLL (add as reference).

Using the Sound Recorder

Note that buffersize and buffercount must be optimized to your Sounddevice and used SamplesPerSecond.

//Create a Recorder
WinSound.Recorder recorder = new WinSound.Recorder();
//Add DataRecording and RecordingStopped Event Functions
recorder.DataRecorded += new WinSound.Recorder.DelegateDataRecorded(OnDataRecorded);
recorder.RecordingStopped += new WinSound.Recorder.DelegateStopped(OnRecordingStopped);
//Start capturing (44100 SamplesPerSecond, 16 BitsPerSample, 2 Channels, 8 * 4096 Byte Buffers)
recorder.Start("Line 1 (Virtual Audio Cable)", 44100, 16, 2, 8, 4096);
//Check if started
bool isStarted = recorder.Started;
//Stop recording

//Called, when datas are incoming
private void OnDataRecorded(Byte[] data)

//Called, when recording has stopped
private void OnRecordingStopped()

Using the Sound Player

Note that buffercount must be optimized to your Sounddevice and used SamplesPerSecond.

//Create a SoundPlayer
WinSound.Player player = new WinSound.Player();
//Add Player Stopped and Player Closed Events
player.PlayerStopped += new WinSound.Player.DelegateStopped(OnPlayerStopped);
player.PlayerClosed += new WinSound.Player.DelegateStopped(OnPlayerClosed);
//Open a SoundDevice (44100 SamplesPerSecond, 16 BitsPerSample, 2 Channels, 8 Buffers)
player.Open("Realtek", 44100, 16, 2, 8);
//Check if open
bool isOpen = player.Opened;          
//Get Sound Datas as linear bytes (maybe from Wav-File)
Byte[] data = GetDatas();
//Play linear datas to SoundDevice
player.PlayData(data, false);
//Check if playing
bool isPlaying = player.Playing
//Start pause
//Check if paused
bool isPaused = player.Paused;
//End pause
//Close Player
//Called, when player is stopped 
private void OnPlayerStopped()


//Called, when player is closed (WaveOut closed)
private void OnPlayerClosed()


Linear Bytes

The linear data bytes you write or read from soundcard, are depending on BitsPerSample and Channel Count. Each "Data Packet" is to interpret as this picture shows.

The Player (Recorder) Tester

This example uses WinSound.dll to play or record a Wav-file. SamplesPerSecond, BitsPerSample and Channels are only used in record mode.

//Create a SoundPlayer
WinSound.Player playerOne = new WinSound.Player();
//Add callback functions for stop and close events (optional)
playerOne.PlayerClosed += new WinSound.Player.DelegateStopped(OnPlayerClosed);
playerOne.PlayerStopped += new WinSound.Player.DelegateStopped(OnPlayerStopped);
//Play a Wav File on a specific Sounddevice
playerOne.PlayFile(@"C:\Record.wav", "Realtek");   
//Close the player
bool hr = playerOne.Close(); 

//Read Wave-Header and payload data from Wav-File
WinSound.WaveFileHeader header = WinSound.WaveFile.Read(@"C:\Record.wav");
//Get the payload data size
uint dataSize = header.DATASize;
//Get the payload data
Byte[] data = header.Payload;

//Write payload data in a new Wav-File 
WinSound.WaveFile.Create(@"C:\Record.wav", 44100, 16, 2, data);
//Add payload data in an existing Wav-File (Append)
WinSound.WaveFile.AppendData(@"C:\Record.wav", data);  

The Repeater Tester

This example is recording Sound-Data from one sound device (WaveIn) to another (WaveOut). Every sound device has its special features, so you have to change the BufferCount and BufferSize for optimal performance. It also differs from operating System Windows-XP, Vista or Windows 7.


//Create the Repeater
WinSound.Repeater repeaterOne = new WinSound.Repeater(); 
//Start the Repeater
repeaterOne.Start("Line 6", "Realtek", samplesPerSecond, bitsPerSample, channels, bufferCount, bufferSize);
//Stop the Repeater 

The Multicast Streamer

This example Streams ULAW RTP-Multicast data from a sound device or a Wav-File. When using sound device streaming, it is possible to synchronise it with the "Time Sync" checkbox. Buffer Count is the amout of buffers, that are used by capturing from sound-device (Use 8 as standard). You can use the Multicast Player to play this Multicast. Also you can use the VLC Media Player for testing (Use Samples Per Second = 8000 and BitsPerSample = 16 with VLC).

//Create a  Multicast Sender and a Sound-Device Recorder
NF.MulticastSender m_MulticastSender = new NF.MulticastSender(Address, Port, TTL);
WinSound.Recorder m_Recorder = new WinSound.Recorder();
//Define a callback function for reveiving datas from soundcard
m_Recorder.DataRecorded += new WinSound.Recorder.DelegateDataRecorded(OnDataReceivedFromSoundcard);
//Start Recorder 
m_Recorder.Start(SoundDeviceName, SamplesPerSecond, BitsPerSample, ChannelCount, BufferCount, BufferSize) 
//In callback function, get the linear datas from soundcard and translate to MuLaw
Byte[] mulawData = WinSound.Utils.LinearToMulaw(linearData, Config.BitsPerSample, Config.Channels);
//Create the RTP Header 
Byte[] rtpBytes = RTPHeader.ToBytes();
//Combine RTP Header and mulawData
Byte[] bytes = new Byte[mulawData.Length + WinSound.RTPPacket.MinHeaderLength];
Array.Copy(rtpBytes, 0, bytes, 0, WinSound.RTPPacket.MinHeaderLength);
Array.Copy(mulawData, 0, bytes, WinSound.RTPPacket.MinHeaderLength, mulawData.Length);
//Send Bytes to Multicast

The Multicast Player

This example plays a ULAW RTP-Multicast stream to a sound device. You can use the Multicast Streamer for this purpose. Note, the packet size of the Multicast Player must be greater or equal than the packet size of the multicast streamer (Use 16000 Bytes as standard) . A Jitter Buffer is used, when entering a minimum value of "2" as jitter count. Jitter count means the amount of RTP-Packets that will be queued as maximum. Values of "0" or "1" means, there is no Jitter Buffer in use. (Use 20 as standard)

//Create a Multicast Receiver and a SoundPlayer 
NF.MulticastReceiver m_Receiver = new NF.MulticastReceiver(PacketSize);
WinSound.Player m_Player = new WinSound.Player(); 
//Define a callback function for receiving datas from multicast
m_Receiver.DataReceived += new NF.MulticastReceiver.DelegateDataReceived(OnDataReceived);
//Connect the Multicast and open the Player
m_Receiver.Connect(MulticasAddress, MulticastPort); 
m_Player.Open(SoundDeviceName, SamplesPerSecond, BitsPerSample, Channels, BufferCount); 
//In the callback function get the rtp header of the multicast packet
WinSound.RTPPacket rtp = new WinSound.RTPPacket(bytes);
//Translate MuLaw to linear
Byte[] linearBytes = WinSound.Utils.MuLawToLinear(rtp.Data, Config.BitsPerSample, Config.Channels);
//Play the linear datas to soundcard
m_Player.PlayData(linearBytes, false);
//Close the Player and the Receiver


  • 31.05.2012 - Added.
  • 30.06.2012 - Updated. Using the CSRC Count Information in RTP Header for Multicast Player.
  • 08.07.2012 - Updated. Wav-File Read/Write operations for Player Tester.
  • 11.08.2012 - Updated. Error resolved, when calling Player.PlayData in blocking mode = true
  • 21.08.2012 - Updated. Error resolved. Garbage Collection caused Application crash.
  • 07.09.2012 - Updated. Error resolved. Reading Wave-Files in different formats.
  • 09.09.2012 - Updated. Better performance when playing wav files.
  • 19.10.2012 - Updated. Added Jitter buffer. Added streaming wav-files directly.
  • 22.10.2013 - Updated. Drawing the linear datas as curve
  • 12.04.2014 - Added Source. WinSound implementation written in C++ as a COM Server (Optional)
  • 22.04.2014 - Updated. Solved possible stability problems


This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


About the Author

Software Developer Telecommunication
Germany Germany
No Biography provided

You may also be interested in...

Comments and Discussions

QuestionIs MulticastStreamer PCM or MP3 ? Pin
Member 1293431131-Jan-17 2:54
memberMember 1293431131-Jan-17 2:54 
AnswerRe: Is MulticastStreamer PCM or MP3 ? Pin
Banjoo12-Feb-17 5:09
memberBanjoo12-Feb-17 5:09 
QuestionVery great project Pin
Jinfaa6-Apr-16 5:30
memberJinfaa6-Apr-16 5:30 
AnswerRe: Very great project Pin
Banjoo6-Apr-16 7:41
memberBanjoo6-Apr-16 7:41 
Question"for thouse who code" and" thouse who does not code" Pin
Member 1242665730-Mar-16 10:02
memberMember 1242665730-Mar-16 10:02 
AnswerRe: "for thouse who code" and" thouse who does not code" Pin
Banjoo30-Mar-16 12:17
memberBanjoo30-Mar-16 12:17 
QuestionUniversal Windows support Pin
cellavadasz30-Jan-16 23:36
membercellavadasz30-Jan-16 23:36 
QuestionAutomatically Open on Client / AutoPlay Pin
Member 112594335-Dec-15 12:28
memberMember 112594335-Dec-15 12:28 
AnswerRe: Automatically Open on Client / AutoPlay Pin
Banjoo28-Jan-16 4:32
memberBanjoo28-Jan-16 4:32 
QuestionHow can i get the status of Barix Devices Pin
PankajMishra21-Sep-15 6:15
memberPankajMishra21-Sep-15 6:15 
AnswerRe: How can i get the status of Barix Devices Pin
Banjoo22-Sep-15 5:55
memberBanjoo22-Sep-15 5:55 
QuestionCannot Extend Channels Pin
MrSafe6-Jun-15 10:42
memberMrSafe6-Jun-15 10:42 
AnswerRe: Cannot Extend Channels Pin
Banjoo18-Jun-15 2:14
memberBanjoo18-Jun-15 2:14 
Questionimplementation of the project Pin
Member 1146146823-Feb-15 5:13
memberMember 1146146823-Feb-15 5:13 
QuestionHi! Pin
michael diaz21-Feb-15 19:53
membermichael diaz21-Feb-15 19:53 
QuestionHELP! I can't get this or VLC to work! Pin
Member 1117036211-Nov-14 13:26
memberMember 1117036211-Nov-14 13:26 
AnswerRe: HELP! I can't get this or VLC to work! Pin
Banjoo11-Nov-14 20:19
memberBanjoo11-Nov-14 20:19 
Questionguy Pin
osunlana22-Apr-14 22:27
memberosunlana22-Apr-14 22:27 
AnswerRe: guy Pin
Banjoo22-Apr-14 22:41
memberBanjoo22-Apr-14 22:41 
QuestionWorth considering Pin
Chenan Wang22-Apr-14 17:26
memberChenan Wang22-Apr-14 17:26 
AnswerRe: Worth considering Pin
Banjoo22-Apr-14 22:35
memberBanjoo22-Apr-14 22:35 
QuestionRe: Worth considering Pin
Chenan Wang23-Apr-14 23:34
memberChenan Wang23-Apr-14 23:34 
AnswerRe: Worth considering Pin
Banjoo24-Apr-14 7:38
memberBanjoo24-Apr-14 7:38 
QuestionRisk of app hanging in WaveOutReset() Pin
ZejulioZ22-Apr-14 5:23
memberZejulioZ22-Apr-14 5:23 
AnswerRe: Risk of app hanging in WaveOutReset() Pin
Banjoo22-Apr-14 12:28
memberBanjoo22-Apr-14 12:28 
GeneralRe: Risk of app hanging in WaveOutReset() Pin
ZejulioZ23-Apr-14 5:56
memberZejulioZ23-Apr-14 5:56 
GeneralRe: Risk of app hanging in WaveOutReset() Pin
Banjoo23-Apr-14 8:00
memberBanjoo23-Apr-14 8:00 
GeneralRe: Risk of app hanging in WaveOutReset() Pin
ZejulioZ23-Apr-14 12:06
memberZejulioZ23-Apr-14 12:06 
GeneralRe: Risk of app hanging in WaveOutReset() Pin
Banjoo23-Apr-14 12:40
memberBanjoo23-Apr-14 12:40 
QuestionGood work bro! Pin
Volynsky Alex13-Apr-14 10:09
professionalVolynsky Alex13-Apr-14 10:09 
AnswerRe: Good work bro! Pin
Banjoo13-Apr-14 15:34
memberBanjoo13-Apr-14 15:34 
GeneralRe: Good work bro! Pin
Volynsky Alex13-Apr-14 21:33
professionalVolynsky Alex13-Apr-14 21:33 
GeneralMy vote of 5 Pin
Volynsky Alex12-Apr-14 21:37
professionalVolynsky Alex12-Apr-14 21:37 
BugStability issues on long run Pin
ZejulioZ11-Apr-14 7:45
memberZejulioZ11-Apr-14 7:45 
GeneralRe: Stability issues on long run Pin
Banjoo11-Apr-14 13:17
memberBanjoo11-Apr-14 13:17 
GeneralRe: Stability issues on long run Pin
ZejulioZ11-Apr-14 23:11
memberZejulioZ11-Apr-14 23:11 
GeneralRe: Stability issues on long run Pin
Banjoo12-Apr-14 14:12
memberBanjoo12-Apr-14 14:12 
GeneralRe: Stability issues on long run Pin
ZejulioZ14-Apr-14 3:02
memberZejulioZ14-Apr-14 3:02 
GeneralRe: Stability issues on long run Pin
Banjoo14-Apr-14 7:47
memberBanjoo14-Apr-14 7:47 
GeneralRe: Stability issues on long run Pin
ZejulioZ15-Apr-14 0:39
memberZejulioZ15-Apr-14 0:39 
GeneralRe: Stability issues on long run Pin
Banjoo15-Apr-14 7:01
memberBanjoo15-Apr-14 7:01 
GeneralRe: Stability issues on long run Pin
ZejulioZ15-Apr-14 9:10
memberZejulioZ15-Apr-14 9:10 
QuestionSample rates Pin
hagver7426-Feb-14 0:19
memberhagver7426-Feb-14 0:19 
AnswerRe: Sample rates Pin
Banjoo26-Feb-14 9:56
memberBanjoo26-Feb-14 9:56 
GeneralRe: Sample rates Pin
hagver7427-Feb-14 0:40
memberhagver7427-Feb-14 0:40 
QuestionStart on execute Pin
Member 1060982619-Feb-14 8:30
memberMember 1060982619-Feb-14 8:30 
AnswerRe: Start on execute Pin
Banjoo19-Feb-14 12:36
memberBanjoo19-Feb-14 12:36 
QuestionPacket size, Buffer count, etc. and Sound Card Pin
sisifo3-Dec-13 2:06
membersisifo3-Dec-13 2:06 
AnswerRe: Packet size, Buffer count, etc. and Sound Card Pin
Banjoo3-Dec-13 2:42
memberBanjoo3-Dec-13 2:42 
GeneralRe: Packet size, Buffer count, etc. and Sound Card Pin
sisifo3-Dec-13 3:39
membersisifo3-Dec-13 3:39 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

Permalink | Advertise | Privacy | Terms of Use | Mobile
Web04 | 2.8.171018.2 | Last Updated 22 Apr 2014
Article Copyright 2012 by Banjoo
Everything else Copyright © CodeProject, 1999-2017
Layout: fixed | fluid