_SNDRAWBATCH

From QB64 Phoenix Edition Wiki
Revision as of 12:22, 8 December 2024 by A740g (talk | contribs) (Add availability info)
Jump to navigation Jump to search

The _SNDRAWBATCH statement plays a batch of sound wave sample frequencies created by a program.


Syntax

_SNDRAWBATCH sampleFrameArray!([index&])[, channels&][, pipeHandle&][, frameCount&]


Parameters

  • sampleFrameArray!([index&]) is an array of SINGLE values representing the audio sample frames. Optionally, an index can be specified to determine the starting point in the array.
  • channels& is number of channels. This can be 1 (mono) or 2 (stereo). It is assumed as mono if not provided.
  • pipeHandle& is a handle to the sound pipe, obtained by using the _SNDOPENRAW function.
  • frameCount& is the number of sample frames to play, not the number of array elements. Each frame corresponds to one set of samples per channel.


Description

  • Unlike _SNDRAW, _SNDRAWBATCH is designed to play a batch of sample frames. This removes the need to call the underlying audio subsystem for each sample frame and thus improves performance.
  • A sample frame is one snapshot of audio data that includes the sound levels for all channels at a specific point in time. In mono audio (1 channel), a sample frame is just 1 value. In stereo audio (2 channels), a sample frame has 2 values: one for the left channel and one for the right channel.
  • Stereo audio data should always be interleaved (a left channel sample followed by a right channel sample).
  • 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.
  • _SNDRAWBATCH 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. However, the 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
Displays and plays 12 notes from octaves 1 through 9 using _SNDRAWBATCH.
OPTION _EXPLICIT

REDIM soundBuffer(0) AS SINGLE
DIM AS LONG oct, octave, note
DIM fq AS SINGLE, noteStr AS STRING

DO
    COLOR 7
    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, noteStr)
        PRINT USING "#####.## \\"; fq, noteStr

        GenWave fq, _SNDRATE, soundBuffer()
        _SNDRAWBATCH soundBuffer()
        _SNDRAWDONE

        DO
            _LIMIT 60
        LOOP WHILE _SNDRAWLEN

        IF LEN(INKEY$) THEN EXIT DO
    NEXT
LOOP

END

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

SUB GenWave (frequency AS SINGLE, sampleRate AS LONG, destBuffer() AS SINGLE)
    REDIM destBuffer(0 TO sampleRate - 1) AS SINGLE

    DIM sndLoop AS LONG

    DO WHILE sndLoop < sampleRate
        destBuffer(sndLoop) = SIN((2! * 4! * ATN(1!) * sndLoop / sampleRate) * frequency) * EXP(-(sndLoop / sampleRate) * 3!)
        sndLoop = sndLoop + 1
    LOOP
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