Sunday, 15 January 2012

c++ - How to find silent parts in audio track -


I have the following code that stores raw audio data from a wav file in a byte buffer:

  byte header [74]; Fred (&; header, sizeof (BYTE), 74, inputfile); Byte * sound_buffer; DWORD data_ size; Fred (& amp; data_ size, size (DWORD), 1, inputfile); Sound_buffer = (byte *) mauloq (BYTE) * data_size); Fred (sound_buffer, size (BYTE), data_size, inputfile);  

Does the audio track quiet (really no sound) and when there is some sound level, is there an algorithm to determine?

OK, your "sound" values ​​will be an array, whether integer or real- on your format Depending on whether the file should be silent or "no sound", the value of that array must be zero, or very close to zero or worst position - if the audio is bias - the value will be sound waves To build, to stay around, instead of fluctuations around.

You can write a simple function that delta for a range, in other words, the difference between the largest and the smallest value, reduce the delta low sound volume. Or alternatively, you can write a function that gives you the given limitations in which the delta is less than the given limit.

For toying, I wrote a nifty class:

  template & lt; Typename T & gt; Class cylinderfinder (public: cylinderfinder (T * data, UIT size, UIT samples): SBEGEN (0), D (data), S (size), damp (sample), position (undefined) {} ​​std :: vector & lt ; Std :: pair & lt; uint, uint & gt; Search (Constant Th Threshold, Constant UI Window) {Auto R = Search (D, S, Threshold, Window); areasToTime (R); Return R; } Private: enum status {silent, loud, undefined}; zero toggle sealance (status st, uit pauses, staid :: vector and left Nant; STD :: pair and UTIT, UITA & gt; & amp; RES) {if (cents == silence} {if (status = = silent) sBegin = pos; position = silence;} Else {if (status == Silence) res.push_back (std :: pair & lt; uint, uint> gt; (sBegin, pos)); position = emphasis;}} zero end (status st, uit paus, stade :: vector & lt; std: : Pair and UTIT, UITT & amp; amp; amp; ridge) {if ((position == silence) & amp; amp; amp; (Saint == silence)) Res.push_back (std: : Pair & lt; uint, uint> (sBegin, pos)); Static Tea Delta (T * Data, Constant Ununt Window) {T Minute = St Diam :: Numerik_lits & lt; T & gt; :: max (), max = std :: numeric_limits & lt; T & gt; :: min (); {TC = Data for the UIT I = 0; I & lt; Window; ++ ii}; If (c & lt; minute) minimum = C; If (C & gt; max) max = C; } Return Maximum - Minimum; } Std :: vector & lt; Std :: pair & lt; Uint, uint> & Gt; Searchilens (T * Data, Constant UIT Size, Constant Threathold, Constant UIT Win) {std :: vector & lt; Std :: pair & lt; Uint, uint> & Gt; Areas; UIT window = win; UIT paus = 0; Condition s = undefined; While ((pause + window) & lt; = size) {if (delta (data + pause, window) & tht; threshold) s = silence; Else s = loud; Toggle Sealance (S., Paus, Area); Pause + = window; } If (delta (data + status, size - position) & lt; threshold) s = silence; Else s = loud; End (s, position, area); Return area; } Zero zonesTotime (Study :: Vector & lt; std :: pair & lt; uint, uint & gt; region) {for (Auto & amp; R: regions) {r.first / = samp; R.second / = samp; }} T * D; Yut SBGIN, S, SAMP; Position status; };  

I have not actually tested it but it seems that it should work. However, it accepts a single audio channel, you have to expand it to work with it and multichannel audio. Here's how you use it:

  SilenceFrenching & lt; Audiodetta type & gt; Finder (for audio data, sizeoffdata, pattern pattern); Auto res = finder.find (threshold, scanvando); // and (auto r: res) std :: cout & lt; & Lt; RFFT & Lt; & Lt; "" & Lt; & Lt; R Seconds & lt; & Lt; Std :: endl;  

Also note that the way it has been implemented now, the "cut" for quiet areas will be very sudden, with such "noise gate" type fillers usually attacked Come and release the parameters, which can be a smooth example for a smooth example, with only a small pop in the silence of 5 seconds, without the attack and release parameter, you will have a 5-minute split in two minutes, and Pop will actually be, but use them By doing this you can apply different sensitivity when cutting it.


No comments:

Post a Comment