Bon voila la bête :
https://www.dropbox.com/s/q3u0xm6bcjco0 ... t.PNG?dl=0
L'interface comporte deux graphes : le premier est l'analyse FFT du son, vous pouvez choisir le mode de visualisation du spectre avec le combobox éponyme, le second est un oscilloscope affichant l'onde sonore (samples), le tout en temps réel. Vous pouvez aussi choisir le périphérique a afficher (que ce soit un haut parleur ou un micro)(si bug avec vos micros, tenez-m'en au courant).
Il y a une fonction d'enregistrement prévue mais pas encore au point, donc non fonctionnel. Quand au réglage automatique du volume ce n'est pas non plus encore au point...
C'est une version béta, fait a l'arrache et pas fini, mais bon...
Voici le code :
Code : Tout sélectionner
IncludeFile "bass.pbi"
IncludeFile "bass2.pbi"
IncludeFile "basswasapi.pbi"
;IncludeFile "bassmix.pbi"
IncludeFile "Wav_structure.pbi"
UsePNGImageDecoder()
Enumeration Gadgets
#Main
#Equalizer
#Wave
#ListDevices
#Frame_0
#Frame_1
#Frame_2
#Frame_3
#Mode
#Rec_dir
#parcourir
#StartStop
#Rec_StartStop
EndEnumeration
Enumeration EqualizerModes ;Modes pour l'égaliseur graphique
#Average ;Moyenne de valeurs de la plage de FFT
#Peaks ;Pics d'intensité du FFT uniquement
#LgstScaled ;Non fonctionnel. FFT pondéré par fonction logistique (bass cut)
#LogScaled ;Non fonctionnel. FFT pondéré par fonction logaritmique (idem, plus dur)
#DBScaled ;non fonctionnel. FFT exprimé en Décibels. Moins significatif mais plus proche du réel.
#LogScaledFrequency ;Fréquences suivant une échelle logaritmique, plus détaillé pour les basses. (D'aprés un code de Celtic)
EndEnumeration
Device.BASS_WASAPI_DEVICEINFO
CurrentDev.BASS_WASAPI_DEVICEINFO
Global Dim Spectre.f(1024), levels.l, Dim Wave.f(4000),Dim WaveBuf.f(1000),Dim TempWave.f(4000);,Dim Wave3.f(1000),Dim Wave4.f(1000)
Global FFT_Type = #LogScaledFrequency
Procedure ToastLogo(File.s,Time.l,Alpha.b=255)
Logo = LoadImage(#PB_Any,File)
Protected width,height,ElapsedTime,StartTime
width = ImageWidth(Logo)
height = ImageHeight(Logo)
toast = OpenWindow(#PB_Any ,0,0,width,height,"Lancement...",#PB_Window_ScreenCentered | #PB_Window_BorderLess | #PB_Window_Invisible)
ImageGadget(0,0,0,width,height,ImageID(Logo),#PB_Image_Raised)
;SetWindowsTransparency(WindowID(toast),1)
HideWindow(toast,#False)
For i=1 To Alpha
;SetWindowsTransparency(WindowID(toast),i)
Delay(5)
Next
StartTime=ElapsedMilliseconds()
Repeat
WaitWindowEvent(10)
ElapsedTime=ElapsedMilliseconds()-StartTime
Until ElapsedTime >=Time
For i=Alpha To 1 Step -5
;SetWindowsTransparency(WindowID(toast),i)
Delay(5)
Next
CloseWindow(toast)
FreeImage(Logo)
EndProcedure
Procedure.f GetScaledValue(RawValue.f,c.f,b.f=9.54e-4,a.f=17.7)
Protected ScaledValue.f,ScaleOffset.f
ScaledValue=Sqr(RawValue)* c *3-4
If ScaledValue > c
ScaledValue = c
EndIf
ProcedureReturn ScaledValue
EndProcedure
Macro VolumeBox(x,y,Width, Height, ScValue, Color, BkColor, bUseGradient=0, EndGradientColor=0)
Box(x,y,Width, Height, Color)
Box(x+1, y+1, Width-2, Height-2, BkColor)
For yval = y+(Height-1) To y+Height - (ScValue*(Height/100)) Step -2
LineXY(x+2,yval,x+(Width-3),yval,Color)
Next
EndMacro
Procedure LeftWord(value.l)
ProcedureReturn value & $FFFF
EndProcedure
Procedure RightWord(value.l)
ProcedureReturn value >> 16 & $FFFF
EndProcedure
Procedure WASAPI_Callback(*buffer, length.l, user.i)
;Calback
ProcedureReturn length
EndProcedure
Procedure Spectrum(param)
Protected.f val,average,topval,Llevel, Rlevel,y1,y2
Repeat
;Analyseur de spectre (equalizer) avec 16 barres (moyenne 64 valeurs)
StartDrawing(CanvasOutput(#Equalizer))
Box(0,0,600,400,RGB(0,20,0))
If FFT_Type = #Average ;Mode moyennes
For i=0 To 15
val=0
For k=(i*64)+2 To (i+1)*64
val = val + Spectre(k-1)
Next
average=(val/64)
VolumeBox(i*20+40,10,14,100,GetScaledValue(average,100),RGB(0,200,0),RGB(0,30,0))
Next
ElseIf FFT_Type = #Peaks ;Mode pics d'impulsion
For i=0 To 15
val=0
For k=(i*64)+1 To (i+1)*64
If Spectre(k-1) > val
val=Spectre(k-1)
EndIf
If val > topval
;Debug val
topval = val;TopVal : 1 echelle logistique f(x)=c/1+a*e^-bx Valeurs calculées par régression : a=17.707 ; b=9.57.10^-4 ; c=100. c : valeur palier, d(x) (dérivée moy sur pente ascendante) = (b/4)*c.
EndIf
If i=0
val=val/2
EndIf
Next
VolumeBox(i*20+40,10,14,100,GetScaledValue(val,100),RGB(0,200,0),RGB(0,30,0))
Next
ElseIf FFT_Type = #LogScaledFrequency; Mode echelle logaritmique (d'aprés code de Celtic)
Protected y.l,b0.l,x.l,peak.f,b1.l
peak=0
b0=0
b1=0
For x=0 To 15
peak = 0
b1 = Pow(2,x * 10.0 / 15)
If (b1 <= b0): b1 = b0 + 1:EndIf
If (b1 > 1023) :b1 = 1023:EndIf
For b0=b0 To b1-1
If (peak < Spectre(b0))
peak = Spectre(b0)
EndIf
Next
VolumeBox(x*20+40,10,14,100,GetScaledValue(peak,100),RGB(0,200,0),RGB(0,30,0))
Next
EndIf
Llevel=LeftWord(levels)
Rlevel=RightWord(levels)
;Debug Llevel
;Debug (Llevel/32768)*100
VolumeBox(10,10,20,130,((Llevel/32768)*100),RGB(0,200,0),RGB(0,30,0))
VolumeBox(370,10,20,130,((Rlevel/32768)*100),RGB(0,200,0),RGB(0,30,0))
StopDrawing()
StartDrawing(CanvasOutput(#Wave))
Box(0,0,400,150,RGB(0,30,0))
ratio=400/1024
;y2=0
For i=0 To 400 Step 1
y1=Wave(i*4)*75
LineXY((i-2),y2+75,i,y1+75,RGB(0,200,0))
y2=y1
Next
StopDrawing()
Delay(25)
ForEver
EndProcedure
;-Code principal
ToastLogo("SoundSenseLogo2.png",2000,200)
OpenWindow(#Main, 0, 0, 440, 470, "SoundSense 1.0", #PB_Window_SystemMenu | #PB_Window_MinimizeGadget | #PB_Window_ScreenCentered)
CanvasGadget(#Equalizer, 20, 20, 400, 150, #PB_Canvas_Border)
CanvasGadget(#Wave, 20, 180, 400, 150, #PB_Canvas_Border)
ComboBoxGadget(#ListDevices, 20, 370, 180, 25)
FrameGadget(#Frame_0, 10, 0, 420, 340, "Visualisations")
FrameGadget(#Frame_1, 10, 350, 200, 50, "Entrée son")
FrameGadget(#Frame_2, 220, 350, 210, 50, "Modes de visualisation")
FrameGadget(#Frame_3, 130, 410, 300, 50, "Enregistrement")
ComboBoxGadget(#Mode, 230, 370, 190, 25)
StringGadget(#Rec_dir, 180, 430, 200, 25, "")
GadgetToolTip(#Rec_dir, "Emplacement de l'enregistrement")
ButtonGadget(#parcourir, 390, 430, 30, 25, "...")
GadgetToolTip(#parcourir, "Parcourir")
ButtonGadget(#StartStop, 15, 420, 100, 30, "Démarrer", #PB_Button_Toggle)
GadgetToolTip(#StartStop, "Lancer/arrêter les mesures.")
ButtonImageGadget(#Rec_StartStop, 140, 430, 30, 25, 0,#PB_Button_Toggle)
AddGadgetItem(#Mode,-1,"Moyennes de fréquences")
AddGadgetItem(#Mode,-1,"Valeurs de crête")
AddGadgetItem(#Mode,-1,"Echelle de fréquences logaritmique")
AddWindowTimer(0,1,20)
DefaultDevice = -1 ;En l'absence de micro, le systéme par défaut est sélectionné
i=0
Debug "Devices :"
While BASS_WASAPI_GetDeviceInfo(i,@Device)
If Device\flags&#BASS_DEVICE_ENABLED And Device\flags&#BASS_DEVICE_INPUT
Name$ = PeekS(Device\name,-1,#PB_Ascii)
Debug "["+Str(i)+"] "+Name$
AddGadgetItem(#ListDevices,-1,Name$)
SetGadgetItemData(#ListDevices,CountGadgetItems(#ListDevices)-1,i)
If Device\type = #BASS_DEVICE_TYPE_MICROPHONE;Sélectionne automatiquement le premier micro détecté.
DefaultDevice = i
EndIf
EndIf
i+1
Wend
recordState = 0
BASS_SetConfig(#BASS_CONFIG_UPDATETHREADS, 0)
BASS_Init(0,44100,0,0,0)
For i=0 To CountGadgetItems(#ListDevices)-1
Dev = GetGadgetItemData(#ListDevices,i)
BASS_WASAPI_Init(Dev,44100,0,#BASS_WASAPI_BUFFER | #BASS_WASAPI_AUTOFORMAT,1,0.1,@WASAPI_Callback(),0)
Debug BASS_ErrorGetCode()
Debug "Device initialized : "+Str(Dev)
Next
Debug BASS_WASAPI_GetDevice()
CreateThread(@Spectrum(),1)
Repeat
event=WaitWindowEvent()
Select event
Case #PB_Event_Timer
If EventTimer() = 1
BASS_WASAPI_GetData(Spectre(),#BASS_DATA_FFT2048);| #BASS_DATA_FFT_NOWINDOW | #BASS_DATA_FFT_REMOVEDC)
levels=BASS_WASAPI_GetLevel()
availdata=BASS_WASAPI_GetData(Wave(),#BASS_DATA_AVAILABLE)
BASS_WASAPI_GetData(Wave(),8000 | #BASS_DATA_FLOAT);Seules 2000 données seront retournées
EndIf
Case #PB_Event_Gadget
Select EventGadget()
Case #StartStop
If recordState = 0
BASS_WASAPI_Start()
SetGadgetText(#StartStop,"Arrêter")
recordState=1
Else
BASS_WASAPI_Stop(0)
SetGadgetText(#StartStop,"Démarrer")
recordState=0
EndIf
Case #ListDevices
DeviceID = GetGadgetItemData(#ListDevices,GetGadgetState(#ListDevices))
Debug DeviceID
BASS_WASAPI_SetDevice(DeviceID)
BASS_ErrorGetCode()
If BASS_WASAPI_GetDevice()
BASS_WASAPI_GetDeviceInfo(BASS_WASAPI_GetDevice(),@CurrentDev)
; Debug PeekS(CurrentDev\name,-1,#PB_Ascii) + "["+Str(DeviceID)+"]"
Debug CurrentDev\id
Else
Debug "No device"
EndIf
Case #Mode
Select GetGadgetState(#Mode)
Case 0
FFT_Type = #Average
Case 1
FFT_Type = #Peaks
Case 2
FFT_Type = #LogScaledFrequency
EndSelect
EndSelect
EndSelect
StopDrawing()
Until event = #PB_Event_CloseWindow
BASS_Free()
Voila c'est tout pour l'instant