I noticed in task manager if I use GENSOUND to load and immediately play audio, the memory usage goes up and does not come down. What is the procedure for using GENSOUND to immediately play a sound, and then free the memory when it's not being played anymore??
dont use GENSOUND for replay the sound. Its just a ID. All its does is fine a empty ID to been used for LOADSOUND and such commands, not to been used for play each sound.
I suppose Darmakwolf if you after play do, Loadsound "something doens't exist" you can free the memory, exactly equal than load an Sprite or loadanim... Using GenSound it's the same like using a variable, ins't?¿, I never used GenSprite or GenSound, I prefer put the ID manually.
Well the problem is, I need this to be dynamic. Making specific sound IDs is not optimal here. Each enemy in the game has a unique sound .wav file given the same name of the monster. I don't want to have to hard code the IDs... there really should be a way to free up the used memory from gensound.
I'm not sure DarmaKwolf...
but in this thread
http://www.glbasic.com/forum/index.php?topic=7569.msg62741#msg62741
You can find this Schranz0r 's code :
FUNCTION LoadSprite2: name$
LOCAL id% = GENSPRITE()
LOADSPRITE name$, id
RETURN id
ENDFUNCTION
FUNCTION FreeSprite: id
LOADSPRITE "",id //delete the sprite
ENDFUNCTION
Chnaginf loadsprite for load sound?¿... I'm not sure of it's what you need... but better wrong than don't say nothing.
Thanks for the help, but I solved it! I even figured out a way of side-stepping one GLB annoyance: IDs for sound. I like being able to specify in code what audio file name I am playing without having to look up an ID every time. Here's how I did it:
made a Wavs folder in Media with all my Wavs.
Created an array of types. This type holds an ID and a file name.
At the beginning of the code it loads all Wavs into the array and stores their name.
When the game calls audio through a function that takes one argument: file name. The function searches the array for an index with a matching filename, and it plays its id. Now anywhere in code I just type:
fplay("click.wav") and it plays, and no memory leak! =D
The only way is to use LOADSOUND "".id to free the memory used.
Each sample stays in memory until removed - if you want on-demand sounds then you would need to use PLAYMUSIC or use FMOD or something and treat everything as music.
mrTAToad, read my previous post. I found a way to load them all into memory at load and call them by name instead of ID.
Thanks Darmakwolf I thinked in your idea sometimes... for now I leave my code equal, but your mode can be very usefull for handle the files in the runtime... Thanks :good:
im did the same thing, thinks its could been done with the very old tvar codesnippes as well. im have never have been fan of numbered ID's but its can overcome of course in a creative ways like those. Personly im did using names as well (etc SoundLoad("sfx/complete.wav", "complete"), but its the same thing in the end.
Mine works like this.
TYPE wavfile
id%
name$
ENDTYPE
GLOBAL wavs[] AS wavfile
loadwavs()
FUNCTION loadwavs:
//Loads ALL .wav files into memory.
LOCAL ok,cur$,num,num_dir,num_file,files$[]
SETCURRENTDIR("Wavs")
cur$ = GETCURRENTDIR$()
num = GETFILELIST("*.wav", files$[])
num_dir = INTEGER(num / 0x10000)
num_file = MOD(num, 0x10000)
DIM wavs[BOUNDS(files$[], 0)]
FOR i=0 TO BOUNDS(files$[], 0)-1
wavs[i].name$ = files$[i]
wavs[i].id = i
LOADSOUND wavs[i].name$,wavs[i].id,soundbuffers
NEXT
SETCURRENTDIR("..")
ENDFUNCTION
FUNCTION fplay:file$
LOCAL n
FOR n = 0 TO LEN(wavs[])-1
IF wavs[n].name$ = file$
LOCAL ok% = PLAYSOUND(wavs[n].id,0,1)
ENDIF
NEXT
ENDFUNCTION
Then you can just call fplay("sound.wav") and it plays :)
Edit: Please use the code tags, makes it easier to read /Moru
Thanks I get to copy the code for future developments... thanks a lot. :good: :good: :good:
Quote from: mentalthink on 2013-Oct-11
Thanks I get to copy the code for future developments... thanks a lot. :good: :good: :good:
Go right ahead! Anything to help make stuff easier. Glad someone can make use of it :D
Nice work, you are doing it just the way it's supposed to be done :-)
Just have a couple of things:
FUNCTION fplay:file$
LOCAL n
FOR n = 0 TO LEN(wavs[])-1
IF wavs[n].name$ = file$
LOCAL ok% = PLAYSOUND(wavs[n].id,0,1)
// Should the function not exit here since it found the sound already?
// instead of looking thru the whole array
ENDIF
NEXT
ENDFUNCTION
This sort of code lends itself very well to FOREACH constructions. Try it, it will make life much easier :-)
Also, when you want to load more sounds, this function will replace all the old sounds possibly leaving some lost in memory. You need to use GENSOUND to find out where the last free ID is. If you want to replace the old sounds you need to first go through your array and delete the sounds from memory before you load the next set. You delete sounds by loading a sound that does not exist into the same ID as the old sound.
eg: LOADSOUND "", 0, 1
// So instead of doing:
wavs[i].id = i
// you can just as well do:
wavs[i].id = GENSOUND()
This will find the next free space for a sound in memory
You should call BREAK after you played the sound. I mean if you have 100 wavs loaded, call fplay and the sound that you want to play is number 3, there is no need to look the rest of the array and check the other 97 entrys.
Besides this, I would not like the string checks, strings are to slow and a waste of exection speed and memory space IMHO.
Yes, that is exactly what I meant. About the string check, depending on how you build your type, you can have all the data connected to the monster like what sprite ID, what sound ID, behaviour and whatever in the same type. That way you don't have to wonder what sound to play, just play the sound connected to the monster or object.
Ah hmm right, there is your comment. :D
At least I did mention BREAK so it wasnt a complete usless post. Of cause there is no point in storing the return value of LOADSOUND in the local variable ok%, if you never check/use it, you can just get rid of everything that stands before LOADSOUND.
Quote from: kanonet on 2013-Oct-11
You should call BREAK after you played the sound. I mean if you have 100 wavs loaded, call fplay and the sound that you want to play is number 3, there is no need to look the rest of the array and check the other 97 entrys.
Besides this, I would not like the string checks, strings are to slow and a waste of exection speed and memory space IMHO.
I noticed that after I posted it and fixed it :P I didn't get much sleep that day. :D
Quote from: kanonet on 2013-Oct-11
You should call BREAK after you played the sound. I mean if you have 100 wavs loaded, call fplay and the sound that you want to play is number 3, there is no need to look the rest of the array and check the other 97 entrys.
Besides this, I would not like the string checks, strings are to slow and a waste of exection speed and memory space IMHO.
Well I was half awake when I typed the code, I realized it lacked return. In this case, I have no problem with sacrificing a negligible amount of performance for ease of programming and flexibility. My game uses no more than 45 MB total at any given time of RAM, and deals with the tiniest resolution (256x224...) I am not trying to squeeze ounces of speed out of a complex 3D game. In my case, it's very useful for a small sprite-based project. I'm pretty sure even my grandmother's computer has 4GB RAM.
im do the same thing with strings in Greedy Mouse, howover even more complex than those code for avoid numbered ids. So its should been no problem at all. Alternative most time the sound mightbeen the same, so you could do a STATIC lastsound as well, which might could reduce cpu time......
Im also never liked the numbered id of things. Alternative you could also do GENSOUND to variables and uses those as ID as well.
But thee is no problems with strings well sound as well images.