Volume Metering and Audio Waveform Display in NAudio
I spent a couple of hours this evening adding two features to NAudio that I have been meaning to add for a long time. They are two Windows Forms controls, one to display volume levels, and the other to display audio waveforms. They are still in a very raw state, and I will probably make some enhancements to their appearance as well as how they calculate their volume levels in the future, but they work pretty well for basic visualisation purposes. I'm also looking forward to creating their equivalents in WPF.
I've made a very short screencast to show them in action. Watch it here: http://screencast.com/t/m13tSFGAG
Want to get up to speed with the the fundamentals principles of digital audio and how to got about writing audio applications with NAudio? Be sure to check out my Pluralsight courses, Digital Audio Fundamentals, and Audio Programming with NAudio.
Comments
Great application!
AnonymousCan you display the complete waveform of the audio track in a control?
that's not a specific feature, although the code wouldn't be too hard to change to do it.
Mark HI'm hoping to add some better waveform drawing support in the future including some WPF rendering
this really is cool... did you ever get the waveform working in SL?
Iron YuppieI have WaveForm display working in WPF. We need to wait for Silverlight 3 before there is any point doing waveform display, as only in SL3 do we get access to the samples during playback.
Mark HHi Mark been looking to use your Volume meter but i can't get them working. Tried also doing the ones with kaxaml but without success. Yours seems to be easier to use. But the thing is i need them to preview the input level before i start recording. can you please help me how i'm going to do it pls
splaxtekthanks
hi Splaxtek,
Mark Hhave a look at my .NET Voice Recorder project (https://github.com/markheath/voicerecorder) to see how you preview volume with NAudio. It's quite simple really, just start 'recording' but only use the data you get to update the meter, don't write it to a file.
Hi Mark!
AnonymousMay I clarify that what you mean for your waveform painter is that the amplitude (I assume thats what it is painting) will never become negative? Because for waveforms, their shape when zoomed in on is usually an 'up-down' shape from the middle (which when looked at normally will result in your waveform shape).
So basically, what it does is, you read data from the WAV file, get a block from the data, and get and display the maximum amplitude or peak for that block. Is this right?
Thanks!
@anonymous, yes this makes a symetric waveform based on the absolute peak over the period aggregated.
Mark Hhi mark,
Anonymousmay i ask, 'have a look at my .NET Voice Recorder project to see how you preview volume with NAudio' as u stated above, i've seen them but i cant really get it. can u pls pinpoint out the functions for me? thanks a lot.
private float lastPeak;
benvoid recorder_MaximumCalculated(object sender, MaxSampleEventArgs e)
{
lastPeak = Math.Max(e.MaxSample, Math.Abs(e.MinSample));
}
public float CurrentInputLevel { get { return lastPeak * 100; } }
void waveIn_DataAvailable(object sender, WaveInEventArgs e)
{
if (this.InvokeRequired)
{
this.BeginInvoke(new EventHandler(waveIn_DataAvailable), sender, e);
}
else
{
writer.WriteData(e.Buffer, 0, e.BytesRecorded);
int secondsRecorded = (int)(writer.Length / writer.WaveFormat.AverageBytesPerSecond);
waveformPainter2.AddMax(CurrentInputLevel);
if (secondsRecorded >= 30)
{
StopRecording();
}
}
}
I'm wondering y this does not work?
private float lastPeak;
benvoid recorder_MaximumCalculated(object sender, MaxSampleEventArgs e)
{
lastPeak = Math.Max(e.MaxSample, Math.Abs(e.MinSample));
}
public float CurrentInputLevel { get { return lastPeak * 100; } }
void waveIn_DataAvailable(object sender, WaveInEventArgs e)
{
if (this.InvokeRequired)
{
this.BeginInvoke(new EventHandler(waveIn_DataAvailable), sender, e);
}
else
{
writer.WriteData(e.Buffer, 0, e.BytesRecorded);
int secondsRecorded = (int)(writer.Length / writer.WaveFormat.AverageBytesPerSecond);
waveformPainter2.AddMax(CurrentInputLevel);
if (secondsRecorded >= 30)
{
StopRecording();
}
}
}
I'm wondering y this does not work?
Hello, do you have an example (WinForms preferred) of how I could implement the NAudio WaveViewer control in a streaming MP3 app like Mp3StreamingDemo. Any help would be appreciated! Regards. S.
Sebastian HoppeOK, solution found...
Sebastian Hoppe