I have a Windows Forms project in C#. In this project there is a WaveOut device that's played back in separate thread. This playback thread periodically needs to call a UI thread method and pass it some data (an array holding the audio information that is being passed to the soundcard). The passAudio method calls the connected EventHandler periodically.
Right now, the waveout device (WaveOutPlayer.cs) has an EventHandler:
public class WaveOutPlayer : IDisposable
{
public event EventHandler<AudioEventArgs> BufferSwapped;
...
private void passAudio(byte[] pAudiodata)
{
AudioEventArgs args = new AudioEventArgs();
args.Data = pAudiodata;
args.WaveFormat = ws.Format;
if (BufferSwapped != null)
{
BufferSwapped.Invoke(this, args);
}
}
}
And the Windows Form instance connects to this EventHandler:
private void Start()
{
WaveStream Audio = new WaveStream("sine440hz_16bit_stereo.wav");
WaveOutPlayer wp = new WaveOutPlayer(audio, 0);
wp.BufferSize = 8192; // testing
wp.Repeat = false; // 'true' not implemented yet
wp.BufferSwapped += Wp_BufferSwapped;
}
private void Wp_BufferSwapped(object sender, AudioEventArgs e)
{
// The audio buffer data can be found in the event args.
// So analyze this Audio and manipulate some of the forms' controls
// accordingly.
this.labelForAmplitude.Text = "some value";
}
However, this results in an exception because the Wp_BufferSwapped-Method actually belongs to the playback thread and thus may not manipulate the label's text.
Now: How can I solve this problem without making the Windows Form's code more difficult? The reason for this is that I want to let my students (high school) do some cool stuff with arrays and simple user interfaces. But at this point they only have a very basic understanding of user interfaces work. They do not know anything about stuff like BeginInvoke or MethodInvoker, yet. So I want to give them the WaveOutPlayer in form of a DLL - and they only need to deal with the Windows Form. Is there a solution for this particular Kind of problem?