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 the same user not shown)
Line 65: Line 65:
{{Cl|END}}
{{Cl|END}}
{{CodeEnd}}
{{CodeEnd}}
{{Small|Code by Artelius (responsible for the implementation of _SNDRAW)}}
{{Small|Code by Artelius}}




Line 90: 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}}



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