Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
square waves (or pulse waves) 8 Hz duty cycle?
#1
Hello everyone,
I'm still busy testing QB64PE. 
For a later experiment, I want to use the PC as a square wave generator (or pulse generator). 
One of the low frequencies I need is 8 Hz. 
This isn't possible using the Sound statement (cfr frequency lower then 30Hz...)

But via F1 help on the _SNDRAW item, I discovered the QB64PE example for sine and square waves
To my great surprise, this works on my old Lenovo ThinkCentre PC from 1 Hz! 

Okay, I'm very happy with that. 

But.... Does anyone know if it is possible to regulate the duty cycle with this _SNDRAW statement?

Code: (Select All)

'Source: QB64PE (_SNDRAW + F1)

'Sound using a sine wave with _SNDRAW Amplitude * SIN(8 * ATN(1) * Duration * (Frequency / _SNDRATE))
'Explanation: The loop Duration is determined
' by the number of seconds times the _SNDRATE number of samples per second.
'Square waves can use the same formula with:
' Amplitude * SGN(SIN(8 * ATN(1) * Duration * (Frequency/_SNDRATE))).
'any frequency desired from 36 to 10,000

'FREQ = 1 'Test Rudy (works on my PC)
FREQ = 8 'Test Rudy (works on my PC)
'FREQ = 10000
Pi2 = 8 * ATN(1) '2 * pi
Amplitude = .3 'amplitude of the signal from -1.0 to 1.0
SampleRate = _SNDRATE 'sets the sample rate
FRate = FREQ / SampleRate '
FOR Duration = 0 TO 5 * SampleRate 'play 5 seconds
  '_SNDRAW Amplitude * SIN(Pi2 * Duration * FRate) 'sine wave
  _SNDRAW Amplitude * SGN(SIN(Pi2 * Duration * FRate)) 'square wave
  ' Works for a frequences starting from 1 Hertz (old Lenovo ThinkCentre, Linux Mint 22)
NEXT
DO: LOOP WHILE _SNDRAWLEN
END
Reply
#2
Not quite sure what your getting from that.  But its **NOT QUITE** a square wave.   A Square Wave goes directly for +Amplitude to -Amplitude no PI involved.  
Pi is for the Sine Wave !


Also not quite sure what your asking about DUTY CYCLE !
Reply
#3
@Petr has done allot work with sound and its regulation.
  724  855  599  923  575  468  400  206  147  564  878  823  652  556 bxor cross forever
Reply
#4
@ahenry3068:

I "suppose" the software creates first a sine-wave (and therefore needs the calculation with PI),
and thereafter "cut off" all the tops of the wave.

OK, its possible not a perfect square wave, but one can use it as square wave.
(In electronic circuits sometimes this is done with two diodes soldered in "anti-parallel")

A good explanation with graphics of duty cycle one can see at the site of Fluke electronic meters:
https://www.fluke.com/en/learn/blog/elec...duty-cycle.

Rudy
Reply
#5
See if this will work for you.

Code: (Select All)

OPTION _EXPLICIT

CONST T! = 0.1! ' 100 ms chunks

DIM v AS SINGLE: v = 0.25! ' 25% volume
DIM d AS SINGLE: d = 0.5! ' 50% duty cycle ~ square wave
DIM b AS SINGLE 'center
DIM f AS SINGLE: f = 100 ' Hz
DIM k AS LONG

DO
    CLS

    PRINT USING "Duty Cycle:  ####%"; d * 100!
    PRINT USING "Volume:      ####%"; v * 100!
    PRINT USING "Balance:    ####"; b * 100!
    PRINT USING "Frequency: ###### Hz"; f
    PRINT
    PRINT "VOL=UP|DN, BAL=LT|RT, DCY=HM|ED, FRQ=PU|PD, ESC"

    _DISPLAY

    k = _KEYHIT

    SELECT CASE k
        CASE _KEY_UP: v = _MIN(v + 0.01!, 1!)
        CASE _KEY_DOWN: v = _MAX(v - 0.01!, 0!)
        CASE _KEY_LEFT: b = _MAX(b - 0.01!, -1!)
        CASE _KEY_RIGHT: b = _MIN(b + 0.01!, 1!)
        CASE _KEY_HOME: d = _MIN(d + 0.01!, 1!)
        CASE _KEY_END: d = _MAX(d - 0.01!, 0!)
        CASE _KEY_PAGEUP: f = _MIN(f + 10!, 192000!)
        CASE _KEY_PAGEDOWN: f = _MAX(f - 10!, 10!)
        CASE _KEY_ESC: EXIT DO
    END SELECT

    _KEYCLEAR 2

    PlayPulseWave f, T, d, v, b

    _DELAY _SNDRAWLEN - 0.005!
LOOP

_AUTODISPLAY
END

SUB PlayPulseWave (frequencyHz AS SINGLE, timeSec AS SINGLE, dutyCycle AS SINGLE, volume AS SINGLE, pan AS SINGLE)
    STATIC phase AS SINGLE

    DIM sampleRate AS SINGLE: sampleRate = _MAX(_SNDRATE, 1!)
    DIM frequency AS SINGLE: frequency = _MAX(frequencyHz, 0.1!)
    DIM samples AS LONG: samples = _MAX(timeSec, 0!) * sampleRate
    DIM duty AS SINGLE: duty = _CLAMP(dutyCycle, 0!, 1!)
    DIM amp AS SINGLE: amp = _CLAMP(volume, 0!, 1!)
    DIM freqStep AS SINGLE: freqStep = frequency / sampleRate
    DIM panMapped AS SINGLE: panMapped = (_CLAMP(pan, -1!, 1!) + 1!) * _PI(0.25!)
    DIM gainLeft AS SINGLE: gainLeft = COS(panMapped)
    DIM gainright AS SINGLE: gainright = SIN(panMapped)
    DIM sample AS SINGLE, i AS LONG

    WHILE i < samples
        phase = phase + freqStep
        IF phase >= 1! THEN phase = phase - INT(phase)

        sample = _IIF(phase < duty, amp, -amp)

        _SNDRAW sample * gainLeft, sample * gainright

        i = i + 1
    WEND
END SUB
Reply
#6
Thanks for the replys and @a420g thanks for the beautiful and good working listing. 

I did immediately a test, and it performs for very well for me.

Thank You again,
Rudy
Reply
#7
And here's something from me too 

Code: (Select All)

FREQ = 8
Pi2 = 8 * Atn(1)
Amplitude = .3
SampleRate = _SndRate
FRate = FREQ / SampleRate

Screen _NewImage(640, 480, 32)

Cls
Color _RGB32(255)
Locate 1
Print "Press + or - to change frequency, ESC to exit"
Locate 2
Print "Frequency: "; FREQ; " Hz"

x = 0
oldY = 240
PSet (0, 240)
ox = 0
oy = 240
Do
    duration = duration + 1
    sample = Amplitude * Sgn(Sin(Pi2 * duration * FRate))
    _SndRaw sample

    y = 240 - sample * 200
    Line (x + 1, y - 130)-(x + 1, y + 130), _RGB32(0)
    PSet (ox, oy)
    Line -(x, y), _RGB32(0, 200, 0)
    ox = x
    oy = y
    oldY = y
    x = x + .05
    If x > 639 Then
        Color _RGB32(255)
        Locate 1
        Print "Press + or - to change frequency, ESC to exit"
        Locate 2
        Print "Frequency: "; FREQ; " Hz"
        x = 0
        Line (0, y - 130)-(0, y + 130), _RGB32(0)
        PSet (0, 240)
    End If

    Do

        i$ = InKey$
        Select Case i$
            Case "+"
                FREQ = FREQ + 1
                If FREQ > 20000 Then FREQ = 20000
                FRate = FREQ / SampleRate
                Locate 2
                Print "Frequency: "; FREQ; " Hz  "

            Case "-"
                FREQ = FREQ - 1
                If FREQ < 1 Then FREQ = 1
                FRate = FREQ / SampleRate
                Locate 2
                Print "Frequency: "; FREQ; " Hz  "
        End Select

    Loop Until _SndRawLen < .1
Loop Until _KeyDown(27)
End


Reply
#8
And you can probably take work from the "seriously serious" to the bank!  LOL Smile

Quote:Thanks for the replys and @a420g thanks for the beautiful and good working listing. 

Yeah @a740g ! Takes awhile to get peoples numbers right @Rudy M try and remember DSMan's number ha!!! (another developer with a740g, Sammy and Matt I think are first names but which is which Wink ).
  724  855  599  923  575  468  400  206  147  564  878  823  652  556 bxor cross forever
Reply
#9
(11-12-2025, 04:51 PM)bplus Wrote: And you can probably take work from the "seriously serious" to the bank!  LOL Smile

Quote:Thanks for the replys and @a420g thanks for the beautiful and good working listing. 

Yeah @a740g ! Takes awhile to get peoples numbers right @Rudy M try and remember DSMan's number ha!!! (another developer with a740g, Sammy and Matt I think are first names but which is which Wink ).

Big Grin

DSMan195276 > Matt
a740g > Sam
Reply
#10
+1 thanks Sam now I know (again) Wink

I am writing it down, now to remember where I put my note...
  724  855  599  923  575  468  400  206  147  564  878  823  652  556 bxor cross forever
Reply


Possibly Related Threads…
Thread Author Replies Views Last Post
  Is there a square monospace font PhilOfPerth 9 1,714 03-08-2025, 12:26 AM
Last Post: madscijr
  where my square pixels at? James D Jarvis 5 1,186 03-09-2023, 07:04 PM
Last Post: James D Jarvis

Forum Jump:


Users browsing this thread: