Sound samples back to back - gapless

BlitzMax Forums/BlitzMax Programming/Sound samples back to back - gapless

Mark1nc(Posted 2006) [#1]
I'm trying to play music loops back to back - using ChannelPlaying() to check when previous sample is complete.
Problem - usually a few ms gap inbetween (due to sound finishing a few ms before I get back to check or other delays.



I was thinking of using elapsed time compared to sample length.
Get MilliSecs() at start of playback.
Compare to current MilliSecs() every time I check (approx every 16ms)

Start next sample when the time left is less than 32ms.

Do you think that will work?
Any other ideas?


H&K(Posted 2006) [#2]
Errrr, whats wrong with a few millisecs?
I would setup an event that gets posted every so often (At The max delay you accept), then check when I catch it.

But even then you have no garrentee that it would work, cos the events could be stuck in a big que.

Maybe yours is a better way. But honestly a "few millisecs" of no music?


Smurftra(Posted 2006) [#3]
it can be annoying to have a few ms of no sound if what he wants to achieve is this (What i'm trying to do):


My song is seperated into 8 beats wavs i have 20 normal wavs, 10 omg i'm going to die wavs and 10 i should hurry up wavs. Each of them can fit with any other wav. Now when the 'mood' changes, i want to switch to the correct bank of wavs, in which i play a random wav everytime the previous wav is over. Now with that in mind, i cant afford gaps between playing my wavs.


Mark1nc(Posted 2006) [#4]
Smurftra - that's it exactly

Right now - I cue up the next snippet to play and when ChannelPlaying comes back false - I play it.

What I need is a 'ChannelAlmostDone()' function! :)


Scott Shaver(Posted 2006) [#5]
I haven't messed with the sound stuff so maybe this can't be done but...

Can you test to see how much data is left in a channel and if it is below a certain theshold start playing the new sound?


Smurftra(Posted 2006) [#6]
Scott:

I was thinking of something like that, exept i'd have to manually add some nonoise time at the start of the next wave and play it on a different channel.
Havent tried that yet as i decided not to work on sound/music until i decide on a free library (fmod, bass, etc)

But basicaly, i think it would have to be like

If TimeTillEndOfSong < 20 ms Then
Add TimeTillEndOfSong ms of nosound to next wave
play next wave
End if


H&K(Posted 2006) [#7]
When you start the channal get the music lenght, post an event hook to be called after that time. When you catch the hook, start the channel with the next music.

But honestly both of you. Just check each frame. The most delay even at 60Htz would be 17MilliSecs


Mark1nc(Posted 2006) [#8]
I was only checking once every 33 ms.
I've reduce it to much smaller now by checking several times per frame.
1 right after segment number could have been updated.
1 after updating all objects
1 after drawing all object
(Any time that is left in the 33ms frame was used as Delay time)
now - I Delay time/4, check channel, Delay time/4 etc.

The gaps are almost unnoticeable now!


Smurftra(Posted 2006) [#9]
The gaps are almost unnoticeable now!
----

i'm a perfectionist and im looking for a solution without the 'almost' :)


SculptureOfSoul(Posted 2006) [#10]
Hmm, I'd like to take a crack at this problem. One question though, how do you determine just how much time is left for a sample? I couldn't find anything in the docs (surprise, surprise :)


H&K(Posted 2006) [#11]


If you place this Type in your code, then invoke it with
Global SoundCheckBeat:TBeat =	New TBeat.Create(1 ,CatchSoundCheckBeat)

Then every milli second (Well not every milli sec, cos Its multi tasking, but yes let say ever milli) it will call
Function CatchSoundCheckBeat()
Where you have a looksee if the sound has finished, and if it has start the new one.

But really guys, at 100Hz thats a max gap of only 10 milli


REDi(Posted 2006) [#12]
H&K that will end up flooding the event list

This is VERY easy to do with openal, but you would need to que at least 3 sound buffers, then when the first buffer has finished playing you release it and just add another one to the end. so it creates an endless stream of audio.


SculptureOfSoul(Posted 2006) [#13]
Is there any internal method or field to get the length of a TSound object?


H&K(Posted 2006) [#14]
@Redi

It does not "Flood" the event list, it (At most) will put 1000 events on the list in a second.
Each one then calls that one function. And as long as you are quick , no problem.

Even if you get like 200 of them in a row, its still just a quick looksee if the sound has finished.

If you want to know to the exacpt millisecond if the sound has finished, then looksee every millisecond.

@RediAgian,

I personaly wouldnt bother, As I think they could looksee every 5milli (say), and then they only have 200 events a second. Or just look every frame, but they wanted "To the Milli second"


REDi(Posted 2006) [#15]
sorry i was thinking more about the delay from Flipping, if you have "flip false" it will work ok (tick every millisecond), but if you had "flip true" (i always do for games) it would fire the events in chuncks every 10 or whatever millisecs.

i think even with flip false, any major game logic/rendering would stop it from hooking the events every millisec, you would probably end up with a flood (10+) of checks every 10+ millisecs.


H&K(Posted 2006) [#16]
Oh I agree on the major locic/rendering, but for this, were they simply want to call channelplaying(), I think a millisecond is well doable.