def refresh_dummy(self):
        print("Refresh Output...")

        # Refresh the config
        ConfigService.instance(self._config_lock).load_config()
        self._config = ConfigService.instance(self._config_lock).config

        # Notifiy the master component, that I'm finished.
        self._notification_queue_out.put(NotificationEnum.config_refresh_finished)

        print("Output refreshed.")
    def refresh(self):
        print("Refresh Output...")

        # Refresh the config
        ConfigService.instance(self._config_lock).load_config()
        self._config = ConfigService.instance(self._config_lock).config

        # Init the led components with the new config again
        self.manual_init()

        # Notifiy the master component, that I'm finished.
        self._notification_queue_out.put(NotificationEnum.config_refresh_finished)

        print("Output refreshed.")
    def start(self, config_lock, notification_queue_in, notification_queue_out,
              effect_queue, audio_queue):
        self.logger = logging.getLogger(__name__)

        self._config_lock = config_lock
        self._config = ConfigService.instance(self._config_lock).config

        self._notification_queue_in = QueueWrapper(notification_queue_in)
        self._notification_queue_out = QueueWrapper(notification_queue_out)
        self._effect_queue = QueueWrapper(effect_queue)
        self._audio_queue = QueueWrapper(audio_queue)

        # Init FPS Limiter.
        self._fps_limiter = FPSLimiter(120)

        self._skip_routine = False
        self._devices = {}
        self.init_devices()
        self.start_devices()

        self.start_time = time()
        self.ten_seconds_counter = time()

        while True:
            try:
                self.routine()
            except KeyboardInterrupt:
                break
    def start(self, config_lock, notification_queue_in, notification_queue_out, output_queue, output_queue_lock):
        print("Starting Output component..")
        self._config_lock = config_lock
        self._output_queue = output_queue
        self._output_queue_lock = output_queue_lock
        self._notification_queue_in = notification_queue_in
        self._notification_queue_out = notification_queue_out
        
        self.ten_seconds_counter = time.time()
        self.sec_ten_seconds_counter = time.time()
        self.start_time = time.time()

        # Initial config load.
        self._config = ConfigService.instance(self._config_lock).config
        
        #Init FPS Limiter
        self.fps_limiter_start = time.time()
        self.max_fps = self._config["audio_config"]["FPS"] + 10
        self.min_waiting_time = 1 / self.max_fps

        # Init all nessessarry components
        self.manual_init()

        self._skip_output = False
        self._cancel_token = False
        print("Output component started.")
        while not self._cancel_token:
            self.output_routine()
    def start(self, config_lock, notification_queue_in, notification_queue_out,
              effect_queue, audio_queue):

        self._config_lock = config_lock
        self._config = ConfigService.instance(self._config_lock).config

        self._notification_queue_in = notification_queue_in
        self._notification_queue_out = notification_queue_out
        self._effect_queue = effect_queue
        print("Effect queue id DeviceManager " + str(id(self._effect_queue)))
        self._audio_queue = audio_queue

        #Init FPS Limiter
        self._fps_limiter = FPSLimiter(200)

        self._skip_routine = False
        self._devices = {}
        self.init_devices()
        self.start_devices()

        self.start_time = time.time()
        self.ten_seconds_counter = time.time()

        while True:
            self.routine()
    def __init__(self, config_lock, notification_queue_in, notification_queue_out, effects_queue):
        self._config_lock = config_lock
        self.notification_queue_in = notification_queue_in
        self.notification_queue_out = notification_queue_out
        self.effects_queue = effects_queue

        # Initial config load.
        self._config_instance = ConfigService.instance(self._config_lock)
        self._config = self._config_instance.config
    def __init__(self, config_lock, notification_queue_in,
                 notification_queue_out, effects_queue, py_audio):
        self.logger = logging.getLogger(__name__)

        self._config_lock = config_lock
        self.notification_queue_in = notification_queue_in
        self.notification_queue_out = notification_queue_out
        self.effects_queue = effects_queue
        self._py_audio = py_audio

        # Initial config load.
        self._config_instance = ConfigService.instance(self._config_lock)
        self._config = self._config_instance.config

        self.export_config_path = self._config_instance.get_config_path()

        self.all_devices_id = "all_devices"
示例#8
0
    def start(self, config_lock, notification_queue_in, notification_queue_out,
              effects_queue):
        self._config_lock = config_lock
        self._notification_queue_in = notification_queue_in
        self._notification_queue_out = notification_queue_out
        self._effects_queue = effects_queue

        # Initial config load.
        self._config_instance = ConfigService.instance(self._config_lock)
        self._config = self._config_instance.config
        self._current_effect = self._config["effects"]["last_effect"]

        Webserver.instance = self

        server.config["TEMPLATES_AUTO_RELOAD"] = True
        server.run(host='0.0.0.0', port=80)

        while True:
            sleep(10)
示例#9
0
    def start(self, config_lock, notification_queue_in, notification_queue_out,
              effects_queue):
        self._config_lock = config_lock
        self.notification_queue_in = notification_queue_in
        self.notification_queue_out = notification_queue_out
        self.effects_queue = effects_queue

        self.webserver_executer = WebserverExecuter(config_lock,
                                                    notification_queue_in,
                                                    notification_queue_out,
                                                    effects_queue)
        Webserver.instance = self

        config_instance = ConfigService.instance(self._config_lock)
        self.export_config_path = config_instance.get_config_path()

        server.config["TEMPLATES_AUTO_RELOAD"] = True
        webserver_port = self.webserver_executer.GetWebserverPort()
        server.run(host='0.0.0.0', port=webserver_port)

        while True:
            sleep(10)
 def reload_config(self):
     self.logger.debug("Entering reload_config()")
     ConfigService.instance(self._config_lock).load_config()
     self._config = ConfigService.instance(self._config_lock).config
     self.logger.debug("Leaving reload_config()")
    def refresh(self):
        print("Refresh effects...")
        # Refresh the config
        ConfigService.instance(self._config_lock).load_config()
        self._config = ConfigService.instance(self._config_lock).config

        # Initial config load.
        self._config = ConfigService.instance(self._config_lock).config
        self._config_colours = self._config["colours"]
        self._config_gradients = self._config["gradients"]

        # Initials color service and build gradients
        self._color_service = ColorService(self._config)
        self._color_service.build_gradients()

        # Init math service
        self._math_service = MathService()

        # Init dsp
        self._dsp = DSP(self._config_lock)

        #Refresh some variables for the effects
        led_count = self._config["device_config"]["LED_Count"]
        n_fft_bins = self._config["audio_config"]["N_FFT_BINS"]

        self.prev_spectrum = np.array([led_count // 2])
        self.freq_channel_history = 40
        self.beat_count = 0
        self.freq_channels = [
            deque(maxlen=self.freq_channel_history) for i in range(n_fft_bins)
        ]

        self.output = np.array([[0 for i in range(led_count)]
                                for i in range(3)])
        self.prev_output = np.array([[0 for i in range(led_count)]
                                     for i in range(3)])

        self.current_freq_detects = {
            "beat": False,
            "low": False,
            "mid": False,
            "high": False
        }
        self.prev_freq_detects = {"beat": 0, "low": 0, "mid": 0, "high": 0}
        self.detection_ranges = {
            "beat":
            (0, int(self._config["audio_config"]["N_FFT_BINS"] * 0.11)),
            "low": (int(self._config["audio_config"]["N_FFT_BINS"] * 0.13),
                    int(self._config["audio_config"]["N_FFT_BINS"] * 0.4)),
            "mid": (int(self._config["audio_config"]["N_FFT_BINS"] * 0.4),
                    int(self._config["audio_config"]["N_FFT_BINS"] * 0.7)),
            "high": (int(self._config["audio_config"]["N_FFT_BINS"] * 0.8),
                     int(self._config["audio_config"]["N_FFT_BINS"]))
        }
        self.min_detect_amplitude = {
            "beat": 0.7,
            "low": 0.5,
            "mid": 0.3,
            "high": 0.3
        }
        self.min_percent_diff = {"beat": 70, "low": 100, "mid": 50, "high": 30}

        # Setup for "Power" (don't change these)
        self.power_indexes = []
        self.power_brightness = 0

        # Setup for "Wave" (don't change these)
        self.wave_wipe_count = 0

        # Notifiy the master component, that I'm finished.
        self._notification_queue_out.put(
            NotificationEnum.config_refresh_finished)
        print("Effects refreshed.")
示例#12
0
    def start(self):
        """
        This function will start all necessary components.
        Let's go :-D
        """
        # We need a lock to prevent too fast saving and loading actions of the config
        self._config_lock = Lock()

        # Create the instance of the config
        self._config_instance = ConfigService.instance(self._config_lock)
        self._config = self._config_instance.config

        self.logger = logging.getLogger(__name__)
        self.logger.info("Initializing MLSC...")

        # Check config compatibility
        self._config_instance.check_compatibility()

        # Prepare the queue for the output
        self._output_queue = Queue(2)
        self._effects_queue = Queue(100)
        self._audio_queue = Queue(2)

        # Prepare all notification queues
        self._notification_queue_audio_in = Queue(100)
        self._notification_queue_audio_out = Queue(100)

        self._notification_queue_device_manager_in = Queue(100)
        self._notification_queue_device_manager_out = Queue(100)

        self._notification_queue_webserver_in = Queue(100)
        self._notification_queue_webserver_out = Queue(100)

        # Start the DeviceManager Service
        self._device_manager = DeviceManager()
        self._device_manager_process = Process(
            target=self._device_manager.start,
            args=(
                self._config_lock,
                self._notification_queue_device_manager_in,
                self._notification_queue_device_manager_out,
                self._effects_queue,
                self._audio_queue,
            ))
        self._device_manager_process.start()

        # Start Notification Service
        self._notification_service = NotificationService()
        self._notification_service_process = Process(
            target=self._notification_service.start,
            args=(
                self._config_lock,
                self._notification_queue_device_manager_in,
                self._notification_queue_device_manager_out,
                self._notification_queue_audio_in,
                self._notification_queue_audio_out,
                self._notification_queue_webserver_in,
                self._notification_queue_webserver_out,
            ))
        self._notification_service_process.start()

        # Start Webserver
        self._webserver = Webserver()
        self._webserver_process = Process(
            target=self._webserver.start,
            args=(self._config_lock, self._notification_queue_webserver_in,
                  self._notification_queue_webserver_out, self._effects_queue))
        self._webserver_process.start()

        # Start audio process
        self._audio = AudioProcessService()
        self._audio_process = Process(
            target=self._audio.start,
            args=(self._config_lock, self._notification_queue_audio_in,
                  self._notification_queue_audio_out, self._audio_queue))
        self._audio_process.start()

        self.logger.info("Initialization finished.")

        try:
            self.logger.info("MLSC started...")

            self._cancel_token = False

            # Do nothing with this thread. Just wait for the exit.
            while not self._cancel_token:
                sleep(10)

        except KeyboardInterrupt:
            self.logger.info("Stopping MLSC...")
            self._notification_service_process.terminate()
            self._webserver_process.terminate()
            self.logger.info("MLSC stopped")
 def reload_config(self):
     print("Enter reload_config()")
     ConfigService.instance(self._config_lock).load_config()
     self._config = ConfigService.instance(self._config_lock).config
     print("Leave reload_config()")
    def start(self, config_lock, notification_queue_in, notification_queue_out,
              audio_queue, audio_queue_lock):

        self._config_lock = config_lock
        self._notification_queue_in = notification_queue_in
        self._notification_queue_out = notification_queue_out
        self._audio_queue = audio_queue
        self._audio_queue_lock = audio_queue_lock

        # Initial config load.
        self._config = ConfigService.instance(self._config_lock).config

        #Init FPS Limiter
        self.fps_limiter_start = time.time()
        self.max_fps = self._config["audio_config"]["FPS"] + 10
        self.min_waiting_time = 1 / self.max_fps

        # Init pyaudio
        self._py_audio = pyaudio.PyAudio()

        self._numdevices = self._py_audio.get_device_count()
        self._default_device_id = self._py_audio.get_default_input_device_info(
        )['index']
        self._devices = []

        print("Found the following audio sources:")

        # Select the audio device you wan to use.
        selected_device_list_index = self._config["audio_config"]["DEVICE_ID"]

        # check if the index is inside the list
        foundMicIndex = False

        #for each audio device, add to list of devices
        for i in range(0, self._numdevices):
            try:
                device_info = self._py_audio.get_device_info_by_host_api_device_index(
                    0, i)

                if device_info["maxInputChannels"] >= 1:
                    self._devices.append(device_info)
                    print(
                        str(device_info["index"]) + " - " +
                        str(device_info["name"]) + " - " +
                        str(device_info["defaultSampleRate"]))

                    if device_info["index"] == selected_device_list_index:
                        foundMicIndex = True
            except Exception as e:
                print("Could not get device infos.")
                print("Unexpected error in AudioProcessService :" + str(e))

        # Could not find a mic with the selected mic id, so i will use the first device I found.
        if not foundMicIndex:
            print("********************************************************")
            print("*                      Error                           *")
            print("********************************************************")
            print("Could not find the mic with the id: " +
                  str(selected_device_list_index))
            print("Use the first mic as fallback.")
            print("Please change the id of the mic inside the config.")
            selected_device_list_index = self._devices[0]["index"]

        for device in self._devices:
            if device["index"] == selected_device_list_index:
                print("Selected ID: " + str(selected_device_list_index))
                print("Use " + str(device["index"]) + " - " +
                      str(device["name"]) + " - " +
                      str(device["defaultSampleRate"]))
                self._device_id = device["index"]
                self._device_name = device["name"]
                self._device_rate = int(device["defaultSampleRate"])
                self._config["audio_config"][
                    "DEFAULT_SAMPLE_RATE"] = self._device_rate
                self._frames_per_buffer = self._config["audio_config"][
                    "FRAMES_PER_BUFFER"]

        self.start_time = time.time()
        self.ten_seconds_counter = time.time()

        self._dsp = DSP(config_lock)

        print("Start open Audio stream")
        self.stream = self._py_audio.open(
            format=pyaudio.paInt16,
            channels=1,
            rate=self._device_rate,
            input=True,
            input_device_index=self._device_id,
            frames_per_buffer=self._frames_per_buffer)

        while True:
            self.audio_service_routine()
    def init_audio_service(self):
        # Initial config load.
        ConfigService.instance(self._config_lock).load_config()
        self._config = ConfigService.instance(self._config_lock).config

        #Init FPS Limiter
        self._fps_limiter = FPSLimiter(100)

        # Init pyaudio
        self._py_audio = pyaudio.PyAudio()

        self._skip_routine = False

        self._numdevices = self._py_audio.get_device_count()
        self._default_device_id = self._py_audio.get_default_input_device_info(
        )['index']
        self._devices = []

        print("Found the following audio sources:")

        # Select the audio device you want to use.
        selected_device_list_index = self._config["general_settings"][
            "DEVICE_ID"]

        # check if the index is inside the list
        foundMicIndex = False

        #for each audio device, add to list of devices
        for i in range(0, self._numdevices):
            try:
                device_info = self._py_audio.get_device_info_by_host_api_device_index(
                    0, i)

                if device_info["maxInputChannels"] >= 1:
                    self._devices.append(device_info)
                    print(
                        str(device_info["index"]) + " - " +
                        str(device_info["name"]) + " - " +
                        str(device_info["defaultSampleRate"]))

                    if device_info["index"] == selected_device_list_index:
                        foundMicIndex = True
            except Exception as e:
                print("Could not get device infos.")
                print("Unexpected error in AudioProcessService :" + str(e))

        # Could not find a mic with the selected mic id, so i will use the first device I found.
        if not foundMicIndex:
            print("********************************************************")
            print("*                      Error                           *")
            print("********************************************************")
            print("Could not find the mic with the id: " +
                  str(selected_device_list_index))
            print("Use the first mic as fallback.")
            print("Please change the id of the mic inside the config.")
            selected_device_list_index = self._devices[0]["index"]

        for device in self._devices:
            if device["index"] == selected_device_list_index:
                print("Selected ID: " + str(selected_device_list_index))
                print("Use " + str(device["index"]) + " - " +
                      str(device["name"]) + " - " +
                      str(device["defaultSampleRate"]))
                self._device_id = device["index"]
                self._device_name = device["name"]
                self._device_rate = self._config["general_settings"][
                    "DEFAULT_SAMPLE_RATE"]
                self._frames_per_buffer = self._config["general_settings"][
                    "FRAMES_PER_BUFFER"]

        self.start_time_1 = time.time()
        self.ten_seconds_counter_1 = time.time()
        self.start_time_2 = time.time()
        self.ten_seconds_counter_2 = time.time()

        self._dsp = DSP(self._config)

        self.audio = np.empty((self._frames_per_buffer), dtype="int16")

        self.audio_buffer_queue = Queue(2)

        # callback function to stream audio, another thread.
        def callback(in_data, frame_count, time_info, status):

            if self._skip_routine:
                return (self.audio, pyaudio.paContinue)

            try:
                self.audio_buffer_queue.put(in_data)
            except:
                pass
#
            self.end_time_1 = time.time()

            if time.time() - self.ten_seconds_counter_1 > 10:
                self.ten_seconds_counter_1 = time.time()
                time_dif = self.end_time_1 - self.start_time_1
                fps = 1 / time_dif
                print("Audio Service Callback | FPS: " + str(fps))

            self.start_time_1 = time.time()

            return (self.audio, pyaudio.paContinue)

        print("Start open Audio stream")
        self.stream = self._py_audio.open(
            format=pyaudio.paInt16,
            channels=1,
            rate=self._device_rate,
            input=True,
            input_device_index=self._device_id,
            frames_per_buffer=self._frames_per_buffer,
            stream_callback=callback)
示例#16
0
    def __init__(self, config_lock):

        self._config_lock = config_lock

        # Initial config load.
        self._config = ConfigService.instance(self._config_lock).config

        # Initialise filters etc. I've no idea what most of these are for but i imagine i won't be getting rid of them soon
        n_fft_bins = self._config["audio_config"]["N_FFT_BINS"]
        min_volume_threshold = self._config["audio_config"][
            "MIN_VOLUME_THRESHOLD"]
        fps = self._config["audio_config"]["FPS"]
        n_rolling_history = self._config["audio_config"]["N_ROLLING_HISTORY"]
        default_sample_rate = self._config["audio_config"][
            "DEFAULT_SAMPLE_RATE"]

        led_count = self._config["device_config"]["LED_Count"]

        self.fft_plot_filter = ExpFilter(np.tile(1e-1, n_fft_bins),
                                         alpha_decay=0.5,
                                         alpha_rise=0.99)
        self.mel_gain = ExpFilter(np.tile(1e-1, n_fft_bins),
                                  alpha_decay=0.01,
                                  alpha_rise=0.99)
        self.mel_smoothing = ExpFilter(np.tile(1e-1, n_fft_bins),
                                       alpha_decay=0.5,
                                       alpha_rise=0.99)
        self.gain = ExpFilter(np.tile(0.01, n_fft_bins),
                              alpha_decay=0.001,
                              alpha_rise=0.99)
        self.r_filt = ExpFilter(np.tile(0.01, led_count // 2),
                                alpha_decay=0.2,
                                alpha_rise=0.99)
        self.g_filt = ExpFilter(np.tile(0.01, led_count // 2),
                                alpha_decay=0.05,
                                alpha_rise=0.3)
        self.b_filt = ExpFilter(np.tile(0.01, led_count // 2),
                                alpha_decay=0.1,
                                alpha_rise=0.5)
        self.common_mode = ExpFilter(np.tile(0.01, led_count // 2),
                                     alpha_decay=0.99,
                                     alpha_rise=0.01)
        self.p_filt = ExpFilter(np.tile(1, (3, led_count // 2)),
                                alpha_decay=0.1,
                                alpha_rise=0.99)
        self.volume = ExpFilter(min_volume_threshold,
                                alpha_decay=0.02,
                                alpha_rise=0.02)
        self.p = np.tile(1.0, (3, led_count // 2))
        # Number of audio samples to read every time frame
        self.samples_per_frame = int(default_sample_rate / fps)
        # Array containing the rolling audio sample window
        self.y_roll = np.random.rand(n_rolling_history,
                                     self.samples_per_frame) / 1e16
        self.fft_window =      np.hamming(int(default_sample_rate / fps)\
                                         * n_rolling_history)

        self.samples = None
        self.mel_y = None
        self.mel_x = None
        self.melbank = Melbank()
        self.create_mel_bank()
示例#17
0
    def init_audio_service(self, show_output=False):
        try:
            # Initial config load.
            ConfigService.instance(self._config_lock).load_config()
            self._config = ConfigService.instance(self._config_lock).config

            # Init FPS Limiter.
            self._fps_limiter = FPSLimiter(120)

            # Init pyaudio.
            self._py_audio = pyaudio.PyAudio()

            self._skip_routine = False

            self._numdevices = self._py_audio.get_device_count()
            self._default_device_id = self._py_audio.get_default_input_device_info()['index']
            self._devices = []

            self.log_output(show_output, logging.INFO, "Found the following audio sources:")

            # Select the audio device you want to use.
            selected_device_list_index = self._config["general_settings"]["DEVICE_ID"]

            # Check if the index is inside the list.
            foundMicIndex = False

            # For each audio device, add to list of devices.
            for i in range(0, self._numdevices):
                try:
                    device_info = self._py_audio.get_device_info_by_host_api_device_index(0, i)

                    if device_info["maxInputChannels"] >= 1:
                        self._devices.append(device_info)
                        self.log_output(show_output, logging.INFO, f'{device_info["index"]} - {device_info["name"]} - {device_info["defaultSampleRate"]}')

                        if device_info["index"] == selected_device_list_index:
                            foundMicIndex = True
                except Exception as e:
                    self.log_output(show_output, logging.ERROR, "Could not get device infos.")
                    self.logger.exception(f"Unexpected error in AudioProcessService: {e}")

            # Could not find a mic with the selected mic id, so I will use the first device I found.
            if not foundMicIndex:
                self.log_output(show_output, logging.ERROR, "********************************************************")
                self.log_output(show_output, logging.ERROR, "*                      Error                           *")
                self.log_output(show_output, logging.ERROR, "********************************************************")
                self.log_output(show_output, logging.ERROR, f"Could not find the mic with the id: {selected_device_list_index}")
                self.log_output(show_output, logging.ERROR, "Using the first mic as fallback.")
                self.log_output(show_output, logging.ERROR, "Please change the id of the mic inside the config.")
                selected_device_list_index = self._devices[0]["index"]

            for device in self._devices:
                if device["index"] == selected_device_list_index:
                    self.log_output(show_output, logging.INFO, f"Selected ID: {selected_device_list_index}")
                    self.log_output(show_output, logging.INFO, f'Using {device["index"]} - {device["name"]} - {device["defaultSampleRate"]}')
                    self._device_id = device["index"]
                    self._device_name = device["name"]
                    self._device_rate = self._config["general_settings"]["DEFAULT_SAMPLE_RATE"]
                    self._frames_per_buffer = self._config["general_settings"]["FRAMES_PER_BUFFER"]
                    self.n_fft_bins = self._config["general_settings"]["N_FFT_BINS"]

            self.start_time_1 = time()
            self.ten_seconds_counter_1 = time()
            self.start_time_2 = time()
            self.ten_seconds_counter_2 = time()

            self._dsp = DSP(self._config)

            self.audio = np.empty((self._frames_per_buffer), dtype="int16")

            # Reinit buffer queue
            self.audio_buffer_queue = Queue(2)

            # callback function to stream audio, another thread.
            def callback(in_data, frame_count, time_info, status):
                if self._skip_routine:
                    return (self.audio, pyaudio.paContinue)

                try:
                    self.audio_buffer_queue.put(in_data)
                except Exception as e:
                    pass

                self.end_time_1 = time()

                if time() - self.ten_seconds_counter_1 > 10:
                    self.ten_seconds_counter_1 = time()
                    time_dif = self.end_time_1 - self.start_time_1
                    fps = 1 / time_dif
                    self.logger.info(f"Callback | FPS: {fps:.2f}")

                self.start_time_1 = time()

                return (self.audio, pyaudio.paContinue)

            self.log_output(show_output, logging.DEBUG, "Starting Open Audio Stream...")
            self.stream = self._py_audio.open(
                format=pyaudio.paInt16,
                channels=1,
                rate=self._device_rate,
                input=True,
                input_device_index=self._device_id,
                frames_per_buffer=self._frames_per_buffer,
                stream_callback=callback
            )
        except Exception as e:
            self.logger.error("Could not init AudioService.")
            self.logger.exception(f"Unexpected error in init_audio_service: {e}")
    def init_audio_service(self, show_output=False):
        try:
            # Initial config load.
            ConfigService.instance(self._config_lock).load_config()
            self._config = ConfigService.instance(self._config_lock).config

            # Init FPS Limiter.
            self._fps_limiter = FPSLimiter(120)
            self._skip_routine = False
            self._devices = AudioInfo.get_audio_devices(self._py_audio)

            self.log_output(show_output, logging.INFO,
                            "Found the following audio sources:")

            # Select the audio device you want to use.
            selected_device_list_index = 0
            try:
                mic_id = self._config["general_settings"]["device_id"]
                if mic_id != "no_mic":
                    selected_device_list_index = int(mic_id)
            except Exception as e:
                self.logger.exception(f"Could not parse audio id: {e}")

            # Check if the index is inside the list.
            self.selected_device = None
            # For each audio device, add to list of devices.
            for current_audio_device in self._devices:

                if current_audio_device.id == selected_device_list_index:
                    self.selected_device = current_audio_device

            self.logger.debug(f"Selected Device: {self.selected_device}")

            # Could not find a mic with the selected mic id, so I will use the first device I found.
            if self.selected_device is None:
                self.log_output(
                    show_output, logging.ERROR,
                    "********************************************************")
                self.log_output(
                    show_output, logging.ERROR,
                    "*                      Error                           *")
                self.log_output(
                    show_output, logging.ERROR,
                    "********************************************************")
                self.log_output(
                    show_output, logging.ERROR,
                    f"Could not find the mic with the id: {selected_device_list_index}"
                )
                self.log_output(show_output, logging.ERROR,
                                "Using the first mic as fallback.")
                self.log_output(
                    show_output, logging.ERROR,
                    "Please change the id of the mic inside the config.")
                self.selected_device = self._devices[0]

            self._device_rate = self._config["general_settings"][
                "default_sample_rate"]
            self._frames_per_buffer = self._config["general_settings"][
                "frames_per_buffer"]
            self.n_fft_bins = self._config["general_settings"]["n_fft_bins"]
            self.log_output(
                show_output, logging.INFO,
                f"Selected Device: {self.selected_device.to_string()}")

            # Init Timer
            self.start_time_1 = time()
            self.ten_seconds_counter_1 = time()
            self.start_time_2 = time()
            self.ten_seconds_counter_2 = time()

            self._dsp = DSP(self._config)

            self.audio = np.empty((self._frames_per_buffer), dtype="int16")

            # Reinit buffer queue
            self.audio_buffer_queue = QueueWrapper(Queue(2))

            # callback function to stream audio, another thread.
            def callback(in_data, frame_count, time_info, status):
                if self._skip_routine:
                    return (self.audio, pyaudio.paContinue)

                self.audio_buffer_queue.put_none_blocking(in_data)

                self.end_time_1 = time()

                if time() - self.ten_seconds_counter_1 > 10:
                    self.ten_seconds_counter_1 = time()
                    time_dif = self.end_time_1 - self.start_time_1
                    fps = 1 / time_dif
                    self.logger.info(f"Callback | FPS: {fps:.2f}")

                self.start_time_1 = time()

                return (self.audio, pyaudio.paContinue)

            self.log_output(show_output, logging.DEBUG,
                            "Starting Open Audio Stream...")
            self.stream = self._py_audio.open(
                format=pyaudio.paInt16,
                channels=1,
                rate=self._device_rate,
                input=True,
                input_device_index=self.selected_device.id,
                frames_per_buffer=self._frames_per_buffer,
                stream_callback=callback)
        except Exception as e:
            self.logger.error("Could not init AudioService.")
            self.logger.exception(
                f"Unexpected error in init_audio_service: {e}")
示例#19
0
    def start(self):
        """
        This function will start all neccesary components.
        Let's go :-D
        """
        print("Init the programm...")

        # We need a lock to prevent too fast save and load actions of the config
        self._config_lock = Lock()

        # Create the instance of the config
        self._config_instance = ConfigService.instance(self._config_lock)
        self._config = self._config_instance.config

        # Prepare the queue for the output
        self._output_queue_lock = Lock()
        self._output_queue = Queue(2)
        self._effects_queue = Queue(2)
        self._audio_queue_lock = Lock()
        self._audio_queue = Queue(2)
        self._server_queue_lock = Lock()
        self._server_queue = Queue(2)

        # Prepare all notification queues
        self._notification_queue_output_in = Queue(2)
        self._notification_queue_output_out = Queue(2)

        self._notification_queue_audio_in = Queue(2)
        self._notification_queue_audio_out = Queue(2)

        self._notification_queue_effects_in = Queue(2)
        self._notification_queue_effects_out = Queue(2)

        self._notification_queue_webserver_in = Queue(2)
        self._notification_queue_webserver_out = Queue(2)

        self._notification_queue_server_in = Queue(2)
        self._notification_queue_server_out = Queue(2)

        # Only activate the output if I'm inside the output mode.
        if (not self._config["development_config"]["deactivate_output"]):
            #Start Output Service
            self._output = Output()
            self._output_process = Process(
                target=self._output.start,
                args=(
                    self._config_lock,
                    self._notification_queue_output_in,
                    self._notification_queue_output_out,
                    self._output_queue,
                    self._output_queue_lock,
                ))
            self._output_process.start()
        else:
            # Start Output Dummy Service
            self._output = Output()
            self._output_process = Process(
                target=self._output.start_dummy,
                args=(self._config_lock, self._notification_queue_output_in,
                      self._notification_queue_output_out, self._output_queue,
                      self._output_queue_lock))
            self._output_process.start()

        # Start the Effect Service
        self._effects = Effects()
        self._effects_process = Process(
            target=self._effects.start,
            args=(self._config_lock, self._notification_queue_effects_in,
                  self._notification_queue_effects_out, self._output_queue,
                  self._output_queue_lock, self._effects_queue,
                  self._server_queue, self._server_queue_lock,
                  self._audio_queue, self._audio_queue_lock))
        self._effects_process.start()

        # Start Notification Service
        self._notification_service = NotificationService()
        self._notification_service_process = Process(
            target=self._notification_service.start,
            args=(
                self._config_lock,
                self._notification_queue_output_in,
                self._notification_queue_output_out,
                self._notification_queue_effects_in,
                self._notification_queue_effects_out,
                self._notification_queue_webserver_in,
                self._notification_queue_webserver_out,
            ))
        self._notification_service_process.start()

        #Start Webserver
        self._webserver = Webserver()
        self._webserver_process = Process(
            target=self._webserver.start,
            args=(
                self._config_lock,
                self._notification_queue_webserver_in,
                self._notification_queue_webserver_out,
                self._effects_queue,
            ))
        self._webserver_process.start()

        #Start Server
        self._server = ServerService()
        self._server_process = Process(
            target=self._server.start,
            args=(self._config_lock, self._notification_queue_server_in,
                  self._notification_queue_server_out, self._server_queue,
                  self._server_queue_lock))
        self._server_process.start()

        #Start audio process
        self._audio = AudioProcessService()
        self._audio_process = Process(
            target=self._audio.start,
            args=(self._config_lock, self._notification_queue_server_in,
                  self._notification_queue_server_out, self._audio_queue,
                  self._audio_queue_lock))
        self._audio_process.start()

        print("Init finished")

        try:

            print("Programm started...")

            self._cancel_token = False

            # Do nothing with this thread. Just wait for the exit.
            while not self._cancel_token:
                sleep(10)

        except KeyboardInterrupt:

            print("Stop the programm...")

            self._output_process.terminate()
            self._effects_process.terminate()
            self._notification_service_process.terminate()
            self._webserver_process.terminate()

            print("Programm stopped")
    def start(self, config_lock, notification_queue_in, notification_queue_out,
              effects_queue, server_queue, server_queue_lock, audio_queue,
              audio_queue_lock):
        """
        Start the effect process. You can change the effect by add a new effect enum inside the enum_queue.
        """

        print("Start Effects component...")

        self._config_lock = config_lock
        self._notification_queue_in = notification_queue_in
        self._notification_queue_out = notification_queue_out
        self._effects_queue = effects_queue
        self._server_queue = server_queue
        self._server_queue_lock = server_queue_lock
        self._audio_queue = audio_queue
        self._audio_queue_lock = audio_queue_lock

        self._lost_arrays_counter = 0
        self.ten_seconds_counter = time.time()
        self.start_time = time.time()

        # Initial config load.
        self._config = ConfigService.instance(self._config_lock).config
        self._config_colours = self._config["colours"]
        self._config_gradients = self._config["gradients"]

        # Initials color service and build gradients
        self._color_service = ColorService(self._config)
        self._color_service.build_gradients()

        # Init math service
        self._math_service = MathService()

        # Init dsp
        self._dsp = DSP(self._config_lock)

        #Init some variables for the effects
        led_count = self._config["device_config"]["LED_Count"]
        n_fft_bins = self._config["audio_config"]["N_FFT_BINS"]

        self.prev_spectrum = np.array([led_count // 2])
        self.freq_channel_history = 40
        self.beat_count = 0
        self.freq_channels = [
            deque(maxlen=self.freq_channel_history) for i in range(n_fft_bins)
        ]

        self.output = np.array([[0 for i in range(led_count)]
                                for i in range(3)])
        self.prev_output = np.array([[0 for i in range(led_count)]
                                     for i in range(3)])

        self.current_freq_detects = {
            "beat": False,
            "low": False,
            "mid": False,
            "high": False
        }
        self.prev_freq_detects = {"beat": 0, "low": 0, "mid": 0, "high": 0}
        self.detection_ranges = {
            "beat":
            (0, int(self._config["audio_config"]["N_FFT_BINS"] * 0.11)),
            "low": (int(self._config["audio_config"]["N_FFT_BINS"] * 0.13),
                    int(self._config["audio_config"]["N_FFT_BINS"] * 0.4)),
            "mid": (int(self._config["audio_config"]["N_FFT_BINS"] * 0.4),
                    int(self._config["audio_config"]["N_FFT_BINS"] * 0.7)),
            "high": (int(self._config["audio_config"]["N_FFT_BINS"] * 0.8),
                     int(self._config["audio_config"]["N_FFT_BINS"]))
        }
        self.min_detect_amplitude = {
            "beat": 0.7,
            "low": 0.5,
            "mid": 0.3,
            "high": 0.3
        }
        self.min_percent_diff = {"beat": 70, "low": 100, "mid": 50, "high": 30}

        # Setup for "Power" (don't change these)
        self.power_indexes = []
        self.power_brightness = 0

        # Setup for "Wave" (don't change these)
        self.wave_wipe_count = 0

        try:
            # Get the last effect and set it.
            last_effect_string = self._config["effects"]["last_effect"]
            last_effect = EffectsEnum[last_effect_string]
            self._current_effect = last_effect

        except Exception:
            print("Could not parse last effect. Set effect to off.")
            self._current_effect = EffectsEnum.effect_off

        # A token to cancle the while loop
        self._cancel_token = False
        self._skip_effect = False
        print("Effects component started.")

        while not self._cancel_token:
            try:
                self.effect_routine()
            except Exception as e:
                print(
                    "Error in Effect Service. Routine Restarted. Exception: " +
                    str(e))

        print("Effects component stopped.")