View Full Version : Avisynth Sound -> Opus Encoder
zerowalker
27th June 2014, 22:57
Is it possible to pipeline the Output Avisynth has to Opus?
Why i want this is because i do some syncing, and the output will be 32bit float, but if i save it to Wave with Foobar for example, it will become 24bit.
So i would like to input the Float directly to Opus to get the best out of it.
(Yes i know it's nothing to really be bothered with in terms of quality, but if it can be done, why not. Saves the extra step as well)
Thanks!
raffriff42
28th June 2014, 04:11
Easy with FFmpeg:ffmpeg.exe -i "test.avs" -vn -c:a opus "test-ogg.ogg"
But Opus is not needed:ffmpeg.exe -i "test.avs" -vn -c:a pcm_f32le "test-pcm_f32le.wav"
zerowalker
28th June 2014, 07:08
Won't telling ffmpeg to use float 32bit just force that?
Can't i just tell it to save in whatever format it is rather then stating it? (For PCM)
raffriff42
28th June 2014, 07:46
Nope (EDIT but a good question, and I thought you would be correct, but no)ffmpeg.exe -i "test.avs" -vn "test.wav"
...
Input #0, avisynth, from 'D:\VideoProjects\raw\test.avs':
Duration: 00:00:01.00, start: 0.000000, bitrate: 162 kb/s
Stream #0:0: Video: rawvideo (BGRA / 0x41524742), bgra, 640x480, 29.97 fps,
29.97 tbr, 29.97 tbn, 29.97 tbc
Stream #0:1: Audio: pcm_f32le, 48000 Hz, 2 channels, flt, 3072 kb/s
Output #0, wav, to 'D:\VideoProjects\work\test.wav':
Metadata:
ISFT : Lavf55.44.100
Stream #0:0: Audio: pcm_s16le ([1][0][0][0] / 0x0001), 48000 Hz, stereo, s16
, 1536 kb/s
Metadata:
encoder : Lavc55.68.100 pcm_s16le
Stream mapping:
Stream #0:1 -> #0:0 (pcm_f32le (native) -> pcm_s16le (native))
foxyshadis
28th June 2014, 09:20
Nope (EDIT but a good question, and I thought you would be correct, but no)[code]ffmpeg.exe -i "test.avs" -vn "test.wav"
Yup, ffmpeg considers all wav files to be standard 16-bit LE unless forced otherwise, because of compatibility. Once you specify -c:a pcm_f32le you can just output to stdout via "-" though, and use any encoder you want.
Unless you want ffmpeg specifically, avs2pipe (https://forum.doom9.org/showthread.php?t=160383) is quicker and simpler, though. It simply outputs exactly whatever format avisynth is using internally.
qyot27
28th June 2014, 11:18
ffmpeg will output whatever AviSynth's output format is if you use copy. AviSynth support is as a demuxer rather than a decoder, so like any other demuxer, copy preserves whatever the input to ffmpeg/output from AviSynth is, just like it would for demuxing any other compression format from its container. It's simply that AviSynth always outputs into the corresponding pcm_***le and rawvideo (as needed pixel format) sinks.
I actually deal with this fairly often because of the bounds issue when resampling with FFMS2 as source filter under AviSynth+'s MT branch. To illustrate:
>ffmsindex -t -1 "draculauntold-tlr1zepk_h1080p.mp4"
Writing index... done... 100%
>echo FFmpegSource2("draculauntold-tlr1zepk_h1080p.mp4",atrack=-1,fpsnum=24000,fpsden=1001).Lanczos4Resize(720,352).AddBorders(0,64,0,64) 1>"16.9 23.976 draculauntold-tlr1zepk_h1080p.avs"
>ffmpeg -i "16.9 23.976 draculauntold-tlr1zepk_h1080p.avs" -vn -acodec copy "16.9 23.976 draculauntold-tlr1zepk_h1080p.wav"
ffmpeg version r64294 git-25f8fda Copyright (c) 2000-2014 the FFmpeg developers
built on Jun 28 2014 01:34:08 with gcc 4.9.0 (GCC)
libavutil 52. 90.101 / 52. 90.101
libavcodec 55. 68.100 / 55. 68.100
libavformat 55. 44.100 / 55. 44.100
libavdevice 55. 13.101 / 55. 13.101
libavfilter 4. 9.100 / 4. 9.100
libavresample 1. 3. 0 / 1. 3. 0
libswscale 2. 6.100 / 2. 6.100
libswresample 0. 19.100 / 0. 19.100
libpostproc 52. 3.100 / 52. 3.100
Guessed Channel Layout for Input Stream #0.1 : stereo
Input #0, avisynth, from '16.9 23.976 draculauntold-tlr1zepk_h1080p.avs':
Duration: 00:02:35.45, start: 0.000000, bitrate: 0 kb/s
Stream #0:0: Video: rawvideo (I420 / 0x30323449), yuv420p, 720x480, 23.98 fps, 23.98 tbr, 23.98 tbn, 23.98 tbc
Stream #0:1: Audio: pcm_f32le, 44100 Hz, 2 channels, flt, 2822 kb/s
[wav @ 093c0360] Using AVStream.codec.time_base as a timebase hint to the muxer is deprecated. Set AVStream.time_base instead.
Output #0, wav, to '16.9 23.976 draculauntold-tlr1zepk_h1080p.wav':
Metadata:
ISFT : Lavf55.44.100
Stream #0:0: Audio: pcm_f32le ([3][0][0][0] / 0x0003), 44100 Hz, stereo, 2822 kb/s
Stream mapping:
Stream #0:1 -> #0:0 (copy)
Press [q] to stop, [?] for help
size= 53552kB time=00:02:35.43 bitrate=2822.4kbits/s
video:0kB audio:53552kB subtitle:0kB other streams:0kB global headers:0kB muxing overhead: 0.000208%
And to show that it does preserve the format:
>mediainfo "16.9 23.976 draculauntold-tlr1zepk_h1080p.wav"
General
Complete name : 16.9 23.976 draculauntold-tlr1zepk_h1080p.wav
Format : Wave
File size : 52.3 MiB
Duration : 2mn 35s
Overall bit rate mode : Constant
Overall bit rate : 2 822 Kbps
Writing application : Lavf55.44.100
Audio
Format : PCM
Format profile : Float
Format settings, Endianness : Little
Format settings, Sign : Signed
Codec ID : 00001000-0000-0300-8000-00AA00389B71
Codec ID/Hint : IEEE
Duration : 2mn 35s
Bit rate mode : Constant
Bit rate : 2 822 Kbps
Channel(s) : 2 channels
Channel positions : Front: L R
Sampling rate : 44.1 KHz
Bit depth : 32 bits
Stream size : 52.3 MiB (100%)
zerowalker
29th June 2014, 03:26
Confused, one say you have to force else it thinks it's 16bit, other says it keeps the original state as Avisynth as a demuxer?
EDIT: Tried avs2pipe, but doesn't seem to work?
avs2pipe --audio "test.avs" | opus "-" "out.opus"
qyot27
29th June 2014, 05:07
Confused, one say you have to force else it thinks it's 16bit, other says it keeps the original state as Avisynth as a demuxer?
And neither statement is wrong, but there are certain assumptions being made.
If you don't tell ffmpeg what to do via -acodec/-c:a, it defaults to acting as a converter based on the output file's extension. So if you output to .wav but don't use -acodec/-c:a, ffmpeg will convert the output to pcm_s16le.
If you tell ffmpeg to use a specific -acodec/-c:a, then it will convert to that format, so long as the output container supports it (it'll complain if it doesn't).
And if the particular -acodec/-c:a you tell ffmpeg to use is copy, then it will copy the samples given to it by AviSynth directly to the output, without converting it.
Part of the assumption here, at least on my part, is that you should be using the codec specifiers any time you process something through ffmpeg. IMO, there's too much that can go awry if you just leave it up to ffmpeg to auto-select a codec to use, so always tell it which one you want. And in normal cases when you don't want ffmpeg to do anything to the audio and just pass it through, you use copy. This is true regardless of whether it's an MKV file or an MP4 file (with any number of lossless or lossy audio streams to select from) or an AviSynth script (that only outputs uncompressed video and audio).
zerowalker
29th June 2014, 05:37
Ah okay, well i tried using ffmpeg copy thing but i am not possible to output to a pipeline no matter how i do it.
ffmpeg -i "test.avs" -vn -acodec copy -f wav - |
For example didn't work. Also no -f wav doesn't work either.
Even specifying 32bit, 16bit or whatever doesn't work:(
qyot27
29th June 2014, 06:46
opusenc can't accept wav headers through a pipe, then. Or at least not the ones ffmpeg writes. Although it's fine with them if you write the .wav file to disk first. If ffmpeg pipes out as wav, opusenc still requires --raw to handle the input from it. Which opens up more cans of worms because the --raw defaults are not what you want and you'd have to still specify them manually to get around that (and --raw-bits doesn't allow 32, only 24).
Again, as raffriff42 pointed out right at the beginning, there's no reason to pipe here. Just encode as opus from ffmpeg itself.
zerowalker
29th June 2014, 06:59
I prefer using the original encoder, can't it ignore the wav header with --ignorelength?
And it's ffmpeg that fails the pipe, it doesn't even reach opus.
Also if i encode with ffmpeg, it doesn't show the settings, i want the settings to be written to the header, it's quite useful to have that information.
sneaker_ger
29th June 2014, 11:19
I had trouble piping wav to opusenc in the past as well but with the current tools this seems to be working (with links to the versions I use):
avs2pipemod (http://www.mediafire.com/download/33fpx9bibdk8y4j/avs2pipemod-0.4.1.7z) -wav "input.avs" | opusenc (https://ftp.mozilla.org/pub/mozilla.org/opus/win32/opus-tools-0.1.9-win32.zip) - "output.opus"
(Not sure if --ignorelength is needed. Check that.)
foxyshadis
29th June 2014, 11:26
Ah okay, well i tried using ffmpeg copy thing but i am not possible to output to a pipeline no matter how i do it.
For example didn't work. Also no -f wav doesn't work either.
Even specifying 32bit, 16bit or whatever doesn't work:(
Huh, that exact commandline works for me, on both Windows and Linux. It spams my terminal window with wav junk or can be redirected to a proper test.wav or piped to opusenc, and Info() says Float 32 bit. My ffmpeg is from zeranoe (http://ffmpeg.zeranoe.com/builds/).
qyot27
29th June 2014, 13:05
(Not sure if --ignorelength is needed. Check that.)
Only if the piped output from the source application would exceed 2GB (or was it 4GB)? As far as I know, that's the only reason an --ignorelength option exists in the audio encoders that have one.
So, it'd be a 'maybe', although it'd probably be a good idea to use just in case.
Reino
29th June 2014, 15:48
If you really want to use opusenc.exe, you shouldn't use -c:a copy at all, as opusenc.exe doesn't accept f32le (or you'll get distorted sound). Instead you should specify/force the format you want to send over the pipe.
Btw, --ignorelength isn't needed either in this case:
Opusenc automatically ignores the length when its implausible (very small or very large) but some STDIN usage may still need this option to avoid truncation.
From my own experience:
avs2pipemod.exe -wav input.avs | opusenc.exe (--bitrate 64) - output.opus
ffmpeg.exe -i input.avs -c:a libopus (-ab 64k) output.opus
ffmpeg.exe -i input.avs -f s24le - | opusenc.exe (--bitrate 64) --raw --raw-bits 24 --raw-rate 44100 - output.opus
//and as a bonus...
ffmpeg.exe -i input.avs -f f32le - | sox.exe -t f4 -r 44100 -c 2 - -t s3 - rate -v 48k | opusenc.exe (--bitrate 64) --raw --raw-bits 24 - output.opus
//...if you want SoX to do the samplerate-conversion. (-f f32le and -t f4 = 32-bit float. -t s3 = 24bit int)
As -f wav changes the volume somehow (and who knows what else), you should use -f s24le instead (or -f s16le of course)
zerowalker
29th June 2014, 21:09
it works with the avspipemod:)
Guess i should use "ignorelength" as i use STDIN?
Is there any drawback using this?
EDIT:
Tried using both on and off, seems same length and same size.
Guess i should just take the one without it?
raffriff42
30th June 2014, 03:32
the output will be 32bit float, but if i save it to Wave with Foobar for example, it will become 24bit.
So i would like to input the Float directly to Opus to get the best out of it. opusenc.exe doesn't accept f32leHuh, you're right, Opus is fixed point only. So why are we even considering Opus here? OP should use PCM or WavPack.
EDIT
Before someone says, "32 bits (fixed point) should be enough for anybody," let me quote Wikipedia (https://en.wikipedia.org/wiki/Audio_bit_depth#Quantization): The resolution of floating point samples is less straightforward than integer samples, but the benefit comes in the increased accuracy of low values. In floating point representation, the space between any two adjacent values is of the same proportion as the space between any other two adjacent values, whereas in an integer representation, the space between adjacent values gets larger in proportion to low-level signals. This greatly increases the SNR because the accuracy of a high-level signal will be the same as the accuracy of an identical signal at a lower level.
And Audacity (http://wiki.audacityteam.org/wiki/Bit_Depth#32_Bit):Audacity uses "float" format for 32 bit recording instead of fixed integer format. Normalised floating point values are quicker and easier to process on computers than fixed integer values and allow greater dynamic range to be retained even after editing.
zerowalker
30th June 2014, 04:21
Wait, what does opus do with it then?
I thought it would take 32 bit float, do it's thing with it.
It seems to accept f32le though, it worked for me.
I am only using 32float as that's the source (after doing some sync stuff with it).
I don't care if it's 16 bit when opus is done with it, i just want to give it the "untouched source".
raffriff42
30th June 2014, 04:44
Sorry, I somehow assumed this was for intermediate storage, and you wanted losslessness above all.
If you need Opus for some reason, fine; but convert to 32 bit fixed first as per CoRoNe (unless using ffmpeg, which converts automatically)ffmpeg.exe -i "test.avs" -vn -c:a opus "test-opus.mka"
...
Input #0, avisynth, from 'D:\VideoProjects\test.avs':
Duration: 00:00:01.00, start: 0.000000, bitrate: 162 kb/s
Stream #0:0: Video: rawvideo (BGRA / 0x41524742), bgra, 640x480, 29.97 fps,
29.97 tbr, 29.97 tbn, 29.97 tbc
Stream #0:1: Audio: pcm_f32le, 48000 Hz, 2 channels, flt, 3072 kb/s
...
Output #0, matroska, to 'D:\VideoProjects\test-opus.mka':
Metadata:
encoder : Lavf55.44.100
Stream #0:0: Audio: opus (libopus) ([255][255][255][255] / 0xFFFFFFFF), 4800
0 Hz, stereo, flt, 96 kb/s
Metadata:
encoder : Lavc55.68.100 libopus
Stream mapping:
Stream #0:1 -> #0:0 (pcm_f32le (native) -> opus (libopus)) The result per ffprobe:
ffprobe version N-64226-g7e8fdf0 Copyright (c) 2007-2014 the FFmpeg developers
...
Input #0, matroska,webm, from 'D:\VideoProjects\test-opus.mka':
Metadata:
ENCODER : Lavf55.44.100
Duration: 00:00:01.01, start: 0.007000, bitrate: 110 kb/s
Stream #0:0: Audio: opus, 48000 Hz, stereo, fltp(default)
Metadata:
ENCODER : Lavc55.68.100 libopus
The result per MediaInfo only says "bit depth - 32 bits".
zerowalker
30th June 2014, 04:48
I simply used the avspipemod -> opus. So i am guessing the results should be the same. Opus get's the entire floating point data, and does it's work on it.
I was only interested in the floating point as that was it's output.
For example, in video, i rather give x264 the 16bit output rather than dithering to 8 bit first. (This is when i use 10bit, so i don't waste 2 bit of information).
Reino
30th June 2014, 11:55
...as opusenc.exe doesn't accept f32le...This is wrong. It only seems to be a problem with ffmpeg. See here (http://www.hydrogenaud.io/forums/index.php?showtopic=103713&view=findpost&p=868589).
I don't care if it's 16 bit when opus is done with it...Bitdepth doesn't exist for lossy audioformats.
qyot27
30th June 2014, 13:38
What FFmpeg actually does when piping wav (it's a posting from 2010, but I doubt the situation has really changed):
http://ffmpeg-users.933282.n4.nabble.com/When-using-pipe-output-wav-files-are-corrupt-only-usable-by-libffmpeg-based-software-td2304011.html
Basically, it would seem to write a placeholder at the beginning of the file in order to populate the length value, so that when encoding finishes, it tracks back to the beginning and writes the proper length there. But tracking back to the beginning is impossible when piping, and opusenc chokes on the placeholder.
And the missing piece provided by a search result on HA:
http://www.hydrogenaud.io/forums/index.php?showtopic=103191&view=findpost&p=848396
ffmpeg -i test.avs -vn -acodec copy -f wav - | qaac --silent -D - -o - | opusenc --ignorelength - output.opus
qaac normalizes the headers (and maybe some other stuff). Testing only with ffmpeg and qaac, the wav qaac writes to the pipe is the same format that was piped out of ffmpeg - in this case, pcm_f32le. So I'd assume that qaac isn't doing any implicit format conversions in there.
foxyshadis
30th June 2014, 23:15
No conversions, except to convert unsigned 8-bit to signed, which is unimportant. Using qaac that way is very clever!
zerowalker
1st July 2014, 00:36
Bitdepth doesn't exist for lossy audioformats.
Knew that it didn't have above 16, so thought it was always at it.
But i guess it does totally transform it (The same way you can't have a lossy format go lossless no matter how much bitrate).
No conversions, except to convert unsigned 8-bit to signed, which is unimportant. Using qaac that way is very clever!
Does QAAC interact with this diffrently than Opus?
Reino
2nd July 2014, 20:12
Is it possible to pipeline the Output Avisynth has to Opus?lvqcl and john33 on the Hydrogenaudio Forums (http://www.hydrogenaud.io/forums/index.php?showtopic=103713&view=findpost&p=868652) fixed the piping bug when piping from ffmpeg.exe to opusenc.exe.
Reino
19th July 2014, 13:52
avs2pipemod.exe -wav input.avs | opusenc.exe (--bitrate 64) - output.opus
ffmpeg.exe -i input.avs -c:a libopus (-ab 64k) output.opus
ffmpeg.exe -i input.avs -f s24le - | opusenc.exe (--bitrate 64) --raw --raw-bits 24 --raw-rate 44100 - output.opus
//and as a bonus...
ffmpeg.exe -i input.avs -f f32le - | sox.exe -t f4 -r 44100 -c 2 - -t s3 - rate -v 48k | ^
opusenc.exe (--bitrate 64) --raw --raw-bits 24 - output.opus
//...if you want SoX to do the samplerate-conversion. (-f f32le and -t f4 = 32-bit float. -t s3 = 24bit int)
Today I realized ffmpeg also includes a sox resampler and because I hadn't updated my previous post yet, with the newly patched opusenc.exe this becomes:
avs2pipemod.exe -wav input.avs | opusenc.exe (--bitrate 64) - output.opus
ffmpeg.exe -i input.avs -c:a libopus (-ab 64k) output.opus
ffmpeg.exe -i input.avs -c:a copy -f wav - | opusenc.exe (--bitrate 64) - output.opus
ffmpeg.exe -i input.avs -af "aresample=resampler=soxr:osr=48000:precision=28" -c:a libopus (-ab 64k) output.opus
// use sox-resampler, output samplerate=48k, 28 equals sox 'very high quality'.
ffmpeg.exe -i input.avs -c:a copy -f wav - | sox.exe -t wav - -t wav - rate -v 48k | opusenc.exe (--bitrate 64) - output.opus
// 'sox.exe WARN wav: wave header missing extended part of fmt chunk'
// 'sox.exe WARN wav: Premature EOF on .wav input file'
// despite these sox warnings, an opus will be created.
vBulletin® v3.8.11, Copyright ©2000-2026, vBulletin Solutions Inc.