SNDRAW: Difference between revisions

From QB64 Phoenix Edition Wiki
Jump to navigation Jump to search
No edit summary
No edit summary
 
(One intermediate revision by one other user not shown)
Line 20: Line 20:
* [[_SNDRATE]] determines how many samples are played per second, but timing is done by the sound card, not your program.
* [[_SNDRATE]] determines how many samples are played per second, but timing is done by the sound card, not your program.
* '''Do not attempt to use [[_TIMER]] or [[_DELAY]] or [[_LIMIT]] to control the timing of _SNDRAW. You may use them for delays or to limit your program's CPU usage, but how much to queue should only be based on the [[_SNDRAWLEN]].'''
* '''Do not attempt to use [[_TIMER]] or [[_DELAY]] or [[_LIMIT]] to control the timing of _SNDRAW. You may use them for delays or to limit your program's CPU usage, but how much to queue should only be based on the [[_SNDRAWLEN]].'''
{{PageAvailability}}
<!-- QB64 = a version or none, QBPE = a version or all, Platforms = yes or no -->
<gallery widths="48px" heights="48px" mode="nolines">
File:Qb64.png|'''v0.927'''
File:Qbpe.png|'''all'''
File:Apix.png
File:Win.png|'''yes'''
File:Lnx.png|'''yes'''
File:Osx.png|'''yes'''
</gallery>
<!-- Additional availability notes go below here -->





Latest revision as of 13:29, 8 December 2024

The _SNDRAW statement plays sound wave sample frequencies created by a program.


Syntax

_SNDRAW leftSample[, rightSample][, pipeHandle&]


Parameters

  • The leftSample and rightSample value(s) can be any SINGLE or DOUBLE literal or variable frequency value from -1.0 to 1.0.
  • The pipeHandle& parameter refers to the sound pipe opened using _SNDOPENRAW.


Description

  • Specifying pipeHandle& allows sound to be played through two or more channels at the same time (version 1.000 and up).
  • If only leftSample value is used, the sound will come out of both speakers.
  • _SNDRAW is designed for continuous play. It will not produce any sound until a significant number of samples have been queued. No sound is played if only a few samples are queued.
  • Ensure that _SNDRAWLEN is comfortably above 0 (until you've finished playing sound). If you get occasional unintended random clicks, this generally means that _SNDRAWLEN has dropped to 0.
  • _SNDRAW is not intended to queue up many minutes worth of sound. It will probably work but will chew up a lot of memory (and if it gets swapped to disk, your sound could be interrupted abruptly).
  • _SNDRATE determines how many samples are played per second, but timing is done by the sound card, not your program.
  • Do not attempt to use _TIMER or _DELAY or _LIMIT to control the timing of _SNDRAW. You may use them for delays or to limit your program's CPU usage, but how much to queue should only be based on the _SNDRAWLEN.


Availability


Examples

Example 1
Sound using a sine wave with _SNDRAW Amplitude * SIN(8 * ATN(1) * Duration * (Frequency / _SNDRATE))
FREQ = 400 'any frequency desired from 36 to 10,000
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
NEXT
_SNDRAWDONE
DO: LOOP WHILE _SNDRAWLEN
END
Code by DarthWho
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))).


Example 2
A simple ringing bell tone that tapers off.
t = 0
tmp$ = "Sample = ##.#####   Time = ##.#####"
LOCATE 1, 60: PRINT "Rate:"; _SNDRATE
DO
    'queue some sound
    DO WHILE _SNDRAWLEN < 0.2 'you may wish to adjust this
        sample = SIN(t * 440 * ATN(1) * 8) '440Hz sine wave (t * 440 * 2p)
        sample = sample * EXP(-t * 3) 'fade out eliminates clicks after sound
        _SNDRAW sample
        t = t + 1 / _SNDRATE 'sound card sample frequency determines time
    LOOP

    'do other stuff, but it may interrupt sound
    LOCATE 1, 1: PRINT USING tmp$; sample; t
LOOP WHILE t < 3.0 'play for 3 seconds

_SNDRAWDONE
DO WHILE _SNDRAWLEN > 0 'Finish any left over queued sound!
LOOP
END
Code by Artelius


Example 3
Routine uses _SNDRAW to display and play 12 notes from octaves 1 through 9.
DIM SHARED rate&
rate& = _SNDRATE
DO
    PRINT "Enter the octave 1 to 8 (0 quits!):";
    oct% = VAL(INPUT$(1)): PRINT oct%
    IF oct% = 0 THEN EXIT DO
    octave = oct% - 4 '440 is in the 4th octave, 9th note
    COLOR oct% + 1
    PRINT USING "Octave: ##"; oct%
    FOR Note = 0 TO 11 'notes C to B
        fq = FreQ(octave, Note, note$)
        PRINT USING "#####.## \\"; fq, note$
        PlaySound fq
        IF INKEY$ > "" THEN EXIT DO
    NEXT
LOOP
END

FUNCTION FreQ (octave, note, note$)
    FreQ = 440 * 2 ^ (octave + (note + 3) / 12 - 1) '* 12 note octave starts at C (3 notes up)
    note$ = MID$("C C#D D#E F F#G G#A A#B ", note * 2 + 1, 2)
END FUNCTION

SUB PlaySound (frq!) ' plays sine wave fading in and out
    SndLoop! = 0
    DO WHILE SndLoop! < rate&
        _SNDRAW SIN((2 * 4 * ATN(1) * SndLoop! / rate&) * frq!) * EXP(-(SndLoop! / rate&) * 3)
        SndLoop! = SndLoop! + 1
    LOOP
    _SNDRAWDONE
    DO: LOOP WHILE _SNDRAWLEN 'flush the sound playing buffer
END SUB
Code by CodeGuy


See also



Navigation:
Main Page with Articles and Tutorials
Keyword Reference - Alphabetical
Keyword Reference - By usage
Report a broken link