Posted: 28th Mar 2025 12:39
The original function was written by Ric 20 years ago. https://forum.thegamecreators.com/thread/49008

I've ported it to AGK, which has a different memblock header, and clarified some previous unknowns in the original code. You can change the sample rate, but altering the number of channels or bits per sample would require you to also update how the sound frames are written to the memblock. Not hard, I just didn't do it. The samples in the code are taken from my old DBC space invaders game which you can still download here: https://zimnox.com/dbcc/index.php?page=games (surprisingly, it still runs ok on win10)

For instance, 16-bit mono requires writing 2-bytes per frame. (each loop in the function writes 1 frame)
16-bit stereo would write 4-bytes per frame; 2 for left channel and 2 for right channel.
Obviously 8-bit audio is then only 1 byte for mono and 2 bytes for stereo.

+ Code Snippet

// Project: sound 
// Created: 2025-03-28

SetErrorMode(2)
SetWindowTitle( "sound" )
SetWindowSize(640, 480, 0 )
SetSyncRate(0, 0)



explosion    = createsound(1000,2000,3500,5,0.1,0.05,0,0,0,10)
ship_bullet  = createsound(1500,100,4000,0.20,1.00,0.00,0,0.00,0,10.00)
alien_fall   = createsound(2000,100,2000,-0.09,6.78,0.30,649,0.00,0,0.00)
block        = createsound(500,41,4000,0.25,8.60,0.00,0,0.00,0,5.82)
alien_bullet = createsound(1200,30,2000,0.06,3.96,0.00,0,0.00,0,1.06)
title        = createsound(1186,3000,4000,0.0,0.00,1.0,3,0.00,0,10.00)
beat1        = createsound(150,100,8000,0.0,0.0,0.0,0,0.0,0,10.00)
beat2        = createsound(120,100,8000,0.0,0.0,0.0,0,0.0,0,10.00)
ufo          = createsound(500,2000,5000,0.00,0.00,0.02,2,0.00,0,10.00)
   


do
    
    
    if getRawKeyPressed(49) then playSound(explosion)
	if getRawKeyPressed(50) then playSound(ship_bullet)
	if getRawKeyPressed(51) then playSound(alien_fall)
	if getRawKeyPressed(52) then playSound(block)
	if getRawKeyPressed(53) then playSound(alien_bullet)
	if getRawKeyPressed(54) then playSound(title)
	if getRawKeyPressed(55) then playSound(beat1)
	if getRawKeyPressed(56) then playSound(beat2)
	if getRawKeyPressed(57) then playSound(ufo)


    
    Sync()
loop




/*
* Originally written by Ric in DarkBasic
* Ported to AGK by Phaelax
*  
* length (ms)
*/
function createSound(fFrequency as float, length as float, fLoudness as float, fBend as float, fDecay as float, fVibratoSpeed as float, fVibratoDepth as float, fTremeloSpeed as float, fTremeloDepth as float, fAttack as float)
	numChannels = 1             // 1=mono, 2=stereo (changing this requires further altering in the loop)
	bitsPerSample = 16          // 8 or 16 (changing this requires further altering in the loop)
	samplesPerSecond = 44100    // 44.1 kHz
	numFrames = ((length / 1000) * samplesPerSecond) * (bitsPerSample / 8) * numChannels
	
	iSamples as integer
	fRiseInLoudness as float
	fFallInLoudness as float
	theta as float
	phi as float
	
	
	m = createMemblock(numFrames*(bitsPerSample/2)+12)
	
		
	setmemblockInt(m, 0, numChannels)      // number of channels
	setmemblockInt(m, 2, bitsPerSample)    // number of bits per sample
	setmemblockInt(m, 4, samplesPerSecond) // samples per second
	setmemblockInt(m, 8, numFrames)        // number of frames in sound data

	
	
	memPos = 12
	
	fRiseInLoudness = fLoudness
	
	for x = 1 to numFrames
		outInteger = trunc(sin((x/122.5)*(fFrequency+fVibratoDepth*sin(theta)))*(fLoudness-fFallInLoudness-fRiseInLoudness+fTremeloDepth*sin(phi))) * 3.0
		if outInteger < -32767 then outInteger = -32767    // is this the valid range?
		if outInteger > 32767  then outInteger = 32767     //
		
		inc theta, fVibratoSpeed
		inc phi, fTremeloSpeed
		dec fFrequency, fBend
		
		if fFallInLoudness < fLoudness then inc fFallInLoudness, fDecay
		if fRiseInLoudness > 0         then dec fRiseInLoudness, fAttack
		
		setMemblockShort(m, memPos, outInteger)
		inc memPos, 2
	next x
	
	snd = createSoundFromMemblock(m)
	deleteMemblock(m)
	
endfunction snd