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 <jasperisja...@gmail.com> 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
>> <https://stackoverflow.com/questions/57960451/how-can-i-play-a-portion-of-an-audio-file-in-a-loop-in-pygame>,
>> 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
>>
>>

Reply via email to