FFMPEG: Properly sidechain_compress stereo background with stereo sidechain into stereo output - audio

I'm doing voiceover and since Sony Vegas does not support sidechaining, I render voiceover into voices.wav and then use sidechain_compress filter, as per ffmpeg documentation:
ffmpeg -y -i background.m4a -i voices.wav -filter_complex \
"[1:a]asplit=2[sc][mix];\
[0:a][sc]sidechaincompress=threshold=0.015:ratio=2:level_sc=0.8:release=500:attack=1[compr];\
[compr][mix]amerge" sidechain_1.wav
voices.wav is a stereo audio file, as well as background.m4a. But here's how the result file looks like when loaded into Sony Vegas:
This shows that in channels 1/2 I get the compressed background, while in channel 3 and 4 I get two mono tracks that somehow differ (probably, that's the original voices input and somewhat altered voices input, both in mono). UPD: I don't want to further process resulting tracks in Sony Vegas, I'd prefer ffmpeg to be the last step in my production process. The screenshot above is for illustration purposes only.
Is the background gets sidechain compressed with only left or right channel of voices? If so, how to change that to make it compressed by both channels (some voices are panned into left or right, so there might be actual difference in compressed result)
What are those channels 3 and 4? Why are they mono?
How do I get single 1/2 stereo track in the output wav file instead of this weird 4 channels in 3 tracks? (I've looked at pan complex filter, but didn't figure out how to set it up in my case).

amerge adds the channels of the inputs. amix uses the channel count of the input with the most channels. So, switch to amix.
ffmpeg -y -i background.m4a -i voices.wav -filter_complex \
"[1:a]asplit=2[sc][mix];\
[0:a][sc]sidechaincompress=threshold=0.015:ratio=2:level_sc=0.8:release=500:attack=1[compr];\
[compr][mix]amix" sidechain_1.wav

Related

How do I mix multiple audio tracks mit FFMPEG and adjust each volume?

Let's say I have an input .mp4 file that contains 4 audio tracks.
How can I change their volumes independently and convert it to a new file that just contains all the 4 audio tracks mixed together and stored in the first audio track? For example I want the first, second and third audio tracks from the input file to be double their original volume and the fourth to be half its original volume, all saved in the output files first audio track. How would that command look like?
Here you can find many good answers: How to overlay/downmix two audio files using ffmpeg
where the most comprehensive one links to https://trac.ffmpeg.org/wiki/AudioChannelManipulation
I recently had a similar use case: freely mixing 6 mono tracks of a multi-track recording to stereo output with different volumes on either or both output channels, which can be achieved like this:
ffmpeg -i 0.flac -i 1.flac -i 2.flac -i 3.flac -i 4.flac -i 5.flac \
-filter_complex [0:a][1:a][2:a][3:a][4:a][5:a]amerge=inputs=6,pan=stereo|c0=c0+1.2*c1+1.2*c2+1.3*c3+c4|c1=c0+1.3*c3+c4+0.8*c5[a] \
-map [a] output.flac

Using FFmpeg or Similar to Normalize audio in a video to EBU R128 standard

This is my first time here on stack overflow asking question.
I am stuck and really struggling with this. I am trying to make some of my MXF video files to be EBU r128 standard for its audio.
This means that it has to be -23 and not higher than 0.5.
My current process
Watch_folder > Encoding to MXF > Output_folder
I need to makesure when its comes to output folder, those MXF files are EBU R128 Loudness compliant.
What I have done so Far:
FFMPEG:
ffmpeg -i input.mxf -af loudnorm=I=-23:LRA=7:tp=-2:print_format=json -f null -
got the result:
Input Integrated: -15.1 LUFS
Input True Peak: +0.0 dBTP
Input LRA: 17.1 LU
Input Threshold: -26.2 LUFS
Output Integrated: -17.1 LUFS
Output True Peak: -1.5 dBTP
Output LRA: 5.3 LU
Output Threshold: -27.6 LUFS
Normalization Type: Dynamic
Target Offset: +1.1 LU
then i did
ffmpeg -i input.mxf -af loudnorm=I=-23:LRA=7:tp=-2:measured_I=-15.1:measured_LRA=17.1:measured_tp=0:measured_thresh=-27.6:offset=1.1 -ar 48k -y output.mxf
However, when i put it through the software Eff, it says that its not EBU compliant.
*EDIT:
This also reduces the quality. for example; my 6 Gb becomes 250 MB and you can tell the quality downgraded
ffmpeg-normalize
I did the following
ffmpeg-normalize input.mxf -c:a pcm_s32le -ar 48000 -o output.mxf
but this gives me errors.
if i do it without the output file type, i get a mkv which will not work for me. i need it to be mxf.
OK, a few issues here.
Firstly, if your file is measured at -26.2 LUFS, you'd need to add 3.2 dB to get it to -23. But you can't do that, because your true peak is too high (you'd be over full scale). You'll need to compress (dynamic audio compression, not file/rate compression) the audio or use at least a limiter to achieve this.
A good R128 audio track should be mixed properly rather than just run through a normaliser, otherwise you risk it either failing the standard or unwanted audio effects.
If you don't have access to audio editing software or someone who can do this for you, then FFMPEG does include an audio limiter, which will give you enough headroom to raise the level to -23 LUFS.
You can do that with something like this:
-filter_complex alimiter=level_in=1:level_out=1:limit=1.5:attack=7:release=100:level=disabled
However, tuning a limiter well depends on what the video file is of (music, speech, etc) and it is something that's worth taking some time over. Alter the attack and release values until you get the result you want.
Secondly, the reason that FFMPEG has produced a smaller file of lower quality is because you didn't specify anything in the video section. FFMPEG's default action with video is (usually) to encode to h264, so whatever your codec here is (I am assuming DNxHD from the fact that you're using an MXF wrapper) needs to be specified. FFMPEG will copy the video stream though and leave it alone if you include the option -c:v copy (which means copy video codec, basically).
Post your results once you have tried these...!

mkv file out of sync with linear drift

I have a bunch of mkv files, with FLAC as the audio codec and FFV1 as the video one.
The files were created using an EasyCap aquisition dongle from a VCR analog source. Specifically, I used VLC's "open acquisition device" prompt and selected PAL. Then, I converted the files (audio PCM, video raw YUV) to (FLAC, FFV1) using
ffmpeg.exe -i input.avi -acodec flac -vcodec ffv1 -level 3 -threads 4 -coder 1 -context 1 -g 1 -slices 24 -slicecrc 1 output.mkv
Now, the files are progressively out of sync. It may be due to the fact that while (maybe) the video has a constant framerate, the FLAC track has variable framerate. So, is there a way to sync the track to audio, or something alike? Can FFmpeg do this? Thanks
EDIT
On Mulvya hint, I plotted the difference in sync at various times; the first column shows the seconds elapsed, the second shows the difference - in secs. The plot seems to behave linearly, with 0.0078 as a constant slope. NOTE: measurements taken by hands, by means of a chronometer
EDIT 2
Playing around with VirtualDub, I found that changing the framerate to 25 fps from the original 24.889 (Video->Frame rate...->Change frame rate to) and using the track converted to wav definitely does work. Two problems, though: VirtualDub crashes when importing the original FFV1-FLAC mkv file, so I had to convert the video to H264 to try it out; more, I find it difficult to use an external encoder to save VirtualDub output.
So, could I avoid using VirtualDub, and simply use ffmpeg for it? Here's the exported vdscript:
VirtualDub.audio.SetSource("E:\\4_track2.wav", "");
VirtualDub.audio.SetMode(0);
VirtualDub.audio.SetInterleave(1,500,1,0,0);
VirtualDub.audio.SetClipMode(1,1);
VirtualDub.audio.SetEditMode(1);
VirtualDub.audio.SetConversion(0,0,0,0,0);
VirtualDub.audio.SetVolume();
VirtualDub.audio.SetCompression();
VirtualDub.audio.EnableFilterGraph(0);
VirtualDub.video.SetInputFormat(0);
VirtualDub.video.SetOutputFormat(7);
VirtualDub.video.SetMode(3);
VirtualDub.video.SetSmartRendering(0);
VirtualDub.video.SetPreserveEmptyFrames(0);
VirtualDub.video.SetFrameRate2(25,1,1);
VirtualDub.video.SetIVTC(0, 0, 0, 0);
VirtualDub.video.SetCompression();
VirtualDub.video.filters.Clear();
VirtualDub.audio.filters.Clear();
The first line imports the wav-converted audio track.
Can I set an equivalent pipe in ffmpeg (possibly, using FLAC - not wav)? SetFrameRate2 is maybe the key, here.

Converting a stereo channel audio file to left channel only, through command line

Say I have a bunch of mp3 files. How would I go about using an audio software command-line tool to decrease the volume completely on one side of the audio file (right), leaving on the left side of the audio file complete? I would then like to save this file to a new mp3 file. This needs to be done entirely over the command line.
As an another approach. Is it possible to use a command line audio file tool to convert a stereo mp3 file to mono, then to merge this mono file with a "silent" track of the same length, creating a left-headphone track with sound and a right-headphone track with silence?
In this SO question, there seems to be a number of approaches to a rather eccentric end goal. In the first possible solution, I just want to decrease the volume of the right side. In the second possible solution, I want to combine a few more common steps to achieve the same end result.
The problems here are that:
I can't find a good command-line tool for modifying audio files, even to do the second approach which should be a more common request.
I'm expecting that I'll first need to convert the mp3 file to wav, using a similar or second tool
This query is eccentric so there aren't many links about it on the web.
Thanks for any help. Audacity would be my go-to normally, but it appears to be GUI only.
SoX lets you do this very easily.
The first case, muted right channel:
sox test.mp3 test-rmuted.mp3 remix 1 0
The second case, summed mono on left channel:
sox test.mp3 test-lmono.mp3 remix 1,2 0
To batch process you could just do a simple for loop.
Muted right channel:
for f in *.mp3
do
basename="${f%.*}"
echo "$basename"
sox "$f" -t wav - remix 1 0 | \
lame --preset standard - "00-${basename}-rmute".mp3
done
Summed mono on left channel only:
for f in *.mp3
do
basename="${f%.*}"
echo "$basename"
sox "$f" -t wav - remix 1,2 0 | \
lame --preset standard - "00-${basename}-lmono".mp3
done
You can forgo LAME and do the encoding with SoX as in the first two examples, but I find this method simpler and more flexible.
As suggested in a comment you should be able to use FFmpeg to process your audio files. Dropping one channel completely would produce a different result than doing conversion to mono first. However, I think either could be achieved with the pan filter in FFMpeg.
https://trac.ffmpeg.org/wiki/AudioChannelManipulation
https://ffmpeg.org/ffmpeg-filters.html#pan
Attenuation of one channel
Decode mp3 file to wav
Create a new stereo wav file using the pan filter 100% to one channel
Encode the resulting wav file to mp3
Mixing both channels evenly in one channel, then attenuating the other channel
Decode mp3 file to wav
Create a new wav file using the pan filter with one channel 50% from left and 50% right, and the other channel with 0 gain
Encode the resulting wav file to mp3

FFMPEG: 4-channel audio workflow suggestions?

I’ve got a bunch of stereo files recorded for a documentary with a Zoom in 4 channel mode. Basically it’s sets of pairs of stereo file s— file A would be a stereo file with a lav or boom mike recording, file B of identical length would be a proper stereo recorded by Zoom itself.
Now I’m trying to convert all this into something I can correctly ingest into editing suite. Files A are a mess but I came up with a ffmpeg script which downconvert them to mono then reconvert them back to stereo (to get rid of inconsistensies). Now how do I merge two stereo files into a single WAV or AIFF file containing two separate stereo channels? I browsed around for any workflows and/or standards on that but can’t really find anything useful.
Any ideas on how to do that with ffmpeg (or anything else, really) would be appreciated!
Don't know if FCP-X reads multi track WAVs but you can output to a multi-track MOV.
ffmpeg -i file1.wav -i file2.wav -c copy -map 0 -map 1 file.mov

Resources