I don't know what exactly you want to do, but here's a snippet that normalizes a single wav - file (pcm or float). It's part of a program I use to batch - normalize / convert the wav - files of a whole directory. For the conversion it uses
.
Code: Select all
#Include "..\fbm_RIFFheader.bas"
#Include "vbcompat.bi"
Const As Integer schwarz = 0, blau = 1, gruen = 2, zyan = 3, cyan = 3, rot = 4, magenta = 5, _
braun = 6, hellgrau = 7, grau = 8, hellblau = 9, hellgruen = 10, hellzyan = 11, _
hellcyan = 11, hellrot = 12, pink = 13, gelb = 14, weiss = 15
Dim As String g
Dim As String quelle, ziel
Dim As Integer laengemerken, keinedatei, header, dateilaenge, subch1, audioformat, kanaele, samplerate, _
byterate, blockalign, bitspersample, subch2, blocklaenge, x, ma
Dim As LongInt samples, gesamtsamples, bloecke, rest
Dim As Single maxamplitude, dauer, sollwertpcm, sollwertfloat, links, rechts, verst, schwelle
Dim As Double geslinks, gesrechts
Dim As Short Ptr gpp
Dim As Single Ptr gpf
Declare Sub maske
Declare Function vh (x As Single) As Single
Declare Function db (x As Single) As Single
'initialize variables
quelle = "g:\RIFF\RMS Abgleichton.wav" 'source file
ziel = "g:\RIFF\mod.wav" 'destination file
sollwertpcm = -18 'desired value (in dB)
sollwertfloat = -18
schwelle = .2
blocklaenge = 2^25
If quelle = ziel Then 'change file name
ziel = Left(ziel,InStrRev(ziel,".") - 1) + "_1" + Mid(ziel,InStrRev(ziel,"."))
EndIf
keinedatei = 0
maxamplitude = 0
geslinks = 0
gesrechts = 0
samples = 0
laengemerken = FileLen(quelle)
If quelle = "" Then
End
EndIf
If Open(quelle For Binary Access Read As #1) Then
Print "File not found"
Sleep
End
EndIf
Print #10, quelle;" "; '***
header = 0
Do 'seek 'data'
header += 1
Seek #1, header
g = Input$(4, #1)
Loop Until g = "data"
header += 7
g = Input$(4, #1)
Print
Seek 1,1 'reset file pointer
'determine file parameters
g = Input(4, #1) 'skip the first 4 bytes
dateilaenge = Cvi(Input(4, #1)) 'file length
g = Input(8, #1) 'skip
subch1 = Cvi(Input(4, #1)) 'size of subchunk1
audioformat = CVShort(Input(2, #1)) 'audio format
kanaele = CVShort(Input(2, #1)) 'number of channels
samplerate = Cvi(Input(4, #1))
byterate = Cvi(Input(4, #1))
blockalign = CVShort(Input(2, #1))
bitspersample = CVShort(Input(2, #1))
g = Input(4, #1) 'skip
Seek 1,header - 3
subch2 = Cvi(Input(4, #1))
gesamtsamples = (Lof(1)-header)/blockalign 'total number of samples
bloecke = Int(gesamtsamples * blockalign / blocklaenge) 'number of blocks (for input)
rest = gesamtsamples * blockalign - bloecke * blocklaenge
maske
'print title
Locate 1,1
Color weiss,schwarz
Print quelle
'print file parameters
Print
Print Tab(17); samplerate; " Hz"
Print Tab(17); bitspersample; " bit ";
Select Case audioformat
Case 1
Print"PCM"
Case 3
Print "float"
Case Else
Color hellrot,schwarz
Print "*** Unbekanntes Audioformat ***"
Color weiss,schwarz
Sleep 2000
Exit Select
End Select
Select Case kanaele
Case 1
Print Tab(18); "Mono"
Case 2
Print Tab(18); "Stereo"
Case Else
Print Tab(17); kanaele
End Select
dauer = subch2 / byterate
x = Int(dauer / 60)
g = Str$(dauer - 60 * x)
If InStr(g,".") = 2 Then
g = "0" + g
EndIf
g = Str$(x) + ":" + g
Print Tab(18); Left$(g,InStr(g,".")+2)
'print file names
Print
Print
Print Tab(18); quelle
Print Tab(18); ziel
Locate 15,1
Select Case audioformat
Case 1 'pcm
Print Tab(18); sollwertpcm; " dB"
Case 3 'float
Print Tab(18); sollwertfloat; " dB"
End Select
Do
g = Input(blocklaenge, #1)
Color weiss,schwarz
Select Case audioformat 'determine actual value
Case 1 'pcm
samples += Len(g)/4
For gpp = Cast(Short Ptr,StrPtr(g)) To Cast(Short Ptr,StrPtr(g) + Len(g) - 1) Step 2
'left value
links = CSng(Abs(*gpp)) / ma 'convert to float and normalize
If links > maxamplitude Then 'determine peak value
maxamplitude = links
EndIf
geslinks += links * links
'right value
rechts = CSng(Abs(*(gpp+1))) / ma 'convert to float and normalize
If rechts > maxamplitude Then 'determine peak value
maxamplitude = rechts
EndIf
gesrechts += rechts * rechts
Next
Case 3 'float
samples += Len(g)/8
For gpf = Cast(Single Ptr,StrPtr(g)) To Cast(Single Ptr,StrPtr(g) + Len(g) -1) Step 2
'right value
rechts = Abs(*(gpf+1))
If rechts > 1 Then
rechts = 0
EndIf
If rechts > maxamplitude Then
maxamplitude = rechts
EndIf
gesrechts += rechts * rechts
'left value
links = Abs(*gpf)
If links > 1 Then
links = 0
EndIf
If links > maxamplitude Then
maxamplitude = links
EndIf
geslinks += links * links
Next
End Select
Loop Until Len(g) < blocklaenge
'************************************************************************************
'compute amplification
Select Case audioformat
Case 1 'pcm
verst = vh(sollwertpcm) / (Sqr((geslinks + gesrechts) / (2*samples)))
Case 3 'float
verst = vh(sollwertfloat) / (Sqr((geslinks + gesrechts) / (2*samples)))
End Select
'print actual value
Locate 16,18,0
Print Int(10 * (db(Sqr(geslinks /samples)))) / 10;" dB"
Locate 17,18,0
Print Int(10 * (db(Sqr(gesrechts/samples)))) / 10;" dB"
Locate 18,18,0
Print Int(10 * (db(Sqr((geslinks + gesrechts) / (2 * samples))))) / 10;" dB"
Close #1
If maxamplitude * verst > 1 Then 'avoid distorsion
Locate 22,1,0
Print "Die Verstärkung wurde um ";_
CInt(Abs(db(maxamplitude * verst))*100)/100;_
"dB abgesenkt,"
Print "um eine Übersteuerung zu verhindern"
verst = verst / (maxamplitude * verst)
EndIf
'print amplification factor
Locate 19,18,0
Print db(verst);" dB"
If Abs(db(verst)) > schwelle Then 'correct volume
Open quelle For Binary Access Read As #1
Open ziel For Output As #2
Print #10, Lof(1);" "; '***
'transfer header
Print #2, Input$(header, #1);
'transfer audio samples with new volume
Do
g = Input(blocklaenge, #1)
Select Case audioformat 'compute audio samples
Case 1 'pcm
For gpp = Cast(Short Ptr,StrPtr(g)) To Cast(Short Ptr,StrPtr(g) + Len(g) - 1)
*gpp *= verst
Next
Print #2, g;
Case 3 'float
For gpf = Cast(Single Ptr,StrPtr(g)) To Cast(Single Ptr,StrPtr(g) + Len(g) - 1)
*gpf *= verst
Next
Print #2, g;
End Select
Loop Until Len(g) < blocklaenge
Close #1
Close #2
Else 'copy file
Locate 13,6,0
Color hellcyan,schwarz
Print " kopieren ";
Color weiss,schwarz
FileCopy(quelle, ziel)
EndIf
Locate 13,1,0
Print " "
Close
Sleep
Sub maske
View Print 1 To 12
Cls
View Print 14 To 25
Cls
Color hellgrau,schwarz
View Print
Locate 1,1,0
Print
Print
Print " Samplerate"
Print " Format"
Print " Kanäle"
Print " Dauer"
Print
Print
Print "Quellverzeichnis"
Print " Zielverzeichnis"
Print " Datei"
Print
Print Tab(18); String(50, "°")
Print
Print " Sollpegel"
Print " Pegel links"
Print " Pegel rechts"
Print " Gesamtpegel"
Print " Verstärkung"
End Sub
Function vh (x As Single) As Single 'rechnet dB in verhältnis um
Return Exp((x / 20) * Log(10))
End Function
Function db (x As Single) As Single 'rechnet verhältnis in dB um
Return 20*(Log(x)/Log(10))
End Function