[Author Prev][Author Next][Thread Prev][Thread Next][Author Index][Thread Index]

Re: [pygame] Question about sound effect playback



I'd assume that deep under the hood, one should be able to advance whatever read pointer to the soundbuffer is used by the channel.

Is that correct?


On Wed, Jul 14, 2021, 15:51 Jasper Phillips <jasperisjaded@xxxxxxxxx> wrote:
Thanks Daniel, that works! Plus using soundarray should be faster than first converting to raw.

So far I don't need to cache, but rollback netcode demands lots of CPU so I suspect I probably will end up optimizing this to improve robustness vs lag.

A pity mixer won't let you start Channels partway through a Sound, as then there'd be no CPU cost.

On Wed, Jul 14, 2021 at 9:15 AM Daniel Foerster <pydsigner@xxxxxxxxx> wrote:
Instead of using the raw sound binary data and winging the slice, I'd recommend throwing things into a sndarray.


def clip_sound(sound, start_time):
    freq = pygame.mixer.get_init()[0]
    offset = round(freq * start_time)
    arr = pygame.sndarray.array(sound)
    clipped = arr[offset:]
    return pygame.sndarray.make_sound(clipped)


It would be worthwhile probably to cache the frequency and the converted array and only do the slice + flip back to Sound but that's premature optimization right now.

On Wed, Jul 14, 2021, 03:15 Jasper Phillips <jasperisjaded@xxxxxxxxx> wrote:
Alas, that is precisely what I did:

def clipEffect( effect, startTime ):
    raw       = effect.get_raw()
    rawStart  = int( len(raw) * startTime / effect.get_length() )
    return mixer.Sound( raw[rawStart:] )

Depending on what sound effect I play the code either:
- Works fine!
- Horribly distorts the audio, though the original Sound plays fine...

Hi Jasper. Try the fourth answer here, by Ted Klein Bergman.

On 7/13/2021 4:24 PM, Jasper Phillips wrote:
I'm working on a networked action game with rollback netcode, and so I need to play sound effects starting an arbitrary amount of time from the beginning of the file so they sync up with game events.

pygame.mixer.music does this via set_pos()... but apparently there's no corresponding method when playing effects directly via a Channel. Unfortunate, as I need to use Channels!

The best I've come up with is to use Sound.get_raw(), trim the starting bytes off then, create a new Sound.  But this fails several different ways, I'm guessing because I'm arbitrarily slicing the bytes and there's some format details I don't know.


Does anyone have any tips for hacking raw Sound data, or perhaps some better approach?

-Jasper