Re: [pygame] Re: Some way to pickle or otherwise save a pygame.mixer.Sound object?
The wav format is not super complicated, you could split every track into 15 second chunks and read them off disk as needed so you always have one extra 15 second chunk than you currently need. You could probably even make fake file objects that mapped to the same file on disk using seeks, and use that to buffer over the files. Then you could throw out the buffers as they were used up. On Sat, Jun 9, 2018, 2:45 PM Christopher Night wrote: > Just to be clear, you need to play two different multi-minute sounds at > once? > > Because your example has one 13-minute track and one 3-second track. If > those are the sounds you need to play at the same time, why don't you just > preload the 3-second one into a pygame.mixer.Sound object and play it > whenever you need it, and play the 13-minute one with pygame.mixer.music? > > On Fri, Jun 8, 2018 at 7:48 PM Alec Bennett wrote: > >> I see that pygame.mixer.Sound supports OGG, I guess I should try that. >>> I've never used OGG before, and I wonder if it supports OGG if MP3 would be >>> an easy addition? >>> >> >> Well so much for using OGG (and probably MP3) to speed up preloading. >> With my 13 minute mono soundfiles, it takes 7.3 seconds to preload the wav >> file (44.1hz, 16 bit, mono) and 43.6 seconds to preload the OGG file... I >> have a feeling it's uncompressing it during preload. >> >>> >> My project needs polyphony, but really only the ability to play two >> sounds at once. I'm currently using this method because it supports that: >> >>> >> channel = 1 # or 2 >> >>> sound_obj = pygame.mixer.Sound("whatever.wav") # long preload at this >> step >> >>> channel = pygame.mixer.Channel(channel) >> >>> channel.play(sound_obj) >> >>> >> This method of playing MP3 works beautifully without preloading, but can >> only play one sound at a time: >> >>> >> pygame.mixer.init() >> >>> pygame.mixer.music.load("whatever.mp3") >> >>> pygame.mixer.music.play() >> >>> pygame.event.wait() >> >>> >> I don't imagine anyone knows of a way to play two sound files >> simultaneously using pygame.mixer.music? Or some other solution in Python >> under Linux that would do it reliably? I suppose I could slave two >> instances of mplayer, but I'd of course prefer to not be forking out >> processes. >> >> If anyone's curious about the files I'm trying to load, I posted some >> test files here: >> >> sinkingsensation.com/dropbox/icecream.zip >> >> >> >> >> On Thu, Jun 7, 2018 at 2:30 PM, Alec Bennett wrote: >> >>> >>> >>> On Thu, Jun 7, 2018 at 7:59 AM, Christopher Night < >>> cosmologi...@gmail.com> wrote: >>> I recommend saving the sound as a raw buffer. First in a separate script: sound = pygame.mixer.Sound("music1.wav") open("music1.buf", "wb").write(sound.get_raw()) Then in your game: sound = pygame.mixer.Sound(buffer=open("music1.buf", "rb").read()) I found about 4x speedup of reading a large file on my desktop using this method. That may or may not be enough for you, especially if you combine with other tips in this thread. >>> >>> >>> Very interesting. Will try this when I'm working on this tonight. >>> >>> >>> >>> >>> >>
Re: [pygame] Re: Some way to pickle or otherwise save a pygame.mixer.Sound object?
Just to be clear, you need to play two different multi-minute sounds at once? Because your example has one 13-minute track and one 3-second track. If those are the sounds you need to play at the same time, why don't you just preload the 3-second one into a pygame.mixer.Sound object and play it whenever you need it, and play the 13-minute one with pygame.mixer.music? On Fri, Jun 8, 2018 at 7:48 PM Alec Bennett wrote: > I see that pygame.mixer.Sound supports OGG, I guess I should try that. >> I've never used OGG before, and I wonder if it supports OGG if MP3 would be >> an easy addition? >> > > Well so much for using OGG (and probably MP3) to speed up preloading. With > my 13 minute mono soundfiles, it takes 7.3 seconds to preload the wav file > (44.1hz, 16 bit, mono) and 43.6 seconds to preload the OGG file... I have a > feeling it's uncompressing it during preload. > >> > My project needs polyphony, but really only the ability to play two sounds > at once. I'm currently using this method because it supports that: > >> > channel = 1 # or 2 > >> sound_obj = pygame.mixer.Sound("whatever.wav") # long preload at this step > >> channel = pygame.mixer.Channel(channel) > >> channel.play(sound_obj) > >> > This method of playing MP3 works beautifully without preloading, but can > only play one sound at a time: > >> > pygame.mixer.init() > >> pygame.mixer.music.load("whatever.mp3") > >> pygame.mixer.music.play() > >> pygame.event.wait() > >> > I don't imagine anyone knows of a way to play two sound files > simultaneously using pygame.mixer.music? Or some other solution in Python > under Linux that would do it reliably? I suppose I could slave two > instances of mplayer, but I'd of course prefer to not be forking out > processes. > > If anyone's curious about the files I'm trying to load, I posted some test > files here: > > sinkingsensation.com/dropbox/icecream.zip > > > > > On Thu, Jun 7, 2018 at 2:30 PM, Alec Bennett wrote: > >> >> >> On Thu, Jun 7, 2018 at 7:59 AM, Christopher Night > > wrote: >> >>> I recommend saving the sound as a raw buffer. First in a separate script: >>> >>> sound = pygame.mixer.Sound("music1.wav") >>> open("music1.buf", "wb").write(sound.get_raw()) >>> >>> Then in your game: >>> sound = pygame.mixer.Sound(buffer=open("music1.buf", "rb").read()) >>> >>> I found about 4x speedup of reading a large file on my desktop using >>> this method. That may or may not be enough for you, especially if you >>> combine with other tips in this thread. >>> >> >> >> Very interesting. Will try this when I'm working on this tonight. >> >> >> >> >> >
Re: [pygame] Re: Some way to pickle or otherwise save a pygame.mixer.Sound object?
> > I see that pygame.mixer.Sound supports OGG, I guess I should try that. > I've never used OGG before, and I wonder if it supports OGG if MP3 would be > an easy addition? > Well so much for using OGG (and probably MP3) to speed up preloading. With my 13 minute mono soundfiles, it takes 7.3 seconds to preload the wav file (44.1hz, 16 bit, mono) and 43.6 seconds to preload the OGG file... I have a feeling it's uncompressing it during preload. > My project needs polyphony, but really only the ability to play two sounds at once. I'm currently using this method because it supports that: > channel = 1 # or 2 > sound_obj = pygame.mixer.Sound("whatever.wav") # long preload at this step > channel = pygame.mixer.Channel(channel) > channel.play(sound_obj) > This method of playing MP3 works beautifully without preloading, but can only play one sound at a time: > pygame.mixer.init() > pygame.mixer.music.load("whatever.mp3") > pygame.mixer.music.play() > pygame.event.wait() > I don't imagine anyone knows of a way to play two sound files simultaneously using pygame.mixer.music? Or some other solution in Python under Linux that would do it reliably? I suppose I could slave two instances of mplayer, but I'd of course prefer to not be forking out processes. If anyone's curious about the files I'm trying to load, I posted some test files here: sinkingsensation.com/dropbox/icecream.zip On Thu, Jun 7, 2018 at 2:30 PM, Alec Bennett wrote: > > > On Thu, Jun 7, 2018 at 7:59 AM, Christopher Night > wrote: > >> I recommend saving the sound as a raw buffer. First in a separate script: >> >> sound = pygame.mixer.Sound("music1.wav") >> open("music1.buf", "wb").write(sound.get_raw()) >> >> Then in your game: >> sound = pygame.mixer.Sound(buffer=open("music1.buf", "rb").read()) >> >> I found about 4x speedup of reading a large file on my desktop using this >> method. That may or may not be enough for you, especially if you combine >> with other tips in this thread. >> > > > Very interesting. Will try this when I'm working on this tonight. > > > > >
Re: [pygame] Re: Some way to pickle or otherwise save a pygame.mixer.Sound object?
On Thu, Jun 7, 2018 at 7:59 AM, Christopher Night wrote: > I recommend saving the sound as a raw buffer. First in a separate script: > > sound = pygame.mixer.Sound("music1.wav") > open("music1.buf", "wb").write(sound.get_raw()) > > Then in your game: > sound = pygame.mixer.Sound(buffer=open("music1.buf", "rb").read()) > > I found about 4x speedup of reading a large file on my desktop using this > method. That may or may not be enough for you, especially if you combine > with other tips in this thread. > Very interesting. Will try this when I'm working on this tonight.
Re: [pygame] Re: Some way to pickle or otherwise save a pygame.mixer.Sound object?
> > > > A second solution is to load the sounds in the background of the game, > especially if you're going to launch on a menu where the sounds won't be > needed. You can pre-populate a dictionary with dummy sounds and use a > thread to go through and load each sound into the dictionary while the user > interacts with the menu. > > SOUND_PATH_MAPPING = {'horn_funny': 'horn_funny.ogg', 'horn_sad': > 'extra_sounds/horn_sad.wav'} > > SOUNDS = {name: None for name in SOUND_PATH_MAPPING} > > def load_sounds(): > > for name, path in SOUND_PATH_MAPPING: > > SOUNDS[name] = pygame.mixer.Sound(path) > > > def load_sounds_background(): > > thread.start_new_thread(load_sounds, ()) > > > There's no menus, it just loads and waits for the user to trigger sounds on a keypad. I could play a single sound while the other sounds are loading, but I'd prefer to have it fully functional at startup if possible.
Re: [pygame] Re: Some way to pickle or otherwise save a pygame.mixer.Sound object?
I recommend saving the sound as a raw buffer. First in a separate script: sound = pygame.mixer.Sound("music1.wav") open("music1.buf", "wb").write(sound.get_raw()) Then in your game: sound = pygame.mixer.Sound(buffer=open("music1.buf", "rb").read()) I found about 4x speedup of reading a large file on my desktop using this method. That may or may not be enough for you, especially if you combine with other tips in this thread. On Thu, Jun 7, 2018 at 10:08 AM Daniel Foerster wrote: > It looks like you may have missed the alternative solution in my email. > > On Thu, Jun 7, 2018, 01:04 Alec Bennett wrote: > >> > I think the answer that sticks out to me is that if these are musical >> horn sounds, you might consider using pygame.mixer.music, which will stream >> the sounds as needed. >> >> A very good idea, and the route I originally took, but as far as I can >> tell pygame.mixer.music doesn't support polyphony, and I occasionally need >> to play multiple sounds at once. >> >> >> >> >> >> On Wed, Jun 6, 2018 at 10:59 PM, Daniel Foerster >> wrote: >> >>> I think the answer that sticks out to me is that if these are musical >>> horn sounds, you might consider using pygame.mixer.music, which will stream >>> the sounds as needed. However, this won't work if you have other music >>> playing or if you want multiple horns to be able to play at the same time. >>> >>> A second solution is to load the sounds in the background of the game, >>> especially if you're going to launch on a menu where the sounds won't be >>> needed. You can pre-populate a dictionary with dummy sounds and use a >>> thread to go through and load each sound into the dictionary while the user >>> interacts with the menu. >>> >>> SOUND_PATH_MAPPING = {'horn_funny': 'horn_funny.ogg', 'horn_sad': >>> 'extra_sounds/horn_sad.wav'} >>> >>> SOUNDS = {name: None for name in SOUND_PATH_MAPPING} >>> >>> def load_sounds(): >>> >>> for name, path in SOUND_PATH_MAPPING: >>> >>> SOUNDS[name] = pygame.mixer.Sound(path) >>> >>> >>> def load_sounds_background(): >>> >>> thread.start_new_thread(load_sounds, ()) >>> >>> >>> If there's a legitimate chance that the player might try to use the horn >>> sounds before they've finished loading, just have the horn logic check for >>> Nones before trying to play or have a dummy sound object with a play method >>> that does nothing. >>> >>> A full example of how you might do this with a class: >>> https://gist.github.com/pydsigner/231c0812f9f91050dd83c744d6d5dc4b >>> >>> On Thu, Jun 7, 2018 at 12:31 AM, Alec Bennett >>> wrote: >>> Sorry, I left out the line where I try to save the file: > pickle.dump( sound_obj, open( "sound.pickled", "wb" ) ) On Wed, Jun 6, 2018 at 10:29 PM, Alec Bennett wrote: > I'm building a musical horn for my car with PyGame, and it works > perfectly, but since it needs to load each of the 20 sounds on startup it > takes about 30 seconds to load. I'm running it on a Raspberry Pi, which > doesn't help of course. > > I thought I'd simply save the Sound objects as pickle objects, but > that produces an error: > > > sound_obj = pygame.mixer.Sound("whatever.wav") > > > can't pickle Sound objects > > I also tried the dill module (https://github.com/uqfoundation/dill) > but with similar results: > > > sound_obj = pygame.mixer.Sound("whatever.wav") > > > Can't pickle : it's not found as __builtin__.Sound > > I don't imagine can think of some clever way to save the preloaded > Sounds, or otherwise speed up the load times? > > > > > >>> >>
Re: [pygame] Re: Some way to pickle or otherwise save a pygame.mixer.Sound object?
It looks like you may have missed the alternative solution in my email. On Thu, Jun 7, 2018, 01:04 Alec Bennett wrote: > > I think the answer that sticks out to me is that if these are musical > horn sounds, you might consider using pygame.mixer.music, which will stream > the sounds as needed. > > A very good idea, and the route I originally took, but as far as I can > tell pygame.mixer.music doesn't support polyphony, and I occasionally need > to play multiple sounds at once. > > > > > > On Wed, Jun 6, 2018 at 10:59 PM, Daniel Foerster > wrote: > >> I think the answer that sticks out to me is that if these are musical >> horn sounds, you might consider using pygame.mixer.music, which will stream >> the sounds as needed. However, this won't work if you have other music >> playing or if you want multiple horns to be able to play at the same time. >> >> A second solution is to load the sounds in the background of the game, >> especially if you're going to launch on a menu where the sounds won't be >> needed. You can pre-populate a dictionary with dummy sounds and use a >> thread to go through and load each sound into the dictionary while the user >> interacts with the menu. >> >> SOUND_PATH_MAPPING = {'horn_funny': 'horn_funny.ogg', 'horn_sad': >> 'extra_sounds/horn_sad.wav'} >> >> SOUNDS = {name: None for name in SOUND_PATH_MAPPING} >> >> def load_sounds(): >> >> for name, path in SOUND_PATH_MAPPING: >> >> SOUNDS[name] = pygame.mixer.Sound(path) >> >> >> def load_sounds_background(): >> >> thread.start_new_thread(load_sounds, ()) >> >> >> If there's a legitimate chance that the player might try to use the horn >> sounds before they've finished loading, just have the horn logic check for >> Nones before trying to play or have a dummy sound object with a play method >> that does nothing. >> >> A full example of how you might do this with a class: >> https://gist.github.com/pydsigner/231c0812f9f91050dd83c744d6d5dc4b >> >> On Thu, Jun 7, 2018 at 12:31 AM, Alec Bennett wrote: >> >>> Sorry, I left out the line where I try to save the file: >>> >>> > pickle.dump( sound_obj, open( "sound.pickled", "wb" ) ) >>> >>> >>> >>> On Wed, Jun 6, 2018 at 10:29 PM, Alec Bennett >>> wrote: >>> I'm building a musical horn for my car with PyGame, and it works perfectly, but since it needs to load each of the 20 sounds on startup it takes about 30 seconds to load. I'm running it on a Raspberry Pi, which doesn't help of course. I thought I'd simply save the Sound objects as pickle objects, but that produces an error: > sound_obj = pygame.mixer.Sound("whatever.wav") > can't pickle Sound objects I also tried the dill module (https://github.com/uqfoundation/dill) but with similar results: > sound_obj = pygame.mixer.Sound("whatever.wav") > Can't pickle : it's not found as __builtin__.Sound I don't imagine can think of some clever way to save the preloaded Sounds, or otherwise speed up the load times? >>> >> >
Re: [pygame] Re: Some way to pickle or otherwise save a pygame.mixer.Sound object?
> I think the answer that sticks out to me is that if these are musical horn sounds, you might consider using pygame.mixer.music, which will stream the sounds as needed. A very good idea, and the route I originally took, but as far as I can tell pygame.mixer.music doesn't support polyphony, and I occasionally need to play multiple sounds at once. On Wed, Jun 6, 2018 at 10:59 PM, Daniel Foerster wrote: > I think the answer that sticks out to me is that if these are musical horn > sounds, you might consider using pygame.mixer.music, which will stream the > sounds as needed. However, this won't work if you have other music playing > or if you want multiple horns to be able to play at the same time. > > A second solution is to load the sounds in the background of the game, > especially if you're going to launch on a menu where the sounds won't be > needed. You can pre-populate a dictionary with dummy sounds and use a > thread to go through and load each sound into the dictionary while the user > interacts with the menu. > > SOUND_PATH_MAPPING = {'horn_funny': 'horn_funny.ogg', 'horn_sad': > 'extra_sounds/horn_sad.wav'} > > SOUNDS = {name: None for name in SOUND_PATH_MAPPING} > > def load_sounds(): > > for name, path in SOUND_PATH_MAPPING: > > SOUNDS[name] = pygame.mixer.Sound(path) > > > def load_sounds_background(): > > thread.start_new_thread(load_sounds, ()) > > > If there's a legitimate chance that the player might try to use the horn > sounds before they've finished loading, just have the horn logic check for > Nones before trying to play or have a dummy sound object with a play method > that does nothing. > > A full example of how you might do this with a class: > https://gist.github.com/pydsigner/231c0812f9f91050dd83c744d6d5dc4b > > On Thu, Jun 7, 2018 at 12:31 AM, Alec Bennett wrote: > >> Sorry, I left out the line where I try to save the file: >> >> > pickle.dump( sound_obj, open( "sound.pickled", "wb" ) ) >> >> >> >> On Wed, Jun 6, 2018 at 10:29 PM, Alec Bennett wrote: >> >>> I'm building a musical horn for my car with PyGame, and it works >>> perfectly, but since it needs to load each of the 20 sounds on startup it >>> takes about 30 seconds to load. I'm running it on a Raspberry Pi, which >>> doesn't help of course. >>> >>> I thought I'd simply save the Sound objects as pickle objects, but that >>> produces an error: >>> >>> > sound_obj = pygame.mixer.Sound("whatever.wav") >>> >>> > can't pickle Sound objects >>> >>> I also tried the dill module (https://github.com/uqfoundation/dill) but >>> with similar results: >>> >>> > sound_obj = pygame.mixer.Sound("whatever.wav") >>> >>> > Can't pickle : it's not found as __builtin__.Sound >>> >>> I don't imagine can think of some clever way to save the preloaded >>> Sounds, or otherwise speed up the load times? >>> >>> >>> >>> >>> >> >
Re: [pygame] Re: Some way to pickle or otherwise save a pygame.mixer.Sound object?
I think the answer that sticks out to me is that if these are musical horn sounds, you might consider using pygame.mixer.music, which will stream the sounds as needed. However, this won't work if you have other music playing or if you want multiple horns to be able to play at the same time. A second solution is to load the sounds in the background of the game, especially if you're going to launch on a menu where the sounds won't be needed. You can pre-populate a dictionary with dummy sounds and use a thread to go through and load each sound into the dictionary while the user interacts with the menu. SOUND_PATH_MAPPING = {'horn_funny': 'horn_funny.ogg', 'horn_sad': 'extra_sounds/horn_sad.wav'} SOUNDS = {name: None for name in SOUND_PATH_MAPPING} def load_sounds(): for name, path in SOUND_PATH_MAPPING: SOUNDS[name] = pygame.mixer.Sound(path) def load_sounds_background(): thread.start_new_thread(load_sounds, ()) If there's a legitimate chance that the player might try to use the horn sounds before they've finished loading, just have the horn logic check for Nones before trying to play or have a dummy sound object with a play method that does nothing. A full example of how you might do this with a class: https://gist.github.com/pydsigner/231c0812f9f91050dd83c744d6d5dc4b On Thu, Jun 7, 2018 at 12:31 AM, Alec Bennett wrote: > Sorry, I left out the line where I try to save the file: > > > pickle.dump( sound_obj, open( "sound.pickled", "wb" ) ) > > > > On Wed, Jun 6, 2018 at 10:29 PM, Alec Bennett wrote: > >> I'm building a musical horn for my car with PyGame, and it works >> perfectly, but since it needs to load each of the 20 sounds on startup it >> takes about 30 seconds to load. I'm running it on a Raspberry Pi, which >> doesn't help of course. >> >> I thought I'd simply save the Sound objects as pickle objects, but that >> produces an error: >> >> > sound_obj = pygame.mixer.Sound("whatever.wav") >> >> > can't pickle Sound objects >> >> I also tried the dill module (https://github.com/uqfoundation/dill) but >> with similar results: >> >> > sound_obj = pygame.mixer.Sound("whatever.wav") >> >> > Can't pickle : it's not found as __builtin__.Sound >> >> I don't imagine can think of some clever way to save the preloaded >> Sounds, or otherwise speed up the load times? >> >> >> >> >> >
[pygame] Re: Some way to pickle or otherwise save a pygame.mixer.Sound object?
Sorry, I left out the line where I try to save the file: > pickle.dump( sound_obj, open( "sound.pickled", "wb" ) ) On Wed, Jun 6, 2018 at 10:29 PM, Alec Bennett wrote: > I'm building a musical horn for my car with PyGame, and it works > perfectly, but since it needs to load each of the 20 sounds on startup it > takes about 30 seconds to load. I'm running it on a Raspberry Pi, which > doesn't help of course. > > I thought I'd simply save the Sound objects as pickle objects, but that > produces an error: > > > sound_obj = pygame.mixer.Sound("whatever.wav") > > > can't pickle Sound objects > > I also tried the dill module (https://github.com/uqfoundation/dill) but > with similar results: > > > sound_obj = pygame.mixer.Sound("whatever.wav") > > > Can't pickle : it's not found as __builtin__.Sound > > I don't imagine can think of some clever way to save the preloaded Sounds, > or otherwise speed up the load times? > > > > >