2Pass wav file gain maximizer and encoding using ffmpeg

Developed or developing a new product in PureBasic? Tell the world about it.
inc.
Enthusiast
Enthusiast
Posts: 406
Joined: Thu May 06, 2004 4:28 pm
Location: Cologne/GER

2Pass wav file gain maximizer and encoding using ffmpeg

Post by inc. »

Code: Select all

Structure WAVEFILEHEADER
  ; RIFF Header
  riffid.l ; 'RIFF'
  filesize.l
  waveid.l ; 'WAVE'
  ; Format chunk
  fmtid.l ; 'fmt '
  fmtlength.l 
  wFormatTag.w
  nChannels.w
  nSamplesPerSec.l
  nAvgBytesPerSec.l
  nBlockAlign.w
  bitspersample.w 
  ; Data chunk
  dataid.l ; 'data'
  DataLength.l
EndStructure

#BufferSize = 4096
Define maxAmp.f = 0, res.l = 0, startadress.l = 0, File.s="", MaxSignVal.f, start.l
Define *mem.Word, *header.WAVEFILEHEADER, Samplesize.l, factor.f, percent.b, prg.l, r.w

percent = 100 ; Wanted max volume in %

File = OpenFileRequester("Choose a PCM Wave file","","Wave files (*.wav)|*.wav",0)
If File
  ReadFile(0, File)
  FileBuffersSize(0, 0) ; As we gonna do read chunks into our own assigned buffer, we switch PBs filebuffering off.
  
  *header     = AllocateMemory(SizeOf(WAVEFILEHEADER))
  *mem        = AllocateMemory(#BufferSize)
  startadress = *mem
  
  ReadData(0, *header, SizeOf(WAVEFILEHEADER))
  Samplesize  = *header\bitspersample/8
  MaxSignVal  = Pow(2,*header\bitspersample-1)-1
  start       = GetTickCount_()
  
  ;- /// First pass: Finding the actual amplitude peak ouf the source audio stream
  
  While Not Eof(0)
    res  = ReadData(0, *mem, #BufferSize)
    Repeat 
      If *mem\w > maxAmp
        maxAmp = *mem\w
      EndIf
      *mem + Samplesize
    Until *mem > (startadress+res)
    *mem = startadress
  Wend
  
  MessageRequester("Finding max amplitude took ", StrF(((GetTickCount_()-start)/1000.0) )+" sec.")
  MessageRequester("Max amplitude found: ", Str(maxAmp)+" (100% = 32767)")
  
  ;- /// The 'factor' will be our multiplicator to obtain our final wanted volume
  factor = ((MaxSignVal / maxAmp)/100)*percent
  
  MessageRequester("Amplitude multiply Factor to obtain 100% volume: ", StrF(factor))
  
  FileSeek(0,SizeOf(WAVEFILEHEADER)) ; Seek back to where the audiodata starts
  
  If OpenWindow(0, 100, 100, 200, 20, "Encoding ...", #PB_Window_WindowCentered|#PB_Window_ScreenCentered)
    If CreateGadgetList(WindowID(0))
      ProgressBarGadget(1, 0,0, 200, 20, 0, 100)
    EndIf
  EndIf 
  
  ;- /// Do change the commandline to your needs (binary location, codec, options, outputfile & -path)
  prg = RunProgram("H:\Stuff\ffmpeg.exe", "-i - -acodec ac3 -ar 48000 -ab 128 -ac 2 G:\Test.ac3", "", #PB_Program_Open|#PB_Program_Write|#PB_Program_Hide)
  
  ;- /// Second pass: Applying the volume gain and encoding via ffmpeg.exe
  If prg
    SetFocus_(WindowID(0))
    WriteProgramData(prg, *header, SizeOf(WAVEFILEHEADER)) ; Writing the Wavefileheader ...
    While Not Eof(0)
      WindowEvent()
      res  = ReadData(0, *mem, #BufferSize)
      Repeat 
        r.w = *mem\w * factor ; Applying gain and assigning the result to a signed word variable ...
        *mem\w = r            ; ... as *mem\w seems to hold an unsigned word value??.
        *mem + Samplesize
      Until *mem > (startadress+res)
      *mem = startadress
      WriteProgramData(prg, *mem, res) ; Writing the audiodata to ffmpeg's stdin.
      SetGadgetState(1, (100*Loc(0))/Lof(0))
    Wend
    WriteProgramData(prg, #PB_Program_Eof, 0)
    CloseProgram(prg)
  EndIf 
  
  CloseFile(0)
  CloseWindow(0)
  FreeMemory(-1)
EndIf 
End
Check out OOP support for PB here!
Henrik
Enthusiast
Enthusiast
Posts: 404
Joined: Sat Apr 26, 2003 5:08 pm
Location: Denmark

Post by Henrik »

Thanks inc. :D
didn't know of ffmpeg before now, seems to worke fine for mp3 too :D

Best Henrik
inc.
Enthusiast
Enthusiast
Posts: 406
Joined: Thu May 06, 2004 4:28 pm
Location: Cologne/GER

Post by inc. »

ffmpeg actually is libavcodec and can handle almost every codec and format at audio and video.

A special Windows Site for ffmpeg:
http://ml20rc.msnfanatic.com/ffmpeg/msysguide.html

and a binary from that site:
http://arrozcru.no-ip.org/ffmpeg_builds ... pl.tar.bz2
Check out OOP support for PB here!
Coolman
Enthusiast
Enthusiast
Posts: 103
Joined: Sat Sep 03, 2005 4:07 pm

Post by Coolman »

Very good job :)

Thanks.
Post Reply