Log in

View Full Version : Cutting sound


vlada
11th November 2007, 21:24
Hi,

I have one very simple question. How can I cut a sound-only clip in AviSynth? I need to trim 30s from the start...

Gerard V
11th November 2007, 22:34
Well, this may not be optimal, but I would do the following.
1. Use Blankclip() to make a clip the same length as the sound
2. Use AudioDub() to dub your sound onto the blank clip.
3. Use trim() to cut of 30s worth of frames.

That is assuming that you cannot just use Trim on the sound track - never tried it.

Adub
11th November 2007, 22:45
Or:
Directshowsource("clip.avi", video=false, audio=true)
trim(x,y)

vlada
12th November 2007, 00:40
Gerard V
I was thinking about this too. But it seemed to me too complicated.

I haven't tried Trim() neither, because it's parameters are frames, so I have no idea what would I put as parameters for audio-only source.

Merlin7777
I don't have an AVI. My file is an .ac3.

Anyway I already solved my problem with BeSplit (I cut the source file). But if anyone knows if there is a simple way to cut audio in AviSynth, I'm still interested.

Adub
12th November 2007, 01:51
Oh, well when you said "clip" I assumed it was an avi.

You just need to assume a certain fps, and cut the specified number of frames. MeGUI actually has a built in cutter, I think AvsP does as well. Preview the audio in MPC or the like and determine where you want to cut and then use the previously mentioned programs.

Either way, the same technique applies, except you just use:
NicAC3Source() or Directshowsource() or FFMPEGSource() etc.

IanB
12th November 2007, 04:34
Yes trimming audio only clips is a deficiency.Function AddVideo(Clip A) {
N=Ceil(1000.*AudioLengthF(A)/AudioRate(A))
BlankClip(N, 16, 16, FPS=1000)
Return AudioDub(A)
}Then use Trim() with the positions in milliseconds as the frame numbers.

Gerard V
12th November 2007, 17:51
@vlada
Might I respectfully suggest that since you're using avisynth you're kinda obligated to be willing to use a script with 3 or 4 lines - that can't really be seen as too complicated (IMHO). I think the avisynth info() function will show you the framerate of your video, but in your case you are creating the video from scratch so you can specify framerate as a parameter in Blankclip(). If you use 25 fps then you'll only need to crop 750 frames . . .

Gerard V
13th November 2007, 00:31
Here are 3 more options:

OPTION A
I assume you want to dub the trimmed sound clip onto your video once the 30s is removed. So
1. Watch your video to the 30s mark (in virtual dub or whatever) and get the number of frames that equals 30s of time. If its a PAL clip then that would be at the 750 frame mark.
2. Make an avisynth script like:
V = Avisource(" . . . .. ")
A = WavSource(" ....")
V = Trim(V,1,750) + V # to make it 30s longer
AudioDub(V,A).Trim(751,0) # Then cut off the excess

OPTION B
Download and install Audacity
Open your wav file
Select the first 30s
hit Delete
Save your wav file.

OPTION C
AudioDub(V,A) # Dub the audio on first, then
DelayAudio(-30.0) #Play the audio 30s earlier.

I think to make it much easier we'd need magic.

Have fun!

Adub
13th November 2007, 01:54
The only problem is that he isn't using wav, he is using AC3. Sure, he could convert to WAV, but that is just an unnecessary step.

IanB
13th November 2007, 07:35
If he wants to directly trim the AC3 stream, he will need an external AC3 stream editor. Avisynth always decodes the audio to wave format on input. Any or all of the above methods can deal with this if decoding and reencoding is not a problem.

Assuming the AC3 editor can only trim at segment boundaries, then the issue becomes maintaining AV sync. At the Avisynth level adding a short blank clip at the start or trimming a small number of frames from the beginning of the clip will compensate for remaining segment offset.

Depending on the AV container format used it may also be possible to simply offset the audio stream from the video stream during the muxing process.

tebasuna51
13th November 2007, 10:02
If he wants to directly trim the AC3 stream, he will need an external AC3 stream editor. Avisynth always decodes the audio to wave format on input. Any or all of the above methods can deal with this if decoding and reencoding is not a problem.
Yep, for instance he can use Delaycut.
Because ac3 frames are 32 ms long (if 48 KHz) the cut may be 29984 or 30016 ms.
Then the ac3 preserve their original quality.

If AviSynth method is required, with decoding (NicAc3Source) and reencoding (SoundOut), the more simple is:
DelayAudio(-30.0) #not needed AudioDub

shevegen
13th November 2007, 16:18
"that can't really be seen as too complicated (IMHO)."
To be honest... I slightly disagree there. I think simple tasks (cut audio, i.e. get only the stream parts you are interested, of a stream) should stay simple.

By making it too long, it gets a bit too complex IMHO.

But I agree, 1 vs 3 lines is not such a big difference.

IanB
14th November 2007, 00:30
Function ATrim(Clip A, Float T1, Float T2) {
# Function to trim based on Audio times
#
# A : Input clip, must have Audio, video optional
# T1 : Start time in seconds
# T2 : End time in seconds. Zero represents the end of the clip.
# Negative values represent a duration

# Examples
# Cut 1.2 seconds starting at 1.4 seconds
# ATrim(1.4, 2.6)
# or ATrim(1.4, -1.2)
#
# Cut from 10.5 seconds to the end
# ATrim(10.5, 0)

Assert(HasAudio(A), "ATrim: clip must have audio")
Assert(T1 >= 0.0, "ATrim: starting time must be >= 0")

# Interpret T2!
T2 = (T2 == 0.0) ? AudioLengthF(A)/AudioRate(A) : T2 # 0 -> End
T2 = (T2 < 0.0) ? T1-T2 : T2 # -ve -> delta

Assert(T2 >= T1, "ATrim: ending time must be >= starting time")

# Get a framerate
Fr=HasVideo(A) ? FrameRate(A) : 100.0
N=Ceil(Fr*T2)

# Make sure clip has video to Trim
HasVideo(A) ? A : AudioDub(BlankCLip(N, 16, 16, FPS=100.0), A)

Assert(N <= FrameCount(), "ATrim: ending time must be <= clip length")

# Chop off end exactly
F2 = Ceil(T2 * Fr)
DelayAudio(F2/Fr - T2) # align audio end with frames
Trim(0, F2, False) # Do not pad audio

# Chop off start exactly
F1 = Floor(T1 * Fr)
DelayAudio(F1/Fr - T1 + T2 - F2/Fr) # alight audio start with frames
Trim(F1, 0, False) # Do not pad audio

Return HasVideo(A) ? Last : KillVideo(Last)
}

MrC
27th October 2008, 13:50
Function ATrim(Clip A, Float T1, Float T2) {
# Function to trim based on Audio times
#
# A : Input clip, must have Audio, video optional
# T1 : Start time in seconds
# T2 : End time in seconds. Zero represents the end of the clip.
# Negative values represent a duration

# Examples
# Cut 1.2 seconds starting at 1.4 seconds
# ATrim(1.4, 2.6)
# or ATrim(1.4, -1.2)
#
# Cut from 10.5 seconds to the end
# ATrim(10.5, 0)

Assert(HasAudio(A), "ATrim: clip must have audio")
Assert(T1 >= 0.0, "ATrim: starting time must be >= 0")

# Interpret T2!
T2 = (T2 == 0.0) ? AudioLengthF(A)/AudioRate(A) : T2 # 0 -> End
T2 = (T2 < 0.0) ? T1-T2 : T2 # -ve -> delta

Assert(T2 >= T1, "ATrim: ending time must be >= starting time")

# Get a framerate
Fr=HasVideo(A) ? FrameRate(A) : 100.0
N=Ceil(Fr*T2)

# Make sure clip has video to Trim
HasVideo(A) ? A : AudioDub(BlankCLip(N, 16, 16, FPS=100.0), A)

Assert(N >= FrameCount(), "ATrim: ending time must be <= clip length")

# Chop off end exactly
F2 = Ceil(T2 * Fr)
DelayAudio(F2/Fr - T2) # align audio end with frames
Trim(0, F2, False) # Do not pad audio

# Chop off start exactly
F1 = Floor(T1 * Fr)
DelayAudio(F1/Fr - T1 + T2 - F2/Fr) # alight audio start with frames
Trim(F1, 0, False) # Do not pad audio

Return HasVideo(A) ? Last : KillVideo(Last)
}

Hi IanB,

I would like to use and distribute your useful ATrim function (as ATrim.avsi file) with next AVStoDVD release. May I have your permission?

Thanks in advance

;)

MrC

Gavino
27th October 2008, 21:30
Assert(N >= FrameCount(), "ATrim: ending time must be <= clip length")
Shouldn't that be the other way round?
Assert(N <= FrameCount(), "ATrim: ending time must be <= clip length")

IanB
28th October 2008, 23:43
@MrC,

Sure, just reference the URL of the post where you got it from.

@Gavino,

Yeah, probably. Thanks.