def visualize_once(self,
                       falloff: float = 0.8,
                       rows: float = 25,
                       col: int = 20,
                       top: int = 100):
        """ Visualize current levels of audio on the razer devices, and render it

        :param falloff: Substraction coefficient to apply to last frame of the animation
        :param rows: Number of rows to have in visualization
        :param col: Number of columns to have in visualization
        :param top: Maximum number expected from the visualization
        """
        r = self.device_controller.r * falloff
        g = self.device_controller.g * falloff
        b = self.device_controller.b * falloff

        # audio data from stream (after fft)
        data = self.audio.read_once(rows, col)
        logging.pprint(str(data[4]), 5)

        # render colors
        new_coef = (data[4] - self.dampen) / (self.ceiling - self.dampen)
        if (new_coef >= self.device_controller.coef):
            self.device_controller.coef = new_coef
        else:
            self.device_controller.coef = self.device_controller.coef * falloff

        if (self.device_controller.coef < self.ambient_brightness_coef):
            self.device_controller.coef = self.ambient_brightness_coef
Example #2
0
    def set(self, r, g, b):
        """ Instantly set color
        """
        self.r = r
        self.g = g
        self.b = b
        self.update_color(self.r, self.g, self.b)

        def update_color(self, r, g, b):
            """ Update and render colors
        """

        logging.pprint(f"setting color to {r},{g},{b}", 5)
        #if(self.delay):
        #    time.sleep(self.delay)
        r = int(r * self.coef)
        g = int(g * self.coef)
        b = int(b * self.coef)

        if (r > 255): r = 255
        if (g > 255): g = 255
        if (b > 255): b = 255

        if (r < 0): r = 0
        if (g < 0): g = 0
        if (b < 0): b = 0

        self.set_ECIO_color(r, g, b)
Example #3
0
 def send(self, data):
     """ Send feature report to HID device
     """
     logging.pprint(f"Sending: {data}", 6)
     return self.hid_dll.HidD_SetFeature(int(self.device.hid_handle),
                                         create_string_buffer(data),
                                         len(data))
 def __del__(self):
     """ Stop stream and close. Terminate pyaudio.
     """
     logging.pprint("Stopping audio stream", 2)
     self.stream.stop_stream()
     self.stream.close()
     self.p.terminate()
    def dfft_reduce(dfft: list, count: int = 25, reduction_coef: float = 50, top: int = 100, skip: int = 30) -> list:
        """ Reduce an fft result to "count" elements.
            This is done by summing "reduction_coef" many results into a single value.
            Whatever remains is ignored after count*reduction_coef elements.

            :param dfft: DFFT data array to reduce
            :param count: Number of partitions to split the spectrum into. Number of steps on the graph from 0hz to max hz. Default is 25.
            :param reduction_coef: Coefficient to to scale the output with. Default is 50. Sensitivity.
            :param top: Maximum value the graph will be scaled up to. Default is 100.
            :param skip: Size of partitions to skip between each partition. Larger is faster, but less precise.
            :rtype: list
            :return: A list of audio output after fast fourier transform
        """
        simplified = []
        sumt = 0
        t = int(top / count)
        for j in range(count):
            for k in range(reduction_coef):
                if dfft[skip + t * j + k] > 0:
                    sumt += dfft[skip + t * j + k]
            simplified.append(sumt)
            sumt = 0

        logging.pprint(f"Simplified FFT: {simplified}", 6)
        return simplified
 def generateKeyboardAnimation(self, binary_file: BinaryFile):
     logging.pprint(f"Generating Keyboard Animation", 4)
     try:
         animation = ChromaAnimation()
         animation.FPS = binary_file.BHeader.hFPS
         for i in range(0, len(binary_file.FrameList)):
             for j in range(0, len(binary_file.FrameList[i].DeviceList)):
                 temp = [[ChromaColor(red=0, green=0, blue=0) for x in range(22)] for y in range(6)]
                 if (i > 0):
                     for row in range(0, len(animation.Frames[i - 1])):
                         for col in range(0, len(animation.Frames[i - 1][row])):
                             red, green, blue = animation.Frames[i - 1][row][col].getRGB()
                             temp[row][col].set(red=red, blue=blue, green=green)
                 if (binary_file.FrameList[i].DeviceList[j].DeviceHeader.dhDevice == 1):
                     for k in range(0, len(binary_file.FrameList[i].DeviceList[j].DeviceDataList)):
                         color = binary_file.FrameList[i].DeviceList[j].DeviceDataList[k].dABGR
                         red = (color >> 0) & 255
                         green = (color >> 8) & 255
                         blue = (color >> 16) & 255
                         temp[binary_file.FrameList[i].DeviceList[j].DeviceDataList[k].dRow][
                             binary_file.FrameList[i].DeviceList[j].DeviceDataList[k].dCol].set(red=red, green=green,
                                                                                                blue=blue)
                     animation.Frames.append(temp)
         return animation
     except:
         # TODO Add proper exception handling
         logging.pprint('Unexpected Error!')
         raise
 def __init__(self, uri: str, maxLED: int = 0):
     logging.pprint(f"Initializing {self.__class__.__name__}", 2)
     self._MaxLED = maxLED
     self._ColorGrid = [
         ChromaColor(red=0, green=0, blue=0) for x in range(self._MaxLED)
     ]
     self.base_URI = uri
     self._URI = ""
Example #8
0
 def reset_colors(self):
     """ Reset colors to default
     """
     logging.pprint(f"Resetting colors", 2)
     self.send(rgb_to_hid_buf(0xff, 0x00, 0x00, 1))
     self.send(rgb_to_hid_buf(0xff, 0x1e, 0x00, 2))
     self.send(rgb_to_hid_buf(0xff, 0x64, 0x00, 3))
     self.send(rgb_to_hid_buf(0x00, 0x64, 0x00, 4))
     self.send(rgb_to_hid_buf(0x00, 0x00, 0x50, 5))
     self.send(rgb_to_hid_buf(0x00, 0x64, 0x00, 6))
     self.send(rgb_to_hid_buf(0xff, 0x00, 0x50, 7))
    def raw_read(self) -> list:
        """Read chunk sized data from stream

        :return: audio data array in format np.int16
        """
        logging.pprint("Reading data...", 6)
        in_data = self.stream.read(self.CHUNK)

        # Format audio data
        logging.pprint("Formatting data...", 6)
        audio_data = np.fromstring(in_data, np.int16)
        return audio_data
Example #10
0
    def render(self, r=None, g=None, b=None):
        """Set keyboard to flat color.
        If either of r/g/b values are given, all the keys will be set to the same color. If not, stored colors will be used.

        For each row of keyboard, send feature request:
            b"\\x00\\x16\\x00" + bytes([i])  + b"\\x00\\x00\\x00\\x00\\x00"

        And send the corresponding color data through output report.

        Finalize with a render request:
        b"\\x00\\x16\\x12\\x00\\x00\\x08\\x01\\x00\\x00\\x00"
        """

        logging.pprint(f"Setting flat color", 4)
        #set r/g/b values if specified
        if (r):
            logging.pprint(f"Red color given, will fill the keyboard", 5)
            for i in range(6):
                for j in range(21):
                    self.red[i][j] = r

        if (g):
            logging.pprint(f"Green color given, will fill the keyboard", 5)
            for i in range(6):
                for j in range(21):
                    self.green[i][j] = g

        if (b):
            logging.pprint(f"Blue color given, will fill the keyboard", 5)
            for i in range(6):
                for j in range(21):
                    self.blue[i][j] = b

        #send set color request
        self.device.send(
            mode_to_hid_buf(mode=LightingMode.FLAT_COLOR,
                            speed=48,
                            brightness=48))

        #for each of the keyboard rows, send notification via feature request, and send the corresponding color data
        d = self.make_keyboard_buffer()

        for i in range(6):
            self.device.send(b"\x00\x16\x00" + bytes([i]) +
                             b"\x00\x00\x00\x00\x00")
            logging.pprint(f"col {i}: {d[i]}", 5)
            self.device.output.send(d[i])

        #render colors
        self.device.send(b"\x00\x16\x12\x00\x00\x08\x01\x00\x00\x00")
Example #11
0
    def update_color(self, r, g, b):
        """ Update and render colors
        """
        #print(r,g,b)
        logging.pprint(f"setting color to {r},{g},{b}", 5)
        #if(self.delay):
        #    time.sleep(self.delay)
        r = int(r * self.coef)
        g = int(g * self.coef)
        b = int(b * self.coef)

        if (r > 255): r = 255
        if (g > 255): g = 255
        if (b > 255): b = 255

        if (r < 0): r = 0
        if (g < 0): g = 0
        if (b < 0): b = 0
        self.set_ECIO_color(r, g, b)
Example #12
0
    def make_keyboard_buffer(self):
        """Convert self.red, self.green and self.blue to keyboard buffer needed for interface

        key values are written to output report, while updates are done via features report.
        
        Following will be written over USB for each row (bottom-up):
        b"\\x00\\x00" + bytes(self.blue[i]) + bytes(self.green[i]) + bytes(self.red[i])
        """

        ret = []
        logging.pprint(f"Creating Keyboard RGB Matrix", 5)
        # set 6x21 array for return buffer
        buf = b""
        for i in range(6):
            buf = b"\x00\x00" + bytes(self.blue[i]) + bytes(
                self.green[i]) + bytes(self.red[i])
            ret.append(buf)

        return ret
    def find_device(self, name: str) -> object:
        """ Find device with the given name

        :param name: Name of the audio device to find.
        :return: Audio device
        :rtype: object
        """
        # Enum sound devices
        info = self.p.get_host_api_info_by_index(0)
        numdevices = info.get('deviceCount')
        for i in range(0, numdevices):
            # print all device names
            if (self.p.get_device_info_by_host_api_device_index(0, i).get('maxInputChannels')) > 0:
                logging.pprint(
                    f"Input Device id {i} - {self.p.get_device_info_by_host_api_device_index(0, i).get('name')}", 6)

        for i in range(self.p.get_device_count()):
            # check if device name starts with expected device name
            if (self.p.get_device_info_by_index(i)["name"].startswith(name)):
                return self.p.get_device_info_by_index(i)["index"]
    def process_audio(self, audio_data: list, count: int, reduction: float) -> list:
        """ Process raw audio data,apply the reduction and partition steps and perform fast fourier on it.

        :param audio_data: Audio data to process.
        :param count: Number of partitions to split the data in
        :param reduction: Reduction coefficient
        :return: DFFT audio data.
        """
        try:
            # Fast Fourier Transform, 10*log10(abs) is to scale it to dB
            # and make sure it's not imaginary
            logging.pprint("Performing FFT...", 6)
            dfft = 10. * np.log10(abs(np.fft.rfft(audio_data) / len(audio_data)))
            dfft = self.dampen(dfft)
        except:
            # if something went wrong (most likely division by 0) send last output and hope it doesn't happen again.
            # Yes. This module runs on hopes and dreams.
            return self.last
        self.last = AudioController.dfft_reduce(dfft, count, reduction)
        return self.last
    def __init__(self, aud_format: int = pyaudio.paInt16, channels: int = 1, rate: int = 48000,
                 device_name: str = "pulse", dampen: float = -25) -> object:

        # Pyaudio parameters
        self.FORMAT = aud_format
        self.CHANNELS = channels
        self.RATE = rate
        self.CHUNK = 1024
        self.device_name = device_name
        self.p = pyaudio.PyAudio()

        self.last = []
        self.dampen_coef = dampen

        logging.pprint("Starting audio stream", 4)
        self.stream = self.p.open(format=self.FORMAT, channels=self.CHANNELS,
                                  rate=self.RATE, input=True, input_device_index=self.find_device(device_name),
                                  frames_per_buffer=self.CHUNK)

        self.stream.start_stream()
Example #16
0
    async def rainbow_fade(self, c):
        """ Rainbow Fade effect
        """
        logging.pprint(f"Starting rainbow fade effect.", 2)

        r = 0xff
        g = 0
        b = 0
        while True:
            for g in range(0, 0x1e):
                self.render(r=r, g=g, b=b)
            for g in range(0x1e, 0x50):
                self.render(r=r, g=g, b=b)
            for r in range(0xff, 0x00, -1):
                self.render(r=r, g=g, b=b)
            for b in range(0x00, 0x50):
                self.render(r=r, g=g - b, b=b)
            g = 0
            for r in range(0x00, 0xff):
                self.render(r=r, g=g, b=b)
            for b in range(0x50, 0x00, -1):
                self.render(r=r, g=g, b=b)
    def setCustomKey(self, key=None, keys=None):
        try:
            if keys is not None:
                for item in keys:
                    row = int(item._Key, 16) >> 8
                    col = int(item._Key, 16) & 0xFF

                    red, green, blue = item._Color.getRGB()
                    self._ColorGrid[row][col].set(red=red,
                                                  green=green,
                                                  blue=blue)

            if key is not None:
                row = int(int(key._Key, 16) >> 8)
                col = int(int(key._Key, 16) & 0xFF)

                red, green, blue = key._Color.getRGB()
                self._ColorGrid[row][col].set(red=red, green=green, blue=blue)
            return True
        except:
            # TODO Add proper exception handling
            logging.pprint('Unexpected Error!')
            raise
Example #18
0
    def Version(self):
        try:
            logging.pprint("Getting Version", 4)
            v = requests.get(
                url='http://localhost:54235/razer/chromasdk').json()['version']
            logging.pprint(f"Chroma SDK Version: {v}", 4)
            return

        except:
            # TODO Add proper exception handling
            logging.pprint('Unexpected Error!')
            raise
 def setEffect(self, effect: str, param=None):
     logging.pprint(f"Setting {self.__class__.__name__} effect to {effect}",
                    5)
     logging.pprint(f"Param: {param}", 6)
     try:
         data = {"effect": effect}
         if (param):
             data["param"] = param
         return checkresult(requests.put(url=self.URI, json=data).json())
     except:
         # TODO Add proper exception handling
         logging.pprint('Unexpected Error!')
         raise
Example #20
0
    def await_session(self):
        self.negotiate_session(self.data)

        #attempt 3 times at session negotiation and give up if it fails.
        for i in range(3):
            try:
                requests.get(self.URI)
                logging.pprint("Session started", 1)
                time.sleep(0.25)
                return
            except:
                logging.pprint("Timeout reached while waiting for session.")
                return self.await_session()

        logging.pprint(
            "All renegotiations failed. Cannot start chromaApp session.")
Example #21
0
import allogate as logging

logging.VERBOSITY = 1
print(f"Verbosity = {logging.VERBOSITY}")
logging.pprint(f"Hello, this is a failure", 0)
logging.pprint(f"Hello, this is a success", 1)
logging.pprint(f"Hello, this is a warning", 2)
logging.pprint(f"Hello, this is an info", 3)
logging.pprint(f"Hello, this is verbose", 4)
logging.pprint(f"Hello, this is very verbose", 12)

logging.VERBOSITY = 3
print(f"Verbosity = {logging.VERBOSITY}")
logging.pprint(f"Hello, this is a failure", 0)
logging.pprint(f"Hello, this is a success", 1)
logging.pprint(f"Hello, this is a warning", 2)
logging.pprint(f"Hello, this is an info", 3)
logging.pprint(f"Hello, this is verbose", 4)
logging.pprint(f"Hello, this is very verbose", 12)

logging.VERBOSITY = 5
print(f"Verbosity = {logging.VERBOSITY}")
logging.pprint(f"Hello, this is a failure", 0)
logging.pprint(f"Hello, this is a success", 1)
logging.pprint(f"Hello, this is a warning", 2)
logging.pprint(f"Hello, this is an info", 3)
logging.pprint(f"Hello, this is verbose", 4)
logging.pprint(f"Hello, this is very verbose", 12)

logging.VERBOSITY = 15
print(f"Verbosity = {logging.VERBOSITY}")
Example #22
0
    def __init__(self, vendor_id=0x048d, product_id=0xce00, index=1):
        logging.pprint(
            f"vendor_id:{hex(vendor_id)}, product_id:{hex(product_id)}", 3)
        #find hid device
        filter = hid.HidDeviceFilter(vendor_id=vendor_id,
                                     product_id=product_id)
        self.hid_devices = filter.get_devices()

        logging.pprint("HID devices (filtered): ", 3)
        for device in self.hid_devices:
            logging.pprint(f"\t{device}", 3)
        self.device = self.hid_devices[index]

        #hook hid.dll from system32
        self.hid_dll = WinDLL("hid")

        #target_usage = hid.get_full_usage_id(0xff03, 0x01)
        #print(hex(target_usage))

        self.device.open()
        logging.pprint(
            "Opened HID device with handle: {self.device.hid_handle}", 3)

        #open all reports
        self.report = self.device.find_any_reports()
        self.output = self.report[1][0]
        logging.pprint(f"Input   reports:{self.report[0]}", 3)
        logging.pprint(f"Output  reports:{self.report[1]}", 3)
        logging.pprint(f"Feature reports:{self.report[2]}", 3)
        logging.pprint(f"{self.report[0][0]}", 3)
        logging.pprint(f"{self.report[1][0]}", 3)
        logging.pprint(f"{self.report[2][0]}", 3)
Example #23
0
 def negotiate_session(self, data):
     logging.pprint("Sending request to /razer/chromasdk", 4)
     response = requests.post(url=self.url, json=data)
     logging.pprint("Received response from /razer/chromasdk", 4)
     self.SessionID, self.URI = response.json()['sessionid'], response.json(
     )['uri']
Example #24
0
 def __del__(self):
     logging.pprint("Shutting down Chroma App.", 6)
     self.heartbeat.stop()
     requests.delete(self.URI)
Example #25
0
    def __init__(self, Info: ChromaAppInfo):
        try:
            self.url = 'http://localhost:54235/razer/chromasdk'

            self.data = {
                "title": Info.Title,
                "description": Info.Description,
                "author": {
                    "name": Info.DeveloperName,
                    "contact": Info.DeveloperContact
                },
                "device_supported": Info.SupportedDevices,
                "category": Info.Category
            }

            #wait for session to fully initialize
            self.await_session()

            logging.pprint(f"URI: {self.URI}", 5)
            logging.pprint("Initializing heartbeat", 4)
            self.heartbeat = Heartbeat(self.URI)
            logging.pprint("Initializing keyboard", 4)
            self.Keyboard = Keyboard(self.URI)
            logging.pprint("Initializing mouse", 4)
            self.Mouse = Mouse(self.URI)
            logging.pprint("Initializing mousepad", 4)
            self.Mousepad = Mousepad(self.URI)
            logging.pprint("Initializing headset", 4)
            self.Headset = Headset(self.URI)
            logging.pprint("Initializing chromalink", 4)
            self.ChromaLink = ChromaLink(self.URI)
            logging.pprint("Initializing chromaBcaHandler", 4)
            self.BcaHandler = ChromaBcaHandler()
        except:
            logging.pprint("ChromaApp Crashed.", 0)
            raise
    def decode(self, filename: str):
        logging.pprint(f"Decode called for {filename}", 4)
        try:
            with open(filename, "rb") as f:
                binary_file = BinaryFile()

                
                """Reading FileHeader"""
                logging.pprint(f"Unpacking fileHeader: {filename}", 5)
                binary_file.FHeader.ftype = struct.unpack("<H", f.read(2))[0]
                binary_file.FHeader.fsize = struct.unpack("<L", f.read(4))[0]
                binary_file.FHeader.fReserved = struct.unpack("<L", f.read(4))[0]
                binary_file.FHeader.fBcaOffset = struct.unpack("<L", f.read(4))[0]

                
                """Reading BCAHeader"""
                logging.pprint(f"Unpacking BCAHeader: {filename}", 5)
                binary_file.BHeader.hSize = struct.unpack("<L", f.read(4))[0]
                binary_file.BHeader.hVersion = struct.unpack("<H", f.read(2))[0]
                binary_file.BHeader.hFrameOffset = struct.unpack("<L", f.read(4))[0]
                binary_file.BHeader.hFPS = struct.unpack("<H", f.read(2))[0]
                binary_file.BHeader.hFrameCount = struct.unpack("<L", f.read(4))[0]
                binary_file.BHeader.hReserved = struct.unpack("<H", f.read(2))[0]

                """Reading Frame"""
                logging.pprint(f"Reading Frame: {filename}", 5)
                for h in range(0, int(binary_file.BHeader.hFrameCount)):
                    binary_file.FrameList.append(BinaryFrame())
                for i in range(0, int(binary_file.BHeader.hFrameCount)):
                    """Reading FrameHeader"""
                    binary_file.FrameList[i].FrameHeader.fhSize = struct.unpack("<H", f.read(2))[0]

                    binary_file.FrameList[i].FrameHeader.fhDeviceCount = struct.unpack("<H", f.read(2))[0]
                    for j in range(0, binary_file.FrameList[i].FrameHeader.fhDeviceCount):
                        binary_file.FrameList[i].DeviceList.append(BinaryDevice())

                    binary_file.FrameList[i].FrameHeader.fhDataSize = struct.unpack("<H", f.read(2))[0]
                    """Reading Frame Data"""

                    for j in range(0, len(binary_file.FrameList[i].DeviceList)):
                        binary_file.FrameList[i].DeviceList[j].DeviceHeader.dhSize = struct.unpack("<B",
                                                                                                   f.read(1))[0]

                        binary_file.FrameList[i].DeviceList[j].DeviceHeader.dhDatatype = struct.unpack("<B",
                                                                                                       f.read(1))[0]

                        binary_file.FrameList[i].DeviceList[j].DeviceHeader.dhDevice = struct.unpack("<H",
                                                                                                     f.read(2))[0]

                        binary_file.FrameList[i].DeviceList[j].DeviceHeader.dhDataSize = struct.unpack("<H",
                                                                                                       f.read(2))[0]

                        dataCount = int(binary_file.FrameList[i].DeviceList[j].DeviceHeader.dhDataSize / 6)
                        for k in range(0, dataCount):
                            binary_file.FrameList[i].DeviceList[j].DeviceDataList.append(BinaryFile.DeviceData())
                        """Reading Device Data"""
                        for k in range(0, len(binary_file.FrameList[i].DeviceList[j].DeviceDataList)):
                            binary_file.FrameList[i].DeviceList[j].DeviceDataList[k].dRow = struct.unpack("<B",
                                                                                                          f.read(1))[0]
                            binary_file.FrameList[i].DeviceList[j].DeviceDataList[k].dCol = struct.unpack("<B",
                                                                                                          f.read(1))[0]
                            binary_file.FrameList[i].DeviceList[j].DeviceDataList[k].dABGR = struct.unpack("<L",
                                                                                                           f.read(4))[0]
                return binary_file
        except:
            # TODO Add proper exception handling
            logging.pprint('Unexpected Error!')
            raise
Example #27
0
def test_function():
    logging.pprint(f"Hello, this is a failure", 0)
    logging.pprint(f"Hello, this is a success", 1)
    logging.pprint(f"Hello, this is a warning", 2)
    logging.pprint(f"Hello, this is an info", 3)
    logging.pprint(f"Hello, this is verbose", 4)
    logging.pprint(f"Hello, this is very verbose", 12)