I want to use Open TK to record on multiple devices at the same time.
As you can see in the question below, Save to Wav file the audio recorded with .NetCore C# on Raspberry pi
I can record on one device, but if I try to do this on two devices at the same time and execute the following code, I may get the error "System.AccessViolationException: Attempted to read or write protected memory. This is often an indication that other memory is corrupt."
What is the cause of this?
Also, how can I write the code to do what I intended?
Task1 and task2 in the code below are almost the same, only the AudioCapture device(recorders[0], recorders[2]...) is different.
var recorders = AudioCapture.AvailableDevices;
for (int i = 0; i < recorders.Count; i++)
{
Console.WriteLine(recorders[i]);
}
Console.WriteLine("-----");
const int samplingRate = 44100; // Samples per second
const ALFormat alFormat = ALFormat.Mono16;
const ushort bitsPerSample = 16; // Mono16 has 16 bits per sample
const ushort numChannels = 1; // Mono16 has 1 channel
var task1 = Task.Run(() =>
{
using (var f = File.OpenWrite("aaa.wav"))
using (var sw = new BinaryWriter(f))
{
// Read This: http://soundfile.sapp.org/doc/WaveFormat/
sw.Write(new char[] { 'R', 'I', 'F', 'F' });
sw.Write(0); // will fill in later
sw.Write(new char[] { 'W', 'A', 'V', 'E' });
// "fmt " chunk (Google: WAVEFORMATEX structure)
sw.Write(new char[] { 'f', 'm', 't', ' ' });
sw.Write(16); // chunkSize (in bytes)
sw.Write((ushort)1); // wFormatTag (PCM = 1)
sw.Write(numChannels); // wChannels
sw.Write(samplingRate); // dwSamplesPerSec
sw.Write(samplingRate * numChannels * (bitsPerSample / 8)); // dwAvgBytesPerSec
sw.Write((ushort)(numChannels * (bitsPerSample / 8))); // wBlockAlign
sw.Write(bitsPerSample); // wBitsPerSample
// "data" chunk
sw.Write(new char[] { 'd', 'a', 't', 'a' });
sw.Write(0); // will fill in later
// 10 seconds of data. overblown, but it gets the job done
const int bufferLength = samplingRate * 10;
int samplesWrote = 0;
Console.WriteLine($"Recording from: {recorders[2]}");
using (var audioCapture = new AudioCapture(
recorders[2], samplingRate, alFormat, bufferLength))
{
var buffer = new short[bufferLength];
audioCapture.Start();
for (int i = 0; i < 10; ++i)
{
Thread.Sleep(1000); // give it some time to collect samples
var samplesAvailable = audioCapture.AvailableSamples;
audioCapture.ReadSamples(buffer, samplesAvailable);
for (var x = 0; x < samplesAvailable; ++x)
{
sw.Write(buffer[x]);
}
samplesWrote += samplesAvailable;
Console.WriteLine($"Wrote {samplesAvailable}/{samplesWrote} samples...");
}
audioCapture.Stop();
}
sw.Seek(4, SeekOrigin.Begin); // seek to overall size
sw.Write(36 + samplesWrote * (bitsPerSample / 8) * numChannels);
sw.Seek(40, SeekOrigin.Begin); // seek to data size position
sw.Write(samplesWrote * (bitsPerSample / 8) * numChannels);
}
});
Thread.Sleep(1000);
var task2 = Task.Run(() => {
using (var g = File.OpenWrite("bbbb.wav"))
using (var sx = new BinaryWriter(g))
{
// Read This: http://soundfile.sapp.org/doc/WaveFormat/
sx.Write(new char[] { 'R', 'I', 'F', 'F' });
sx.Write(0); // will fill in later
sx.Write(new char[] { 'W', 'A', 'V', 'E' });
// "fmt " chunk (Google: WAVEFORMATEX structure)
sx.Write(new char[] { 'f', 'm', 't', ' ' });
sx.Write(16); // chunkSize (in bytes)
sx.Write((ushort)1); // wFormatTag (PCM = 1)
sx.Write(numChannels); // wChannels
sx.Write(samplingRate); // dwSamplesPerSec
sx.Write(samplingRate * numChannels * (bitsPerSample / 8)); // dwAvgBytesPerSec
sx.Write((ushort)(numChannels * (bitsPerSample / 8))); // wBlockAlign
sx.Write(bitsPerSample); // wBitsPerSample
// "data" chunk
sx.Write(new char[] { 'd', 'a', 't', 'a' });
sx.Write(0); // will fill in later
// 10 seconds of data. overblown, but it gets the job done
const int bufferLength = samplingRate * 10;
int samplesWrote = 0;
Console.WriteLine($"Recording from: {recorders[0]}");
using (var audioCapture = new AudioCapture(
recorders[0], samplingRate, alFormat, bufferLength))
{
var buffer = new short[bufferLength];
audioCapture.Start();
for (int i = 0; i < 10; ++i)
{
Thread.Sleep(1000); // give it some time to collect samples
var samplesAvailable = audioCapture.AvailableSamples;
audioCapture.ReadSamples(buffer, samplesAvailable);
for (var x = 0; x < samplesAvailable; ++x)
{
sx.Write(buffer[x]);
}
samplesWrote += samplesAvailable;
Console.WriteLine($"Wrote {samplesAvailable}/{samplesWrote} samples...");
}
audioCapture.Stop();
}
sx.Seek(4, SeekOrigin.Begin); // seek to overall size
sx.Write(36 + samplesWrote * (bitsPerSample / 8) * numChannels);
sx.Seek(40, SeekOrigin.Begin); // seek to data size position
sx.Write(samplesWrote * (bitsPerSample / 8) * numChannels);
}
});
await Task.WhenAll(task1, task2);
question from:
https://stackoverflow.com/questions/65938285/how-to-record-from-multiple-devices-at-the-same-time-using-opne-tk