GENSOUND and Memory

Previous topic - Next topic

Darmakwolf

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??

spacefractal

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.
Genius.Greedy Mouse - Karma Miwa - Spot Race - CatchOut - PowerUp Elevation - The beagle Jam - Cave Heroes 2023 - https://spacefractal.itch.io/

mentalthink

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.

Darmakwolf

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.

mentalthink

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.

Darmakwolf

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

MrTAToad

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.

Darmakwolf

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.

mentalthink

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:

spacefractal

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.
Genius.Greedy Mouse - Karma Miwa - Spot Race - CatchOut - PowerUp Elevation - The beagle Jam - Cave Heroes 2023 - https://spacefractal.itch.io/

Darmakwolf

#10
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

mentalthink

Thanks I get to copy the code for future developments... thanks a lot.  :good: :good: :good:

Darmakwolf

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

Moru

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

kanonet

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.
Lenovo Thinkpad T430u: Intel i5-3317U, 8GB DDR3, NVidia GeForce 620M, Micron RealSSD C400 @Win7 x64