Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to detect silence and cut mp3 file without re-encoding using NAudio and .NET

Tags:

naudio

I've been looking for an answer everywhere and I was only able to find some bits and pieces. What I want to do is to load multiple mp3 files (kind of temporarily merge them) and then cut them into pieces using silence detection.

My understanding is that I can use Mp3FileReader for this but the questions are: 1. How do I read say 20 seconds of audio from an mp3 file? Do I need to read 20 times reader.WaveFormat.AverageBytesPerSecond? Or maybe keep on reading frames until the sum of Mp3Frame.SampleCount / Mp3Frame.SampleRate exceeds 20 seconds? 2. How do I actually detect the silence? I would look at an appropriate number of the consecutive samples to check if they are all below some threshold. But how do I access the samples regardless of them being 8 or 16bit, mono or stereo etc.? Can I directly decode an MP3 frame? 3. After I have detected silence at say sample 10465, how do I map it back to the mp3 frame index to perform the cutting without re-encoding?

like image 783
bosmart Avatar asked Jan 16 '14 09:01

bosmart


1 Answers

Here's the approach I'd recommend (which does involve re-encoding)

  1. Use AudioFileReader to get your MP3 as floating point samples directly in the Read method
  2. Find an open source noise gate algorithm, port it to C#, and use that to detect silence (i.e. when noise gate is closed, you have silence. You'll want to tweak threshold and attack/release times)
  3. Create a derived ISampleProvider that uses the noise gate, and in its Read method, does not return samples that are in silence
  4. Either: Pass the output into WaveFileWriter to create a WAV File and and encode the WAV file to MP3 Or: use NAudio.Lame to encode directly without a WAV step. You'll probably need to go from SampleProvider back down to 16 bit WAV provider first
like image 196
Mark Heath Avatar answered Sep 20 '22 15:09

Mark Heath