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