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__(self, device): self._device = device # Initial config load. self._config = self._device.config self._config_colours = self._config["colors"] self._config_gradients = self._config["gradients"] self._device_config = self._device.device_config self._output_queue = self._device.output_queue self._audio_queue = self._device.audio_queue # Initialize color service and build gradients. self._color_service = ColorService(self._config, self._device_config) self._color_service.build_gradients() self._color_service.build_fadegradients() self._color_service.build_slidearrays() self._color_service.build_slidearrays() self._color_service.build_bubblearrays() # Init math service. self._math_service = MathService() # Init dsp. self._dsp = DSP(self._config, self._device_config) # Init some variables for the effects. self.led_count = self._device_config["led_count"] self.n_fft_bins = self._config["general_settings"]["n_fft_bins"] self.prev_spectrum = np.array([self.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(self.n_fft_bins) ] self.output = np.array([[0 for i in range(self.led_count)] for i in range(3)]) self.prev_output = np.array([[0 for i in range(self.led_count)] for i in range(3)]) self.speed_counter = 0 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["general_settings"]["n_fft_bins"] * 0.13)), "low": (int(self._config["general_settings"]["n_fft_bins"] * 0.13), int(self._config["general_settings"]["n_fft_bins"] * 0.4)), "mid": (int(self._config["general_settings"]["n_fft_bins"] * 0.4), int(self._config["general_settings"]["n_fft_bins"] * 0.7)), "high": (int(self._config["general_settings"]["n_fft_bins"] * 0.8), int(self._config["general_settings"]["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 this). self.wave_wipe_count = 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) 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}")
class AudioProcessService: def start(self, config_lock, notification_queue_in, notification_queue_out, audio_queue): 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._audio_queue = audio_queue self.audio_buffer_queue = Queue(2) self.stream = None self.init_audio_service(show_output=True) while True: try: self.audio_service_routine() self._fps_limiter.fps_limiter() except KeyboardInterrupt: break 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 log_output(self, show_output, log_level, message): if show_output: if log_level == logging.INFO: self.logger.info(message) elif log_level == logging.DEBUG: self.logger.debug(message) elif log_level == logging.ERROR: self.logger.error(message) else: self.logger.debug(message) else: self.logger.debug(message) def audio_service_routine(self): try: if not self._notification_queue_in.empty(): current_notification_item = self._notification_queue_in.get() if current_notification_item.notification_enum is NotificationEnum.config_refresh: if self.stream is not None: self.stream.stop_stream() self.stream.close() self.init_audio_service() self._notification_queue_out.put(NotificationItem(NotificationEnum.config_refresh_finished, current_notification_item.device_id)) elif current_notification_item.notification_enum is NotificationEnum.process_continue: self._skip_routine = False elif current_notification_item.notification_enum is NotificationEnum.process_pause: self._skip_routine = True if self._skip_routine: return try: in_data = self.audio_buffer_queue.get(block=True, timeout=1) except Empty as e: self.logger.debug("Audio in timeout. Queue is Empty") return # Convert the raw string audio stream to an array. y = np.fromstring(in_data, dtype=np.int16) # Use the type float32. y = y.astype(np.float32) # Process the audio stream. audio_datas = self._dsp.update(y) # Check if value is higher than min value. if audio_datas["vol"] < self._config["general_settings"]["MIN_VOLUME_THRESHOLD"]: # Fill the array with zeros, to fade out the effect. audio_datas["mel"] = np.zeros(self.n_fft_bins) if self._audio_queue.full(): try: pre_audio_data = self._audio_queue.get(block=True, timeout=0.033) del pre_audio_data except Exception as e: pass self._audio_queue.put(audio_datas, False) self.end_time_2 = time() if time() - self.ten_seconds_counter_2 > 10: self.ten_seconds_counter_2 = time() time_dif = self.end_time_2 - self.start_time_2 fps = 1 / time_dif self.logger.info(f"Routine | FPS: {fps:.2f}") self.start_time_2 = time() except IOError: self.logger.exception("IOError while reading the Microphone Stream.") pass except Exception as e: self.logger.error("Could not run AudioService routine.") self.logger.exception(f"Unexpected error in routine: {e}")
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()
class AudioProcessService: def start(self, config_lock, notification_queue_in, notification_queue_out, audio_queue, py_audio): self.logger = logging.getLogger(__name__) self._config_lock = config_lock self._notification_queue_in = QueueWrapper(notification_queue_in) self._notification_queue_out = QueueWrapper(notification_queue_out) self._audio_queue = QueueWrapper(audio_queue) self.audio_buffer_queue = QueueWrapper(Queue(2)) self._py_audio = py_audio self.stream = None self.init_audio_service(show_output=True) while True: try: self.audio_service_routine() self._fps_limiter.fps_limiter() except KeyboardInterrupt: break 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}") def log_output(self, show_output, log_level, message): if show_output: if log_level == logging.INFO: self.logger.info(message) elif log_level == logging.DEBUG: self.logger.debug(message) elif log_level == logging.ERROR: self.logger.error(message) else: self.logger.debug(message) else: self.logger.debug(message) def audio_service_routine(self): try: if not self._notification_queue_in.empty(): current_notification_item = self._notification_queue_in.get_blocking( ) if current_notification_item.notification_enum is NotificationEnum.config_refresh: if self.stream is not None: self.stream.stop_stream() self.stream.close() self.init_audio_service() self._notification_queue_out.put_blocking( NotificationItem( NotificationEnum.config_refresh_finished, current_notification_item.device_id)) elif current_notification_item.notification_enum is NotificationEnum.process_continue: self._skip_routine = False elif current_notification_item.notification_enum is NotificationEnum.process_pause: self._skip_routine = True if self._skip_routine: return in_data = None in_data = self.audio_buffer_queue.get_blocking_with_timeout() if in_data is None: self.logger.debug("Audio in timeout. Queue is Empty") return # Convert the raw string audio stream to an array. y = np.fromstring(in_data, dtype=np.int16) # Use the type float32. y = y.astype(np.float32) # Process the audio stream. audio_datas = self._dsp.update(y) # Check if value is higher than min value. if audio_datas["vol"] < self._config["general_settings"][ "min_volume_threshold"]: # Fill the array with zeros, to fade out the effect. audio_datas["mel"] = np.zeros(self.n_fft_bins) self._audio_queue.put_none_blocking(audio_datas) self.end_time_2 = time() if time() - self.ten_seconds_counter_2 > 10: self.ten_seconds_counter_2 = time() time_dif = self.end_time_2 - self.start_time_2 fps = 1 / time_dif self.logger.info(f"Routine | FPS: {fps:.2f}") self.start_time_2 = time() except IOError: self.logger.exception( "IOError while reading the Microphone Stream.") pass except Exception as e: self.logger.error("Could not run AudioService routine.") self.logger.exception(f"Unexpected error in routine: {e}")
class AudioProcessService: 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 audio_service_routine(self): try: # Limit the fps to decrease laggs caused by 100 percent cpu self.fps_limiter() raw_data_from_stream = self.stream.read( self._frames_per_buffer, exception_on_overflow=False) # Convert the raw string audio stream to an array. y = np.fromstring(raw_data_from_stream, dtype=np.int16) # Use the type float32 y = y.astype(np.float32) # Process the audio stream audio_datas = self._dsp.update(y) #Check if value is higher than min value if audio_datas["vol"] < self._config["audio_config"][ "MIN_VOLUME_THRESHOLD"]: # Fill the array with zeros, to fade out the effect. audio_datas["mel"] = np.zeros(1) # Send the new audio data to the effect process. if self._audio_queue.full(): pre_audio_data = self._audio_queue.get() self._audio_queue.put(audio_datas["mel"]) self.end_time = time.time() if time.time() - self.ten_seconds_counter > 10: self.ten_seconds_counter = time.time() self.time_dif = self.end_time - self.start_time self.fps = 1 / self.time_dif print("Audio Service | FPS: " + str(self.fps)) self.start_time = time.time() except IOError: print("IOError during reading the Microphone Stream.") pass def fps_limiter(self): self.fps_limiter_end = time.time() time_between_last_cycle = self.fps_limiter_end - self.fps_limiter_start if time_between_last_cycle < self.min_waiting_time: sleep(self.min_waiting_time - time_between_last_cycle) self.fps_limiter_start = time.time()
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)
class AudioProcessService: def start(self, config_lock, notification_queue_in, notification_queue_out, audio_queue): 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.init_audio_service() 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) def audio_service_routine(self): try: if not self._notification_queue_in.empty(): current_notification_item = self._notification_queue_in.get() if current_notification_item.notification_enum is NotificationEnum.config_refresh: if not self.stream is None: self.stream.stop_stream() self.stream.close() self.init_audio_service() self._notification_queue_out.put( NotificationItem( NotificationEnum.config_refresh_finished, current_notification_item.device_id)) elif current_notification_item.notification_enum is NotificationEnum.process_continue: self._skip_routine = False elif current_notification_item.notification_enum is NotificationEnum.process_pause: self._skip_routine = True if self._skip_routine: return in_data = self.audio_buffer_queue.get() # Convert the raw string audio stream to an array. y = np.fromstring(in_data, dtype=np.int16) # Use the type float32 y = y.astype(np.float32) # Process the audio stream audio_datas = self._dsp.update(y) #Check if value is higher than min value if audio_datas["vol"] < self._config["general_settings"][ "MIN_VOLUME_THRESHOLD"]: # Fill the array with zeros, to fade out the effect. audio_datas["mel"] = np.zeros(1) if self._audio_queue.full(): try: pre_audio_data = self._audio_queue.get(block=True, timeout=0.033) del pre_audio_data except: pass self._audio_queue.put(audio_datas, False) self.end_time_2 = time.time() if time.time() - self.ten_seconds_counter_2 > 10: self.ten_seconds_counter_2 = time.time() time_dif = self.end_time_2 - self.start_time_2 fps = 1 / time_dif print("Audio Service Routine | FPS: " + str(fps)) self.start_time_2 = time.time() except IOError: print("IOError during reading the Microphone Stream.") pass
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.")
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.")