|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Announcements
Chapters
Services
Feature Zones
|
IntroductionIt's surprising that there are no components for sound capturing in .NET Framework 3.5. Even designers of WPF and Silverlight 2.0 were focused on graphics so deeply, that they forgot about applications recording sound from user's microphone. It is said that the next version of Silverlight will provide such functionality. However, what you often want to achieve is to store the recorded sound in MP3 file (or send it as MP3 stream). That's legally complicated due to MP3 patent constraints. And for the same legal reason, we can assume that we will not see MP3 functionality in Microsoft technologies soon (there is WMA instead). Here you find an easy to use .NET 3.5 component, providing Sound Capturing functionality for a Windows application. It outputs data as raw PCM samples or a regular WAV file. Or you can just set one boolean property to use LAME DLL and perform MP3 compression on the fly. This article uses a subset of C# MP3 Compressor libraries written by Idael Cardoso which in turn are partially based on A low level audio player in C# by Ianier Munoz. See this website for technical and copyright information regarding the LAME project. BackgroundI chose Managed DirectX (MDX) 1.1 to capture sound. The MDX project is currently frozen since Microsoft moved to XNA Game Studio Express (a solution rather inadequate just for capturing bits of sound). MDX is descended by SlimDX Open Source project which exposes roughly similar interfaces and delegates to the native DirectSound libraries. MDX comprises of .NET assemblies delegating calls to native DirectX DLLs of 2006. We expect DirectX in a version backward compatible with the 2006 interfaces to be installed on virtually every Windows computer (yes, also works on Vista). The component captures sound via MDX from a sound card in raw PCM format. PCM format is a simple sequence of sound sample values. The samples can be 8bit (0..255) or 16bit (-32768..32767) each. Stereo sound is a sequence of pairs of samples (left, right, left, right...). PCM is a proper format for streaming of raw data. Streaming means passing data in small chunks while the total volume of the data may be unknown. Raw PCM is the most basic type of output of WAV (RIFF) format requires the raw PCM data to be prefixed with RIFF header, which apart from format information also contains information about the total length of the PCM data in the file. That's why you can't really stream RIFF data, as the total size of the stream is usually unknown. WAV (RIFF) format is the second type of output of the The third type of Using the CodeSetting UpFrom your application, add a reference to Istrib.Sound.Mp3.dll assembly (see If you experience "Loader Lock" warning while debugging your application, refer here for a workaround. Istrib.Sound.Mp3.dll assembly contains a single component: Component ConstructionYou may use Visual Studio Component Designer to drag and drop the mp3SoundCapture = new Mp3SoundCapture();
The component is ready to use just after construction. The default output is MP3 128kbit/s sampled at 22kHz, 16bit, mono. You specify sampling parameters and output format by setting the component properties. Capturing Device (e.g. A Microphone)You may use a default Windows recording device: mp3SoundCapture.CaptureDevice = SoundCaptureDevice.Default;
Or choose one of the installed system sound capture devices: mp3SoundCapture.CaptureDevice = SoundCaptureDevice.AllAvailable.First();
Output FormatYou set one of the 3 output types:
mp3SoundCapture.OutputType = Mp3SoundCapture.Outputs.Mp3;
Sampling ParametersFor PCM or WAV output, you may select any available sampling parameters supported by the sound card ( mp3SoundCapture.WaveFormat = PcmSoundFormat.StandardFormats.First();
... or if you wish to hardcode it: mp3SoundCapture.WaveFormat = PcmSoundFormat.Pcm22kHz16bitMono;
Sampling parameters for MP3 format are restricted to values returned by mp3SoundCapture.WaveFormat = myMp3BitRate.CompatibleSourceFormats.First();
//Or: mp3SoundCapture.WaveFormat = Mp3SoundFormat.AllSourceFormats.First();
MP3 Bit RateFor MP3 output format, you specify one of the available bit rates. Again - you cannot pair each bit rate with each sampling parameters. If you choose sampling parameters prior to bit rate, then you may use mp3SoundCapture.Mp3BitRate = myPcmSoundFormat.GetCompatibleMp3BitRates().First();
//Or mp3SoundCapture.Mp3BitRate = Mp3BitRate.AllValues.First();
... or if you wish to hardcode it: mp3SoundCapture.Mp3BitRate = Mp3BitRate.BitRate128;
Volume Normalization OptionOften when an application records and stores many pieces of sound, it is required to adjust their volume so that all of them were at similar volume level. The mp3SoundCapture.NormalizeVolume = true;
Note that the normalization algorithm must read the whole stream to find the loudest place, then rewrite the whole stream adjusting the volume of each sample. It means that the entire stream must be buffered before it is directed to the output. CapturingTo start capturing, just call To stop capturing, just call the Asynchronous Stop()As mentioned above, when normalizing, it may take some time after calling mp3SoundCapture.WaitOnStop = false;
Note that you cannot close your output buffer passed to private void mp3SoundCapture_Stopped(object sender, Mp3SoundCapture.StoppedEventArgs e)
{
//Now the e.OutputFileName file is ready and contains all captured data
dataAvailableLbl.Text = "Data available in " + e.OutputFileName;
dataAvailableLbl.Visible = true;
}
Points of InterestIn some development environment configurations, you may get "Loader Lock" error (which is really a warning) while starting your application under the debugger. It's a well-known design issue in Managed DirectX. You may disable this error in Visual Studio debugger settings (most people do this without observable consequences). I preferred not to do this. Instead I found a workaround: if the project which references Istrib.Sound.Mp3.dll also explicitly references Managed DirectX assemblies ( However - what I experienced - you cannot use Visual Studio Add Reference... wizard to add the DirectX GAC assembly reference. That's not an issue when you reference a local copy of DirectX assemblies (like in the example: DirectX subdirectory). The workaround for the GAC problem is to add the reference to GAC assemblies manually editing your csproj file with a text editor: <ItemGroup>
...
<Reference Include="Microsoft.DirectX">
<Name>Microsoft.DirectX</Name>
</Reference>
<Reference Include="Microsoft.DirectX.DirectSound">
<Name>Microsoft.DirectX.DirectSound</Name>
</Reference>
...
</ItemGroup>
Visual Studio Add Reference... wizard generates identical XML except it includes full assembly version info. This should work as well... but it does not, at least on my machines. History
|
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||