示例#1
0
class VizContainer(object):
    REDIS_CONF_DEF_KEY = 'prmd:active_viz_config_def'
    REDIS_CONF_CHANGED_KEY = 'prmd:config_changed'
    REDIS_CONF_VALUE_KEY = 'prmd:config_value'
    REDIS_VIZ_LIST = 'prmd:viz_list'
    REDIS_ACTIVE_VIZ = 'prmd:active_viz'

    active_viz = None
    use_redis = True

    FADECANDY_SERVER = 'localhost:7890'

    LEFT = FlatViz.LEFT_BEACON
    RIGHT = FlatViz.RIGHT_BEACON

    global_config = {
        'left_on': True,
        'left_color': (147 / 255.0, 0 / 255.0, 255 / 255.0),
        'left_lum': 30,
        'left_rows': [1, 1, 1, 1, 1, 1, 1, 1, 1],
        'left_sides': [1, 1, 1, 1],
        'left_spectrum': [1] * 20,

        'right_on': True,
        'right_color': (147 / 255.0, 0 / 255.0, 255 / 255.0),
        'right_lum': 30,
        'right_rows': [1, 1, 1, 1, 1, 1, 1, 1, 1],
        'right_sides': [1, 1, 1, 1],
        'right_spectrum': [1] * 20,
    }

    def __init__(self, audio_input):
        self.layout = Layout()
        self.audio_input = audio_input
        if self.use_redis:
            self.redis = redis.StrictRedis()
        self.fc_client = opc.Client(self.FADECANDY_SERVER)

        # create a list of all visualizations, add new ones here
        self.create_viz_list()

        # event loop: read config, run current viz and save layout
        self.audio_input.register_read_listener(
            self.config_reader
        )
        self.audio_input.register_read_listener(
            self.current_viz
        )
        self.audio_input.register_read_listener(
            self.layout_handler
        )
        self.audio_input.register_read_listener(
            self.print_stats
        )

        # use first visualization as the initial one
        self.activate_viz(0)

    def create_viz_list(self):
        self.visualizations = [
            CustomViz(self),
            FlatViz(self)
        ]
        if self.use_redis:
            self.redis.delete(self.REDIS_VIZ_LIST)
            self.redis.rpush(
                self.REDIS_VIZ_LIST, *[v.name for v in self.visualizations]
            )

    def get_conf(self, name):
        return self.global_config.get(name, None)

    def config_reader(self, data, time_diff=None):
        if not self.use_redis:
            return
        changed = self.redis.getset(self.REDIS_CONF_CHANGED_KEY, "0")
        if changed == "1":
            config = json.loads(self.redis.get(self.REDIS_CONF_VALUE_KEY))
            for key in config['global']:
                if '_rows' in key or '_sides' in key:
                    for update in config['global'][key]:
                        config['global'][key] = self.global_config[key]
                        config['global'][key][update[0]] = update[1]
            self.global_config.update(config['global'])
            self.visualizations[self.active_viz].update_config(config['viz'])

    def layout_handler(self, data, time_diff=None):
        self._apply_global_config()
        self.fc_client.put_pixels(self.layout.get_output())

    def activate_viz(self, viz_index):
        self.visualizations[viz_index].active = True
        self.active_viz = viz_index

        if self.use_redis:
            config = json.dumps(self.visualizations[viz_index].config_def)
            self.redis.set(self.REDIS_CONF_DEF_KEY, config)
            self.redis.set(
                self.REDIS_ACTIVE_VIZ, self.visualizations[viz_index].name
            )

    def current_viz(self, data, time_diff=None):
        if self.active_viz is not None:
            self.visualizations[self.active_viz].visualize(
                data, time_diff=time_diff)

    def start(self):
        self.audio_input.read_loop()

    def print_stats(self, data, time_diff):
        fps = int(1 / time_diff)
        if fps < 24:
            print("############ Low FPS: %s" % fps)

    def _apply_global_config(self):
        if not self.global_config['left_on']:
            self.layout.set_beacon(self.LEFT, self.layout._off)
        if not self.global_config['right_on']:
            self.layout.set_beacon(self.RIGHT, self.layout._off)

        for i, row in enumerate(self.global_config['left_rows']):
            if not row:
                self.layout.set_row(i, self.layout._off, beacon=self.LEFT)
        for i, row in enumerate(self.global_config['right_rows']):
            if not row:
                self.layout.set_row(i, self.layout._off, beacon=self.RIGHT)

        for i, side in enumerate(self.global_config['left_sides']):
            if not side:
                self.layout.set_side(i, self.layout._off, beacon=self.LEFT)
        for i, side in enumerate(self.global_config['right_sides']):
            if not side:
                self.layout.set_side(i, self.layout._off, beacon=self.RIGHT)