Welcome!
This is the community forum for my apps Pythonista and Editorial.
For individual support questions, you can also send an email. If you have a very short question or just want to say hello — I'm @olemoritz on Twitter.
Playing and stop a sound with same button
-
Hi forum,
I’m trying to make a simple soundboard type ui.
I have a grid of buttons that play different sounds and a button to stop all effects.
Ie sound.play_effect() and sound.stop_all_effects()What I would like to do though is play the sounds and colour the respective button a different colour for as long as it’s playing and then if the button is pressed again whilst the sound is still playing - stop that specific sound ..
How can I do this?
The effect is only created upon playing and is unique so how can I stop that exact effect? -
@rb try this. You have to use sound.Player instead of sound.effect if you want to be warned when your sound effect is ended, so you can reset your button colour. I did not test this quick and dirty code with a lot of buttons and with multiple effects at same moment
import ui import sound v = ui.View() v.background_color = 'lightgray' v.frame = (0,0,400,400) def b_action(sender): if sender.player == None: player = sound.Player(sender.title) player.number_of_loops = 4 def sound_end(): sender.background_color = 'white' player.finished_handler = sound_end sender.player = player if not sender.player.playing: sender.background_color = 'yellow' sender.player.play() else: sender.player.stop() sender.background_color = 'white' b1 = ui.Button() b1.frame = (10,10,100,32) b1.background_color = 'white' b1.title = 'piano:A3' b1.action = b_action b1.player = None v.add_subview(b1) b2 = ui.Button() b2.frame = (10,52,100,32) b2.background_color = 'white' b2.title = 'piano:D4' b2.action = b_action b2.player = None v.add_subview(b2) v.present('sheet')
-
@cvp that works perfectly thankyou. Your help and this forum is another reason I love pythonista!
more questions though….
If instead of stopping the sound I wanted instead to fade the sound and then stop it..
ui.animate ?And if I wanted a way of fading and stopping ALL sounds how can I get all instances of player to iterate through them at once?or is there another way?
Thanks!
-
@rb asked
If instead of stopping the sound I wanted instead to fade the sound and then stop it..
ui.animate ?What is fading a sound? Decrease its volume?
ui.animate ?
Ui.animate is used to change an ui atteibute. Sound volume is not ui.
I think it would be possible via a thread changing player volume. I could try this afternoon (Belgian time )
Note that doc does not describe volume Player's attribute but a dir of the created Player object lists also volume...
-
@cvp right yep ui.animate was a stupid idea - just how I was fading alphas previously.
And yes fading would be reducing volume to 0 over time then stopping player I think.
Don’t understand the threading thing but will look it up thanks again. -
@rb try this
import ui import sound import threading import time class fade_player(threading.Thread): def __init__(self,player): threading.Thread.__init__(self) self.player = player def run(self): while self.player.volume > 0 and self.player.current_time > 0: #print(self.player.current_time,self.player.duration, self.player.volume) time.sleep(0.4) self.player.volume -= 0.01 self.player.stop() v = ui.View() v.background_color = 'lightgray' v.frame = (0,0,400,400) def b_action(sender): if sender.player == None: player = sound.Player(sender.title) #player.number_of_loops = 4 # for testing a longer duration only def sound_end(): sender.background_color = 'white' player.finished_handler = sound_end sender.player = player if not sender.player.playing: sender.background_color = 'yellow' sender.player.play() else: #sender.player.stop() sender.background_color = 'white' mythread = fade_player(sender.player) mythread.start() b1 = ui.Button() b1.frame = (10,10,100,32) b1.background_color = 'white' b1.title = 'piano:A3' b1.action = b_action b1.player = None v.add_subview(b1) b2 = ui.Button() b2.frame = (10,52,100,32) b2.background_color = 'white' b2.title = 'piano:D4' b2.action = b_action b2.player = None v.add_subview(b2) b_stop_all = ui.Button() b_stop_all.title = 'stop all' b_stop_all.frame = (10,350,100,32) b_stop_all.background_color = 'white' b_stop_all.player = None def b_stop_all_action(sender): for sv in v.subviews: if isinstance(sv,ui.Button): if sv.player.player.playing: sv.action(sv) b_stop_all.action = b_stop_all_action v.add_subview(b_stop_all) v.present('sheet')
-
@cvp that works great thanks with a longer duration.
Also added a fade up:
class fade_playerUp(threading.Thread): def __init__(self,player): threading.Thread.__init__(self) self.player = player self.player.volume=0 def run(self): while self.player.volume < 1 : #print(self.player.current_time,self.player.duration, self.player.volume) self.player.play() time.sleep(0.1) self.player.volume += 0.01 #self.player.stop() ``` Cheers!
-
@rb 👍...........
-
The effect is only created upon playing and is unique so how can I stop that exact effect?
-
@harrietzaspel when you create a sound object (called player in the script) using an effect, by sound.Player(...), memorize this created object and use player.stop() to stop it.
In the script, each button refers to a sound effect, and its Player object is stored in player attribute of the button object. Assume your button is called b, b.player is the associated Player object and thus b.player.stop() will stop the sound.
Hoping I'm clear enough