|
|||||||||||||||||||||||
|
|||||||||||||||||||||||
|
Announcements
Want a new Job?
Chapters
Services
Feature Zones
|
IntroductionAs I already mentioned in my article A low-level audio player in C#, there are no built-in classes in the .NET framework for dealing with sound. This holds true not only for audio playback, but also for audio capture. It should be noted, though, that the Managed DirectX 9 SDK does include classes for high-level and low-level audio manipulation. However, sometimes you don’t want your application to depend on the full DX 9 runtime, just to do basic sound playback and capture, and there are also some areas where Managed DirectSound doesn’t help at all (for example, multi-channel sound playback and capture). Nevertheless, I strongly recommend you to use Managed DirectSound for sound playback and capture unless you have a good reason for not doing so. This article describes a sample application that uses the Using the codeThe sample code reuses the The The Creating an instance of private void Start()
{
Stop();
try
{
WaveLib.WaveFormat fmt = new WaveLib.WaveFormat(44100, 16, 2);
m_Player = new WaveLib.WaveOutPlayer(-1, fmt, 16384, 3,
new WaveLib.BufferFillEventHandler(Filler));
m_Recorder = new WaveLib.WaveInRecorder(-1, fmt, 16384, 3,
new WaveLib.BufferDoneEventHandler(DataArrived));
}
catch
{
Stop();
throw;
}
}
The The first parameter is the ID of the wave input device that you want to use. The value The second parameter is the format of the audio samples. The third and forth parameters are the size of the internal wave buffers and the number of buffers to allocate. You should set these to reasonable values. Smaller buffers will give you less latency, but the captured audio may have gaps on it if your computer is not fast enough. The fifth and last parameter is a delegate that will be called periodically as internal audio buffers are full of captured data. In the sample application we just write the captured data to the FIFO, like this: private void DataArrived(IntPtr data, int size)
{
if (m_RecBuffer == null || m_RecBuffer.Length < size)
m_RecBuffer = new byte[size];
System.Runtime.InteropServices.Marshal.Copy(data, m_RecBuffer, 0, size);
m_Fifo.Write(m_RecBuffer, 0, m_RecBuffer.Length);
}
Similarly, the private void Filler(IntPtr data, int size)
{
if (m_PlayBuffer == null || m_PlayBuffer.Length < size)
m_PlayBuffer = new byte[size];
if (m_Fifo.Length >= size)
m_Fifo.Read(m_PlayBuffer, 0, size);
else
for (int i = 0; i < m_PlayBuffer.Length; i++)
m_PlayBuffer[i] = 0;
System.Runtime.InteropServices.Marshal.Copy(m_PlayBuffer,
0, data, size);
}
Note that we declared the temporary buffers To stop streaming, just call private void Stop()
{
if (m_Player != null)
try
{
m_Player.Dispose();
}
finally
{
m_Player = null;
}
if (m_Recorder != null)
try
{
m_Recorder.Dispose();
}
finally
{
m_Recorder = null;
}
m_Fifo.Flush(); // clear all pending data
}
ConclusionThis sample demonstrates how to combine the
|
||||||||||||||||||||||