Hello SoftMotion,
Today I found some time to create a simple set of functions to load .wav files to an array.
It just misses a function to merge sounds.
You can even apply a lowpass or highpass filter to the sound array data. The visualisation of the sound data
can help you to understand whats going on. Do some functions with modfications - its nearly a full .wav editor
I've attached you the whole project with media.
// Project: GenerateSoundFromArray
// Alex Schmidt 2016
// Created: 04.11.2016
// set window properties
SetWindowTitle( "GenerateSoundFromArray" )
SetWindowSize( 1280,720, 0 )
// set display properties
SetVirtualResolution( 1280,720 )
SetOrientationAllowed( 1, 1, 1, 1 )
type OA_SOUNDGENERATOR_DEF
name$ as string
channels as integer
bits as integer
hz as integer
totallength as integer
channel1 as integer[]
channel2 as integer[]
endtype
global dim OAGenSoundArray[] as OA_SOUNDGENERATOR_DEF
sound = LoadSound("Right Stereo Test - Right Stereo Test.wav")
// this command can load a sound to the array
SndArr = LoadSoundToArray("Right Stereo Test - Right Stereo Test.wav",sound)
// this command can create a new sound from the array,
// this should be called after you have manipulated the OAGenSoundArray at SndArr
// keep in mind that agk can currently only save 8 and 16 bit sounds due to limitations in CreateSoundFromMemblock
newsound = CreateSoundFromArray(SndArr)
do
// this command draws the Soundarray to screen
DisplaySoundArray(SndArr,40,300,800,200)
if GetRawKeyPressed(27)=1 then end
Sync()
loop
function LoadSoundToArray(name$,soundnum)
// define channel signal variables
outWord1 as integer
outWord2 as integer
position as integer
// create sound memblock
SndMem = CreateMemblockFromSound(soundnum)
// increase array size
OAGenSoundArray.length = OAGenSoundArray.length + 1
arraypos = OAGenSoundArray.length
OAGenSoundArray[arraypos].name$ = name$
OAGenSoundArray[arraypos].channels = GetMemblockShort(SndMem,0)
OAGenSoundArray[arraypos].bits = GetMemblockShort(SndMem,2)
OAGenSoundArray[arraypos].hz = GetMemblockInt(SndMem,4)
OAGenSoundArray[arraypos].totallength = GetMemblockInt(SndMem,8)
samples = OAGenSoundArray[arraypos].totallength/(OAGenSoundArray[arraypos].channels/(OAGenSoundArray[arraypos].bits/8.0))
position=12
for i=0 to samples
// increase channel array
// mono
OAGenSoundArray[arraypos].channel1.length = OAGenSoundArray[arraypos].channel1.length + 1
// stereo
if OAGenSoundArray[arraypos].channels=2
OAGenSoundArray[arraypos].channel2.length = OAGenSoundArray[arraypos].channel2.length + 1
endif
chpos = OAGenSoundArray[arraypos].channel1.length // both have the same length, so take that of channel 1
if (OAGenSoundArray[arraypos].bits/8)=1 // if we are in the 8 bit mode
// mono
outWord1 = GetMemblockByte(SndMem,position) // 0-level is at 127 Rage:(0 to 255)
inc position
// stereo
if OAGenSoundArray[arraypos].channels=2
outWord2 = GetMemblockByte(SndMem,position) // 0-level is at 127 Rage:(0 to 255)
inc position
endif
endif
if (OAGenSoundArray[arraypos].bits/8)=2 // if we are in the 16 bit mode
// mono
outWord1 = GetMemblockShort(SndMem,position) // 0-level is at 0 Rage:(-32768 to 32768)
inc position,2
// stereo
if OAGenSoundArray[arraypos].channels=2
outWord2 = GetMemblockShort(SndMem,position) // 0-level is at 0 Rage:(-32768 to 32768)
inc position,2
endif
endif
// write Outword to the array
// mono
OAGenSoundArray[arraypos].channel1[chpos] = outWord1
// stereo
if OAGenSoundArray[arraypos].channels=2
OAGenSoundArray[arraypos].channel2[chpos] = outWord2
endif
if syndelay=0
print("loading sound into array...")
print(str(i)+"/"+str(samples))
syndelay=2000
sync()
else
syndelay=syndelay-1
endif
next i
endfunction arraypos
function DisplaySoundArray(arraypos,px,py,sx,sy)
print("Name: "+OAGenSoundArray[arraypos].name$)
print("Channels: "+str(OAGenSoundArray[arraypos].channels))
print("Bits: "+str(OAGenSoundArray[arraypos].bits))
print("Hz: "+str(OAGenSoundArray[arraypos].hz))
print("Totallength: "+str(OAGenSoundArray[arraypos].totallength))
color = MakeColor(255,255,255)
color2 = MakeColor(0,255,255)
// borders
// =
DrawLine(px,py,px+sx,py,color,color)
DrawLine(px,py+sy,px+sx,py+sy,color,color)
// ||
DrawLine(px,py,px,py+sy,color,color)
DrawLine(px+sx,py,px+sx,py+sy,color,color)
start_x# = px
start_y# = py+sy/2.0
// 2nd border for stereo
// borders
// =
DrawLine(px,py+sy,px+sx,py+sy,color,color)
DrawLine(px,py+sy+sy,px+sx,py+sy+sy,color,color)
// ||
DrawLine(px,py+sy,px,py+sy+sy,color,color)
DrawLine(px+sx,py+sy,px+sx,py+sy+sy,color,color)
start_x# = px
start_y# = py+sy/2.0
start2_x# = px
start2_y# = py+sy+sy/2.0
samples = OAGenSoundArray[arraypos].channel1.length
if OAGenSoundArray[arraypos].channels=1
DT# = 255.0
else
DT# = 32768.0*2.0
endif
x_scale# = ((sx*1.0)/(samples * 1.0))*1.0
y_scale# = (sy*1.0 / (DT# * 1.0))*1.0
for i=0 to samples
// mono
signal# = OAGenSoundArray[arraypos].channel1[i]
// stereo
if OAGenSoundArray[arraypos].channels=2
signal2# = OAGenSoundArray[arraypos].channel2[i]
endif
// if we are in 8 bit mode, shift array 127 units down
if OAGenSoundArray[arraypos].bits/8=1
signal#=signal#-(255/2.0)
endif
// mono
if i=<(samples-1)
DrawLine((start_x#+i*x_scale#),start_y#-oldsignal#*y_scale#,(start_x#+(i+1)*x_scale#),start_y#-signal#*y_scale#,color2,color2)
endif
oldsignal#=signal#
// stereo
if OAGenSoundArray[arraypos].channels=2
if i=<(samples-1)
DrawLine((start2_x#+i*x_scale#),start2_y#-oldsignal2#*y_scale#,(start2_x#+(i+1)*x_scale#),start2_y#-signal2#*y_scale#,color2,color2)
endif
oldsignal2#=signal2#
endif
next i
endfunction
// waveform 0=sinus 1=saw 2=sqare wave
function CreateSoundFromArray(arraypos)
// define temporary variables
outWord1 as integer
outWord2 as integer
position as integer
// header bytes
channels = OAGenSoundArray[arraypos].channels
bits = OAGenSoundArray[arraypos].bits
hz = OAGenSoundArray[arraypos].hz
samples = OAGenSoundArray[arraypos].channel1.length
totallength=(samples*(bits/8)*channels) ` TOTAL LENGTH (4 bytes)
// create a new, empty memblock
SndMem=CreateMemblock(12+totallength)
// header total size 12 bytes
// Header for a wav file
SetMemblockShort(SndMem,position,channels)
inc position,2
SetMemblockShort(SndMem,position,bits)
inc position,2
SetMemblockInt(SndMem,position,hz)
inc position,4
SetMemblockInt(SndMem,position,totallength)
inc position,4
// now position = 12
for i=0 to samples
// left signal
outSignal_1#=OAGenSoundArray[arraypos].channel1[i]
outWord1=outSignal_1#
// right signal
if channels=2
outSignal_2#=OAGenSoundArray[arraypos].channel2[i]
outWord2=outSignal_2#
endif
if (bits/8)=1 // if we are in the 8 bit mode
SetMemblockByte(SndMem,position,outWord1) // 0-level is at 127 Rage:(0 to 255)
inc position
if channels=2
SetMemblockByte(SndMem,position,outWord2) // 0-level is at 127 Rage:(0 to 255)
inc position
endif
endif
if (bits/8)=2 // if we are in the 16 bit mode
SetMemblockShort(SndMem,position,outWord1) // 0-level is at 0 Rage:(-32768 to 32768)
inc position,2
if channels=2
SetMemblockShort(SndMem,position,outWord2) // 0-level is at 0 Rage:(-32768 to 32768)
inc position,2
endif
endif
next i
// create sound file from memblock
soundnumber = CreateSoundFromMemblock(SndMem)
// memblock no longer required
DeleteMemblock(SndMem)
endfunction soundnumber
View from AGK:
View from Audio Editor:
seems legit