Newsgroup: it.comp.software.divx
Titolo: DivX + Linux + Normalizzazione audio

Sto realizzando alcuni DivX in Linux e mi sto trovando veramente bene! Il
risultato e ottimo e in pochissimo tempo (2 orette) riesco a convertire un
intero film!
Ultimamente pero' sono incappato in un piccolo problema dal quale non riesco
ad uscire.
Di solito proseguo in questo modo:
1)Con "avidemux2" tolgo la pubblicità dal film, lo salvo in mpeg
(Audio+Video) e recupero alcuni dati come le coordinate di croppaggio e
durata in secondi dell'intero film
2)Con "mencoder" creo un file frameno.avi che in pratica contiene solo
l'audio compresso finale in mp3 (filtro video = frameno, filtro audio =
mp3lame)
3) Calcolo il bitrate tramite una semplice formuletta
4) Recupero le dimensioni che deve avere il filmato alla fine tramite uno
script in perl
5) Eseguo la prima passata con mencoder (filtro video = lavc)
6) Eseguo la seconda passata con mencoder (stesso filtro video, l'audio lo
copio dal file frameno.avi)
Alla fine di questi 6 punti, dopo circa due orette e un pezzo, ho il mio
DivX bello e pronto! 
Il problema e' che a volte vorrei normalizzare l'audio perche' se guardo il
film sulla TV si sente bassissimo! (E' un problema del mpeg iniziale) Come
posso fare a normalizzarlo? Ho provato il comando "normalize" nel modo
seguente:
1) come prima
2) Con "mplayer" estraggo l'audio dal film in formato WAV (filtro video =
null, filtro audio = PCM)
3) Normalizzo il file WAV con "normalize"
4) Converto in file WAV in MP3
5) come punto 3) precedente
6) come punto 4) precedente
7) come punto 5) precendete
8) come punto 6) precedente solo che l'audio lo prendo dal file MP3 creato
nel punto 3)
L'audio nel file DivX finale e' in effetti normalizzato, si sente benissimo
ma con l'andar del tempo perde la sincronia (Per i primi 2-3 minuti tutto
OK, in mezzo al film ci saranno 30 secondi di asincronia e alla fine anche
1-2 minuti).
Avete qualche consiglio per risolvere il problema? L'ideale sarebbe un
programma che riesca a normalizzare l'audio gia' direttamente nel file mpeg
iniziale o a livello di frameno.avi. E' possibili?
Grazie  a tutti e scusate la lunghezza del post!
GiAn

 iniziale o a livello di frameno.avi. E' possibili?
si'.
la soluzione piu' semplice e' quella di usare il sotto-parametro "vol" del
parametro "-lameopts", quando usi "-ovc frameno" e "-oac mp3lame" per
generare "frameno.avi":
  vol=<0-10>
     audio input gain
un'alternativa e' quella di usare il programma "mp3gain" (con google trovi
facilmente il codice sorgente compilabile su qualsiasi sistema; se non lo
trovi dimmelo e te lo mando gia' compilato per linux e anche debuggato :-))
in pratica devi procedere in modo simile a come hai gia' tentato, ma senza
decomprimere la traccia audio:
1) estrai la traccia audio in mp3 che hai creato con "-ovc mp3lame":
   mplayer film.avi -dumpaudio
2) normalizzi il mp3 con un comando simile a questo:
   mp3gain -s s -r -c stream.dump
3) lo reinfili nell'AVI al posto dell'altro, nel modo che gia' sai (punto
   6) del tuo metodo), cioe':
   mencoder -mc 0 film.avi -audiofile stream.dump -o film2.avi -oac copy
   -ovc copy
ti conviene farti uno script che faccia una tale normalizzazione dell'audio
in automatico...

 dell'audio in automatico...
Scarico tutto e faccio le prove... Se ho ancora problemi ti faccio sapere!
Per ora... Grazie!!!
GiAn

 Scarico tutto e faccio le prove... Se ho ancora problemi ti faccio sapere!
il file che devi cercare e scaricare e' questo:
mp3gain-1_4_6-src.zip (111,408 bytes)
una volta scompattato, ti conviene modificare il file "gain_analysis.c"
sostituendo questa riga:
#define MAX_SAMPLES_PER_WINDOW  (size_t) (MAX_SAMP_FREQ * RMS_WINDOW_TIME)   
con questa:
#define MAX_SAMPLES_PER_WINDOW  (size_t) (2.0 * MAX_SAMP_FREQ *
RMS_WINDOW_TIME)   
dopodiche' batti "make mp3gain"
se tutto va bene ottieni l'eseguibile "mp3gain", che andrai a copiare
dove ti pare (tipo /usr/local/bin)
battendo "mp3gain -h" ottieni la lista delle opzioni;
comunque, per quello che serve a te, dovrebbe andarti bene questa
riga:
mp3gain -s s -r -c audio.mp3
(effettua un'analisi del file e individua automaticamente il guadagno
piu' adatto)
lo stream non viene ricodificato, e la modifica e' quindi reversibile
ciao

 wrote:
FrankFrank> in pratica devi procedere in modo simile a come hai gia'
Frank> tentato, ma senza decomprimere la traccia audio:
Frank> 1) estrai la traccia audio in mp3 che hai creato con "-ovc
Frank> mp3lame": mplayer film.avi -dumpaudio
Frank> 2) normalizzi il mp3 con un comando simile a questo: mp3gain -s
Frank> s -r -c stream.dump
Frank> 3) lo reinfili nell'AVI al posto dell'altro, nel modo che gia'
Frank> sai (punto 6) del tuo metodo), cioe': mencoder -mc 0 film.avi
Frank> -audiofile stream.dump -o film2.avi -oac copy -ovc copy
Frank> ti conviene farti uno script che faccia una tale
Frank> normalizzazione dell'audio in automatico...
Questo e' lo script Tcl (per Linux) che ho realizzato tempo fa.  Usa
avimerge, mencoder/mplayer, transcode e mp3gain per normalizzare il
volume sonoro di un file DIVX (.avi):
#!/bin/sh
# -*- tcl -*- the next line restarts using wish \
exec tclsh "$0" ${1+"$@"}
package require opt
::tcl::OptProc checkopts {
  {file -any {AVI file}}
} {
  foreach i [info locals] {
    set ::pargs($i) [set $i]
    # puts "$i: [set $i]"
  }
}
if {[catch {eval checkopts $argv} msg]} {
  puts stderr $msg
  exit 20
}
set file $pargs(file)
set rootname [file rootname $file]
set extension [file extension $file]
set mp3file "${rootname}.mp3"
set ifile "${rootname}-orig${extension}"
set noaudiofile "${rootname}-na${extension}"
file rename $file $ifile
puts "\#\#\#\# mencoder -ovc copy -nosound $ifile -o $noaudiofile"
exec >@stdout 2>@stderr mencoder -ovc copy -nosound $ifile -o $noaudiofile
puts "\#\#\#\# tcextract -i $ifile -x mp3 -a 0 > $mp3file"
exec >@stdout 2>@stderr tcextract -i $ifile -x mp3 -a 0 > $mp3file
puts "\#\#\#\# mp3gain -r -k $mp3file"
set rc [catch {exec >@stdout 2>@stderr mp3gain -r -k $mp3file} msg]
if {$rc != 1} {
  error "Error running mp3gain, abort"
}
puts "\#\#\#\# avimerge -i $noaudiofile -p $mp3file -o $file"
exec >@stdout 2>@stderr avimerge -i $noaudiofile -p $mp3file -o $file
file delete $noaudiofile
file delete $mp3file
exit

 volume sonoro di un file DIVX (.avi):
ciao Alberto :-)
ho provato lo script e mi si blocca su un errore che non capisco...
ecco cosa ho fatto:
ho salvato lo script su un file "avi-audio-normalize", ho fatto
"chmod 755 avi-audio-normalize", poi ho battuto:
./avi-audio-normalize subsonica-abitudine.avi
#### mencoder -ovc copy -nosound subsonica-abitudine-orig.avi -o
subsonica-abitudine-na.avi
[...]
#### tcextract -i subsonica-abitudine-orig.avi -x mp3 -a 0 >
subsonica-abitudine.mp3
[...]
#### mp3gain -r -k subsonica-abitudine.mp3
subsonica-abitudine.mp3
Applying mp3 gain change of -2 to subsonica-abitudine.mp3...
Error running mp3gain, abort                       
    while executing
"error "Error running mp3gain, abort""
    invoked from within
"if {$rc != 1} {
  error "Error running mp3gain, abort"
}"
    (file "./avi-audio-normalize" line 38)
in pratica funziona tutto bene, ma il programma ritiene che
l'esecuzione di "mp3gain" sia fallita (invece finisce bene)
lo script procede cosi':
- rinomina il file originale in "subsonica-abitudine-orig.avi"
- crea una copia senza audio "subsonica-abitudine-na.avi"
- estrae il mp3 dal file originale
- applica mp3gain al mp3
- qui dovrebbe usare avimerge per creare il file finale, ma
  come ti ho detto, si ferma perche' ritiene che mp3gain sia
  terminato con errore...
a questo punto ho fatto queste prove: ho estratto il mp3 dal
file originale con tcextract e ho applicato mp3gain:
$ tcextract -i subsonica-abitudine-orig.avi -x mp3 -a 0 > pippo.mp3
tc_memcpy: using mmxext for memcpy
$ mp3gain -r -k pippo.mp3   
pippo.mp3
Applying mp3 gain change of -2 to pippo.mp3...   
$
non c'e' nessun errore...
ho anche provato a estrarre il mp3 con mplayer
$ mplayer subsonica-abitudine-orig.avi -dumpaudio
MPlayer 1.0pre6-3.2 (C) 2000-2004 MPlayer Team
[...]
$ mp3gain -r -k stream.dump             
stream.dump
Applying mp3 gain change of -2 to stream.dump... 
$
anche qui non ho nessun errore...
del resto i tre file normalizzati sono tutti identici:
$ md5sum subsonica-abitudine.mp3 stream.dump pippo.mp3 
ca2c43d3acd56b7666d2660cae6c9356  subsonica-abitudine.mp3
ca2c43d3acd56b7666d2660cae6c9356  stream.dump
ca2c43d3acd56b7666d2660cae6c9356  pippo.mp3
l'errore viene rilevato da queste righe dello script:
-----------------------------------
puts "\#\#\#\# mp3gain -r -k $mp3file"
set rc [catch {exec >@stdout 2>@stderr mp3gain -r -k $mp3file} msg]
if {$rc != 1} {
  error "Error running mp3gain, abort"
}
-----------------------------------
perche' accade? :-)
infine, volevo chiederti: che differenza c'e' tra usare "avimerge"
e "mencoder" per multiplexare il file finale?
(tra l'altro usando "mencoder" non c'e' bisogno di creare il filmato
intermedio privo di audio)
ciao

 l'audio originale con quello normalizzato.  E' possibile?
si', con l'opzione "-audiofile":
mencoder -mc 0 film.avi -audiofile audio.mp3 -o film2.avi -oac copy
 -ovc copy
con questo comando, il file di uscita (film2.avi) avra' lo stesso
stream video di "film.avi", ma l'audio sara' rimpiazzato dal file
"audio.mp3"
credevo che ci fossero motivi particolari per preferire avimerge...
mi pare che avimerge sia piu' "accurato" di mencoder (ad esempio,
avimerge, al contrario di mencoder, evita di inserire eventuali
chunk audio che inizino oltre la fine dell'ultimo frame video)...
ma forse in questo specifico caso conviene usare mencoder, in
quanto evita la creazione del file temporaneo senza audio...
ciao

> possibile?
Frank> si', con l'opzione "-audiofile":
Frank> mencoder -mc 0 film.avi -audiofile audio.mp3 -o film2.avi -oac
Frank> copy -ovc copy
Frank> con questo comando, il file di uscita (film2.avi) avra' lo
Frank> stesso stream video di "film.avi", ma l'audio sara' rimpiazzato
Frank> dal file "audio.mp3"
[...]
Funziona!  Per chi fosse interessato, ecco la script Tcl aggiornata di
normalizzazione dell'audio di un DIVX, che evita anche visualizzare
tutto l'output di mencoder (a meno che non ci sia un errore):
#!/bin/sh
# -*- tcl -*- the next line restarts using wish \
exec tclsh "$0" ${1+"$@"}
package require opt
::tcl::OptProc checkopts {
  {file -any {AVI file}}
} {
  foreach i [info locals] {
    set ::pargs($i) [set $i]
    # puts "$i: [set $i]"
  }
}
if {[catch {eval checkopts $argv} msg]} {
  puts stderr $msg
  exit 20
}
set file $pargs(file)
set rootname [file rootname $file]
set extension [file extension $file]
set mp3file "${rootname}.mp3"
set ifile "${rootname}-orig${extension}"
# set noaudiofile "${rootname}-na${extension}"
file rename $file $ifile
# puts "\#\#\#\# mencoder -ovc copy -nosound $ifile -o $noaudiofile"
# exec >@stdout 2>@stderr mencoder -ovc copy -nosound $ifile -o $noaudiofile
puts "\#\#\#\# tcextract -i $ifile -x mp3 -a 0 > $mp3file"
exec >@stdout 2>@stderr tcextract -i $ifile -x mp3 -a 0 > $mp3file
puts "\#\#\#\# mp3gain -r -k $mp3file"
exec >@stdout 2>@stderr mp3gain -r -k $mp3file
# puts "\#\#\#\# avimerge -i $noaudiofile -p $mp3file -o $file"
# exec >@stdout 2>@stderr mencoder -ovc copy -nosound $ifile -o $noaudiofile
puts "\#\#\#\# tcextract -i $ifile -x mp3 -a 0 > $mp3file"
exec >@stdout 2>@stderr tcextract -i $ifile -x mp3 -a 0 > $mp3file
puts "\#\#\#\# mp3gain -r -k $mp3file"
exec >@stdout 2>@stderr mp3gain -r -k $mp3file
# puts "\#\#\#\# avimerge -i $noaudiofile -p $mp3file -o $file"
# exec >@stdout 2>@stderr avimerge -i $noaudiofile -p $mp3file -o $file
puts "\#\#\#\# mencoder -mc 0 $ifile -audiofile $mp3file -o $file -oac copy -ovc copy"
# exec >@stdout 2>@stderr  mencoder -mc 0 $ifile -audiofile $mp3file -o $file -oac copy -ovc copy
set rc [catch {exec mencoder -mc 0 $ifile -audiofile $mp3file -o $file -oac copy -ovc copy} msg]
if {$errorCode != {NONE}} {
  error "error when replacing audio by using mencoder (mencoder out follows)\n$msg"
}
# file delete $noaudiofile
file delete $mp3file
puts stderr "Left original file saved as '$ifile'"
exit
Ciao.

 exec >@stdout 2>@stderr mp3gain -r -k $mp3file
questa parte l'hai ripetuta due volte, forse hai fatto "copia e incolla"
involontariamente :-)
il resto e' tutto ok, l'ho provato e funziona bene.
una cosa che potresti aggiungere e' l'opzione "-s s" di mp3gain,
che serve a non generare il tag (essendo una traccia da inserire in
un AVI, il tag non serve);
inoltre, se dall'analisi dell'audio, mp3gain decide di non apportare
nessuna modifica, stampa quanto segue:
No changes to z.mp3 are necessary
...but tag needs update: Writing tag information for z.mp3
(la seconda riga non viene, se si usa l'opzione "-s s")
in questo caso, sarebbe bene se il programma evitasse di riunire
il file mp3 all'AVI di partenza, perche' in questo processo di
estrazione e reinserimento dell'audio, per qualche motivo che non
conosco, va perso il chunk iniziale...
per verificarlo, fai questa prova:
prendi un filmato z.avi e ripeti una decina di volte questo comando:
rm -f z-orig.avi ; avi-audio-norm z.avi
(dove "avi-audio-norm" e' il tuo script)
a partire dalla seconda volta, mp3gain non fara' niente perche'
l'audio ormai e' gia' normalizzato; quindi, il programma si limita
a estrarre l'audio e a ricreare un nuovo AVI, che in teoria
dovrebbe essere identico a quello in ingresso...
a questo punto, pero', se fai riprodurre z.avi, ti accorgerai che
l'audio e' in anticipo rispetto al video, perche' ogni volta e'
stato tolto un pezzettino all'inizio...
comunque non e' un gran problema, perche' una sola applicazione
provoca una asincronia praticamente impercettibile...
ciao e grazie

 conosco, va perso il chunk iniziale...
ho fatto un po' di esperimenti...
ti ricordi quando ti ho chiesto che differenza ci fosse tra usare
mencoder e avimerge per ricreare l'AVI finale?
ebbene, adesso a me sembra molto meglio avimerge!
non so per quale motivo, ma avimerge e' piu' accurato di mencoder
(mi riferisco alla versione che ho io, cioe' 1.0pre7)
ho applicato l'ultima versione dello script su un AVI e nel
risultato l'audio e' in evidente anticipo...
inoltre, come dicevo ieri, se la traccia audio non viene modificata,
in teoria il risultato dovrebbe essere identico all'ingresso, ma
usando mencoder non e' cosi'!
invece, usando avimerge, non ho mai riscontrato alcun problema, e,
nel caso in cui la traccia audio non viene modificata, il
risultato e' identico all'ingresso...
inoltre, anche con avimerge non e' necessario creare il file
temporaneo senza audio, basta usare l'opzione "-A 0" (ha
l'effetto di rimpiazzare la traccia esistente con la nuova)
in conclusione, la sequenza di comandi che mi sembra funzionare
meglio e' questa:
tcextract -i ingresso.avi -x mp3 -a 0 > audio.mp3
mp3gain -s s -r -k audio.mp3
avimerge -i ingresso.avi -o uscita.avi -A 0 -p audio.mp3
rm audio.mp3
ciao