GLBasic forum

Main forum => GLBasic - en => Topic started by: Darmakwolf on 2013-Oct-10

Title: GENSOUND and Memory
Post by: Darmakwolf on 2013-Oct-10
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??
Title: Re: GENSOUND and Memory
Post by: spacefractal on 2013-Oct-10
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.
Title: Re: GENSOUND and Memory
Post by: mentalthink on 2013-Oct-10
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.
Title: Re: GENSOUND and Memory
Post by: Darmakwolf on 2013-Oct-10
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.
Title: Re: GENSOUND and Memory
Post by: mentalthink on 2013-Oct-10
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 : 

Code (glbasic) Select
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.
Title: SOLVED!
Post by: Darmakwolf on 2013-Oct-10
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
Title: Re: GENSOUND and Memory
Post by: MrTAToad on 2013-Oct-10
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.
Title: Re: GENSOUND and Memory
Post by: Darmakwolf on 2013-Oct-10
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.
Title: Re: GENSOUND and Memory
Post by: mentalthink on 2013-Oct-10
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:
Title: Re: GENSOUND and Memory
Post by: spacefractal on 2013-Oct-10
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.
Title: Re: GENSOUND and Memory
Post by: Darmakwolf on 2013-Oct-11
Mine works like this.
Code (glbasic) Select

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
Title: Re: GENSOUND and Memory
Post by: mentalthink on 2013-Oct-11
Thanks I get to copy the code for future developments... thanks a lot.  :good: :good: :good:
Title: Re: GENSOUND and Memory
Post by: Darmakwolf on 2013-Oct-11
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
Title: Re: GENSOUND and Memory
Post by: Moru on 2013-Oct-11
Nice work, you are doing it just the way it's supposed to be done :-)
Just have a couple of things:

Code (glbasic) Select
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

Code (glbasic) Select

// 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
Title: Re: GENSOUND and Memory
Post by: 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.
Title: Re: GENSOUND and Memory
Post by: Moru on 2013-Oct-11
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.
Title: Re: GENSOUND and Memory
Post by: kanonet on 2013-Oct-11
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.
Title: Re: GENSOUND and Memory
Post by: Darmakwolf on 2013-Oct-11
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
Title: Re: GENSOUND and Memory
Post by: Darmakwolf on 2013-Oct-12
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.
Title: Re: GENSOUND and Memory
Post by: spacefractal on 2013-Oct-12
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.