omz:forum

    • Register
    • Login
    • Search
    • Recent
    • Popular

    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

    Pythonista
    3
    10
    136
    Loading More Posts
    • Oldest to Newest
    • Newest to Oldest
    • Most Votes
    Reply
    • Reply as topic
    Log in to reply
    This topic has been deleted. Only users with topic management privileges can see it.
    • rb
      rb last edited by

      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?

      cvp 1 Reply Last reply Reply Quote 0
      • cvp
        cvp @rb last edited by cvp

        @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')
        
        rb 1 Reply Last reply Reply Quote 0
        • rb
          rb @cvp last edited by

          @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!

          cvp 1 Reply Last reply Reply Quote 0
          • cvp
            cvp @rb last edited by cvp

            @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...

            rb 1 Reply Last reply Reply Quote 0
            • rb
              rb @cvp last edited by

              @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.

              cvp 1 Reply Last reply Reply Quote 0
              • cvp
                cvp @rb last edited by cvp

                @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')
                
                rb 1 Reply Last reply Reply Quote 0
                • rb
                  rb @cvp last edited by

                  @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!
                  cvp 1 Reply Last reply Reply Quote 0
                  • cvp
                    cvp @rb last edited by

                    @rb 👍...........

                    1 Reply Last reply Reply Quote 0
                    • harrietzaspel
                      harrietzaspel last edited by

                      The effect is only created upon playing and is unique so how can I stop that exact effect?

                      cvp 1 Reply Last reply Reply Quote 0
                      • cvp
                        cvp @harrietzaspel last edited by cvp

                        @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

                        1 Reply Last reply Reply Quote 0
                        • First post
                          Last post
                        Powered by NodeBB Forums | Contributors