On sait jamais, ca pourra toujours servir a quelqun...
Ce code permet (d'ouvrir une musique, mais ca on s'y attend) puis d'afficher en temps réel au choix soit la sinusoïde (l'onde sonore (wave)) ou le spectre (analyse des fréquences présentes).
Promenez la souris dans le bas de l'oscilloscope pour faire apparaitre une barre de menu avec des zolis boutons :
Vous avez un bouton "ouvrir", pour ouvrir, un bouton "pause" pour mettre en pause une trackbar pour le volume et un bouton qui permet de switcher entre la fréquence et l’amplitude (sinusoide).
Enfin, il y a deux indicateurs de niveau sonore, l'un dans l'oscillo, le deuxiéme dans une stickywindow pas trés loin. En glissant cette fenêtre sur l'autre barre de niveau sonore, vous la faites disparaitre.
Une classique barre de lecture vous permet de sauter a la position désirée du morceau en lecture d'un clic
J'ait fait ca pour m'habituer a Fmod (truc absolument génial d'ailleurs), en reprenant des codes de Falsam trouvés sur ce forum et en les modifiant un peu... Au passage, merci de tous tes exemples d'utilisation de FMOD, Falsam, ca m'est trés utile tout ca!
Je vous met le code, et en dessous un zip qui contient l'include de Fmod et ses DLLs, de même que les 3 images que j'ait intégrées.
Code : Tout sélectionner
;##Oscilloscope## - Lecture d'une musique et affichage de son spectre/de l'onde sonore - Codes de Falsam, modifiés (un peu) par moi pour l'occasion. -- JohnJohnsonSHERMAN
EnableExplicit
IncludeFile "fmodex(short).pbi"
Enumeration
#Mainform
#Frame3D_0
#File
#OpenFile
#Play
#Pause
#Stop
#Volume
#Spectrum
#Wave
#Switch
EndEnumeration
Define.l Event, GEvent, TiEvent
Define y,state,hThreadSpectrum,hThreadWave,i
Global WindowStyle.i=#PB_Window_SystemMenu|#PB_Window_ScreenCentered
Global fmodsystem.i, Channel.i, Sound.i, Volume.f = 0.5, PauseStatus.b,Analyse,Mutex
Global File.s
Analyse = 0 ;O= Wave (amplitude), 1= Spectre (fréquences)
UsePNGImageDecoder()
LoadImage(0,"OscilloToSpectrum.png")
LoadImage(1,"OscilloToWave.png")
LoadImage(2,"OscilloInTransition.png")
For i =0 To 2
ResizeImage(i,70,70)
Next
Procedure ShowSpectrum(param)
Repeat
Protected Dim SpectrumArray.f(1024), i.i, j.i, Max, Position.i,Yspect,YlowSpec
FMOD_Channel_GetSpectrum(Channel, SpectrumArray(), 1024, 0, #FMOD_DSP_FFT_WINDOW_BLACKMANHARRIS)
LockMutex(Mutex)
If Analyse=0
UnlockMutex(Mutex)
While Analyse = 0
Delay(100)
Wend
EndIf
StartDrawing(CanvasOutput(#Wave))
;Clear de l'histogramme
Box(0, 0, 1260, 500, RGB(0,30,0))
;Cadre autour de l'histogramme
DrawingMode(#PB_2DDrawing_Outlined)
Box(0, 0, 1260, 500, RGB(0, 200, 0))
;Dessin des points
DrawingMode(#PB_2DDrawing_Default)
For i=1 To 1024 Step 2
YlowSpec=(SpectrumArray(i)*1000)
Yspect=250-YlowSpec
LineXY(i+1,250,i+1,YlowSpec+250,RGB(0,150,20))
LineXY(i+1,Yspect,i+1,251,RGB(0,200,50))
If Yspect < 99 And Yspect > 1
; Plot(i+1,Yspect,RGB(0,90,0))
EndIf
Next
StopDrawing()
Delay(25)
UnlockMutex(Mutex)
ForEver
EndProcedure
Procedure ShowWaveAmp(param)
Repeat
Protected Dim WaveArray.f(1024), i.i, j.i, Max, Position.i,YCurrentWave,YOldWave
FMOD_Channel_GetWaveData(Channel, WaveArray(), 1024, 0)
LockMutex(Mutex)
If Analyse=1
UnlockMutex(Mutex)
While Analyse = 1
Delay(100)
Wend
EndIf
StartDrawing(CanvasOutput(#Wave))
;Clear de l'histogramme
Box(0, 0, 1026, 500, RGB(0,30,0))
;Cadre autour de l'histogramme
DrawingMode(#PB_2DDrawing_Outlined)
Box(0, 0, 1026, 500, RGB(0, 200, 0))
;Dessin des points
DrawingMode(#PB_2DDrawing_Default)
For i=1 To 1024
YOldWave=(WaveArray(i-1)+1)*250
YCurrentWave=(WaveArray(i)+1)*250
LineXY(i-1,YOldWave,i,YCurrentWave,RGB(0,200,50))
LineXY(i-1,YOldWave+1,i,YCurrentWave+1,RGB(0,90,50))
LineXY(i-1,YOldWave-1,i,YCurrentWave-1,RGB(0,110,50))
Next
StopDrawing()
Delay(25)
UnlockMutex(Mutex)
Debug "Déverrouillage du mutex, thread : Wave"
ForEver
Debug "#######################################################"
EndProcedure
Enumeration FormFont
#Font_Mainform_0
EndEnumeration
LoadFont(#Font_Mainform_0,"Arial", 16)
Procedure OpenMainform(x = 0, y = 0, width = 1024, height = 500)
OpenWindow(#Mainform, x, y, width, height, "Oscilloscope", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)
CanvasGadget(#Wave, 0, 0, 1024, 500)
ButtonGadget(#OpenFile, 20, 510, 80, 25, "Ouvrir")
TextGadget(#File,110,510,200,25,"Aucun fichier ouvert.")
ButtonGadget(#Pause, 420, 510, 70, 40, "Pause")
SetGadgetFont(#Pause, FontID(#Font_Mainform_0))
ButtonImageGadget(#Switch,500,510,60,60,ImageID(0))
SetGadgetAttribute(#Switch,#PB_Button_PressedImage,ImageID(2))
TrackBarGadget(#Volume, 750, 520, 260, 25, 0, 100)
SetGadgetState(#Volume, 50)
FrameGadget(#Frame3D_0, 740, 500, 280, 50, "Volume")
AddWindowTimer(#MainForm,1,25)
AddWindowTimer(#MainForm,2,2500)
EndProcedure
OpenMainform()
FMOD_System_Create(@fmodsystem)
FMOD_System_Init(fmodsystem, 32, #FMOD_INIT_NORMAL, 0)
Mutex=CreateMutex()
hThreadSpectrum=CreateThread(@ShowSpectrum(),1)
hThreadWave=CreateThread(@ShowWaveAmp(),1)
Repeat
Event = WaitWindowEvent(100)
GEvent = EventGadget()
Select Event
Case #PB_Event_Timer
Select EventTimer()
Case 1
If WindowMouseY(#Mainform) > 450 And state=0
For y=0 To 60 Step 3
ResizeWindow(#Mainform,#PB_Ignore,#PB_Ignore,#PB_Ignore,500+y)
WindowEvent()
Delay(10)
Next
state=1
EndIf
Case 2
If WindowMouseY(#Mainform) < 450 And state=1
For y=60 To 0 Step -3
ResizeWindow(#Mainform,#PB_Ignore,#PB_Ignore,#PB_Ignore,500+y)
WindowEvent()
Delay(10)
Next
state=0
EndIf
EndSelect
Case #PB_Event_Gadget
Select GEvent
Case #OpenFile
File = OpenFileRequester("Sélectionner un fichier mp3","","Musique|*.mp3;*.wav;*.ogg;*.flac",0)
If File <> ""
SetGadgetText(#File, GetFilePart(File))
If Sound <> 0
FMOD_Sound_Release(Sound)
EndIf
FMOD_System_CreateStream(fmodsystem, @File, #FMOD_SOFTWARE, 0, @sound)
FMOD_Channel_SetLoopCount(Channel,-1)
FMOD_System_PlaySound(fmodsystem, #FMOD_CHANNEL_FREE, sound, 0, @channel)
FMOD_Channel_SetVolume(Channel, Volume)
EndIf
Case #Volume
Volume = GetGadgetState(#Volume)/100
FMOD_Channel_SetVolume(Channel, Volume)
Case #Pause
FMOD_Channel_GetPaused(Channel, @PauseStatus)
If PauseStatus = #False
FMOD_Channel_SetPaused(Channel, #True)
SetGadgetText(#Pause, "Play")
Else
FMOD_Channel_SetPaused(Channel, #False)
SetGadgetText(#Pause, "Pause")
EndIf
Case #Stop
FMOD_Channel_Stop(Channel)
Case #Switch
If Analyse=0
SetGadgetAttribute(#Switch,#PB_Button_Image,ImageID(1))
Analyse=1
Else
SetGadgetAttribute(#Switch,#PB_Button_Image,ImageID(0))
Analyse=0
EndIf
EndSelect
Case #PB_Event_CloseWindow
FMOD_Channel_Stop(Channel)
FMOD_System_Release(fmodsystem)
End
EndSelect
ForEver
Le zip : c'est ici (tout est dedans... les dll, les codes, les images et l'Exe)