SNDRAW: Difference between revisions

From QB64 Phoenix Edition Wiki
Jump to navigation Jump to search
(Created page with "{{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...")
 
No edit summary
 
(8 intermediate revisions by 2 users not shown)
Line 1: Line 1:
{{DISPLAYTITLE:_SNDRAW}}
{{DISPLAYTITLE:_SNDRAW}}
The [[_SNDRAW]] statement plays sound wave sample frequencies created by a program.  
The [[_SNDRAW]] statement plays sound wave sample frequencies created by a program.




Line 7: Line 7:




{{Parameters}}
{{PageParameters}}
* 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|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]].  
* The {{Parameter|pipeHandle&}} parameter refers to the sound pipe opened using [[_SNDOPENRAW]].




Line 19: Line 19:
* 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.
* 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).
* _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.  
* [[_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]].'''


Line 27: Line 27:
{{CodeStart}}
{{CodeStart}}
FREQ = 400                            'any frequency desired from 36 to 10,000
FREQ = 400                            'any frequency desired from 36 to 10,000
Pi2 = 8 * {{Cl|ATN}}(1)                      '2 * pi  
Pi2 = 8 * {{Cl|ATN}}(1)                      '2 * pi
Amplitude = .3                        'amplitude of the signal from -1.0 to 1.0
Amplitude = .3                        'amplitude of the signal from -1.0 to 1.0
SampleRate = {{Cl|_SNDRATE}}                  'sets the sample rate
SampleRate = {{Cl|_SNDRATE}}                  'sets the sample rate
Line 35: Line 35:
       '{{Cl|_SNDRAW}} Amplitude * {{Cl|SGN}}({{Cl|SIN}}(Pi2 * Duration * FRate))      'square wave
       '{{Cl|_SNDRAW}} Amplitude * {{Cl|SGN}}({{Cl|SIN}}(Pi2 * Duration * FRate))      'square wave
{{Cl|NEXT}}
{{Cl|NEXT}}
{{Cl|_SNDRAWDONE}}
{{Cl|DO}}: LOOP {{Cl|WHILE}} {{Cl|_SNDRAWLEN}}
{{Cl|DO}}: LOOP {{Cl|WHILE}} {{Cl|_SNDRAWLEN}}
{{Cl|END}} '' ''
{{Cl|END}}
{{CodeEnd}}
{{CodeEnd}}
{{small|Code by DarthWho}}
{{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))).
:''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))).


Line 48: Line 49:
DO
DO
   'queue some sound
   'queue some sound
   DO WHILE {{Cl|_SNDRAWLEN}} < 0.1             'you may wish to adjust this  
   DO WHILE {{Cl|_SNDRAWLEN}} < 0.2             'you may wish to adjust this
     sample = {{Cl|SIN}}(t * 440 * {{Cl|ATN}}(1) * 8)  '440Hz sine wave (t * 440 * 2π)  
     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
     sample = sample * {{Cl|EXP}}(-t * 3)      'fade out eliminates clicks after sound
     {{Cl|_SNDRAW}} sample
     {{Cl|_SNDRAW}} sample
Line 59: Line 60:
LOOP WHILE t < 3.0                      'play for 3 seconds
LOOP WHILE t < 3.0                      'play for 3 seconds


{{Cl|_SNDRAWDONE}}
DO WHILE {{Cl|_SNDRAWLEN}} > 0                'Finish any left over queued sound!
DO WHILE {{Cl|_SNDRAWLEN}} > 0                'Finish any left over queued sound!
LOOP
LOOP
{{Cl|END}} '' ''
{{Cl|END}}
{{CodeEnd}}
{{CodeEnd}}
{{small|Code by Artelius (responsible for the implementation of _SNDRAW)}}
{{Small|Code by Artelius}}




''Example 3:'' Routine uses _SNDRAW to display and play 12 notes from octaves 1 through 9.
''Example 3:'' Routine uses _SNDRAW to display and play 12 notes from octaves 1 through 9.
{{CodeStart}} '' ''
{{CodeStart}}
{{Cl|DIM}} {{Cl|SHARED}} rate&
{{Cl|DIM}} {{Cl|SHARED}} rate&
rate& = {{Cl|_SNDRATE}}
rate& = {{Cl|_SNDRATE}}
Line 88: Line 90:
{{Cl|FUNCTION}} FreQ (octave, note, note$)
{{Cl|FUNCTION}} FreQ (octave, note, note$)
FreQ = 440 * 2 ^ (octave + (note + 3) / 12 - 1) '* 12 note octave starts at C (3 notes up)
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)
note$ = {{Cl|MID$ (function)|MID$}}("C C#D D#E F F#G G#A A#B ", note * 2 + 1, 2)
{{Cl|END FUNCTION}}
{{Cl|END FUNCTION}}


Line 97: Line 99:
   SndLoop! = SndLoop! + 1
   SndLoop! = SndLoop! + 1
{{Cl|LOOP}}
{{Cl|LOOP}}
{{Cl|_SNDRAWDONE}}
{{Cl|DO}}: {{Cl|LOOP}} {{Cl|WHILE}} {{Cl|_SNDRAWLEN}}  'flush the sound playing buffer
{{Cl|DO}}: {{Cl|LOOP}} {{Cl|WHILE}} {{Cl|_SNDRAWLEN}}  'flush the sound playing buffer
{{Cl|END SUB}} '' ''
{{Cl|END SUB}}
{{CodeEnd}}
{{CodeEnd}}
{{small|Code by CodeGuy}}
{{Small|Code by CodeGuy}}




Line 108: Line 111:
* [[_SNDOPEN]]
* [[_SNDOPEN]]
* [[PLAY]], [[BEEP]]
* [[PLAY]], [[BEEP]]
* Music Frequency table in [[SOUND]].
* [[DTMF Phone Demo]]
* [[DTMF Phone Demo]]




{{PageNavigation}}
{{PageNavigation}}

Latest revision as of 22:56, 19 February 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.
  • 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.


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 * 2π)
    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