I have a program which produces audio signals which supposed to be played simultaneously. For this, I play an interval of 100 ms of audio stream in each 100 ms period. But I have undesired signals in beginning and ending of each 100 ms audio stream (because of DC) so that the output sound is not smooth even the value of signals is the same. My code is attached bellow. Please help me what I should do to have a correct real-time audio.
using System;
using System.Windows.Forms;
using Microsoft.DirectX.DirectSound;
using System.IO;
namespace TestSound
{
class CSound : Form
{
const int HEADER_SIZE = 44;
const bool FLAG_STEREO = true;
const short BITS_PER_SAMPLE = 16;
const int SAMPLE_RATE = 44100;
int numberOfSamples;
MemoryStream stream;
BinaryWriter writer;
Device ApplicationDevice = null;
SecondaryBuffer buffer = null;
BufferDescription description;
public CSound()
{
try
{
ApplicationDevice = new Device();
}
catch
{
MessageBox.Show("Unable to create sound device.");
ApplicationDevice = null;
return;
}
ApplicationDevice.SetCooperativeLevel(this, CooperativeLevel.Priority);
description = new BufferDescription();
description.ControlEffects = false;
stream = new MemoryStream();
writer = new BinaryWriter(stream);
}
private void AddHeader()
{
stream.Position = 0;
writer.Write(0x46464952); // "RIFF" in ASCII
writer.Write((int)(HEADER_SIZE + (numberOfSamples * BITS_PER_SAMPLE * (FLAG_STEREO ? 2 : 1) / 8)) - 8);
writer.Write(0x45564157); // "WAVE" in ASCII
writer.Write(0x20746d66); // "fmt " in ASCII
writer.Write(16);
writer.Write((short)1);
writer.Write((short)(FLAG_STEREO ? 2 : 1));
writer.Write(SAMPLE_RATE);
writer.Write(SAMPLE_RATE * (FLAG_STEREO ? 2 : 1) * BITS_PER_SAMPLE / 8);
writer.Write((short)((FLAG_STEREO ? 2 : 1) * BITS_PER_SAMPLE / 8));
writer.Write(BITS_PER_SAMPLE);
writer.Write(0x61746164); // "data" in ASCII
writer.Write((int)(numberOfSamples * BITS_PER_SAMPLE * (FLAG_STEREO ? 2 : 1) / 8));
}
public void Play(short[] samples)
{
if (ApplicationDevice == null)
return;
stream.Position = HEADER_SIZE;
numberOfSamples = samples.Length;
for (int i = 0; i < numberOfSamples; i++)
{
writer.Write(samples[i]);
if (FLAG_STEREO)
writer.Write(samples[i]);
}
AddHeader();
stream.Position = 0;
try
{
if (buffer != null)
{
buffer.Dispose();
buffer = null;
}
buffer = new SecondaryBuffer(stream, description, ApplicationDevice);
buffer.Play(0, BufferPlayFlags.Default);
}
catch (Exception e)
{
MessageBox.Show(e.Message);
}
}
static short[] samples = new short[4410]; // 100 ms
static CSound sound;
static void Main()
{
Form form = new Form();
form.Show();
sound = new CSound();
Random random = new Random();
for (int i = 0; i < samples.Length; i++)
samples[i] = 1000; // constant value
while (true)
{
sound.Play(samples);
System.Threading.Thread.Sleep(100); // 100 ms
}
}
}
}
If your looking for a way to play audio out through a defined stream, have you considered NAudio http://naudio.codeplex.com/?
You can define a stream, from either a file or some other location (i.e. memory) and then populate the stream with the data you want played back. As long as you are able to continue providing audio data to the stream before the read pointer arrives at the end of the buffer, you wont hear these artefacts in the generated audio.
BTW - I assume you know that the Managed Direct X libraries for .Net are no longer being developed and is effectively a dead end for this sort of Audio development?