mirror of
https://github.com/QB64Official/qb64.git
synced 2024-08-31 11:10:18 +00:00
114 lines
5.3 KiB
Text
114 lines
5.3 KiB
Text
{{DISPLAYTITLE:_SNDRAW}}
|
|
The [[_SNDRAW]] statement plays sound wave sample frequencies created by a program.
|
|
|
|
|
|
{{PageSyntax}}
|
|
: [[_SNDRAW]] {{Parameter|leftSample}}[, {{Parameter|rightSample}}][, {{Parameter|pipeHandle&}}]
|
|
|
|
|
|
{{Parameters}}
|
|
* The {{Parameter|leftSample}} and {{Parameter|rightSample}} value(s) can be any [[SINGLE]] or [[DOUBLE]] literal or variable frequency value from -1.0 to 1.0.
|
|
* The {{Parameter|pipeHandle&}} parameter refers to the sound pipe opened using [[_SNDOPENRAW]].
|
|
|
|
|
|
{{PageDescription}}
|
|
* Specifying {{Parameter|pipeHandle&}} allows sound to be played through two or more channels at the same time ('''version 1.000 and up''').
|
|
* If only {{Parameter|leftSample}} value is used, the sound will come out of both speakers.
|
|
* Using _SNDRAW will pause any currently playing music.
|
|
* _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 actually finished playing sound). If you are getting 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]].'''
|
|
|
|
|
|
{{PageExamples}}
|
|
''Example 1:'' Sound using a sine wave with _SNDRAW Amplitude * SIN(8 * ATN(1) * Duration * (Frequency / _SNDRATE))
|
|
{{CodeStart}}
|
|
FREQ = 400 'any frequency desired from 36 to 10,000
|
|
Pi2 = 8 * {{Cl|ATN}}(1) '2 * pi
|
|
Amplitude = .3 'amplitude of the signal from -1.0 to 1.0
|
|
SampleRate = {{Cl|_SNDRATE}} 'sets the sample rate
|
|
FRate = FREQ / SampleRate'
|
|
{{Cl|FOR...NEXT|FOR}} Duration = 0 {{Cl|TO}} 5 * SampleRate 'play 5 seconds
|
|
{{Cl|_SNDRAW}} Amplitude * {{Cl|SIN}}(Pi2 * Duration * FRate) 'sine wave
|
|
'{{Cl|_SNDRAW}} Amplitude * {{Cl|SGN}}({{Cl|SIN}}(Pi2 * Duration * FRate)) 'square wave
|
|
{{Cl|NEXT}}
|
|
{{Cl|DO}}: LOOP {{Cl|WHILE}} {{Cl|_SNDRAWLEN}}
|
|
{{Cl|END}} '' ''
|
|
{{CodeEnd}}
|
|
{{small|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.
|
|
{{CodeStart}}t = 0
|
|
tmp$ = "Sample = ##.##### Time = ##.#####"
|
|
LOCATE 1, 60: PRINT "Rate:"; {{Cl|_SNDRATE}}
|
|
DO
|
|
'queue some sound
|
|
DO WHILE {{Cl|_SNDRAWLEN}} < 0.1 'you may wish to adjust this
|
|
sample = {{Cl|SIN}}(t * 440 * {{Cl|ATN}}(1) * 8) '440Hz sine wave (t * 440 * 2π)
|
|
sample = sample * {{Cl|EXP}}(-t * 3) 'fade out eliminates clicks after sound
|
|
{{Cl|_SNDRAW}} sample
|
|
t = t + 1 / {{Cl|_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
|
|
|
|
DO WHILE {{Cl|_SNDRAWLEN}} > 0 'Finish any left over queued sound!
|
|
LOOP
|
|
{{Cl|END}} '' ''
|
|
{{CodeEnd}}
|
|
{{small|Code by Artelius (responsible for the implementation of _SNDRAW)}}
|
|
|
|
|
|
''Example 3:'' Routine uses _SNDRAW to display and play 12 notes from octaves 1 through 9.
|
|
{{CodeStart}} '' ''
|
|
{{Cl|DIM}} {{Cl|SHARED}} rate&
|
|
rate& = {{Cl|_SNDRATE}}
|
|
DO
|
|
{{Cl|PRINT}} "Enter the octave 1 to 8 (0 quits!):";
|
|
oct% = {{Cl|VAL}}({{Cl|INPUT$}}(1)): {{Cl|PRINT}} oct%
|
|
{{Cl|IF...THEN|IF}} oct% = 0 {{Cl|THEN}} {{Cl|EXIT DO}}
|
|
octave = oct% - 4 '440 is in the 4th octave, 9th note
|
|
{{Cl|COLOR}} oct% + 1
|
|
{{Cl|PRINT USING}} "Octave: ##"; oct%
|
|
{{Cl|FOR...NEXT|FOR}} Note = 0 {{Cl|TO}} 11 'notes C to B
|
|
fq = FreQ(octave, Note, note$)
|
|
{{Cl|PRINT USING}} "#####.## \\"; fq, note$
|
|
PlaySound fq
|
|
{{Cl|IF...THEN|IF}} {{Cl|INKEY$}} > "" {{Cl|THEN}} {{Cl|EXIT DO}}
|
|
{{Cl|NEXT}}
|
|
{{Cl|LOOP}}
|
|
{{Cl|END}}
|
|
|
|
{{Cl|FUNCTION}} FreQ (octave, note, note$)
|
|
FreQ = 440 * 2 ^ (octave + (note + 3) / 12 - 1) '* 12 note octave starts at C (3 notes up)
|
|
note$ = {{Cl|MID$}}("C C#D D#E F F#G G#A A#B ", note * 2 + 1, 2)
|
|
{{Cl|END FUNCTION}}
|
|
|
|
{{Cl|SUB}} PlaySound (frq!) ' plays sine wave fading in and out
|
|
SndLoop! = 0
|
|
{{Cl|DO...LOOP|DO}} {{Cl|WHILE}} SndLoop! < rate&
|
|
{{Cl|_SNDRAW}} {{Cl|SIN}}((2 * 4 * {{Cl|ATN}}(1) * SndLoop! / rate&) * frq!) * {{Cl|EXP}}(-(SndLoop! / rate&) * 3)
|
|
SndLoop! = SndLoop! + 1
|
|
{{Cl|LOOP}}
|
|
{{Cl|DO}}: {{Cl|LOOP}} {{Cl|WHILE}} {{Cl|_SNDRAWLEN}} 'flush the sound playing buffer
|
|
{{Cl|END SUB}} '' ''
|
|
{{CodeEnd}}
|
|
{{small|Code by CodeGuy}}
|
|
|
|
|
|
{{PageSeeAlso}}
|
|
* [[_SNDRATE]], [[_SNDRAWLEN]]
|
|
* [[_SNDOPENRAW]], [[_SNDRAWDONE]]
|
|
* [[_SNDOPEN]]
|
|
* [[PLAY]], [[BEEP]]
|
|
* Music Frequency table in [[SOUND]].
|
|
* [[DTMF Phone Demo]]
|
|
|
|
|
|
{{PageNavigation}}
|