Closed mithunvs closed 6 years ago
So you want to save the audio data in a file AND post it to an api at the same time? Would suggest to intercept the audio data. Use this sample as a reference: https://github.com/filoe/cscore/blob/master/Samples/Recorder/MainWindow.cs
Some dummy code to show you an example:
//1. init capture
var soundIn = new WasapiCapture ...
soundIn.Initialize();
//2. wrap capture to an audio stream
var soundInSource = new SoundInSource(soundIn);
//3. wrap audio stream within an NotificationSource in order to intercept samples
var notificationSource = new NotificationSource(soundInSource);
notificationSource.Interval = 5000; //5 seconds
notificationSource.BlockRead += (s, e) =>
{
//send data provided by eventargs to api
};
//4. convert whole chain back to WaveSource to write wave to the file
var waveSource = notificationSource.ToWaveSource();
//5. initialize the wave writer
var writer = new WaveWriter("out.wav", waveSource.WaveFormat);
//buffer for reading from the wavesource
byte[] buffer = new byte[waveSource.WaveFormat.BytesPerSecond / 2];
//6. if capture serves new data to the audio stream chain, read from the last chain element (wavesource) and write it back to the file
this will process audio data from capture to notificationSource to wavesource and will also trigger the blockread event of the notificationSource
soundInSource.DataAvailable += (s, e)
{
int read;
while((read = waveSource.Read(buffer, 0, buffer.Length)) > 0)
writer.Write(buffer, 0, read);
};
I have to write the samples in the file ,If i provide 5 second interval, I have to get 5 seconds of data written to a file and in next 5 seconds next data should be written to another file and so on. If u understand my problem please give me a solution.I have to sent these files to my api
The source above will do that. As soon as a block of 5 seconds was processed, it will provide it to you. Use e.Data to get the read samples.
I used a code like this because the e.data gives float values but the wave writer only writes the byte values and still i get a 1 second of data,can u please suggest the code to get a 5 second data
` class recorder
{
private WasapiCapture soundIn;
private IWriteable writer;
public void Start()
{
soundIn = new WasapiLoopbackCapture();
soundIn.Initialize();
var soundInSource = new SoundInSource(soundIn);
var notificationSource = new NotificationSource(soundInSource.ToSampleSource());
notificationSource.Interval = 5000;
notificationSource.BlockRead += (s, e) =>
{
float[] interceptsBuff = new float[notificationSource.WaveFormat.BytesPerSecond / 2];
string directory = System.IO.Directory.GetCurrentDirectory();
string filename = /*DateTime.Now.Ticks.ToString()*/ "sample"+ ".wav";
directory = directory + "\\Cache\\";
string fileName = System.IO.Path.Combine(directory + filename);
var intercepts = new WaveWriter(fileName, notificationSource.WaveFormat);
interceptsBuff = e.Data;
byte[] buff= new byte[interceptsBuff.Length * 4];
Buffer.BlockCopy(interceptsBuff, 0, buff, 0, buff.Length);
intercepts.Write(buff, 0, e.Length);
intercepts.Dispose();
};
var waveSource = notificationSource.ToWaveSource();
writer = new WaveWriter("out.wav", waveSource.WaveFormat);
byte[] buffer = new byte[waveSource.WaveFormat.BytesPerSecond / 2];
soundInSource.DataAvailable += (s, e) =>
{
int read;
while ((read = waveSource.Read(buffer, 0, buffer.Length)) > 0)
writer.Write(e.Data, 0, read);
};
soundIn.Start();
}
public void stop()
{
soundIn.Stop();
soundIn.Dispose();
soundIn = null;
if (writer is IDisposable)
((IDisposable)writer).Dispose();
}
}`
So you want to create a new wave file every few seconds? Why would you want to do that? To post it to an api? Why don't you just stream the byte data to the api?
Yes i want to create a file every few seconds. I need this 5 seconds data for later use. Is there any way for doing that.
Well, it is doing what you want. Take a look at this one:
//1. init capture
var soundIn = new WasapiLoopbackCapture();
soundIn.Initialize();
//2. wrap capture to an audio stream
var soundInSource = new SoundInSource(soundIn);
//3. wrap audio stream within an NotificationSource in order to intercept samples
var notificationSource = new NotificationSource(soundInSource.ToSampleSource());
notificationSource.Interval = 5000; //5 seconds
notificationSource.BlockRead += (s, e) =>
{
var filename = $"{DateTime.Now.Ticks}.wav";
//send data provided by eventargs to api
using (var writer = new WaveWriter(filename, notificationSource.WaveFormat))
{
Debug.Assert(e.Data.Length == e.Length);
writer.WriteSamples(e.Data, 0, e.Length);
}
var length = TimeConverterFactory.Instance.GetTimeConverterForSource(notificationSource)
.ToTimeSpan(notificationSource.WaveFormat, e.Length);
Console.WriteLine($"Written {e.Length} ({length:g}) samples to file {filename}");
};
//4. convert whole chain back to WaveSource to write wave to the file
var waveSource = notificationSource.ToWaveSource();
//buffer for reading from the wavesource
byte[] buffer = new byte[waveSource.WaveFormat.BytesPerSecond / 2];
//5. if capture serves new data to the audio stream chain, read from the last chain element (wavesource) and write it back to the file
// this will process audio data from capture to notificationSource to wavesource and will also trigger the blockread event of the notificationSource
soundInSource.DataAvailable += (s, e) =>
{
int read;
while ((read = waveSource.Read(buffer, 0, buffer.Length)) > 0)
{
//do nothing
}
};
soundIn.Start();
Console.ReadKey();
Thanks that's what I've been looking for. Works like a charm. By the way you have a great library
Take a look at the source of the NotificationSource and write your own implementation of it.
Yes that worked perfectly.Thank you for your advice. Keep up the good work
Im new to cscore audio library. Im trying to write a wave file while recording in the wasapi capture data available event, at the same time i need the written data to post to an API in fixed intervals.I want to get access to the file being written but if i dispose the file it will not write in the same fileand if i dont dispose the file i cant use the file to post to the API .Please help..