Playing a segment of audio

Questions about the LÖVE API, installing LÖVE and other support related questions go here.
Forum rules
Before you make a thread asking for help, read this.
Post Reply
MachineCode
Citizen
Posts: 70
Joined: Fri Jun 20, 2014 1:33 pm

Playing a segment of audio

Post by MachineCode »

Just a question about audio and the Source:play(). Is there any way to play a section from one point to another? I am thinking of a sound effects library in a single source that has a lookup table of start and end for each effect.

I can see that using a :seek(start) then :play() and a timer activated :pause() would do this.
Alternatively, loading all the sound effects separately would also work, but I am not sure how much overhead this would involve.

Is there a reason that a Source:play(start, finish) is not useful?
User avatar
raidho36
Party member
Posts: 2063
Joined: Mon Jun 17, 2013 12:00 pm

Re: Playing a segment of audio

Post by raidho36 »

Because you can simply use multiple sources and thus not have to manage the audio internals manually.
User avatar
zorg
Party member
Posts: 3441
Joined: Thu Dec 13, 2012 2:55 pm
Location: Absurdistan, Hungary
Contact:

Re: Playing a segment of audio

Post by zorg »

Short answer, probably performance reasons.

Also, with 0.11, you will be able to create a queueable source, and you can manually push in as many samples from as many sounddata objects as you want (manually mixed into another sounddata, of course); allowing arbitrary playback from custom points or even reverse playback.
Me and my stuff :3True Neutral Aspirant. Why, yes, i do indeed enjoy sarcastically correcting others when they make the most blatant of spelling mistakes. No bullying or trolling the innocent tho.
MachineCode
Citizen
Posts: 70
Joined: Fri Jun 20, 2014 1:33 pm

Re: Playing a segment of audio

Post by MachineCode »

Thanks zorg. Is there a link to the details of queuable source?

One of the other things I want to try is generating a sound from a parametric descriptor held in a table or maybe generated by procedure. This may result in sample data of arbitrary length.

Using 0.10, for each instance I could make a new SoundData, :setSample( i, sample ) the computed samples in, then make a Source and play it. Alternatively, make a big general SoundData once, push the computed samples in right justified, make a Source, then seek and play. I don't have any idea about how expensive these operations are - maybe they are cheap enough that it doesn't matter.

If there is a more streamlined way to do this in 0.11, that sounds promising.
User avatar
zorg
Party member
Posts: 3441
Joined: Thu Dec 13, 2012 2:55 pm
Location: Absurdistan, Hungary
Contact:

Re: Playing a segment of audio

Post by zorg »

MachineCode wrote: Sun Aug 20, 2017 4:45 am Thanks zorg. Is there a link to the details of queuable source?

One of the other things I want to try is generating a sound from a parametric descriptor held in a table or maybe generated by procedure. This may result in sample data of arbitrary length.

Using 0.10, for each instance I could make a new SoundData, :setSample( i, sample ) the computed samples in, then make a Source and play it. Alternatively, make a big general SoundData once, push the computed samples in right justified, make a Source, then seek and play. I don't have any idea about how expensive these operations are - maybe they are cheap enough that it doesn't matter.

If there is a more streamlined way to do this in 0.11, that sounds promising.
Not really, slime et al make new docs after they are sure all new features are locked for the new release, so for now, you can look at the minor branch of the source code on bitbucket, see what stuff it takes (for convenience, its paramlist is the following: samplingrate, bitdepth, channelcount)



Even if you have arbitrary length data you want to generate, you'd still use shorter buffers and keep track of how many samplepoints of data you generated; that's the usual way. You shouldn't create SoundData objects seconds long, for instance. (Unless they store literal samples, unchanging that is.) Buffer lengths typically go from 1 ms to a few hundred ms (1000 ms is 1 second); though the sampling rate's inverse, the sampling period is about 20 microseconds, which is a thousandth of a milisecond.



The 0.10 approach is only problematic for two reasons, creating multiple SoundData objects take too long (relatively speaking), though you can alleviate that by using just 1, 2 or 3, of the same sizes, and always writing data back to them in turns; the bigger issue is that you need to also create new Source objects with those (and normal Sources don't have :refresh methods like how Image objects have, that would get any modified data from their "paired" ImageData objects.) and that again, both takes up time, and it's hard to sync them up perfectly so they play gapless(ly?).

Even if the constant construction of these objects isn't an issue processing speed or memory-wise, the not quite gapless playback is.



In 0.11, QueueableSources give you the ability to just use on of those Source objects, and queue up SoundData objects ("Buffers") for continuous playback. All queued data will be played back in a serial manner, one after another, samplepoint-perfectly.

I myself don't consider this a downside that what you cannot do is queue data up at a specific time/samplepoint... by default i mean; you can write logic for that as well, though at the moment, i find that idea not that useful.
Me and my stuff :3True Neutral Aspirant. Why, yes, i do indeed enjoy sarcastically correcting others when they make the most blatant of spelling mistakes. No bullying or trolling the innocent tho.
MachineCode
Citizen
Posts: 70
Joined: Fri Jun 20, 2014 1:33 pm

Re: Playing a segment of audio

Post by MachineCode »

OK, so that means you could continuously synthesise audio using a single queueableSource and use a set of SoundData buffers in a round robin configuration to receive the output of your generator using setSample. These buffers would be refilled, then tacked on to the queue for the source to play.

In that case, to synth an arbitrary sound effect, I would have a set of short soundData buffers of 50 - 100mS each, fill them (with the first zero left padded), then queue the set to be played from a queued source. That seems to be a workable solution, assuming setSample is efficient.
User avatar
zorg
Party member
Posts: 3441
Joined: Thu Dec 13, 2012 2:55 pm
Location: Absurdistan, Hungary
Contact:

Re: Playing a segment of audio

Post by zorg »

MachineCode wrote: Sun Aug 20, 2017 3:51 pm OK, so that means you could continuously synthesise audio using a single queueableSource and use a set of SoundData buffers in a round robin configuration to receive the output of your generator using setSample. These buffers would be refilled, then tacked on to the queue for the source to play.
Exactly! (Though let me edit this post with something meaningful as well: You don't even need to double-buffer stuff; one's enough, at least it is on my end.)
MachineCode wrote: Sun Aug 20, 2017 3:51 pm In that case, to synth an arbitrary sound effect, I would have a set of short soundData buffers of 50 - 100mS each, fill them (with the first zero left padded), then queue the set to be played from a queued source. That seems to be a workable solution, assuming setSample is efficient.
It is as efficient as using ffi and setting the SD objects directly, so you don't have to worry about that.
Also, if you want a working example: https://github.com/zorggn/LoveTracker
Last edited by zorg on Mon Aug 21, 2017 4:06 pm, edited 1 time in total.
Me and my stuff :3True Neutral Aspirant. Why, yes, i do indeed enjoy sarcastically correcting others when they make the most blatant of spelling mistakes. No bullying or trolling the innocent tho.
MachineCode
Citizen
Posts: 70
Joined: Fri Jun 20, 2014 1:33 pm

Re: Playing a segment of audio

Post by MachineCode »

Thanks again zorg. I think I have enough to start playing around with this now.
Post Reply

Who is online

Users browsing this forum: No registered users and 88 guests