Python Forum
Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
Miniature theater
#2
I would use a parser and a specific format that describes the entire action.
The following is a sketch, but is almost completed, and probably will be helpful for you.

import RPi.GPIO as GPIO
import time
import random
import pygame
  
pygame.mixer.init()
pygame.mixer.music.load("/home/pi/Music/Romance para teatro.mp3")
  
 
class Theater:
    freq = 100
     
    actors = {
            'defunto': 1,   # put comments here directional central etc...
            'caveira': 2, 
             
            # ... define the same way all 12 items/switches?!
            'int_caveira': 11
            'geral':   12
             
            }
     
    takt_executors = {
            'mplay': '_mplay_exec',
            'mstop': '_mstop_exec',
            'o': '_o_exec',
            's': '_s_exec'
            }
 
 
    def __init__(self):
         
        self.iface = GPIO
        self.iface.setmode(self.iface.BCM)
         
        # do setup
        for actor, num in Theater.actors.items():
            self.iface.setup(num)
         
         
    def output(self): 
        """ Docstring needs be here. 
             
        I didn't see that you use this function?!
        It seems to be never called in your code.
         
        """
        # is this allowed, or you need to split
        # it into 2 separated for-loops?
        for actor, num in Theater.actors.items():
            self.iface.output(num, False)
            self.iface.PWM(num, Theater.freq).start(0)
             
    def load_episode(self, episode):
        """ Docstring needs be here. """
        self.episode = episode
 
    def play(self, mode=None):
        """ Docstring needs be here. """
 
        if self.episode is None:
            # I don't know, where it will be printed in case of GPIO?!
            print("No episode was loaded. Load an episode first")
        try:
            if mode == 'always':
                while True:
                    self._play()
            else: # you can define more modes using elif statement...
                self._play()  # play only once
        except KeyboardInterrupt:
            pass
        finally:
            pygame.mixer.music.stop()       #Stop music.
            GPIO.cleanup()
     
     
    def _parse(self):
        if self.episode is None:
            return []
 
        result = []
        for token in map(str.strip, self.episode.split('\n')):
            if token == 'mplay':
                result.append(("mplay", None, None))
            elif token == 'mstop':
                result.append(("mstop", None, None))
            elif token.startswith('s'):
                try:
                    result.append(('s', float(token[1:]), None))
                except (ValueError, IndexError):
                    pass
            elif token.startswith('o'):
                try:
                    result.append(('o', token[2:-2],
                                   True if token[-1] == 't' else False))
                except (ValueError, IndexError):
                    pass
        return result
     
     
    def _mplay_exec(self, *args):
        pygame.mixer.music.play()
     
    def _mstop_exec(self, *args):
        pygame.mixer.music.stop()
     
    def _o_exec(self, *args):
        channel = Theater.actors.get(args[1])
        if ch is not None:
            self.iface.output(channel, args[-1])
            
    def _s_exec(self, *args):
        time.sleep(args[1])
     
    def _nothing_exec(self, *args):
        pass
         
     def _play(self):
        for takt in self._parse():
            exec_name = self.takt_executors.get(takt[0], '_nothing_exec')
            getattr(self, exec_name)(*takt)
             
             
     
     
 
# --------------------- Structure of episode description ---------------
# This is your action, it is written as a string, so it can be saved
# to a file, read and played again. 
episode = """
            mplay
            s2.5
            o_caveira_t
            s1.2
            o_caveira_f
            s0

             
            # complete full action; syntax is self-explanatory, i hope
            o_int_caveira_f
            s1.9
            mstop
"""
# mstop, mplay -- stop  and play music respectively    
             
theater = Theater()
theater.load_episode(episode)
theater.play(mode='always')
I am sorry about too few comments ( I am tired), but I hope the code is self-explanatory
and almost working...

====
UPD: I updated the code. It is not tested, however. The main idea is to use human understandable commands
that describe the theatrical performance. If you look at episode variable, it is just a string.
Each new line is a new command. Awesome invention, I think. Hope that helps.
Reply


Messages In This Thread
Miniature theater - by vieira_diniz - Mar-20-2020, 04:34 AM
RE: Miniature theater - by scidam - Mar-20-2020, 11:18 PM

Forum Jump:

User Panel Messages

Announcements
Announcement #1 8/1/2020
Announcement #2 8/2/2020
Announcement #3 8/6/2020