Log in

View Full Version : Lame MP3 ABR wrong bitrate


vanger
9th January 2009, 18:50
I tried to compress mp2 (mpa) audio to mp3 ABR 128Kbit/s but the result bitrate is about 104kbit/s and file (5354sec) is 68*604*000 bytes.
For 112ABR the result is 84kbit/s and so on.
The MeGUI 0.3.1.1009, lame version 3.98.2.
Here is the log:
[Information] Log
-[Information] Versions
--[NoImage] MeGUI Version : 0.3.1.1009
--[NoImage] OS : Microsoft Windows XP Professional SP3 (5.1.196608.2600)
--[NoImage] Framework used : 2.0 SP1 (2.0.50727.1433)
-[Information] Hardware
--[NoImage] CPU : AMD Phenom(tm) 9550 Quad-Core Processor
-[Information] Log for job2 (audio, ub4 PID 044 L2 2ch 48 224 DELAY 88ms.mp2 -> ub4 PID 044 L2 2ch 48 224 DELAY 0ms.mp3)
--[Information] [09.01.2009 23:07:48] Started handling job
--[Information] [09.01.2009 23:07:48] Preprocessing
--[NoImage] Avisynth script
---[NoImage] NicMPG123Source("D:\addons\video\avs2qxvid\ub4 PID 044 L2 2ch 48 224 DELAY 88ms.mp2")
---[NoImage] DelayAudio(88.0/1000.0)
---[NoImage] 6<=Audiochannels(last)?x_stereo04a014548db6470e90388ee0d552e831(ConvertAudioToFloat(last)):last
---[NoImage] 32==Audiobits(last)?ConvertAudioTo32bit(last):last
---[NoImage] Normalize()
---[NoImage] 32==Audiobits(last)?ConvertAudioTo16bit(last):last
---[NoImage] return last
---[NoImage] function x_stereo04a014548db6470e90388ee0d552e831(clip a)
---[NoImage] {
---[NoImage] fl = GetChannel(a, 1)
---[NoImage] fr = GetChannel(a, 2)
---[NoImage] c = GetChannel(a, 3)
---[NoImage] lfe = GetChannel(a, 4)
---[NoImage] sl = GetChannel(a, 5)
---[NoImage] sr = GetChannel(a, 6)
---[NoImage] l_sl = MixAudio(fl, sl, 0.2929, 0.2929)
---[NoImage] c_lfe = MixAudio(lfe, c, 0.2071, 0.2071)
---[NoImage] r_sr = MixAudio(fr, sr, 0.2929, 0.2929)
---[NoImage] l = MixAudio(l_sl, c_lfe, 1.0, 1.0)
---[NoImage] r = MixAudio(r_sr, c_lfe, 1.0, 1.0)
---[NoImage] return MergeChannels(l, r)
---[NoImage] }
--[NoImage] Commandline used: --abr 128 -h --silent - "{0}"
--[Information] [09.01.2009 23:07:48] Encoding started
--[Information] [09.01.2009 23:07:48] Encode thread started
--[Information] [09.01.2009 23:07:48] Avisynth script environment opened
--[Information] [09.01.2009 23:08:11] Script loaded
--[Information] Output Decoder
---[NoImage] Channels: 2
---[NoImage] Bits per sample: 16
---[NoImage] Sample rate: 48000
--[NoImage] Commandline: D:\addons\video\megui\tools\lame\lame.exe --abr 128 -h --silent - "D:\addons\video\avs2qxvid\ub4 PID 044 L2 2ch 48 224 DELAY 0ms.mp3"
--[Information] [09.01.2009 23:08:11] Encoder process started
--[Information] [09.01.2009 23:20:39] Postprocessing
---[Information] Deleting intermediate files
----[Information] [09.01.2009 23:20:39] Successfully deleted D:\addons\video\avs2qxvid\ub4 PID 044 L2 2ch 48 224 DELAY 88ms.mp2.d2a
--[Information] [09.01.2009 23:20:39] Job completed

I tried BeHappy tool with lame 3.98.beta8 but result is the same - bitrate is smaller than desired :(

Now I tried foobar with lame 3.98.2 (parameters --abr 112 -h --silent) and the result is 93kbit/s.

How to get the desired bitrate?

tebasuna51
9th January 2009, 21:11
And what is the problem?

You never can obtain a exact average bitrate without a 2 pass method.

Seems your file is easy to compress, try with 128 to obtain 112.

Only CBR can do the job. If you don't need CBR use always VBR, ABR is useless for me.

vanger
10th January 2009, 05:17
I read in different places, that ABR is using for specified filesize, but is better than CBR.
ABR: average bitrate mode. A compromise between VBR and CBR modes, ABR encoding varies bits around a specified target bitrate.

Use ABR when you need to know the final size of the file but still want to allow the encoder some flexibility to decide which passages need more bits.

tebasuna51
10th January 2009, 12:59
Like you can see is a compromise between VBR and CBR modes, but without any advantage.

bmnot
12th January 2009, 18:44
you can use -V 2.231 multi-pass encode to get vbr with targeted bitrate, but it will need some time.

tebasuna51
12th January 2009, 19:47
Please can you explain how use multi-pass with Lame encoder

bmnot
13th January 2009, 22:01
You need to run it manually with different V values:
lame -V 1.000 input.wav 1000.mp3
lame -V 3.000 input.wav 3000.mp3
lame -V 2.000 input.wav 2000.mp3
lame -V 2.500 input.wav 2500.mp3
lame -V 2.250 input.wav 2250.mp3
lame -V 2.735 input.wav 2735.mp3
...
2-3 digits after point will be enough to get bitrate with great accuracy, but it will need upto 10 runs

You can run 2 process at the same time if you have dual core processor (or more if you have more cores).

tebasuna51
14th January 2009, 02:36
Oh, yeah!

But:
lame -V 2.735 input.wav 2735.mp3 ??

maybe:
lame -V 2.375 input.wav 2375.mp3
is the next value to try

Dark Shikari
14th January 2009, 03:27
You need to run it manually with different V values:
lame -V 1.000 input.wav 1000.mp3
lame -V 3.000 input.wav 3000.mp3
lame -V 2.000 input.wav 2000.mp3
lame -V 2.500 input.wav 2500.mp3
lame -V 2.250 input.wav 2250.mp3
lame -V 2.735 input.wav 2735.mp3
...
2-3 digits after point will be enough to get bitrate with great accuracy, but it will need upto 10 runsYou can probably do it in just 2-4 runs if you use Newton's Method... ;) ;)

vanger
14th January 2009, 12:52
You can probably do it in just 2-4 runs if you use Newton's Method... ;) ;)
I've read about Newton's Method on wiki but can you explain how to apply it in this case?

Dark Shikari
14th January 2009, 15:18
I've read about Newton's Method on wiki but can you explain how to apply it in this case?The purpose of Newton's Method is to find the zero of a function. In this case, you want the zero of f(x) = Bitrate(V) - 128, that is, the point at which a given quality value V gives you a bitrate of 128.

http://upload.wikimedia.org/math/b/d/6/bd6345f0774a5b241ac0bffa05eea170.png

To find the numerical derivative, you just assume that the slope between your first two guesses is linear and take the numerical derivative and use the formula to derive your next guess. Each time you use a new guess, you use the value of your closest other guess to calculate the approximate derivative to insert into the formula.

It's actually pretty trivial to write a script to do this--this is the same way that computers calculate square roots. It saves time because it gives much better guesses to try than a binary search (which is was shown above).

vanger
14th January 2009, 17:00
The purpose of Newton's Method is to find the zero of a function. In this case, you want the zero of f(x) = Bitrate(V) - 128, that is, the point at which a given quality value V gives you a bitrate of 128.

http://upload.wikimedia.org/math/b/d/6/bd6345f0774a5b241ac0bffa05eea170.png

To find the numerical derivative, you just assume that the slope between your first two guesses is linear and take the numerical derivative and use the formula to derive your next guess. Each time you use a new guess, you use the value of your closest other guess to calculate the approximate derivative to insert into the formula.

It's actually pretty trivial to write a script to do this--this is the same way that computers calculate square roots. It saves time because it gives much better guesses to try than a binary search (which is was shown above).

And derivative of function Bitrate(V) equals V ?

Dark Shikari
14th January 2009, 17:04
And derivative of function Bitrate(V) equals V ?No, the derivative is calculated numerically.

For example:

If you measured V=3.0 as 100kbps and V=4.0 as 140kbps, the derivative would be:

(140 - 100) / (4.0 - 3.0) = 40

So, your target is 128kbps. This means your next guess should be 3.7.

Let's say now that 3.7 is 134kbps. Your new derivative is (140-134) / (4.0 - 3.7) = 20.

vanger
14th January 2009, 17:39
No, the derivative is calculated numerically.

For example:

If you measured V=3.0 as 100kbps and V=4.0 as 140kbps, the derivative would be:

(140 - 100) / (4.0 - 3.0) = 40

So, your target is 128kbps. This means your next guess should be 3.7.

Let's say now that 3.7 is 134kbps. Your new derivative is (140-134) / (4.0 - 3.7) = 20.

Yes, now it's clear :thanks:

bmnot
14th January 2009, 22:19
Wich algorythm/method can be optimized for multi-thread computing?

Fenyő
7th May 2011, 00:30
Hi!

I've made a little Console Application for this problem to solve! :)

You just pass the desired ABR to the app, and it "finds out" the correct -V parameter
with multiple passes. (multi-threaded of course!)
After that, it makes the final encode for you.

You can probably do it in just 2-4 runs if you use Newton's Method... ;) ;)
A little more than 2-4. :) (i've tried that too)
BTW Newton's method is not a quite good idea.
1) It is not guaranteed to converge.
2) It surely does not converge at all if the function has a breaking point, and the target is near to (or in) the breaking point.
And the function LameEnc's -V parameter gives us usually HAS breaking points!
(this means not all ABR can be achieved)

My implementation rather uses Monotone cubic interpolation (http://en.wikipedia.org/wiki/Monotone_cubic_interpolation) combined with False position method (http://en.wikipedia.org/wiki/False_position_method).
It surely converges, and usually very fast.

Usually 3 passes are enough to find the right -V param in most cases with 4 threads.
Unfortunatelly, in some cases not all ABR can be achieved with the -V parameter either.
In these cases MultiPassLame uses the closest (but lower) ABR than the specified,
and usually 6-7 passes are required (with 4 threads) to find out that the target can not be achieved.

You can freely download my application with source code here:
http://fenyo1.web.elte.hu/MultiPassLame