Reputation: 69
I am trying to get the audio from the sound card and write the audio data to the byte array.
So far, I could manage these: Get the audio, save the file in wav format, get byte array from the wav file.
But, I need to get the byte array from a live audio [simultaneously], not from a saved file. So, how can I do that? I read some documentation but could not find a specific implementation.
public partial class Form1 : Form
{
[DllImport("winmm.dll")]
private static extern long mciSendString(string command, StringBuilder retstrign, int Returnlength, IntPtr callback);
public Form1()
{
InitializeComponent();
mciSendString("open new Type waveaudio alias recsound", null, 0, IntPtr.Zero);
button1.Click += new EventHandler(this.button1_Click);
}
private void button1_Click(object sender, EventArgs e)
{
// throw new NotImplementedException();
mciSendString("record recsound", null, 0, IntPtr.Zero);
button2.Click += new EventHandler(this.button2_Click);
}
private void button2_Click(object sender, EventArgs e)
{
string filename = @"C:\Users\seymk\Downloads\BackwardsApp-master\test.wav";
//throw new NotImplementedException();
mciSendString(@"save recsound C:\Users\seymk\Downloads\BackwardsApp-master\test.wav", null, 0, IntPtr.Zero);
mciSendString("close recsound", null, 0, IntPtr.Zero);
//ReadWav(filename, out float[] L, out float[] R);
using (WaveFileReader reader = new WaveFileReader("filename"))
{
Assert.AreEqual(16, reader.WaveFormat.BitsPerSample, "Only works with 16 bit audio");
byte[] buffer = new byte[reader.Length];
int read = reader.Read(buffer, 0, buffer.Length);
short[] sampleBuffer = new short[read / 2];
Buffer.BlockCopy(buffer, 0, sampleBuffer, 0, read);
}
}
}
UPDATE
Below, I can record and listen to the audio simultaneously. I still couldn't figure out how to get the byte array at the same time.
Because when I try to get the byte array from the wav file, since it is still being processed, I get the error that the file is in usage by other applications.
public partial class Form1 : Form
{
private WaveIn recorder;
private BufferedWaveProvider bufferedWaveProvider;
private SavingWaveProvider savingWaveProvider;
private WaveOut player;
private string filename = @"C:\Users\seymk\Downloads\BackwardsApp-master\test.wav";
public Form1()
{
InitializeComponent();
}
private void button1_Click_1(object sender, EventArgs e)
{
// set up the recorder
recorder = new WaveIn();
recorder.DataAvailable += RecorderOnDataAvailable;
// set up our signal chain
bufferedWaveProvider = new BufferedWaveProvider(recorder.WaveFormat);
savingWaveProvider = new SavingWaveProvider(bufferedWaveProvider, filename);
// set up playback
player = new WaveOut();
player.Init(savingWaveProvider);
// begin playback & record
player.Play();
recorder.StartRecording();
}
private void button2_Click_1(object sender, EventArgs e)
{
// stop recording
recorder.StopRecording();
// stop playback
player.Stop();
// finalise the WAV file
savingWaveProvider.Dispose();
}
private void RecorderOnDataAvailable(object sender, WaveInEventArgs waveInEventArgs)
{
bufferedWaveProvider.AddSamples(waveInEventArgs.Buffer, 0, waveInEventArgs.BytesRecorded);
}
}
public class SavingWaveProvider : IWaveProvider, IDisposable
{
private readonly IWaveProvider sourceWaveProvider;
private readonly WaveFileWriter writer;
private bool isWriterDisposed;
public SavingWaveProvider(IWaveProvider sourceWaveProvider, string wavFilePath)
{
this.sourceWaveProvider = sourceWaveProvider;
writer = new WaveFileWriter(wavFilePath, sourceWaveProvider.WaveFormat);
}
public int Read(byte[] buffer, int offset, int count)
{
var read = sourceWaveProvider.Read(buffer, offset, count);
if (count > 0 && !isWriterDisposed)
{
writer.Write(buffer, offset, read);
}
if (count == 0)
{
Dispose(); // auto-dispose in case users forget
}
return read;
}
public WaveFormat WaveFormat { get { return sourceWaveProvider.WaveFormat; } }
public void Dispose()
{
if (!isWriterDisposed)
{
isWriterDisposed = true;
writer.Dispose();
}
}
}
Upvotes: 1
Views: 974