I'm recording in NAudio with a PS3Eye camera, using CLEye drivers.
The camera has a 4 microphone array, and presents 4 channels of audio to the system.
By default, all of the channels are being recorded by NAudio. I'm recording to PCM wave, and getting a 4-channel WAV output file.
When I try to play the file in NAudio, I receive an MmException 'NoDriver' calling acmFormatSuggest. Stereo files play fine.
My sound card can only output 2 channels, which appears to cause the error. Setting my Windows audio settings to Quadraphonic does not resolve this issue.
Perhaps I can ask NAudio to record only 2 channels, or implement my own WaveStream somewhere?
Does anybody have any ideas for down-sampling the number of channels in NAudio? (preferably at record time). Big thanks!
isn't it as simple as declaring it in your WaveFormat? 12000 is the sample rate and "1" is the number of channels.
waveInStream = new WaveIn(WaveCallbackInfo.FunctionCallback());
waveInStream.WaveFormat = new WaveFormat(12000, 1);
waveInStream.DeviceNumber = 2;
AudioWriter = new WaveFileWriter("c:\\MyAudio.wav", waveInStream.WaveFormat);
waveInStream.DataAvailable += waveInStream_DataAvailable;
waveInStream.StartRecording();
thats how i setup my code for a basic webcam recorder and with stereo mics it outputs mono wav files.
Related
I am trying to record two audio input (webcam + microphone) and one video input (webcam) via MediaCapture from C#. Just 1 audio and 1 video input works like a charm but the class itself does not allow to specify two audio input device ids.
An example:
var captureDeviceSettings = new MediaCaptureInitializationSettings
{
VideoDeviceId = videoDeviceId, #Webcam video input
AudioDeviceId = audioDeviceId, #Webcam audio input
StreamingCaptureMode = StreamingCaptureMode.AudioAndVideo,
}
I thought about using audio graph and using a submix node but, I need to specify a device ID for the media capture, the submix node does not give that. Further on, using the output device of audio graph seems not like the solution, I do not want to play microphone to default output device. Tried that but sounds horrible. I thought about creating a virtual audio device but I don't know how.
Any suggestions on that?
MediaCapture won't be able to do this, WASAPI maybe possibile, but it is not trivial to do.
Best option may be to utilize https://learn.microsoft.com/en-us/windows/win32/coreaudio/loopback-recording.
You will still have to mux in video stream though if you get loopback recording to work.
I'm recording sound via the WasapiLoopbackCapture and write it to an MP3-File via the NAudio.Lame lib:
LAMEPreset quality = LAMEPreset.ABR_320;
audiostream = new WasapiLoopbackCapture();
audiostream.DataAvailable += stream_DataAvailable;
audiostream.RecordingStopped += stream_RecordingStopped;
mp3writer = new LameMP3FileWriter(Environment.GetEnvironmentVariable("USERPROFILE") + #"\Music\record_temp.mp3",
audiostream.WaveFormat, quality);
audiostream.StartRecording();
When the user presses the stop-recording-button, I save the MP3 and stop the recording:
mp3writer.Flush();
audiostream.Dispose();
mp3writer.Dispose();
All works fine, except that the output file has some disturbing crackle noises in it. (See here for example). I think it might be the case, that my computer is a bit to slow to do the process of compressing and writing the audio data in realtime, so some of the values get lost, but that is just my guess
Edit: When recording to WAVE, the errors dont appear.
What may be the problem here and how could I possibly solve it / work around it?
start off by saving your audio to a WAV file. Does that have crackles in it? If so the crackles are coming from the soundcard. If not, they are coming from the encoding to MP3 code.
I'd like to be able to mix the microphone output with a mp3-File, and output that to a specific device.
I got playing the mp3-File to a specific device working:
Mp3FileReader reader = new Mp3FileReader("C:\\Users\\Victor\\Music\\Musik\\Attack.mp3");
var waveOut = new WaveOut();// or WaveOutEvent()
waveOut.DeviceNumber = deviceId; //deviceId, like 0 or 1
waveOut.Init(reader);
waveOut.Play();
So would I would like to be able to do is basically send the microphone output always to specific output and overlay that output to that specific device with the sound of a mp3-file when for example a button is pressed.
Now is what I'm trying to do possible with naudio and if so how would I go about it?
Thanks!
The basic strategy is to put the audio rececived from the microphone into a BufferedWaveProvider. Then turn that into an ISampleProvider with the ToSampleProvider extension method. Now you can pass that into a MixingSampleProvider. Then play from the MixingSampleProvider. Now at any time you can mix in other audio by adding an input into the MixingSampleProvider
All my sound clips are in mp3, so I do not really feel like translating them tp wav.
If I try to play a mp3 file I get a exception, but the code works fine for .wav files.
I figure there must be a way to play mp3 files.
Stream s = TitleContainer.OpenStream("sounds/bag.mp3");
// throws a exceptio if its a mp3 file
SoundEffect effect = SoundEffect.FromStream(s);
FrameworkDispatcher.Update();
effect.Play();
It is by design - SoundEffect.FromStream only works with wave files. As per MSDN:
The Stream object must point to the head of a valid PCM wave file.
Also, this wave file must be in the RIFF bitstream format.
The audio format has the following restrictions:
Must be a PCM wave file
Can only be mono or stereo
Must be 8 or 16 bit
Sample rate must be between 8,000 Hz and 48,000 Hz
Try to use Media Element..
MediaElement MyMedia = new MediaElement();
MyMedia.Source = new Uri("sounds/bag.mp3", UriKind.RelativeOrAbsolute);
MyMedia.Play();
I know there are lots of question like this.
But I don't want to use the Windows media encoder 9 because it's a problem to get one, and then it is no longer supported.
I know that, one possibility is to capture lots of screenshots and create a video with ffmpeg but I don't want use third party executables.
Is there are a .net only solution?
the answer is the Microsoft Expression Encoder. It is according to my opinion the easiest way to record something on vista and windows 7
private void CaptureMoni()
{
try
{
Rectangle _screenRectangle = Screen.PrimaryScreen.Bounds;
_screenCaptureJob = new ScreenCaptureJob();
_screenCaptureJob.CaptureRectangle = _screenRectangle;
_screenCaptureJob.ShowFlashingBoundary = true;
_screenCaptureJob.ScreenCaptureVideoProfile.FrameRate = 20;
_screenCaptureJob.CaptureMouseCursor = true;
_screenCaptureJob.OutputScreenCaptureFileName = string.Format(#"C:\test.wmv");
if (File.Exists(_screenCaptureJob.OutputScreenCaptureFileName))
{
File.Delete(_screenCaptureJob.OutputScreenCaptureFileName);
}
_screenCaptureJob.Start();
}
catch(Exception e) { }
}
Edit Based on Comment Feedback:
A developer by the name baSSiLL has graciously shared a repository that has a screen recording c# library as well as a sample project in c# that shows how it can be used to capture the screen and mic.
Starting a screen capture using the sample code is as straight forward as:
recorder = new Recorder(_filePath,
KnownFourCCs.Codecs.X264, quality,
0, SupportedWaveFormat.WAVE_FORMAT_44S16, true, 160);
_filePath is the path of the file I'd like to save the video to.
You can pass in a variety of codecs including AVI, MotionJPEG, X264, etc. In the case of x264 I had to install the codec on my machine first but AVI works out of the box.
Quality only comes into play when using AVI or MotionJPEG. The x264 codec manages its own quality settings.
The 0 above is the audio device I'd like to use. The Default is zero.
It currently supports 2 wave formats. 44100 at 16bit either stereo or mono.
The true parameter indicates that I want the audio encoded into mp3 format. I believe this is required when choosing x264 as the uncompressed audio combined in a .mp4 file would not play back for me.
The 160 is the bitrate at which to encode the audio.
~~~~~
To stop the recording you just
recorder.Dispose();
recorder = null;
Everything is open source so you can edit the recorder class and change dimensions, frames per second, etc.
~~~~
To get up and running with this library you will need to either download or pull from the github / codeplex libraries below. You can also use NuGet:
Install-Package SharpAvi
Original Post:
Sharp AVI:
https://sharpavi.codeplex.com/
or
https://github.com/baSSiLL/SharpAvi
There is a sample project within that library that has a great screen recorder in it along with a menu for settings/etc.
I found Screna first from another answer on this StackoverFlow question but I ran into a couple issues involving getting Mp3 Lame encoder to work correctly. Screna is a wrapper for SharpAVI. I found by removing Screna and going off of SharpAvi's sample I had better luck.