Code : Tout sélectionner
;http://purebasic.fr/english/viewtopic.php?p=409247#p409247
IncludeFile"MeterGadget.pbi"
EnableExplicit
#Title = "Line_In_Monitor"
#MainWin = 0
#MainMenu = 0
Enumeration ;menu items
#MenuItemExit = 0
#Mono = 1
#Stereo = 2
EndEnumeration
Enumeration ; gadgets
#Meter_Left
#Meter_Right
#ChkBox_L
#ChkBox_R
EndEnumeration
Global hWindow, threadID, threadID2, audioSemaphore, meterSemaphore
Global wpa.l, lpa.l
Global lBuf, nDev, size, nBuf = 8
Global *buffer, *wave, *audioBuffer = AllocateMemory(32768)
Global format.WAVEFORMATEX
Global Dim inHdr.WAVEHDR(nBuf - 1)
Procedure Verify(result, text.s)
If result = 0
MessageRequester("Fatal Error!", "Unable to execute --> " + text)
End
EndIf
ProcedureReturn result
EndProcedure
Procedure GUI_CALLBACK(hWnd.l, Msg.l, wParam.l, lParam.l)
If Msg = #MM_WIM_DATA
wpa = wParam
lpa = lParam
SignalSemaphore(audioSemaphore) ; trigger for AUDIO_LOOP()
EndIf
ProcedureReturn #PB_ProcessPureBasicEvents
EndProcedure
Procedure INIT_GUI()
Protected WinWidth = 540
Protected WinHeight = 220 + MenuHeight()
Protected Flags = #PB_Window_ScreenCentered | #PB_Window_SystemMenu | #PB_Window_MinimizeGadget
hWindow = Verify(OpenWindow(#MainWin, 0, 0, WinWidth, WinHeight, #Title, Flags), "OpenWindow")
Verify(CreateMenu(#MainMenu, WindowID(#MainWin)), "CreateMenu")
MenuTitle("File")
MenuItem(#MenuItemExit, "Exit")
MenuTitle("Config")
MenuItem(#Mono, "Mono")
MenuItem(#stereo, "Stereo")
SetMenuItemState(#MainMenu, #Stereo, #True)
Flags = #MTR_STYLE_VU | #MTR_STYLE_LED
Verify(MeterGadget(#Meter_Left, 10, 10, 250, "Left", Flags), "MeterGadget")
Verify(MeterGadget(#Meter_Right, 280, 10, 250, "Right", Flags), "MeterGadget")
CheckBoxGadget(#ChkBox_L, 010, 185, 120, 25, "Enable Smoothing")
CheckBoxGadget(#ChkBox_R, 280, 185, 120, 25, "Enable Smoothing")
SetWindowCallback(@GUI_CALLBACK())
EndProcedure
Procedure INIT_CAPTURE()
Protected i, lBufopt.f, refreshTime.i, result
If IsThread(threadID) <> 0 : PauseThread(threadID) : EndIf
refreshTime = 85 ; approximate meter refresh rate in milliseconds
With format
\nChannels = GetMenuItemState(#MainMenu, #Stereo) + 1
\nSamplesPerSec = 11025
\wFormatTag = #WAVE_FORMAT_PCM
\wBitsPerSample = 16
\cbSize = 0
\nBlockAlign = (\nChannels * \wBitsPerSample) / 8
\nAvgBytesPerSec = \nSamplesPerSec * \nBlockAlign
; calculate optimum buffer size using approximate refreshTime
lBufopt = 2 * \nSamplesPerSec * (refreshTime / 1000) * \nChannels
; actual buffer size must be a power of 2
; this calculates the next larger power of 2 from lBufopt
lBuf = Pow(2, Int(Log(lBufopt) / Log(2)) + 1)
EndWith
If #MMSYSERR_NOERROR = waveInOpen_(@*wave,#WAVE_MAPPER,@format,hWindow,#Null,#CALLBACK_WINDOW|#WAVE_FORMAT_DIRECT)
For i = 0 To nBuf - 1
inHdr(i)\lpData = AllocateMemory(lBuf)
inHdr(i)\dwBufferLength = lBuf
waveInPrepareHeader_(*wave, inHdr(i), SizeOf(WAVEHDR))
waveInAddBuffer_(*wave, inHdr(i), SizeOf(WAVEHDR))
Next
If waveInStart_(*wave) : Verify(#False, "waveInStart") : EndIf
EndIf
If IsThread(threadID) <> 0 : ResumeThread(threadID) : EndIf
EndProcedure
Procedure CAPTURE_STOP()
Protected i
If *wave
waveInReset_(*wave)
waveInStop_(*wave)
For i = 0 To nBuf - 1
If inHdr(i)\lpData
waveInUnprepareHeader_(*wave,inHdr(i),SizeOf(WAVEHDR))
FreeMemory(inHdr(i)\lpData)
inHdr(i)\lpData = 0
EndIf
Next
waveInClose_(*wave)
EndIf
EndProcedure
Procedure EVENT_LOOP()
Protected Quit = #False
Repeat
Select WaitWindowEvent()
Case #PB_Event_CloseWindow
Quit = #True
Case #PB_Event_Menu
Select EventMenu()
Case #MenuItemExit : Quit = #True
Case #Mono
SetMenuItemState(#MainMenu, #Mono, #True)
SetMenuItemState(#MainMenu, #Stereo, #False)
CAPTURE_STOP() : INIT_CAPTURE()
Case #Stereo
SetMenuItemState(#MainMenu, #Mono, #False)
SetMenuItemState(#MainMenu, #Stereo, #True)
CAPTURE_STOP() : INIT_CAPTURE()
EndSelect
Case #PB_Event_Gadget
Select EventGadget()
Case #ChkBox_L
If GetGadgetState(#ChkBox_L) : SetMeterSmoothing(#Meter_Left, 8)
Else : SetMeterSmoothing(#Meter_Left, 0)
EndIf
Case #ChkBox_R
If GetGadgetState(#ChkBox_R) : SetMeterSmoothing(#Meter_Right, 8)
Else : SetMeterSmoothing(#Meter_Right, 0)
EndIf
EndSelect
EndSelect
Until Quit = #True
EndProcedure
Procedure METER_REFRESH()
Protected maxL, maxR, ch, i, amp, inc, limit, value.w
inc = format\nChannels * 2
limit = lBuf - inc
maxL = 0 : maxR = 0 : i = 0
For ch = 1 To format\nChannels
Repeat
value = PeekW(*audioBuffer + i)
If value < 0 : value = -value : EndIf
If value > maxR : maxR = value : EndIf
i + inc
Until i > limit
If ch = 1 : Swap maxL, maxR : EndIf
i = 2
limit + 2
Next ch
maxL * 100 / 32767 + 1
maxR * 100 / 32767 + 1
SetMeterState(#Meter_Left, maxL)
SetMeterState(#Meter_Right, maxR)
EndProcedure
Procedure AUDIO_LOOP(null)
Protected *hWave.WAVEHDR
Repeat
WaitSemaphore(audioSemaphore)
*hWave = lpa
*buffer = *hWave\lpData
size = *hWave\dwBytesRecorded
waveInAddBuffer_(wpa, *hWave, SizeOf(WAVEHDR))
If *buffer <> 0
CopyMemory(*buffer, *audioBuffer, size)
EndIf
METER_REFRESH()
ForEver
EndProcedure
audioSemaphore = CreateSemaphore(0)
threadID = CreateThread(@AUDIO_LOOP(), #Null) ; THREAD TO HANDLE CALLBACK
INIT_GUI()
INIT_CAPTURE()
EVENT_LOOP()
End
si sa peu être dans un Thread le init et la lecture avec un Sémaphore pour evité que je me retrouve avec du data qui bouge pendant que je tape l'incruste dans la memoir