Oscilloscope

Applications, Games, Tools, User libs and useful stuff coded in PureBasic
User avatar
BasicallyPure
Enthusiast
Enthusiast
Posts: 536
Joined: Thu Mar 24, 2011 12:40 am
Location: Iowa, USA

Re: Oscilloscope

Post by BasicallyPure »

Audio generator with square wave option.

Code: Select all

; AudioGenerator.pb
; by BasicallyPure
; 08.17.2015
; windows only
; PB 5.31

EnableExplicit

;{ Constants
#MainWin = 0
#OutDevice_1 = 0
#PIx2 = 2*#PI
#Mono = 1
#Stereo = 2
#ScopeBkgndColor = $276724
#LeftColor  = $27CF24
#RighttColor = $27E4D3
#SpinLostFocus = 512
#Input_Finished = #PB_EventType_FirstCustomValue

; gadgets
#BtnHop     = 0
#BtnPause   = 1
#SpinLeft   = 2
#SpinRight  = 3
#TrackLeft  = 4
#TrackRight = 5
#Rsquare    = 6
#Lsquare    = 7

; menus
#Menu_1 = 0
;}

;{ Procedure declarations
Declare WinCallback(hwnd, uMsg, wParam, lParam)
Declare StartSoundOutput()
Declare StopSoundOutput()
Declare MAKE_WAVE(*SBuf)
Declare Init_GUI()
Declare EventLoop()
Declare ProcessSpin(nGad,*Freq)
;}

;{ Global variables
Global SampleClock     = 44100   ; Sampling frequency in 'samples per second'
Global BlockSize       = 8192    ; Number of samples in block
Global BytesPerSample  = 2       ; Number of bytes needed for each sample, don't change this
Global Channels        = #Stereo ; Number of channels, 1 for mono, 2 for stereo.
Global nBuf            = 8       ; Number of buffers
Global DevOut          = 1       ; default audio output device
Global Frequency_Left  = 1000
Global Frequency_Right = 440
Global Volume_Left.f   = 0.25 * 32767
Global Volume_Right.f  = 0.25 * 32767
Global hWaveOut
Global Hop     = #False
Global Pause   = #False
Global Lsquare = #False
Global Rsquare = #False
Global NumOutDevs

Global PlayFormat.WAVEFORMATEX
Global MyOutDevs.WAVEOUTCAPS
Global Dim outHdr.WAVEHDR(nBuf)
;}

If Init_GUI()
   EventLoop()
   StopSoundOutput()
EndIf

End

Procedure Init_GUI()
   Protected n, result = 1
   
   If OpenWindow(#MainWin,0,0,350,120,"Audio generator",#PB_Window_SystemMenu |#PB_Window_ScreenCentered)
      
      ButtonGadget(#BtnHop,10,10,50,25,"Hop",#PB_Button_Toggle)
      ButtonGadget(#BtnPause,70,10,50,25,"Pause",#PB_Button_Toggle)
      SpinGadget(#SpinLeft,130,02,70,25,100,5000)
         SetGadgetState(#SpinLeft,Frequency_Left) : SetGadgetText(#SpinLeft,Str(Frequency_Left))
         SetGadgetColor(#SpinLeft,#PB_Gadget_BackColor,#LeftColor)
      SpinGadget(#SpinRight,235,02,70,25,100,5000)
         SetGadgetState(#SpinRight,Frequency_Right) : SetGadgetText(#SpinRight,Str(Frequency_Right))
         SetGadgetColor(#SpinRight,#PB_Gadget_BackColor,#RighttColor)
      TrackBarGadget(#TrackLeft,125,30,100,25,0,100) : SetGadgetState(#TrackLeft,Volume_Left / 327.67)
      TrackBarGadget(#TrackRight,230,30,100,25,0,100) : SetGadgetState(#TrackRight,Volume_Right /327.67)
      CheckBoxGadget(#Lsquare,135,60,100,25,"L square")
      CheckBoxGadget(#Rsquare,240,60,100,25,"R square")
      CreateMenu(#Menu_1, WindowID(#MainWin))
      
      ; locate all sound output devices
         OpenSubMenu("Sound Output Devices")
         NumOutDevs = waveOutGetNumDevs_()
         If NumOutDevs <> 0
            For n = 0 To NumOutDevs - 1
               If waveOutGetDevCaps_(n,@MyOutDevs,SizeOf(WAVEOUTCAPS)) = 0
                     MenuItem(n + #OutDevice_1,PeekS(@MyOutDevs\szPname))
               EndIf
            Next
            CloseSubMenu()
            SetMenuItemState(#Menu_1,#OutDevice_1,#True)
            SetWindowCallback(@WinCallback()) ; Handle Sound Output callback
            StartSoundOutput()
         Else
            MessageRequester("Error!","No audio output device found.")
            result = 0
         EndIf
   Else
      result = 0
   EndIf
   
   ProcedureReturn result
EndProcedure

Procedure EventLoop()
   Protected menuSelection, ActiveGadget, n, Quit = #False
   
   Repeat
      Select WaitWindowEvent()
         Case #PB_Event_CloseWindow
            Quit = #True
         Case #PB_Event_Gadget
            Select EventGadget()
               Case #BtnHop
                  Hop = GetGadgetState(#BtnHop)
                  Frequency_Left = GetGadgetState(#SpinLeft)
                  Frequency_Right = GetGadgetState(#SpinRight)
               Case #BtnPause
                  Pause = GetGadgetState(#BtnPause)
                  If Pause
                     waveOutPause_(hWaveOut)
                  Else
                     waveOutRestart_(hWaveOut)
                  EndIf
               Case #SpinLeft   : ProcessSpin(#SpinLeft, @Frequency_Left)
               Case #SpinRight  : ProcessSpin(#SpinRight, @Frequency_Right)
               Case #TrackLeft  : Volume_Left = GetGadgetState(#TrackLeft) * 327.67
               Case #TrackRight : Volume_Right = GetGadgetState(#TrackRight) * 327.67
               Case #Rsquare    : Rsquare = GetGadgetState(#Rsquare)
               Case #Lsquare    : Lsquare = GetGadgetState(#Lsquare)
            EndSelect
         Case #PB_Event_Menu
            menuSelection = EventMenu()
            If GetMenuItemState(#Menu_1,menuSelection) = #False
               Select menuSelection
                  Case #OutDevice_1 To #OutDevice_1 + NumOutDevs - 1 ; Output device selection
                     For n = #OutDevice_1 To #OutDevice_1 + NumOutDevs - 1
                        If n = menuSelection
                           SetMenuItemState(#Menu_1,menuSelection,#True)
                        Else
                           SetMenuItemState(#Menu_1,n,#False)
                        EndIf
                     Next
                     DevOut = menuSelection - #OutDevice_1 + 1
                     StopSoundOutput()
                     StartSoundOutput()
               EndSelect
            EndIf
         Case #WM_KEYUP
            ActiveGadget = GetActiveGadget()
            Select ActiveGadget
               Case #SpinLeft To #SpinRight
                  If EventwParam() = #VK_RETURN
                     PostEvent(#PB_Event_Gadget,#MainWin,ActiveGadget,#Input_Finished)
                  EndIf
            EndSelect
      EndSelect
   Until Quit = #True
   
EndProcedure

Procedure WinCallback(hwnd, uMsg, wParam, lParam)
   ; Window callback to service sound output message
   Static *hWaveO.WAVEHDR
   
   Select uMsg
      Case #MM_WOM_DONE           ; Sound output, a play buffer has been returned.
         *hWaveO.WAVEHDR = lParam                        ; lParam has the address of WAVEHDR
         MAKE_WAVE(*hWaveO\lpData)                       ; send pointer where to write NEW data
         *hWaveO\dwBytesRecorded = BlockSize             ; Number of bytes written into buffer
         waveOutWrite_(hWaveOut,lParam, SizeOf(WAVEHDR)) ; Send to sound device => jack socket => cable =>
   EndSelect
   
   ProcedureReturn #PB_ProcessPureBasicEvents
EndProcedure

Procedure StartSoundOutput()
   Protected T,i, *P
   Static *OutBufMem
   
   With PlayFormat
      \wFormatTag      = #WAVE_FORMAT_PCM
      \nChannels       = Channels
      \wBitsPerSample  = BytesPerSample * 8
      \nSamplesPerSec  = SampleClock
      \nBlockAlign     = Channels * BytesPerSample
      \nAvgBytesPerSec = \nSamplesPerSec * \nBlockAlign
   EndWith
   
   If *OutBufMem : FreeMemory(*OutBufMem) : EndIf   ; Free a prior assignement
   *OutBufMem = AllocateMemory(BlockSize * nBuf)    ; Reserve memory for all the buffers
   
   T =  waveOutOpen_(@hWaveOut, #WAVE_MAPPER+DevOut, @PlayFormat, WindowID(#MainWin), #True, #CALLBACK_WINDOW | #WAVE_FORMAT_DIRECT)
   If T = #MMSYSERR_NOERROR
      
      *P = *OutBufMem                               ; Pointer to start of memory
      For i = 0 To nBuf-1                           ; For each buffer
         outHdr(i)\lpData         = *P              ; start of buffer
         outHdr(i)\dwBufferLength = BlockSize       ; size of buffer
         outHdr(i)\dwFlags        = 0
         outHdr(i)\dwLoops        = 0
         T | waveOutPrepareHeader_(hWaveOut, outHdr(i), SizeOf(WAVEHDR))
         *P + BlockSize
      Next
      
      For i = 0 To nBuf-1
         PostMessage_(WindowID(#MainWin),#MM_WOM_DONE,0,outHdr(i))
      Next 
      
   EndIf
   
   If T = #MMSYSERR_NOERROR : ProcedureReturn 1 : Else : ProcedureReturn 0 : EndIf
   
EndProcedure

Procedure StopSoundOutput()
   Protected i
   waveOutReset_(hWaveOut)
   For i = 0 To nBuf - 1
      waveOutUnprepareHeader_(hWaveOut, outHdr(i), SizeOf(WAVEHDR))
   Next
   waveOutClose_(hWaveOut)
EndProcedure

Procedure MAKE_WAVE(*SBuf)
   ; This routine generates Left and Right waveforms.
   
   Static.d Angle, Kl, Kr, La, Ra
   Static.i sample
   Static.l Vl, Vr
   
   If Hop
      Frequency_Left = Random(1220,220)
      Frequency_Right = Random(1220,220)
   EndIf
   
   ; Calculate the frequency scaling factors
   Kl = #PIx2 * Frequency_Left  / SampleClock
   Kr = #PIx2 * Frequency_Right / SampleClock
   
   sample = 1
   Repeat ; Generate waveform data
      ; Left sample
      If Lsquare
         Vl = Sign(#PI-La) * Volume_Left
      Else
         Vl = Sin(La) * Volume_Left
      EndIf
      
      La + Kl                            ; calculate angle for next time
      If La > #PIx2 : La - #PIx2 : EndIf ; limit to 2*PI radians
      PokeW(*SBuf,Vl)                    ; Put point in buffer
      *SBuf + BytesPerSample             ; move buffer pointer to next sample
      
      ; Right sample
      If Rsquare
         Vr = Sign(#PI-Ra) * Volume_Right
      Else
         Vr = Sin(Ra) * Volume_Right
      EndIf
      
      Ra + Kr
      If Ra > #PIx2 : Ra - #PIx2 : EndIf
      PokeW(*SBuf,Vr)
      *SBuf + BytesPerSample
      
      sample + PlayFormat\nBlockAlign
   Until sample > BlockSize
   
EndProcedure

Procedure ProcessSpin(nGad,*Freq)
   Select EventType()
      Case #PB_EventType_Up, #PB_EventType_Down
         SetGadgetText(nGad, Str(GetGadgetState(nGad)))
         PokeI(*Freq, GetGadgetState(nGad))
      Case #Input_Finished, #SpinLostFocus
         SetGadgetState(nGad,Val(GetGadgetText(nGad)))
         SetGadgetText(nGad, Str(GetGadgetState(nGad)))
         PokeI(*Freq, GetGadgetState(nGad))
   EndSelect
EndProcedure
BasicallyPure
Until you know everything you know nothing, all you have is what you believe.
Simo_na
Enthusiast
Enthusiast
Posts: 177
Joined: Sun Mar 03, 2013 9:01 am

Re: Oscilloscope

Post by Simo_na »

BasicallyPure wrote:Audio generator with square wave option.
Thank you

If I change this:

Code: Select all

Global Channels        = #Stereo ; Number of channels, 1 for mono, 2 for stereo.
in this:

Code: Select all

Global Channels        = #Mono   ; Number of channels, 1 for mono, 2 for stereo.
i get :
[08:48:26] [ERROR] Invalid memory access. (write error at address 93396992)
in this line

Code: Select all

PokeW(*SBuf,Vl) 
:)

PS
but how I might do for creation of a squarewave with 20% duty cycle ??
User avatar
BasicallyPure
Enthusiast
Enthusiast
Posts: 536
Joined: Thu Mar 24, 2011 12:40 am
Location: Iowa, USA

Re: Oscilloscope

Post by BasicallyPure »

Simo_na wrote:i get :
[08:48:26] [ERROR] Invalid memory access. (write error at address 93396992)
Fixed.
Simo_na wrote:but how I might do for creation of a squarewave with 20% duty cycle ??
Done.
I have added a new global variable 'DutyCycle".
The value of DutyCycle is a function of #PI and is calculated by multiplying #PI by a certain value.
The multiplier is calculated as 0.02 * DesiredDutyCycle.
If your desired duty cycle is 20% then the multiplier becomes 0.02 * 20 or 0.4
The variable 'DutyCycle' then becomes DutyCycle = #PI * 0.4

Code: Select all

; AudioGenerator.pb
; by BasicallyPure
; 08.17.2015
; windows only
; PB 5.31

EnableExplicit

;{ Constants
#MainWin = 0
#OutDevice_1 = 0
#PIx2 = 2*#PI
#Mono = 1
#Stereo = 2
#LeftColor  = $27CF24
#RighttColor = $27E4D3
#SpinLostFocus = 512
#Input_Finished = #PB_EventType_FirstCustomValue

; gadgets
#BtnHop     = 0
#BtnPause   = 1
#SpinLeft   = 2
#SpinRight  = 3
#TrackLeft  = 4
#TrackRight = 5
#Rsquare    = 6
#Lsquare    = 7

; menus
#Menu_1 = 0
;}

;{ Procedure declarations
Declare WinCallback(hwnd, uMsg, wParam, lParam)
Declare StartSoundOutput()
Declare StopSoundOutput()
Declare MAKE_WAVE(*SBuf)
Declare Init_GUI()
Declare EventLoop()
Declare ProcessSpin(nGad,*Freq)
;}

;{ Global variables
Global SampleClock     = 44100   ; Sampling frequency in 'samples per second'
Global BlockSize       = 8192    ; Number of samples in block
Global BytesPerSample  = 2       ; Number of bytes needed for each sample, don't change this
Global Channels        = #Mono   ; Number of channels, 1 for mono, 2 for stereo.
Global DutyCycle.f     = #PI*0.4 ; For square wave only, 0.02*%=multiplier, so for 20%: multiplier=0.02*20=0.4
Global nBuf            = 8       ; Number of buffers
Global DevOut          = 1       ; default audio output device
Global Frequency_Left  = 1000
Global Frequency_Right = 440
Global Volume_Left.f   = 0.25 * 32767
Global Volume_Right.f  = 0.25 * 32767
Global hWaveOut
Global Hop     = #False
Global Pause   = #False
Global Lsquare = #False
Global Rsquare = #False
Global NumOutDevs

Global PlayFormat.WAVEFORMATEX
Global MyOutDevs.WAVEOUTCAPS
Global Dim outHdr.WAVEHDR(nBuf)
;}

If Init_GUI()
   EventLoop()
   StopSoundOutput()
EndIf

End

Procedure Init_GUI()
   Protected n, result = 1
   
   If OpenWindow(#MainWin,0,0,350,120,"Audio generator",#PB_Window_SystemMenu |#PB_Window_ScreenCentered)
      
      ButtonGadget(#BtnHop,10,10,50,25,"Hop",#PB_Button_Toggle)
      ButtonGadget(#BtnPause,70,10,50,25,"Pause",#PB_Button_Toggle)
      SpinGadget(#SpinLeft,130,02,70,25,100,5000)
         SetGadgetState(#SpinLeft,Frequency_Left) : SetGadgetText(#SpinLeft,Str(Frequency_Left))
         SetGadgetColor(#SpinLeft,#PB_Gadget_BackColor,#LeftColor)
      SpinGadget(#SpinRight,235,02,70,25,100,5000)
         SetGadgetState(#SpinRight,Frequency_Right) : SetGadgetText(#SpinRight,Str(Frequency_Right))
         SetGadgetColor(#SpinRight,#PB_Gadget_BackColor,#RighttColor)
      TrackBarGadget(#TrackLeft,125,30,100,25,0,100) : SetGadgetState(#TrackLeft,Volume_Left / 327.67)
      TrackBarGadget(#TrackRight,230,30,100,25,0,100) : SetGadgetState(#TrackRight,Volume_Right /327.67)
      CheckBoxGadget(#Lsquare,135,60,100,25,"L square")
      CheckBoxGadget(#Rsquare,240,60,100,25,"R square")
      CreateMenu(#Menu_1, WindowID(#MainWin))
      
      ; locate all sound output devices
         OpenSubMenu("Sound Output Devices")
         NumOutDevs = waveOutGetNumDevs_()
         If NumOutDevs <> 0
            For n = 0 To NumOutDevs - 1
               If waveOutGetDevCaps_(n,@MyOutDevs,SizeOf(WAVEOUTCAPS)) = 0
                     MenuItem(n + #OutDevice_1,PeekS(@MyOutDevs\szPname))
               EndIf
            Next
            CloseSubMenu()
            SetMenuItemState(#Menu_1,#OutDevice_1,#True)
            SetWindowCallback(@WinCallback()) ; Handle Sound Output callback
            StartSoundOutput()
         Else
            MessageRequester("Error!","No audio output device found.")
            result = 0
         EndIf
   Else
      result = 0
   EndIf
   
   ProcedureReturn result
EndProcedure

Procedure EventLoop()
   Protected menuSelection, ActiveGadget, n, Quit = #False
   
   Repeat
      Select WaitWindowEvent()
         Case #PB_Event_CloseWindow
            Quit = #True
         Case #PB_Event_Gadget
            Select EventGadget()
               Case #BtnHop
                  Hop = GetGadgetState(#BtnHop)
                  Frequency_Left = GetGadgetState(#SpinLeft)
                  Frequency_Right = GetGadgetState(#SpinRight)
               Case #BtnPause
                  Pause = GetGadgetState(#BtnPause)
                  If Pause
                     waveOutPause_(hWaveOut)
                  Else
                     waveOutRestart_(hWaveOut)
                  EndIf
               Case #SpinLeft   : ProcessSpin(#SpinLeft, @Frequency_Left)
               Case #SpinRight  : ProcessSpin(#SpinRight, @Frequency_Right)
               Case #TrackLeft  : Volume_Left = GetGadgetState(#TrackLeft) * 327.67
               Case #TrackRight : Volume_Right = GetGadgetState(#TrackRight) * 327.67
               Case #Rsquare    : Rsquare = GetGadgetState(#Rsquare)
               Case #Lsquare    : Lsquare = GetGadgetState(#Lsquare)
            EndSelect
         Case #PB_Event_Menu
            menuSelection = EventMenu()
            If GetMenuItemState(#Menu_1,menuSelection) = #False
               Select menuSelection
                  Case #OutDevice_1 To #OutDevice_1 + NumOutDevs - 1 ; Output device selection
                     For n = #OutDevice_1 To #OutDevice_1 + NumOutDevs - 1
                        If n = menuSelection
                           SetMenuItemState(#Menu_1,menuSelection,#True)
                        Else
                           SetMenuItemState(#Menu_1,n,#False)
                        EndIf
                     Next
                     DevOut = menuSelection - #OutDevice_1 + 1
                     StopSoundOutput()
                     StartSoundOutput()
               EndSelect
            EndIf
         Case #WM_KEYUP
            ActiveGadget = GetActiveGadget()
            Select ActiveGadget
               Case #SpinLeft To #SpinRight
                  If EventwParam() = #VK_RETURN
                     PostEvent(#PB_Event_Gadget,#MainWin,ActiveGadget,#Input_Finished)
                  EndIf
            EndSelect
      EndSelect
   Until Quit = #True
   
EndProcedure

Procedure WinCallback(hwnd, uMsg, wParam, lParam)
   ; Window callback to service sound output message
   Static *hWaveO.WAVEHDR
   
   Select uMsg
      Case #MM_WOM_DONE           ; Sound output, a play buffer has been returned.
         *hWaveO.WAVEHDR = lParam                        ; lParam has the address of WAVEHDR
         MAKE_WAVE(*hWaveO\lpData)                       ; send pointer where to write NEW data
         *hWaveO\dwBytesRecorded = BlockSize             ; Number of bytes written into buffer
         waveOutWrite_(hWaveOut,lParam, SizeOf(WAVEHDR)) ; Send to sound device => jack socket => cable =>
   EndSelect
   
   ProcedureReturn #PB_ProcessPureBasicEvents
EndProcedure

Procedure StartSoundOutput()
   Protected T,i, *P
   Static *OutBufMem
   
   With PlayFormat
      \wFormatTag      = #WAVE_FORMAT_PCM
      \nChannels       = Channels
      \wBitsPerSample  = BytesPerSample * 8
      \nSamplesPerSec  = SampleClock
      \nBlockAlign     = Channels * BytesPerSample
      \nAvgBytesPerSec = \nSamplesPerSec * \nBlockAlign
   EndWith
   
   If *OutBufMem : FreeMemory(*OutBufMem) : EndIf   ; Free a prior assignement
   *OutBufMem = AllocateMemory(BlockSize * nBuf)    ; Reserve memory for all the buffers
   
   T =  waveOutOpen_(@hWaveOut, #WAVE_MAPPER+DevOut, @PlayFormat, WindowID(#MainWin), #True, #CALLBACK_WINDOW | #WAVE_FORMAT_DIRECT)
   If T = #MMSYSERR_NOERROR
      
      *P = *OutBufMem                               ; Pointer to start of memory
      For i = 0 To nBuf-1                           ; For each buffer
         outHdr(i)\lpData         = *P              ; start of buffer
         outHdr(i)\dwBufferLength = BlockSize       ; size of buffer
         outHdr(i)\dwFlags        = 0
         outHdr(i)\dwLoops        = 0
         T | waveOutPrepareHeader_(hWaveOut, outHdr(i), SizeOf(WAVEHDR))
         *P + BlockSize
      Next
      
      For i = 0 To nBuf-1
         PostMessage_(WindowID(#MainWin),#MM_WOM_DONE,0,outHdr(i))
      Next 
      
   EndIf
   
   If T = #MMSYSERR_NOERROR : ProcedureReturn 1 : Else : ProcedureReturn 0 : EndIf
   
EndProcedure

Procedure StopSoundOutput()
   Protected i
   waveOutReset_(hWaveOut)
   For i = 0 To nBuf - 1
      waveOutUnprepareHeader_(hWaveOut, outHdr(i), SizeOf(WAVEHDR))
   Next
   waveOutClose_(hWaveOut)
EndProcedure

Procedure MAKE_WAVE(*SBuf)
   ; This routine generates Left and Right waveforms.
   
   Static.d Angle, Kl, Kr, La, Ra
   Static.i sample
   Static.l Vl, Vr
   
   If Hop
      Frequency_Left = Random(1220,220)
      Frequency_Right = Random(1220,220)
   EndIf
   
   ; Calculate the frequency scaling factors
   Kl = #PIx2 * Frequency_Left  / SampleClock
   Kr = #PIx2 * Frequency_Right / SampleClock
   
   sample = 1
   Repeat ; Generate waveform data
      ; Left/Mono sample
      If Lsquare
         Vl = Sign(DutyCycle-La) * Volume_Left
      Else
         Vl = Sin(La) * Volume_Left
      EndIf
      
      La + Kl                            ; calculate angle for next time
      If La > #PIx2 : La - #PIx2 : EndIf ; limit to 2*PI radians
      PokeW(*SBuf,Vl)                    ; Put point in buffer
      *SBuf + BytesPerSample             ; move buffer pointer to next sample
      
      ; Right sample
      If Channels = #Stereo
         If Rsquare
            Vr = Sign(DutyCycle-Ra) * Volume_Right
         Else
            Vr = Sin(Ra) * Volume_Right
         EndIf
         
         Ra + Kr
         If Ra > #PIx2 : Ra - #PIx2 : EndIf
         PokeW(*SBuf,Vr)
         *SBuf + BytesPerSample
      EndIf
      
      sample + PlayFormat\nBlockAlign
   Until sample > BlockSize
   
EndProcedure

Procedure ProcessSpin(nGad,*Freq)
   Select EventType()
      Case #PB_EventType_Up, #PB_EventType_Down
         SetGadgetText(nGad, Str(GetGadgetState(nGad)))
         PokeI(*Freq, GetGadgetState(nGad))
      Case #Input_Finished, #SpinLostFocus
         SetGadgetState(nGad,Val(GetGadgetText(nGad)))
         SetGadgetText(nGad, Str(GetGadgetState(nGad)))
         PokeI(*Freq, GetGadgetState(nGad))
   EndSelect
EndProcedure
BasicallyPure
Until you know everything you know nothing, all you have is what you believe.
User avatar
Keya
Addict
Addict
Posts: 1891
Joined: Thu Jun 04, 2015 7:10 am

Re: Oscilloscope

Post by Keya »

btw you might want to add some extra error checking code in INIT_GUI() as it fails on my XP-32 system. I broke it down to isolate the problem ... OpenWindow() is fine, InitSprite() is fine, but OpenWindowedScreen is failing (and looking at your call it's hard to see why, everything in that function call is simple and looks fine). I think it might just be because i probably dont have DirectX or OpenGL or whatever installed so it's probably not an issue with your code :)
Simo_na
Enthusiast
Enthusiast
Posts: 177
Joined: Sun Mar 03, 2013 9:01 am

Re: Oscilloscope

Post by Simo_na »

BasicallyPure wrote: The variable 'DutyCycle' then becomes DutyCycle = #PI * 0.4
for 80% DCycle is 1.6, I understand , thank you.

with external oscilloscope's (Rigol and Tektronix)
the sinewave work very very well,
squarewave work fine, only a tiny offset error..

thank you again :D
User avatar
Psychophanta
Addict
Addict
Posts: 4996
Joined: Wed Jun 11, 2003 9:33 pm
Location: Lípetsk, Russian Federation
Contact:

Re: Oscilloscope

Post by Psychophanta »

Thank you very much for share BasicallyPure.
It is a good idea. :!: Specially now when some sound cards allow inputs up to more than 100 Khz
I didn't watch this until now. :x
http://www.zeitgeistmovie.com

While world=business:world+mafia:Wend
Will never leave this forum until the absolute bugfree PB :mrgreen:
Simo_na
Enthusiast
Enthusiast
Posts: 177
Joined: Sun Mar 03, 2013 9:01 am

Re: Oscilloscope

Post by Simo_na »

BasicallyPure wrote:
Simo_na wrote:i get :
[08:48:26] [ERROR] Invalid memory access. (write error at address 93396992)
Fixed.
I really like this code :D
can you add a function of 3 multi-tone ? (mono - sinewave)
EG
258 Hz - 1550 Hz - 9300 Hz


like this :
Image
User avatar
BasicallyPure
Enthusiast
Enthusiast
Posts: 536
Joined: Thu Mar 24, 2011 12:40 am
Location: Iowa, USA

Re: Oscilloscope

Post by BasicallyPure »

Simo_na wrote:I really like this code
can you add a function of 3 multi-tone ? (mono - sinewave)
EG
258 Hz - 1550 Hz - 9300 Hz
Before I try and reinvent the wheel I think AudioPlayground
will do what you want. It produces mono output and you can combine as many sinewaves as you want.
Run AudioPlayground and paste this into the recipe window.

Code: Select all

Reset
Frequency 258
BuildWaveform
Add
Frequency 1550
Add
Frequency 9300
Add
then click the 'Build Recipe' button.
Then under the 'composite' window click the 'loop' button then 'play'.
That should do it.
BasicallyPure
Until you know everything you know nothing, all you have is what you believe.
Simo_na
Enthusiast
Enthusiast
Posts: 177
Joined: Sun Mar 03, 2013 9:01 am

Re: Oscilloscope

Post by Simo_na »

BasicallyPure wrote: Before I try and reinvent the wheel
:mrgreen:

I know AudioPlayground, it is a good application but...the sinewave of the AudioGenerator.pb have a floor of noise very low, more than of AudioPlayground, also AudioGenerator have bell ground more than narrow of AudioPlayground (The Q of the sinewave)

AudioPlayground = __/\__
AudioGenerator = __|__

i prefer AudioGenerator code sorry
:D
User avatar
futek2
New User
New User
Posts: 3
Joined: Wed Apr 27, 2016 2:01 pm
Location: Poland

Re: Oscilloscope

Post by futek2 »

Hello.
Once upon a time I was looking for a simple oscilloscope and today I managed to find something and came across your project.
I was looking for this meter to his small PV power plant built optimize yourself.
I want to do search and control point MPP.
To do this I have to add this project to the graphic and the button (L * R) - power (I * U = P).
And I wanted to make a record every 30 seconds and every 60 seconds to a file CSV or TXT.
Then I would do the calculations in MS EXCEL.
MPP for the optimal point of measurement for a long time.

https://en.wikipedia.org/wiki/Maximum_p ... t_tracking

http://www.mdpi.com/sensors/sensors-16- ... 9-1024.png

http://coder-tronics.com/wp-content/upl ... -curve.png

Recording wanted me to take place without limitation of time, eg 1 week - 168 hours and more.
The save file to be following column numeric values:
date, time, L, R, L * R,

With the knowledge of the oscilloscope I found the choice too easy to modify.
But it might have been simpler to perform three meter with digital display:
Voltage ranges 0-10V, 0-100V, 0-500V (left channel)
Current ranges 0-1A, 0-5A, 0-10. (Right channel)
Power - calculation (V * A) Wat.
I write to a file every 30 seconds or 60 seconds of the CSV or TXT data:
Date, time, V, A, Wat

Recording time up to 168 hours and even more to do then analyze the results using MS EXCEL.

Input signals to the measurements to the SOUND CARD stereo.

Could I ask you to add these options and compilations?

I do not know how to program'm just a retired electronics.

Futek2
Wolfram
Enthusiast
Enthusiast
Posts: 568
Joined: Thu May 30, 2013 4:39 pm

Re: Oscilloscope

Post by Wolfram »

Can someone help me to translate it to OSX?
How can I do "waveOutOpen_()" on OSX?
macOS Catalina 10.15.7
wilbert
PureBasic Expert
PureBasic Expert
Posts: 3870
Joined: Sun Aug 08, 2004 5:21 am
Location: Netherlands

Re: Oscilloscope

Post by wilbert »

Wolfram wrote:Can someone help me to translate it to OSX?
How can I do "waveOutOpen_()" on OSX?
There is no simple translation but you can generate audio on OSX as well.
http://www.purebasic.fr/english/viewtop ... 19&t=53672
Windows (x64)
Raspberry Pi OS (Arm64)
firace
Addict
Addict
Posts: 902
Joined: Wed Nov 09, 2011 8:58 am

Re: Oscilloscope

Post by firace »

Sadly stereo mix input ('what u hear' recording) is no longer available in Windows 10 :(

However there seems to be a new way to access it programmatically, via WASAPI.

See https://mediarealm.com.au/articles/ster ... indows-10/

Has anyone managed to do this in PB?
Post Reply