Welcome to Doom9's Forum, THE in-place to be for everyone interested in DVD conversion. Before you start posting please read the forum rules. By posting to this forum you agree to abide by the rules. |
3rd August 2019, 20:48 | #1 | Link |
Registered User
Join Date: Oct 2014
Posts: 476
|
Removing regular audio dropouts?
I have an audio file that has dropouts every 1000ms. These dropouts increase in duration as follows:
0ms (no gap) 4ms 6ms 8 11 14 16 19 and then back to 0 (there may be slight variations in the gap length between cycles, on the order of 1ms, but I'm not worried about that being audible) Is there a way to programmatically cut these out? If not with avisynth, is there another tool? The audio is over 3 hours long so doing it manually would take a while. |
3rd August 2019, 22:23 | #2 | Link |
Wouter van Doorn
Join Date: Jul 2019
Location: Central Scotland
Posts: 13
|
I think your best bet is Audacity (a free audio editor). When you select the entire track, there is an option to 'truncate silence'. Haven't tried it, but that should be about right - unless there's other silences that you need to retain. If so, you'd have to go through it parts at the time.
Good luck!
__________________
Wouter |
4th August 2019, 05:50 | #3 | Link |
Registered User
Join Date: Feb 2002
Location: California
Posts: 2,695
|
I have the (expensive) iZotope RX which has a "spectral repair" tool that is specifically designed to fix small audio gaps by interpolating from surrounding sound. It is not automatic, but it sure works well. You could download the trial and see if it can do what you want.
|
4th August 2019, 07:32 | #4 | Link | |
Registered User
Join Date: Oct 2014
Posts: 476
|
Unfortunately that doesn't work very well since it isn't necessarily complete silence, and there's good sections which have levels down at the level of the little blips of noise.
Going through 3 hours of audio multiple times to fix what it gets wrong would take me longer than deleting manually one second at a time. Quote:
Last edited by kuchikirukia; 4th August 2019 at 07:48. |
|
4th August 2019, 10:54 | #5 | Link | |
Moderator
Join Date: Feb 2005
Location: Spain
Posts: 6,915
|
I don't know if I understand your problem. But ...
Quote:
And now you can use Timeline editing filters like Trim or SelectEvery to select the desired part.
__________________
BeHappy, AviSynth audio transcoder. |
|
4th August 2019, 11:59 | #6 | Link |
Registered User
Join Date: Oct 2014
Posts: 476
|
How would I do that since the values change?
It's a cycle of 8000 frames out of which I want to cut frames 1000-1003, 2000-2005, 3000-3007, 4000-4010, 5000-5013, 6000-6015, and 7000-7018. Is it going to have to be in steps? Like Selectrangeevery(8000,7996,1000) then Selectrangeevery(7996,7994,1996) since we've cut 4 frames Is there an audio graph for avisynth so I could look at what the audio is doing frame by frame? Last edited by kuchikirukia; 4th August 2019 at 13:02. |
4th August 2019, 12:20 | #7 | Link |
HeartlessS Usurer
Join Date: Dec 2009
Location: Over the rainbow
Posts: 10,980
|
Take a look at Wonkey_Donkey WaveForm:- https://forum.doom9.org/showthread.p...light=Waveform
From last post in that thread. Is it "Digital Silence", ie multiple values of exactly 0 ? EDIT: You might have to do something like AssumeFPS(1000.0) beforehand to see something useful. [@ eg 48KHz, then 48 samples per frame (of course frame numbers will be off/wrong)] Code:
Colorbars Assumefps(1000.0) WINDOW = 1 # Frames Wide = 2 * WINDOW + 1 HEIGHT = 1.0 # Audio graphs height, 0.333 = 1/3 of result filmstrip image height. UNDER = True # True, then audio graphs stacked under video, else overlay over video. ZOOM = 1.0 # Amplify audio signal for viewing (1.0=No Amp). SUBSIZE = 0.2 # Suggest 0.0(off) to about 0.5. (0.0 <= SubSize <= 1.0) : 0.0 = No Frame Number, 1.0=biggest size for current clip Height (probably too big). SHOWAUDIO = True # Default True. If False, Switches OFF WaveForm Display, Shows FilmStrip Only. W = 264 # Default -1, (or 0 or +ve). -1 = Normal Downscale behaviour, filmstrip width ~= input clip width. #H = Undefined # Undefined, Let W govern height of thumbnail images (or just dont use h=H in function call, same as h=Undefined). WaveForm_FilmStrip(window=WINDOW,Height=HEIGHT,under=UNDER,zoom=ZOOM,subSize=SUBSIZE,ShowAudio=SHOWAUDIO,w=W) #,h=H) Upper channel above is digital silence. Code:
Colorbars Assumefps(1000.0) WINDOW = 1 # Frames Wide = 2 * WINDOW + 1 HEIGHT = 1.0 # Audio graphs height, 0.333 = 1/3 of result filmstrip image height. UNDER = True # True, then audio graphs stacked under video, else overlay over video. ZOOM = 1.0 # Amplify audio signal for viewing (1.0=No Amp). SUBSIZE = 0.2 # Suggest 0.0(off) to about 0.5. (0.0 <= SubSize <= 1.0) : 0.0 = No Frame Number, 1.0=biggest size for current clip Height (probably too big). SHOWAUDIO = True # Default True. If False, Switches OFF WaveForm Display, Shows FilmStrip Only. W = 480 # Default -1, (or 0 or +ve). -1 = Normal Downscale behaviour, filmstrip width ~= input clip width. #H = Undefined # Undefined, Let W govern height of thumbnail images (or just dont use h=H in function call, same as h=Undefined). WaveForm_FilmStrip(window=WINDOW,Height=HEIGHT,under=UNDER,zoom=ZOOM,subSize=SUBSIZE,ShowAudio=SHOWAUDIO,w=W) #,h=H)
__________________
I sometimes post sober. StainlessS@MediaFire ::: AND/OR ::: StainlessS@SendSpace "Some infinities are bigger than other infinities", but how many of them are infinitely bigger ??? Last edited by StainlessS; 4th August 2019 at 15:13. |
4th August 2019, 12:37 | #8 | Link |
Registered User
Join Date: Oct 2014
Posts: 476
|
I got audiograph working.
Now I don't know any way to trim this without 12,900 individual trim commands, which would take longer to type than to just delete them manually. e: ok, let's see if something like this works... e2: doesn't work. "Argument list too long" So how am I going to do trim(0,1000)++trim(1003,2000)++trim(2005,3000)++trim(3007,4000)++trim(4010,5000)++trim(5013,6000)++trim(6015,7000)++trim(7018,8000) and get it to repeat? e3: ok, so trim doesn't trim the audio so even that doesn't work. e3, ok, baby steps. selectrangeevery(8000,7996,980) got rid of the 4ms gap every 8000ms. So now we do the 6ms, so we should be 4 frames cut every 8k so it should be a new cycle of 7996 frames. Last edited by kuchikirukia; 4th August 2019 at 13:22. |
4th August 2019, 13:37 | #9 | Link |
HeartlessS Usurer
Join Date: Dec 2009
Location: Over the rainbow
Posts: 10,980
|
If you can produce a file of either frames to delete, or frames to keep, then can use one of below functions, requires both FrameSel and Prune plugins.
Code:
Function RejectRanges(clip c,String "SCmd",String "Cmd",Bool "TrimAudio",Float "FadeMS") { # RejectRanges() by StainlessS. Required:- FrameSel, Prune, RT_Stats # Wrapper to delete frames/ranges along with audio, can supply frames/ranges in SCmd string And/Or Cmd file. # The wrapper makes for easier usage of Prune() which supports up to 256 input clips, but requires a clip index, # eg '3, 100,200' would specify clip 3, range 100 to 200. The wrapper does away with the necessity for the clip index as we # are only using a single clip here. Prune also does not have a 'reject' arg to delete specified frames rather than select them, # this wrapper also converts a list of frames to delete into a list of frames to select so that we can use Prune and its audio # capability. # # SCmd: Frames/Ranges specified in String (Frames/Ranges either Chr(10) or ';' separated, infix ',' specifies range, eg 'start,end'). # Cmd: Frames/Ranges specified in file (one frame/range per line, comments also allowed, see FrameSel for Further info). # TrimAudio: # True(default), deletes audio belonging to deleted frames # False, returns original audio, probably out of sync. # FadeMS: (default 1.0 millisec). Linear Audio Fade duration at splices when TrimAudio==true, 0 = dont fade (might result in audio 'clicks/cracks'). c TrimAudio=Default(TrimAudio,True) # default true trims audio, false returns original audio (audiodubbed, as Framesel returns no audio) FadeMS=Float(Default(FadeMS,1.0)) # 1 millisecond linear fadeout/fadein at splices PruneCmd = (TrimAudio) ? "~Prune_"+RT_LocalTimeString+".txt" : "" (!TrimAudio) \ ? FrameSel(scmd=SCmd,cmd=Cmd,reject=true) \ : FrameSel_CmdReWrite(PruneCmd,scmd=SCmd,cmd=Cmd,reject=true,Prune=True,range=true) (TrimAudio) ? Prune(Cmd=PruneCmd,FadeIn=True,FadeSplice=True,FadeOut=True,Fade=FadeMS) : NOP # If TrimAudio==true then delete Prune temp file, Else restore original Audio to the now audio-less clip (TrimAudio) \ ? RT_FileDelete(PruneCmd) \ : (c.HasAudio) ? AudioDub(c) : NOP Return Last } Function SelectRanges(clip c,String "SCmd",String "Cmd",Bool "TrimAudio",Float "FadeMS",Bool "Ordered") { # SelectRanges() by StainlessS. Required:- FrameSel, Prune, RT_Stats # Wrapper to Select frames/ranges along with audio, can supply frames/ranges in SCmd string And/Or Cmd file. # The wrapper makes for easier usage of Prune() which supports up to 256 input clips, but requires a clip index, # eg '3, 100,200' would specify clip 3, range 100 to 200. The wrapper does away with the necessity for the clip index as we # are only using a single clip here. # # SCmd: Frames/Ranges specified in String (Frames/Ranges either Chr(10) or ';' separated, infix ',' specifies range, eg 'start,end'). # Cmd: Frames/Ranges specified in file (one frame/range per line, comments allowed, see FrameSel for Further info). # *** NOTE ***, If both Cmd and SCmd supplied AND Ordered == False, then will process Cmd file and then SCmd string afterwards, ie # Will select ranges in Cmd file and in order specified (rather than auto ordering ranges) and then append ranges specified in # SCmd string (and in order specified). # TrimAudio: # True(default), selects audio belonging to selected frames/ranges # False, returns original audio, probably out of sync (maybe totally out of whack if Ordered == false and selected ranges out of order). # FadeMS: (default 1.0 millisec). Linear Audio Fade duration at splices when TrimAudio==true, 0 = dont fade (might result in audio 'clicks/cracks'). # Ordered: # True(default), all frames/ranges are returned in sequencial order. Any frame specified more than once will return only 1 instance. # False, All frames/Ranges are returned in specified order, Cmd processed first and then SCmd. Frames/ranges specified more than once # will return multiple instances. Allows out-of-order trimming of clip, eg re-sequencing of scenes in movie. # # Does not make much sense to select individual frames with audio, best used with ranges. # Will coalesce individually selected adjacent frames/ranges before any Fade, ie only audio fade where sensible to do so. # TrimAudio==false with non Ordered selection will result in completely out of sync audio. c TrimAudio=Default(TrimAudio,True) # default true trims audio, false returns original audio (audiodubbed, as Framesel returns no audio) FadeMS=Float(Default(FadeMS,1.0)) # 1 millisecond linear fadeout/fadein at splices Ordered=Default(Ordered,True) # True (default) frames/ranges will be Ordered and selected only once even if specified more than once. # False, frames/ranges returned in specified order, Cmd processed 1st and then SCmd. PruneCmd = (TrimAudio) ? "~Prune_"+RT_LocalTimeString+".txt" : "" (!TrimAudio) \ ? FrameSel(scmd=SCmd,cmd=Cmd,Ordered=Ordered) \ : FrameSel_CmdReWrite(PruneCmd,scmd=SCmd,cmd=Cmd,Ordered=Ordered,Prune=True,range=true) (TrimAudio) ? Prune(Cmd=PruneCmd,FadeIn=True,FadeSplice=True,FadeOut=True,Fade=FadeMS) : NOP # If TrimAudio==true then delete Prune temp file, Else restore original Audio to the now audio-less clip (TrimAudio) \ ? RT_FileDelete(PruneCmd) \ : (c.HasAudio) ? AudioDub(c) : NOP Return Last } Rough code to produce Frames file, you choose, either frames to keep or frames to reject. Below untested in any way, writes single frames, but easily converted to ranges, if you pick a method to choose frames/range. Code:
FN=".\Frames.txt" FN=RT_GetFullPathName(FN) RT_FileDelete(FN) Avisource(...) Assumefps(1000.0) # EDIT: Actually use your BlankClip code FC = FrameCount M = (FC-1) / 1000 For(i=0,M) { n = i * 1000 # multiple of 1000 frame number For(j=0,999) { f = n + j # frame number if(f < FC) { # do process existing frames Process= ??? # Frame to Process (Process) { RT_WriteFile(FN, "%d",f,Append=True) # To Write Ranges, eg: RT_WriteFile(FN, "%d %d",S,E,Append=True) } } Else { j = 999 # Break, all done i = M # Ditto } } } return MessageClip("DONE") EDIT: If you choose RejectRanges method (which would seem the easier way), then can use FrameSel(Reject=False) together with the same Frames file, to extract the deleted frame/audio, so that you can see what is/was deleted. And if you choose the SelectRanges method, then can use FrameSel(Reject=True), to do the same thing and view deleted frames/audio. EDIT: Ignore above, forgot that FrameSel only returns VIDEO frames, NOT AUDIO. BUT, Can use the alternate ranges function to view Video/Audio that was deleted. Ie, if using RejectRanges() method then use SelectRanges() with same frames file to view deleted audio, if using SelectRanges() method, then use RejectRanges() to view deleted audio.
__________________
I sometimes post sober. StainlessS@MediaFire ::: AND/OR ::: StainlessS@SendSpace "Some infinities are bigger than other infinities", but how many of them are infinitely bigger ??? Last edited by StainlessS; 4th August 2019 at 14:12. |
4th August 2019, 15:01 | #11 | Link |
HeartlessS Usurer
Join Date: Dec 2009
Location: Over the rainbow
Posts: 10,980
|
Show us some of your Frames file, and did you try both FadeMS=0.0 and default FadeMs=1.0
Assuming you chose RejecRanges() method, then also take a peek at SelectRanges() with same Frames file, and with FadeMS=0.0. It will show deleted frames/audio. EDIT: Also show us an image of typical problem using WaveForm_FilmStrip(preferable with wide enough range to show full extent) or audiograph. EDIT: And check your numbers, ie 0->1000 is 1001 frames, and 0->8000, is 8001 frames. When you;ve checked and corrected your numbers then say again what it should be.
__________________
I sometimes post sober. StainlessS@MediaFire ::: AND/OR ::: StainlessS@SendSpace "Some infinities are bigger than other infinities", but how many of them are infinitely bigger ??? Last edited by StainlessS; 4th August 2019 at 15:20. |
4th August 2019, 16:08 | #12 | Link |
HeartlessS Usurer
Join Date: Dec 2009
Location: Over the rainbow
Posts: 10,980
|
OK, this easier for you to make same as your hand edits.
Untested Code:
# ... # Your source to 1000 FPS # Using Global to check for USER errors, and for short function call. Global FN=RT_GetFullPathName(".\Frames.txt") Global CHUNK_SZ = 8000 Global FC = FrameCount Global CHKMX = (FC-1) / CHUNK_SZ RT_FileDelete(FN) # Your frames (not well spec'ed, should spec in range eg 0->999, not 0->1000, otherwise next group dont start at 1000, but at 1001, same for 0->8000, should be 0->7999). # trim(0,1000)++trim(1003,2000)++trim(2005,3000)++trim(3007,4000)++trim(4010,5000)++trim(5013,6000)++trim(6015,7000)++trim(7018,8000) and get it to repeat? For(i=0,CHKMX) { # repeated every 8000 When CHUNK_SZ = 8000 Global Chunk_Num = i ### List of frames to Delete in every chunk of CHUNK_SZ frames, may be in range 0 -> CHUNK_SZ-1 # trim(0,1000) # Nothing to do # trim(1003,2000) DF(1001) DF(1002) # trim(2005,3000) DF(2001) DF(2002) DF(2003) DF(2004) # trim(3007,4000) DF(3001) DF(3002) DF(3003) DF(3004) DF(3005) DF(3006) # trim(4010,5000) DF(4001) DF(4002) DF(4003) DF(4004) DF(4005) DF(4006) DF(4007) DF(4008) DF(4009) # trim(5013,6000) DF(5001) DF(5002) DF(5003) DF(5004) DF(5005) DF(5006) DF(5007) DF(5008) DF(5009) DF(5010) DF(5011) DF(5012) # trim(6015,7000) DF(6001) DF(6002) DF(6003) DF(6004) DF(6005) DF(6006) DF(6007) DF(6008) DF(6009) DF(6010) DF(6011) DF(6012) DF(6013) DF(6014) # trim(7018,8000) # bad spec 8000, is in next chunk [unless CHUNK_SZ should be 8001 frames) DF(7001) DF(7002) DF(7003) DF(7004) DF(7005) DF(7006) DF(7007) DF(7008) DF(7009) DF(7010) DF(7011) DF(7012) DF(7013) DF(7014) DF(7015) DF(7016) DF(7017) } return Messageclip("Done") Function DF(Int Chunk_ix) { # delete chunk ix frame myName="DF: " Assert(Chunk_ix < CHUNK_SZ,RT_string("%sInvalid Chunk_Ix(%d) Max allowed CHUNK_SZ-1(%d)",myName,Chunk_ix,CHUNK_SZ)) Assert(Chunk_num <= CHKMX,RT_string("%sInvalid Chunk_Num(%d) Max allowed CHKMX(%d)",myName,Chunk_num,CHKMX)) # EDIT: Changed < to <= ChunkBase = Chunk_num * CHUNK_SZ # Multiple of CHUNK_SZ eg 0, 8000, 16000, 24000, 32000, etc n = ChunkBase + Chunk_ix # Frame number if(n < FC) { RT_WriteFile(FN, "%d",n,Append=True) } }
__________________
I sometimes post sober. StainlessS@MediaFire ::: AND/OR ::: StainlessS@SendSpace "Some infinities are bigger than other infinities", but how many of them are infinitely bigger ??? Last edited by StainlessS; 4th August 2019 at 18:07. |
4th August 2019, 16:19 | #13 | Link |
Registered User
Join Date: Oct 2014
Posts: 476
|
This is what it looks like:
Is selectrangeevery(8000,7996) 8000 frames? It looks like it. I'm going like 10% into the thing and it looks like I'm still cutting in exactly the right spot but it sounds like crap, when my eyeballed mouse selections in audacity sound great. New plan: I'm going to leave one frame of silence on each side and just close the big gap in the middle, just to make sure I'm not cutting off too much. There's be one less step to this if MeGUI could output in WAV. Edit2: Well that failed. New new plan -- get values from Audacity. Last edited by kuchikirukia; 4th August 2019 at 16:58. |
4th August 2019, 16:24 | #14 | Link |
HeartlessS Usurer
Join Date: Dec 2009
Location: Over the rainbow
Posts: 10,980
|
Prev script should be exactly like your bad spec'ed trim list.
can you upload audio sample somewhere,
__________________
I sometimes post sober. StainlessS@MediaFire ::: AND/OR ::: StainlessS@SendSpace "Some infinities are bigger than other infinities", but how many of them are infinitely bigger ??? |
4th August 2019, 17:17 | #15 | Link |
Registered User
Join Date: Oct 2014
Posts: 476
|
File:
https://www.filehosting.org/file/det...0Link%20VR.mka The skips shift at 1:57:52. Still look to be 1000ms apart, they just don't align with the first part. |
5th August 2019, 17:19 | #16 | Link |
HeartlessS Usurer
Join Date: Dec 2009
Location: Over the rainbow
Posts: 10,980
|
OK, got the audio clip.
I used this Code:
FN=RT_GetFullPathName(".\190719 Bilibili Macro Link VR.mka") FFAudioSource(FN) V=BlankClip(Length=Int(1000*AudioLengthF/AudioRate),Width=800,Pixel_Type="RGB24",fps=1000,last) AudioDub(V,Last) ZOOM=4.0 # Will clip peaks, but easier to see WaveForm_FilmStrip(Window=1,Height=1.0,Under=true,Zoom=ZOOM,Marks=true,SubSize=.2,ShowAudio=true,W=640) return last How did you convert mka to WAV, so I can see same as you ? [ffmpeg ?] these are first few silences that I'm seeing Code:
520, 532 1520,1534 2520,2538 EDIT: Maybe this is you best bet [ffmpeg] Google "ffmpeg trim silence audio" :- https://www.google.co.uk/search?q=ff...w=1920&bih=920
__________________
I sometimes post sober. StainlessS@MediaFire ::: AND/OR ::: StainlessS@SendSpace "Some infinities are bigger than other infinities", but how many of them are infinitely bigger ??? Last edited by StainlessS; 5th August 2019 at 17:41. |
5th August 2019, 17:52 | #17 | Link |
HeartlessS Usurer
Join Date: Dec 2009
Location: Over the rainbow
Posts: 10,980
|
I tried using this
Code:
ffmpeg -i 1.mka -af silenceremove=10-50dB output.wav pause from Here (StackOverflow):- https://stackoverflow.com/questions/...-audio-silence EDIT: Above stuff did not seem to do anything, will need mod to "silenceremove=10-50dB" part, presumably. Oops, should have used ffmpeg -i 1.mka -af silenceremove=1:0:-50dB output.wav I'll try again EDIT: Nope, still no difference, still 3:36:29.56 length
__________________
I sometimes post sober. StainlessS@MediaFire ::: AND/OR ::: StainlessS@SendSpace "Some infinities are bigger than other infinities", but how many of them are infinitely bigger ??? Last edited by StainlessS; 5th August 2019 at 18:07. |
5th August 2019, 18:34 | #18 | Link | |
Registered User
Join Date: Jan 2012
Posts: 271
|
Quote:
Please consult fine documentation here: http://ffmpeg.org/ffmpeg-filters.html#silenceremove Make sure to not use RMS detection and to use shortest window possible. |
|
5th August 2019, 19:43 | #20 | Link | |
HeartlessS Usurer
Join Date: Dec 2009
Location: Over the rainbow
Posts: 10,980
|
Quote:
Result was about 30 mins shorter than original. so is chopping out too much. Given the script from post #12 [delete x number of frames for every 8000], from FrameFile generated, we require in the region of 104 seconds of silence removed. [103905 video frames at 1000FPS] FFMPeg produces warning with above command [output stream #0:0 @ 030ebba0] 100 buffers queued in output stream 0:0, something may be wrong. EDIT: Code:
3:36:29.56 Original length 3:35:45.56 Roughly required 3:06:00.00 silenceremove=stop_periods=-1:stop_duration=0.000083333:detection=peak:window=0:stop_threshold=-40dB [Approximate time, not doing it again for exact timing] 3:27:50.85 ffmpeg -i 1.mka -af silenceremove=stop_periods=-1:stop_duration=0.0083333:detection=peak:window=0:stop_threshold=-40dB output.wav
__________________
I sometimes post sober. StainlessS@MediaFire ::: AND/OR ::: StainlessS@SendSpace "Some infinities are bigger than other infinities", but how many of them are infinitely bigger ??? Last edited by StainlessS; 5th August 2019 at 20:20. |
|
|
|