예제 #1
0
    def process(self):
        if self._inputBuffer is None or self._outputBuffer is None:
            return
        if not self._inputBufferValid(0, buffer_type=effect.AudioBuffer.__name__):
            self._outputBuffer[0] = None
            return
        color = self._inputBuffer[1]
        if color is None:
            color = self._default_color

        y = self._inputBuffer[0].audio
        fs = self._inputBuffer[0].sample_rate

        if self.lowcut_hz > 0 or self.highcut_hz < 20000:
            # construct filter if needed
            if self._bandpass is None:
                self._bandpass = dsp.Bandpass(self.lowcut_hz, self.highcut_hz, fs, 3)
            # update bandpass
            self._bandpass.updateParams(self.lowcut_hz, self.highcut_hz, fs, 3)
            # process audio
            y = self._bandpass.filter(np.array(y), fs)

        rms = dsp.rms(y)
        # calculate rms over hold_time
        while len(self._hold_values) > self.n_overlaps:
            self._hold_values.pop()
        self._hold_values.insert(0, rms)
        rms = dsp.rms(self._hold_values)
        db = 20 * math.log10(max(rms, 1e-16))
        scal_value = (self.db_range + db) / self.db_range
        bar = np.zeros(self._num_pixels) * np.array([[0], [0], [0]])
        index = int(self._num_pixels * scal_value)
        index = np.clip(index, 0, self._num_pixels - 1)
        bar[0:3, 0:index] = color[0:3, 0:index]
        self._outputBuffer[0] = bar
    def process(self):
        if self._inputBuffer is None or self._outputBuffer is None:
            return
        buffer = self._inputBuffer[0]
        if buffer is None:
            self._outputBuffer[0] = None
            return
        color = self._inputBuffer[1]
        if color is None:
            color = self._default_color

        y = self._inputBuffer[0]
        rms = dsp.rms(y)
        # calculate rms over hold_time
        while len(self._hold_values) > self.n_overlaps:
            self._hold_values.pop()
        self._hold_values.insert(0, rms)
        rms = dsp.rms(self._hold_values)
        db = 20 * math.log10(max(rms, 1e-16))
        scal_value = (self.db_range + db) / self.db_range
        bar = np.zeros(self._num_pixels) * np.array([[0], [0], [0]])
        index = int(self._num_pixels * scal_value)
        index = np.clip(index, 0, self._num_pixels - 1)
        bar[0:3, 0:index] = color[0:3, 0:index]
        self._outputBuffer[0] = bar
예제 #3
0
 def process(self):
     if self._inputBuffer is None or self._outputBuffer is None:
         return
     if not self._inputBufferValid(0, buffer_type=effect.AudioBuffer.__name__):
         return
     y = self._inputBuffer[0].audio
     rms = dsp.rms(y)
     # calculate rms over hold_time
     while len(self._hold_values) > 20 * self.smoothing:
         self._hold_values.pop()
     self._hold_values.insert(0, rms)
     rms = dsp.rms(self._hold_values)
     db = 20 * math.log10(max(rms, 1e-16))
     scal_value = (self.db_range + db) / self.db_range
     self._outputBuffer[0] = self._inputBuffer[1] * (1 - self.amount) + self._inputBuffer[1] * scal_value * self.amount
예제 #4
0
    def process(self):
        if self._inputBuffer is None or self._outputBuffer is None:
            return
        if not self._inputBufferValid(0, buffer_type=effect.AudioBuffer.__name__):
            return
        if not self._inputBufferValid(1):
            self._outputBuffer[0] = None
            return

        # Init audio
        audio = self._inputBuffer[0].audio
        fs = self._inputBuffer[0].sample_rate

        # construct filter if needed
        if self._bandpass is None:
            self._bandpass = dsp.Bandpass(self.lowcut_hz, self.highcut_hz, fs, 3)
        # update bandpass
        self._bandpass.updateParams(self.lowcut_hz, self.highcut_hz, fs, 3)
        # apply bandpass to audio
        y = self._bandpass.filter(np.array(audio), fs)

        x = self._inputBuffer[1]
        rms = dsp.rms(y)
        # calculate rms over hold_time
        while len(self._hold_values) > 20 * self.smoothing:
            self._hold_values.pop()
        self._hold_values.insert(0, rms)
        rms = dsp.rms(self._hold_values)
        db = 20 * math.log10(max(rms, 1e-16))
        db = max(db, -self.db_range)

        scal_value = (self.db_range + db) / self.db_range
        try:
            scal_value = scal_value**self.peak_filter
        except Exception:
            scal_value = scal_value
        scal_value = scal_value * self.peak_scale

        dt_move = self._t - self._last_t
        shift = dt_move * self.speed * 0.1 * scal_value
        self._shift_pixels = math.fmod((self._shift_pixels + shift), np.size(x, axis=1))
        self._last_t = self._t
        self._outputBuffer[0] = sp.ndimage.interpolation.shift(x, [0, self._shift_pixels], mode='wrap', prefilter=True)
    def _handleSysex(self, data,
                     serverconfig: serverconfiguration.ServerConfiguration,
                     proj: project.Project):
        if len(data) < 2:
            logger.error("Sysex message too short")
            return

        if data[0] == 0x00 and data[1] == 0x00:
            # Version
            logger.info("MIDI-BLE REQ Version")
            if self._sendMidiCallback is not None:
                self._sendMidiCallback(self._createVersionMsg())
        elif data[0] == 0x00 and data[1] == 0x10:
            # Update
            logger.info("MIDI-BLE REQ Update")
            logger.info("Checking for update, current version is {}".format(
                version.get_version()))
            self._updatePathsAndUrls(serverconfig)
            if not self._isUpdating:
                self._isUpdating = True
                # New Downloaders will be created on request
                self.client.refresh()
                app_update = self.client.update_check('Molecole',
                                                      version.get_version())
                if app_update is not None:
                    logger.info("Update {} available".format(
                        app_update.current_version))
                    threading.Thread(target=self._updateApp,
                                     args=[app_update]).start()
                else:
                    self._isUpdating = False
                    logger.info("Update check returned no update")
                    if self._sendMidiCallback is not None:
                        self._sendMidiCallback(
                            self._createUpdateNotAvailableMsg())
            else:
                if self._sendMidiCallback is not None:
                    self._sendMidiCallback(self._createUpdateBusyMsg())
        elif data[0] == 0x00 and data[1] == 0x11:
            # Update check
            logger.info("MIDI-BLE REQ Update check")
            logger.info("Checking for update, current version is {}".format(
                version.get_version()))
            self._updatePathsAndUrls(serverconfig)

            if not self._isUpdating:
                self._isUpdating = True
                try:
                    # Move version.gz to force a reload
                    oldFile = os.path.join(self.client.data_dir,
                                           self.client.version_file)
                    if os.path.exists(oldFile):
                        shutil.move(oldFile, oldFile.replace('.gz', '.gz.bak'))

                    oldFile = os.path.join(self.client.data_dir,
                                           self.client.version_file_compat)
                    if os.path.exists(oldFile):
                        shutil.move(oldFile, oldFile.replace('.gz', '.gz.bak'))

                    self.client.refresh()
                    app_update = self.client.update_check(
                        'Molecole', version.get_version())
                    self._isUpdating = False
                    if app_update is not None:
                        logger.info("Update {} available".format(
                            app_update.version))
                        if self._sendMidiCallback is not None:
                            self._sendMidiCallback(
                                self._createUpdateVersionAvailableMsg(
                                    app_update.version))
                    else:
                        logger.info("Update check returned no update")
                        if self._sendMidiCallback is not None:
                            self._sendMidiCallback(
                                self._createUpdateNotAvailableMsg())
                except Exception as e:
                    logger.error("Error trying to update: {}".format(e))
                    self._isUpdating = False
            else:
                if self._sendMidiCallback is not None:
                    self._sendMidiCallback(self._createUpdateBusyMsg())
        elif data[0] == 0x00 and data[1] == 0x20:
            # Active project metadata
            if self._sendMidiCallback is not None:
                metadata = serverconfig.getProjectMetadata(proj.id)
                self._sendMidiCallback(self._createActiveProjectMsg(metadata))
        elif data[0] == 0x00 and data[1] == 0x30:
            # Get projects
            if self._sendMidiCallback is not None:
                metadata = serverconfig.getProjectsMetadata()
                self._sendMidiCallback(self._createProjectsMsg(metadata))
        elif data[0] == 0x00 and data[1] == 0x40:
            # Activate project
            projUid = str(bytes(sysex_data.decode(data[2:])), encoding='utf8')
            logger.info("MIDI-BLE REQ Activate project {}".format(projUid))
            proj = serverconfig.getProject(projUid)
            if proj is not None:
                if self._sendMidiCallback is not None:
                    self._sendMidiCallback(
                        self._createActivateProjSuccessfulMsg())
            else:
                if self._sendMidiCallback is not None:
                    self._sendMidiCallback(
                        self._createActivateProjNotFoundMsg())
        elif data[0] == 0x00 and data[1] == 0x50:
            # Import project
            logger.info("MIDI-BLE REQ Import project")
            dec = sysex_data.decode(data[2:])
            projGzip = zlib.decompress(bytes(dec))
            projJson = str(projGzip, encoding='utf8')
            try:
                serverconfig.importProject(projJson)
                if self._sendMidiCallback is not None:
                    self._sendMidiCallback(
                        self._createImportProjSuccessfulMsg())
            except Exception:
                if self._sendMidiCallback is not None:
                    self._sendMidiCallback(self._createImportProjErrorMsg())
        elif data[0] == 0x00 and data[1] == 0x60:
            # Export project
            byteArr = bytes(sysex_data.decode(data[2:]))
            logger.debug("Decoded {} to {}".format([hex(c) for c in data[2:]],
                                                   byteArr))
            projUid = str(byteArr, encoding='utf8')
            logger.info("MIDI-BLE REQ Export project {}".format(projUid))
            proj = serverconfig.getProject(projUid)
            if proj is not None:
                if self._sendMidiCallback is not None:
                    self._sendMidiCallback(
                        self._createExportProjSuccessfulMsg(proj))
            else:
                if self._sendMidiCallback is not None:
                    self._sendMidiCallback(self._createExportProjNotFoundMsg())
        elif data[0] == 0x00 and data[1] == 0x70:
            # Activate project
            projUid = str(bytes(sysex_data.decode(data[2:])), encoding='utf8')
            logger.info("MIDI-BLE REQ Delete project {}".format(projUid))
            proj = serverconfig.getProject(projUid)
            if proj is not None:
                serverconfig.deleteProject(projUid)
                if self._sendMidiCallback is not None:
                    self._sendMidiCallback(self._deleteProjSuccessfulMsg())
            else:
                if self._sendMidiCallback is not None:
                    self._sendMidiCallback(self._deleteProjNotFoundMsg())
        elif data[0] == 0x01 and data[1] == 0x00:
            # Get active scene ID
            logger.info("MIDI-BLE REQ Active scene index")
            sceneId = serverconfig.getActiveProjectOrDefault().activeSceneId
            if self._sendMidiCallback is not None:
                self._sendMidiCallback(
                    self._createGetActiveSceneIdMsg(sceneId))
        elif data[0] == 0x01 and data[1] == 0x10:
            # Get active scene metadata
            logger.info("MIDI-BLE REQ Get active scene metadata")
            proj = serverconfig.getActiveProjectOrDefault()
            metadata = proj.getSceneMetadata(proj.activeSceneId)
            if self._sendMidiCallback is not None:
                self._sendMidiCallback(
                    self._createActiveSceneMetadataMsg(metadata))
        elif data[0] == 0x01 and data[1] == 0x20:
            # Get scenes metadata
            logger.info("MIDI-BLE REQ Get scenes")
            proj = serverconfig.getActiveProjectOrDefault()
            metadata = proj.sceneMetadata
            if self._sendMidiCallback is not None:
                self._sendMidiCallback(self._createScenesMetadataMsg(metadata))
        elif data[0] == 0x01 and data[1] == 0x30:
            # Get enabled controllers for active scene
            logger.info("MIDI-BLE REQ Get controller enabled for active scene")
            proj = serverconfig.getActiveProjectOrDefault()
            if self._sendMidiCallback is not None:
                self._sendMidiCallback(self._createEnabledControllersMsg(proj))
        elif data[0] == 0x01 and data[1] == 0x40:
            # Request controller values for active project
            logger.info("MIDI-BLE REQ Get controller values for active scene")
            proj = serverconfig.getActiveProjectOrDefault()
            self._sendControllerStatus(proj)
        elif data[0] == 0x01 and data[1] == 0x50:
            # Reset controller values for active project
            logger.info("MIDI-BLE REQ Reset controller for active scene")
            proj = serverconfig.getActiveProjectOrDefault()
            proj.resetControllerModulation()
            self._sendControllerStatus(proj)
        elif data[0] == 0x02 and data[1] == 0x00:
            # Get server configuration
            logger.info("MIDI-BLE REQ Get server configuration")
            config = serverconfig.getFullConfiguration()
            if self._sendMidiCallback is not None:
                self._sendMidiCallback(self._createGetServerConfigMsg(config))
        elif data[0] == 0x02 and data[1] == 0x10:
            # Update server configuration
            logger.info("MIDI-BLE REQ Update server configuration")
            dec = sysex_data.decode(data[2:])
            configGzip = zlib.decompress(bytes(dec))
            configJson = str(configGzip, encoding='utf8')
            config = json.loads(configJson)
            try:
                serverconfig.setConfiguration(config)
                if self._sendMidiCallback is not None:
                    self._sendMidiCallback(
                        self._createUpdateServerConfigSuccessfulMsg())
            except Exception:
                if self._sendMidiCallback is not None:
                    self._sendMidiCallback(
                        self._createUpdateServerConfigErrorMsg())
        elif data[0] == 0x02 and data[1] == 0x20:
            logger.info("MIDI-BLE REQ Audio rms")
            rms = {"0": "NO_BUFFER"}
            if audio.GlobalAudio.buffer is not None:
                if isinstance(audio.GlobalAudio.buffer, Iterable):
                    numChannels = len(audio.GlobalAudio.buffer)

                    for i in range(numChannels):
                        rmsFromChannel = dsp.rms(audio.GlobalAudio.buffer[i])
                        rms[str(i)] = rmsFromChannel
                else:
                    logger.debug("audio.GlobalAudio.buffer not iterateable")
            if self._sendMidiCallback is not None:
                self._sendMidiCallback(self._createAudioRMSMsg(
                    json.dumps(rms)))
        else:
            logger.error("MIDI-BLE Unknown sysex {} {}".format(
                hex(data[0]), hex(data[1])))