Code: Select all
XIncludeFile "PortAudio.pb"
#MinFreq = 100
#MaxFreq = 10000
#SampleRate = 44100
#PI2 = 6.28318530717958
Enumeration
#WIN_MAIN
#PlayPauseButton
#SelectedWave
#FrequenceText
#FrequenceString
#FrequenceTrack
EndEnumeration
Enumeration
#Sine
#Saw
#Square
EndEnumeration
Procedure Error(err)
Debug Pa_GetErrorText(err)
MessageRequester("", PeekS(Pa_GetErrorText(err)))
End
EndProcedure
Prototype.d WaveFormFnProto(Phh.d)
Global Stream, Streaming, WaveFormFn.WaveFormFnProto
Global Phase.d, PhaseAdd.d
Procedure.d Sine(Phh.d)
ProcedureReturn Phh
EndProcedure
Procedure.d Saw(Phh.d)
If Phh < 0.5
ProcedureReturn 0.35 * Sin(Phh)
Else
ProcedureReturn (0.35 * Sin(1 - Phh)) + 0.5
EndIf
EndProcedure
Procedure.d Sq(Phh.d)
If Phh < 0.5
ProcedureReturn 0.25
Else
ProcedureReturn 0.75
EndIf
EndProcedure
ProcedureC PaStreamCallback(*in, *output.Float, frameCount, *timeInfo.PaStreamCallbackTimeInfo, statusFlags, *userData)
While frameCount
*output\f = Sin(#PI2 * WaveFormFn(Phase))
Phase + PhaseAdd
If Phase > 1 : Phase = Phase - 1 : EndIf
*output + 4
frameCount - 1
Wend
EndProcedure
err = Pa_Initialize()
If err <> #paNoError : Error(err) : EndIf
op.PaStreamParameters
op\channelCount = 1
op\device = Pa_GetDefaultOutputDevice()
op\sampleFormat = #paFloat32
op\suggestedLatency = 150/1000
err = Pa_OpenStream(@Stream, #Null, @op, #SampleRate, 0, #paNoFlag, @PaStreamCallback(), 0)
If err <> #paNoError : Error(err) : EndIf
If OpenWindow(#WIN_MAIN, 0, 0, 200, 180, "Interaction", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)
ComboBoxGadget(#SelectedWave, 40, 20, 140, 20)
AddGadgetItem(#SelectedWave, -1, "Sine")
AddGadgetItem(#SelectedWave, -1, "Saw")
AddGadgetItem(#SelectedWave, -1, "Square")
SetGadgetState(#SelectedWave,0)
WaveFormFn = @Sine()
TrackBarGadget(#FrequenceTrack, 10, 10, 20, 110, #MinFreq, #MaxFreq, #PB_TrackBar_Vertical)
TextGadget(#FrequenceText, 40, 70, 80, 20, "Frequency:")
StringGadget(#FrequenceString, 40, 90, 60, 20, "200",#PB_String_Numeric)
SetGadgetState(#FrequenceTrack, 200)
ButtonGadget(#PlayPauseButton, 10, 130, 180, 30, "Play")
Quit = #False
Repeat
Event = WaitWindowEvent()
Select Event
Case #PB_Event_Gadget
Select EventGadget()
Case #SelectedWave
Select GetGadgetState(#SelectedWave)
Case #Sine
WaveFormFn = @Sine()
Case #Saw
WaveFormFn = @Saw()
Case #Square
WaveFormFn = @Sq()
EndSelect
Case #FrequenceTrack
SetGadgetText(#FrequenceString, Str(GetGadgetState(#FrequenceTrack)))
Case #FrequenceString
Select EventType()
Case #PB_EventType_Change
Value = Val(GetGadgetText(#FrequenceString))
If Value < #MinFreq : Value = #MinFreq
ElseIf Value > #MaxFreq : Value = #MaxFreq : EndIf
SetGadgetState(#FrequenceTrack, Value)
Case #PB_EventType_LostFocus
SetGadgetText(#FrequenceString, Str(GetGadgetState(#FrequenceTrack)))
EndSelect
Case #PlayPauseButton
Streaming = ~Streaming
If Streaming
Pa_StartStream(Stream)
SetGadgetText(#PlayPauseButton, "Pause")
Else
Pa_StopStream(Stream)
SetGadgetText(#PlayPauseButton, "Play")
EndIf
EndSelect
Freq = Val(GetGadgetText(#FrequenceString))
PhaseAdd = Freq / #SampleRate
Case #PB_Event_CloseWindow
Quit = #True
EndSelect
Until Quit
EndIf
Pa_Terminate()

