Hello,
I need to convert MP3 audio to WAV audio. I've done a fair amount of research and it looks like LAME can do the job for me. The converted WAV audio needs to be 16-bit mono at 11025Hz. I'd also preferably like to lower the volume by ~20dB. Can this be done with LAMe on the command line?
Hello,
I need to convert MP3 audio to WAV audio. I've done a fair amount of research and it looks like LAME can do the job for me. The converted WAV audio needs to be 16-bit mono at 11025Hz. I'd also preferably like to lower the volume by ~20dB. Can this be done with LAMe on the command line?
Why do you want to do that? (just curious)
I think the best way to do it would be to decompress the audio with LAME to whatever format it is already, and then use SoX (http://sox.sourceforge.net/) to change the sample rate and number of channels on a WAV file.
You can decode directly with SoX (http://sox.sourceforge.net/ (http://sox.sourceforge.net/)) if you put
"libmad.dll" into the folder where
"sox.exe" is located:
$ sox x.mp3 -c 1 -b 16 x.wav gain -20 rate 11025
$ sox --i x.wav
Input File : 'x.wav'
Channels : 1
Sample Rate : 11025
Precision : 16-bit
Duration : 00:03:03.38 = 2021760 samples ~ 13753.5 CDDA sectors
File Size : 4.04M
Bit Rate : 176k
Sample Encoding: 16-bit Signed Integer PCM
-c 1: one channel, i.e. mono
-b 2: two bytes, i.e. 16 bit
"libmad" provides 24 bit dynamic resolution, to my knowledge "lame" only 16 bit.
I'm not sure that there's a need for Sox in this instance. Lame should be able to handle it.
http://lame.cvs.sourceforge.net/viewvc/lam...ml/switchs.html (http://lame.cvs.sourceforge.net/viewvc/lame/lame/doc/html/switchs.html)
for the 20dB attenuation, you can use the --scale switch:
* --scale n scales input by n
* --scale-l n scales input channel 0 (left) by n
* --scale-r n scales input channel 1 (right) by n
Scales input by n. This just multiplies the PCM data (after it has been converted to floating point) by n.
n > 1: increase volume
n = 1: no effect
n < 1: reduce volume
Use with care, since most MP3 decoders will truncate data which decodes to values greater than 32768.
I'm not sure that there's a need for Sox in this instance. Lame should be able to handle it.
Oviously not. Try the following:
First use SoX as described above:
pbelkner ~/sounds
$ sox x.mp3 -b 16 x-sox.wav gain -18 rate 11025 stats
Overall Left Right
DC offset 0.000413 0.000413 0.000375
Min level -0.136472 -0.131937 -0.136472
Max level 0.136097 0.136097 0.134131
Pk lev dB -17.30 -17.32 -17.30
RMS lev dB -34.75 -34.25 -35.32
RMS Pk dB -24.55 -25.02 -24.55
RMS Tr dB -83.19 -83.19 -70.26
Crest factor - 7.02 7.97
Flat factor 0.00 0.00 0.00
Pk count 2 2 2
Bit-depth 30/32 30/32 30/32
Num samples 2.02M
Length s 183.380
Scale max 1.000000
Window s 0.050
pbelkner ~/sounds
$ sox --i x-sox.wav
Input File : 'x-sox.wav'
Channels : 2
Sample Rate : 11025
Precision : 16-bit
Duration : 00:03:03.38 = 2021760 samples ~ 13753.5 CDDA sectors
File Size : 8.09M
Bit Rate : 353k
Sample Encoding: 16-bit Signed Integer PCM
pbelkner ~/sounds
$ _
Attenuation by 18 dB (about 1/4, i.e. scale by 0.125), resampled to 11025 Hz, as expected.
Now give lame a try:
pbelkner ~/sounds
$ lame --decode --resample 11025 --scale 0.125 x.mp3 x-lame.wav
ID3v2 found. Be aware that the ID3 tag is currently lost when transcoding.
input: x.mp3 (44.1 kHz, 2 channels, MPEG-2.5 Layer III)
output: x-lame.wav (16 bit, Microsoft WAVE)
skipping initial 1105 samples (encoder+decoder delay)
Frame# 7021/7021 64 kbps MS
pbelkner ~/sounds
$ sox x-lame.wav y-lame.wav stats
Overall Left Right
DC offset 0.003278 0.003278 0.002978
Min level -1.000000 -1.000000 -1.000000
Max level 0.999969 0.999969 0.999969
Pk lev dB 0.00 0.00 0.00
RMS lev dB -16.74 -16.24 -17.31
RMS Pk dB -6.53 -7.02 -6.53
RMS Tr dB -67.46 -67.46 -54.54
Crest factor - 6.48 7.33
Flat factor 11.90 12.30 11.54
Pk count 232 218 245
Bit-depth 16/16 16/16 16/16
Num samples 8.09M
Length s 183.381
Scale max 1.000000
Window s 0.050
pbelkner ~/sounds
$ sox --i x-lame.wav
Input File : 'x-lame.wav'
Channels : 2
Sample Rate : 44100
Precision : 16-bit
Duration : 00:03:03.38 = 8087087 samples = 13753.5 CDDA sectors
File Size : 32.3M
Bit Rate : 1.41M
Sample Encoding: 16-bit Signed Integer PCM
pbelkner ~/sounds
$ _
No attenuation nor resampling.
As far as I know the lame switches
--scale and
--resample only apply to
encoding.
You can decode directly with SoX (http://sox.sourceforge.net/ (http://sox.sourceforge.net/)) if you put [font= "Courier New"]"libmad.dll"[/font] into the folder where [font= "Courier New"]"sox.exe"[/font] is located
That doesn't work for me. I pipe lame output so that sox can recognize mp3 input
Using libmad.dll (from 2004 found on this forums) in sox folder errors to this:
[font= "Courier New"]Unable to load MAD decoder library (libmad) function "mad_timer_multiply"[/font]
I guess library is old or similar, and trying to compile the library under cygwin fails for known issue:
[font= "Courier New"]cc1: error: unrecognized command line option "-fforce-mem"
etc...[/font]
How have you managed above to work for you?
Using libmad.dll (from 2004 found on this forums) in sox folder errors to this:
Unable to load MAD decoder library (libmad) function "mad_timer_multiply"
Unfortunately this version of "libmad.dll" seems to be stripped:
pbelkner ~/tmp
$ nm libMAD.dll
d:\mingw\bin\nm.exe: libMAD.dll: no symbols
pbelkner ~/tmp
$ _
In order to load "libMAD.dll" dynamically SoX needs the symbols defined.
How have you managed above to work for you?
I've compiled it myself.
You may try
"madplay.exe" from the same site you've found
"libmad.dll":
pbelkner ~/tmp
$ madplay -a -20 -b 32 -d -o wav:- x.mp3|sox - -c 1 -b 16 x.wav rate 11025 stats
MPEG Audio Decoder 0.15.2 (beta) - Copyright (C) 2000-2004 Robert Leslie et al.
7021 frames decoded (0:03:03.4), -17.7 dB peak amplitude, 0 clipped samples
sox.exe WARN wav: Premature EOF on .wav input file
Overall Left Right
DC offset 0.000328 0.000328 0.000298
Min level -0.124783 -0.124783 -0.117905
Max level 0.123345 0.122203 0.123345
Pk lev dB -18.08 -18.08 -18.18
RMS lev dB -36.75 -36.25 -37.32
RMS Pk dB -26.51 -26.94 -26.51
RMS Tr dB -87.24 -87.24 -74.41
Crest factor - 8.10 9.06
Flat factor 0.00 0.00 0.00
Pk count 2 2 2
Bit-depth 29/32 29/32 29/32
Num samples 2.02M
Length s 183.405
Scale max 1.000000
Window s 0.050
pbelkner ~/tmp
$ sox --i x.wav
Input File : 'x.wav'
Channels : 1
Sample Rate : 11025
Precision : 16-bit
Duration : 00:03:03.40 = 2022040 samples ~ 13755.4 CDDA sectors
File Size : 4.04M
Bit Rate : 176k
Sample Encoding: 16-bit Signed Integer PCM
pbelkner ~/tmp
$ _
Using madplay instead of lame has the advantage that you can pipe 32 bit into SoX instead of 16 bit only:
[blockquote]
-a -20: attenuate by 20 dB
-b 32: 32 bit output
-d: don't dither, dithering is done by SoX automatically after resampling
-o wav:-: output as wav to stdout[/blockquote]
thanks for the explanation and madplay tip
works well that way
Possibly the most easyist way is just using madplay:
pbelkner ~/tmp
$ madplay -a -20 -R 11025 -o x.wav x.mp3
MPEG Audio Decoder 0.15.2 (beta) - Copyright (C) 2000-2004 Robert Leslie et al.
output: resampling 44100 Hz to 11025 Hz
7021 frames decoded (0:03:03.4), -18.1 dB peak amplitude, 0 clipped samples
pbelkner ~/tmp
$ _
Whether to use SoX or not depends, of course, on your opinion regarding the quality of the resampling and dithering algorithms provided by madplay and SoX, respectively.
and trying to compile the library under cygwin fails for known issue:
cc1: error: unrecognized command line option "-fforce-mem"
etc...
How have you managed above to work for you?
I compile "libmad" under MSys/MinGW after applying the following patch:
diff -rc libmad-0.15.1b/configure libmad-0.15.1b-updated/configure
*** libmad-0.15.1b/configure Thu Feb 5 09:34:07 2004
--- libmad-0.15.1b-updated/configure Wed May 12 12:04:17 2010
***************
*** 19099,19105 ****
case "$optimize" in
-O|"-O "*)
optimize="-O"
! optimize="$optimize -fforce-mem"
optimize="$optimize -fforce-addr"
: #x optimize="$optimize -finline-functions"
: #- optimize="$optimize -fstrength-reduce"
--- 19099,19105 ----
case "$optimize" in
-O|"-O "*)
optimize="-O"
! # optimize="$optimize -fforce-mem"
optimize="$optimize -fforce-addr"
: #x optimize="$optimize -finline-functions"
: #- optimize="$optimize -fstrength-reduce"
diff -rc libmad-0.15.1b/configure.ac libmad-0.15.1b-updated/configure.ac
*** libmad-0.15.1b/configure.ac Fri Jan 23 09:41:32 2004
--- libmad-0.15.1b-updated/configure.ac Wed May 12 12:04:04 2010
***************
*** 140,146 ****
case "$optimize" in
-O|"-O "*)
optimize="-O"
! optimize="$optimize -fforce-mem"
optimize="$optimize -fforce-addr"
: #x optimize="$optimize -finline-functions"
: #- optimize="$optimize -fstrength-reduce"
--- 140,146 ----
case "$optimize" in
-O|"-O "*)
optimize="-O"
! # optimize="$optimize -fforce-mem"
optimize="$optimize -fforce-addr"
: #x optimize="$optimize -finline-functions"
: #- optimize="$optimize -fstrength-reduce"
Thanks again pbelkner,
that seems self-explanatory now, but I wasn't sure that if I change that switch, another wouldn't pop, as if error isn't some obvious dependency I just leave cygwin
mkdir -p -- . /usr/local/lib
/bin/sh ./libtool --mode=install /usr/bin/install -c libmad.la /usr/local/lib/libmad.la
/usr/bin/install -c .libs/libmad.lai /usr/local/lib/libmad.la
/usr/bin/install -c .libs/libmad.a /usr/local/lib/libmad.a
ranlib /usr/local/lib/libmad.a
chmod 644 /usr/local/lib/libmad.a
encoding
That was a complete oversight on my part.
mkdir -p -- . /usr/local/lib
/bin/sh ./libtool --mode=install /usr/bin/install -c libmad.la /usr/local/lib/libmad.la
/usr/bin/install -c .libs/libmad.lai /usr/local/lib/libmad.la
/usr/bin/install -c .libs/libmad.a /usr/local/lib/libmad.a
ranlib /usr/local/lib/libmad.a
chmod 644 /usr/local/lib/libmad.a
I'm not certain whether you've managed to create the DLL. In case not use the following
"Makefile" for generic DLL creation (don't forget to make sure that the tabs are expanded):
CC=gcc
LIBDIR=/usr/local/lib
LDFLAGS=-Wl,--enable-auto-import
LDLIBS=-lwsock32
%.dll.a: %.dll
test -f $@ && touch $@
%.dll: %.def $(LIBDIR)/%.a
$(CC) -shared -o $@ -Wl,--out-implib,$@.a $^ $(LDFLAGS) $(LDLIBS)
%.def: $(LIBDIR)/%.a
echo "EXPORTS" > $@
nm $<|sed -n "s/.* \(D\|R\) _\(.*\)/\2 DATA/p" >> $@
nm $<|sed -n "s/.* T _//p" >> $@
.PHONY: clean
clean:
rm -f *.dll.a *.dll *.def
Assuming that static
"libmad.a" exists in
"/usr/local/lib" just call
"make libmad.dll":
pbelkner ~/tmp
$ make libmad.dll
echo "EXPORTS" > libmad.def
nm /usr/local/lib/libmad.a|sed -n "s/.* \(D\|R\) _\(.*\)/\2 DATA/p" >> libmad.def
nm /usr/local/lib/libmad.a|sed -n "s/.* T _//p" >> libmad.def
gcc -shared -o libmad.dll -Wl,--out-implib,libmad.dll.a libmad.def /usr/local/lib/libmad.a -Wl,--enable-auto-import -lwsock32
Creating library file: libmad.dll.a
rm libmad.def
pbelkner ~/tmp
$ ls
Makefile libmad.dll libmad.dll.a
pbelkner ~/tmp
$ _
You are right unfortunately, and I had a long day yesterday
I used cygwin test as I had it handy at the moment and seeing that all went OK I left for later managing msys, as I had mingw but not msys
It will take me many lines to describe my experience with msys, autoconf... but I wouldn't encourage anyone to try
From the time when I initially tried to make sox mp3 aware one thing changed and that is VS2008
I build sox with libmad in VS in less time
I'm sure your fine instructions provide solution to those interested, I'll stay at my current point to leave GNU ports when errors aren't obvious to me till next time
Thanks for your time
Thanks for the replies everyone! I was on vacation and could not respond.
Possibly the most easyist way is just using madplay:
pbelkner ~/tmp
$ madplay -a -20 -R 11025 -o x.wav x.mp3
MPEG Audio Decoder 0.15.2 (beta) - Copyright (C) 2000-2004 Robert Leslie et al.
output: resampling 44100 Hz to 11025 Hz
7021 frames decoded (0:03:03.4), -18.1 dB peak amplitude, 0 clipped samples
pbelkner ~/tmp
$ _
Whether to use SoX or not depends, of course, on your opinion regarding the quality of the resampling and dithering algorithms provided by madplay and SoX, respectively.
Using your example on a random MP3 I get the following:
C:\Users\Steven\Desktop>madplay -a -20 -R 11025 -o "C:\Users\Desktop\Steven\croo
kedteeth.wav" "D:\Music\Death Cab For Cutie\Plans\08-death_cab_for_cutie-crooked
_teeth.mp3"
madplay: unknown output format type for "C:\Users\Desktop\Steven\crookedteeth.wa
v"
C:\Users\Steven\Desktop>
Simply adding "wave:" before the output file did the trick. Many thanks, pbelkner.
EDIT: I can't seem to get it to output as 16-bit. This is what I'm trying right now:
C:\Users\Steven\Desktop>madplay -v --display-time=remaining -m -a -20 -R 11025 -
d -b 16 -o wave:C:\Users\Steven\Desktop\jackass.wav "D:\Music\Beck\Odelay\07 - jack
-ass.mp3"
Using your example on a random MP3 I get the following:
C:\Users\Steven\Desktop>madplay -a -20 -R 11025 -o "C:\Users\Desktop\Steven\crookedteeth.wav" "D:\Music\Death Cab For Cutie\Plans\08-death_cab_for_cutie-crooked_teeth.mp3"
madplay: unknown output format type for "C:\Users\Desktop\Steven\crookedteeth.wav"
C:\Users\Steven\Desktop>
As it seems
"madplay" don't understand backslashes in
"-o" option. Try the following:
C:\Users\Steven\Desktop>madplay -a -20 -R 11025 -o "crookedteeth.wav" "D:\Music\Death Cab For Cutie\Plans\08-death_cab_for_cutie-crooked_teeth.mp3"
C:\Users\Steven\Desktop>
I.e. first
"cd" into the target directory.