Sign in to follow this  

DirectSound Network player

This topic is 4166 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Hi, I have a UDP server receiving about 10 000 bytes per second. Wav sound format is (8000hz, 16bits, 1 channel). Using DirectSound I would like to create a player to play this data. Sometime, is it possible that server doesn't receive data for a couple a seconde and the player must no crash for that reason. However, I did not found any good exemple to help me. Thank

Share this post


Link to post
Share on other sites
Hi,

Using the Microsoft SDK sample (CaptureSound), I have now done an implementation of what I need. But there is a problem when playing data from the stream. Sounds like the buffer isn't filled correctly, size or time, don't know... Here is the code :


public class StreamPlayer
{
public const int NumberPlayNotifications = 16;
private SecondaryBuffer m_PlayBuffer = null;
private WaveFormat m_WaveFormat;
private BufferDescription m_PlayBufferDescription;
private AutoResetEvent m_NotificationEvent = null;
private BufferPositionNotify[] m_PositionNotify = new BufferPositionNotify[NumberPlayNotifications + 1];
private Thread m_NotifyThread = null;
private Notify m_ApplicationNotify = null;
private int m_PlayBufferSize = 0;
private int m_NextPlayOffset = 0;
private int m_NotifySize = 0;
private int m_SampleCount = 0;
private Device m_SoundDevice;
private bool m_Playing = false;

// File to play
private FileStream m_FileStream = null;

// Constructor
public StreamPlayer( Control owner )
{
m_SoundDevice = new Device();
m_SoundDevice.SetCooperativeLevel(owner, CooperativeLevel.Normal);

// Define the format for the raw waveform data.
m_WaveFormat = new WaveFormat();
m_WaveFormat.SamplesPerSecond = 8000;
m_WaveFormat.BitsPerSample = 16;
m_WaveFormat.Channels = 1;
m_WaveFormat.FormatTag = WaveFormatTag.Pcm;
m_WaveFormat.BlockAlign = (short)(m_WaveFormat.Channels * (m_WaveFormat.BitsPerSample / 8));
m_WaveFormat.AverageBytesPerSecond = m_WaveFormat.SamplesPerSecond * m_WaveFormat.BlockAlign;

// Sound buffer description
m_PlayBufferDescription = new BufferDescription(m_WaveFormat);

// Load wav file (hard coded here to test class)
m_FileStream = new FileStream("Test.riff", FileMode.Open, FileAccess.Read);
}

// Create capture buffer
private void CreatePlayerBuffer()
{
// Free ressource
if (m_ApplicationNotify != null)
{
m_ApplicationNotify.Dispose();
m_ApplicationNotify = null;
}
if (m_PlayBuffer != null)
{
m_PlayBuffer.Dispose();
m_PlayBuffer = null;
}

// Set the notification size
m_NotifySize = (1024 > m_WaveFormat.AverageBytesPerSecond / 8) ? 1024 : (m_WaveFormat.AverageBytesPerSecond / 8);
m_NotifySize -= m_NotifySize % m_WaveFormat.BlockAlign;

// Set the buffer sizes
m_PlayBufferDescription.BufferBytes = m_PlayBufferSize = (m_NotifySize * NumberPlayNotifications);
m_PlayBufferDescription.ControlVolume = true;
m_PlayBufferDescription.GlobalFocus = true;
m_PlayBufferDescription.ControlPositionNotify = true;

// Create the actual sound buffer; the heart of the streaming sound features.
m_PlayBuffer = new SecondaryBuffer(m_PlayBufferDescription, m_SoundDevice);

// Play buffer is set to 0
m_NextPlayOffset = 0;

// Init notifications
InitNotifications();
}

// Init notifications
private void InitNotifications()
{
// Create a thread to monitor the notify events
if (m_NotifyThread == null)
{
m_NotifyThread = new Thread(new ThreadStart(WaitThread));
m_Playing = true;
m_NotifyThread.Start();

// Create a notification event, for when the sound stops playing
m_NotificationEvent = new AutoResetEvent(false);
}

// Setup the notification positions
for (int i = 0; i < NumberPlayNotifications; i++)
{
m_PositionNotify[i].Offset = (m_NotifySize * i) + m_NotifySize - 1;
m_PositionNotify[i].EventNotifyHandle = m_NotificationEvent.Handle;
}
m_ApplicationNotify = new Notify( m_PlayBuffer );
m_ApplicationNotify.SetNotificationPositions(m_PositionNotify, NumberPlayNotifications);
}

// Wait thread (waiting for notification)
private void WaitThread()
{
// Start playing buffer content now
this.m_PlayBuffer.Play(0, BufferPlayFlags.Looping);

// Wait for notification
while (m_Playing)
{
// Sit here and wait for a message to arrive
m_NotificationEvent.WaitOne(Timeout.Infinite, true);
FillBuffer();
}
}

/// Fill buffer on notification
private void FillBuffer()
{
try
{
// Read n data in file stream
byte[] playData = null;
int fileStreamLength = (int)m_FileStream.Length;
if (m_SampleCount >= fileStreamLength)
{
// Sound has been sucessfully played
m_Playing = false;
return;
}
else if ((m_SampleCount + m_NotifySize) <= fileStreamLength)
{
// Fill playing buffer with n data from file stream
m_FileStream.Seek(m_SampleCount, SeekOrigin.Current);
playData = new byte[m_NotifySize];
m_FileStream.Read(playData, 0, m_NotifySize);
m_PlayBuffer.Write(m_NextPlayOffset, playData, LockFlag.None);
m_SampleCount += playData.Length;
m_NextPlayOffset += playData.Length;
}
else if ((m_SampleCount + m_NotifySize) > fileStreamLength)
{
// Fill playing buffer with lefting data from file stream
m_FileStream.Seek(m_SampleCount, SeekOrigin.Current);
playData = new byte[m_NotifySize];
int byteLefting = fileStreamLength - m_SampleCount;
m_FileStream.Read(playData, 0, byteLefting);
m_PlayBuffer.Write(m_NextPlayOffset, playData, LockFlag.None);
m_SampleCount += byteLefting;
m_NextPlayOffset += byteLefting;
}

// Circular buffer
m_NextPlayOffset %= m_PlayBufferSize;
}
catch (Exception e)
{
System.Console.WriteLine("StreamPlayer : FillBuffer (" + e.ToString() + ")");
}

}

// Start playing
public void StartPlaying()
{
CreatePlayerBuffer();
}

// Stop playing
public void StopPlaying()
{
this.m_Playing = false;
if (m_PlayBuffer != null)
{
m_PlayBuffer.Stop();
m_PlayBuffer = null;
}
}
}


The song is playing but it seem to be play to much faster or something else. Or maybe I did something wrong. The WAV file "Test.riff" was make using SoundRec32 with (8000hz, 16bit, 1 channel) format. After that I open it with UltraEdit and I removed the wav riff header just to keep the essential (DATA) ;)

Thank to help me.

Share this post


Link to post
Share on other sites

This topic is 4166 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this