Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
Is it possible to make a _SNDNEW song this way?
#6
Quote:Instead of playing with _SNDRAW like this, Is it possible to feed the data to a _SNDNEW memory instead so I could have the song with a handle for using it with _SNDPLAY controls?
It is! That's exactly the reason why we added _SNDNEW. Mixing two sounds into the buffer is just a matter of summing the samples of the sounds (assuming they are signed and of the same format).

Here is a crude example of _SNDNEW. GenerateSineWave() simply inserts the samples into the buffer created by _SNDNEW using ProcSoundInsertSampleFrame(). It also mixes a tiny bit of noise into the sine waveform.

Code: (Select All)
OPTION _EXPLICIT

'-------------------------------------------------------------------------------
TYPE ProcSoundType
    handle AS LONG
    buffer AS _MEM
    cursor AS _UNSIGNED _OFFSET
END TYPE
'-------------------------------------------------------------------------------

' Since the sound buffer size cannot be changed after it is created, we'll need to know the exact frames we need in advance
CONST FRAMES = 65536

DIM ps(1 TO 7) AS ProcSoundType, i AS LONG

FOR i = 1 TO 7
    ProcSoundCreate ps(i), FRAMES
NEXT i

GenerateSineWave ps(1), 262!
GenerateSineWave ps(2), 294!
GenerateSineWave ps(3), 330!
GenerateSineWave ps(4), 349!
GenerateSineWave ps(5), 392!
GenerateSineWave ps(6), 440!
GenerateSineWave ps(7), 494!

PRINT "Press 1 - 7"

DIM k AS LONG

DO
    k = _KEYHIT

    SELECT CASE k
        CASE 49
            _SNDPLAYCOPY ProcSoundGetHandle(ps(1))

        CASE 50
            _SNDPLAYCOPY ProcSoundGetHandle(ps(2))

        CASE 51
            _SNDPLAYCOPY ProcSoundGetHandle(ps(3))

        CASE 52
            _SNDPLAYCOPY ProcSoundGetHandle(ps(4))

        CASE 53
            _SNDPLAYCOPY ProcSoundGetHandle(ps(5))

        CASE 54
            _SNDPLAYCOPY ProcSoundGetHandle(ps(6))

        CASE 55
            _SNDPLAYCOPY ProcSoundGetHandle(ps(7))
    END SELECT

    _LIMIT 60
LOOP UNTIL k = 27

FOR i = 1 TO 7
    ProcSoundDelete ps(i)
NEXT i

END

SUB GenerateSineWave (ps AS ProcSoundType, frequency AS SINGLE)
    DIM angleDelta AS SINGLE: angleDelta = _PI(2!) * frequency / _SNDRATE
    DIM angle AS SINGLE

    ProcSoundSeek ps, 0

    DO UNTIL ProcSoundIsFull(ps)
        ProcSoundInsertSampleFrame ps, SIN(angle) + ((RND - RND) * 0.05!)
        angle = angle + angleDelta
    LOOP
END SUB

'-------------------------------------------------------------------------------
SUB ProcSoundDelete (ps AS ProcSoundType)
    IF ps.handle THEN
        _SNDCLOSE ps.handle
        ps.handle = 0
        ps.cursor = 0
    END IF
END SUB

SUB ProcSoundCreate (ps AS ProcSoundType, sampleFrames AS _UNSIGNED LONG)
    ProcSoundDelete ps
    ps.handle = _SNDNEW(sampleFrames, 1, 32) ' hardcoded to create mono 32-bit FP buffer
    ps.cursor = 0
    ps.buffer = _MEMSOUND(ps.handle)
END SUB

FUNCTION ProcSoundGetHandle& (ps AS ProcSoundType)
    ProcSoundGetHandle = ps.handle
END FUNCTION

FUNCTION ProcSoundIsFull%% (ps AS ProcSoundType)
    ProcSoundIsFull = ps.cursor >= ps.buffer.SIZE
END FUNCTION

FUNCTION ProcSoundGetFrames~%& (ps AS ProcSoundType)
    ProcSoundGetFrames = ps.buffer.SIZE \ ps.buffer.ELEMENTSIZE
END FUNCTION

SUB ProcSoundSeek (ps AS ProcSoundType, frame AS _UNSIGNED _OFFSET)
    ps.cursor = frame * ps.buffer.ELEMENTSIZE
END SUB

FUNCTION ProcSoundGetPosition~%& (ps AS ProcSoundType)
    ProcSoundGetPosition = ps.cursor \ ps.buffer.ELEMENTSIZE
END FUNCTION

SUB ProcSoundInsertSampleFrame (ps AS ProcSoundType, sample AS SINGLE)
    _MEMPUT ps.buffer, ps.buffer.OFFSET + ps.cursor, sample AS SINGLE
    ps.cursor = ps.cursor + ps.buffer.ELEMENTSIZE ' ELEMENTSIZE here is 4 since sizeof(single) = 4
END SUB
'-------------------------------------------------------------------------------
Reply


Messages In This Thread
RE: Is it possible to make a _SNDNEW song this way? - by a740g - 09-07-2024, 05:55 PM



Users browsing this thread: 3 Guest(s)