void EnttecDMXDevice::opcMapPixelColors(const OPC::Message &msg, const Value &inst)
{
    /*
     * Parse one JSON mapping instruction, and copy any relevant parts of 'msg'
     * into our framebuffer. This looks for any mapping instructions that we
     * recognize:
     *
     *   [ OPC Channel, OPC Pixel, Pixel Color, DMX Channel ]
     */

    unsigned msgPixelCount = msg.length() / 3;

    if (inst.IsArray() && inst.Size() == 4) {
        // Map a range from an OPC channel to our framebuffer

        const Value &vChannel = inst[0u];
        const Value &vPixelIndex = inst[1];
        const Value &vPixelColor = inst[2];
        const Value &vDMXChannel = inst[3];

        if (vChannel.IsUint() && vPixelIndex.IsUint() && vPixelColor.IsString() && vDMXChannel.IsUint()) {
            unsigned channel = vChannel.GetUint();
            unsigned pixelIndex = vPixelIndex.GetUint();
            const char *pixelColor = vPixelColor.GetString();
            unsigned dmxChannel = vDMXChannel.GetUint();

            if (channel != msg.channel || pixelIndex >= msgPixelCount) {
                return;
            }

            const uint8_t *pixel = msg.data + (pixelIndex * 3);

            switch (pixelColor[0]) {

                case 'r':
                    setChannel(dmxChannel, pixel[0]);
                    break;

                case 'g':
                    setChannel(dmxChannel, pixel[1]);
                    break;

                case 'b':
                    setChannel(dmxChannel, pixel[2]);
                    break;

                case 'l':
                    setChannel(dmxChannel, (unsigned(pixel[0]) + unsigned(pixel[1]) + unsigned(pixel[2])) / 3);
                    break;

            }
            return;
        }
    }

    // Still haven't found a match?
    if (mVerbose) {
        std::clog << "Unsupported JSON mapping instruction\n";
    }
}
Example #2
0
void FCDevice::opcSetGlobalColorCorrection(const OPC::Message &msg)
{
    /*
     * Parse the message as JSON text, and if successful, write new
     * color correction data to the device.
     */

    // Mutable NUL-terminated copy of the message string
    std::string text((char*)msg.data + 4, msg.length() - 4);

    // Parse it in-place
    rapidjson::Document doc;
    doc.ParseInsitu<0>(&text[0]);

    if (doc.HasParseError()) {
        if (mVerbose) {
            std::clog << "Parse error in color correction JSON at character "
                << doc.GetErrorOffset() << ": " << doc.GetParseError() << "\n";
        }
        return;
    }

    /*
     * Successfully parsed the JSON. From here, it's handled identically to
     * objects that come through the config file.
     */
    writeColorCorrection(doc);
}
Example #3
0
void FCDevice::opcSysEx(const OPC::Message &msg)
{
    if (msg.length() < 4) {
        if (mVerbose) {
            std::clog << "SysEx message too short!\n";
        }
        return;
    }

    unsigned id = (unsigned(msg.data[0]) << 24) |
                  (unsigned(msg.data[1]) << 16) |
                  (unsigned(msg.data[2]) << 8)  |
                   unsigned(msg.data[3])        ;

    switch (id) {

        case OPC::FCSetGlobalColorCorrection:
            return opcSetGlobalColorCorrection(msg);

        case OPC::FCSetFirmwareConfiguration:
            return opcSetFirmwareConfiguration(msg);

    }

    // Quietly ignore unhandled SysEx messages.
}
Example #4
0
void FCDevice::opcMapPixelColors(const OPC::Message &msg, const Value &inst)
{
    /*
     * Parse one JSON mapping instruction, and copy any relevant parts of 'msg'
     * into our framebuffer. This looks for any mapping instructions that we
     * recognize:
     *
     *   [ OPC Channel, First OPC Pixel, First output pixel, pixel count ]
     */

    unsigned msgPixelCount = msg.length() / 3;

    if (inst.IsArray() && inst.Size() == 4) {
        // Map a range from an OPC channel to our framebuffer

        const Value &vChannel = inst[0u];
        const Value &vFirstOPC = inst[1];
        const Value &vFirstOut = inst[2];
        const Value &vCount = inst[3];

        if (vChannel.IsUint() && vFirstOPC.IsUint() && vFirstOut.IsUint() && vCount.IsUint()) {
            unsigned channel = vChannel.GetUint();
            unsigned firstOPC = vFirstOPC.GetUint();
            unsigned firstOut = vFirstOut.GetUint();
            unsigned count = vCount.GetUint();

            if (channel != msg.channel) {
                return;
            }

            // Clamping, overflow-safe
            firstOPC = std::min<unsigned>(firstOPC, msgPixelCount);
            firstOut = std::min<unsigned>(firstOut, unsigned(NUM_PIXELS));
            count = std::min<unsigned>(count, msgPixelCount - firstOPC);
            count = std::min<unsigned>(count, NUM_PIXELS - firstOut);

            // Copy pixels
            const uint8_t *inPtr = msg.data + (firstOPC * 3);
            unsigned outIndex = firstOut;

            while (count--) {
                uint8_t *outPtr = fbPixel(outIndex++);
                outPtr[0] = inPtr[0];
                outPtr[1] = inPtr[1];
                outPtr[2] = inPtr[2];
                inPtr += 3;
            }

            return;
        }
    }

    // Still haven't found a match?
    if (mVerbose) {
        std::clog << "Unsupported JSON mapping instruction\n";
    }
}
Example #5
0
void BitWizardWSDevice::opcMapPixelColors(const OPC::Message &msg, const Value &inst)
{
  /*
   * Parse one JSON mapping instruction, and copy any relevant parts of 'msg'
   * into our framebuffer. This looks for any mapping instructions that we
   * recognize:
   *
   *   [ OPC Channel, OPC Pixel, Pixel Color, DMX Channel ]
   */

  unsigned msgPixelCount = msg.length() / 3;

  if (inst.IsArray() && inst.Size() == 4) {
    // Map a range from an OPC channel to our framebuffer

    const Value &vChannel  = inst[0u];
    const Value &vFirstOPC = inst[1];
    const Value &vFirstOut = inst[2];
    const Value &vCount    = inst[3];


    if (vChannel.IsUint() && vFirstOPC.IsUint() && 
	vFirstOut.IsUint() && vCount.IsUint()) {
      unsigned channel  = vChannel.GetUint();
      unsigned firstOPC = vFirstOPC.GetUint();
      unsigned firstOut = vFirstOut.GetUint();
      unsigned count    = vCount.GetUint();
      

      if (channel != msg.channel) {
	return;
      }

      // Clamping, overflow-safe
      firstOPC = std::min<unsigned>(firstOPC, msgPixelCount);
      firstOut = std::min<unsigned>(firstOut, unsigned(NUM_PIXELS));
      count = std::min<unsigned>(count, msgPixelCount - firstOPC);
      count = std::min<unsigned>(count, NUM_PIXELS - firstOut);
      
      // Copy pixels
      const uint8_t *inPtr = msg.data + (firstOPC * 3);
      unsigned outIndex = firstOut;

      //std::cout  << "mapping " << count << " pixels at " << firstOut << "...\n";
      
      while (count--) {
	uint8_t *outPtr = fbPixel(outIndex++);
	outPtr[0] = inPtr[0];
	outPtr[1] = inPtr[1];
	outPtr[2] = inPtr[2];
	inPtr += 3;
	if (outIndex >= NUM_PIXELS) return;
      }
      
      return;
    }
  }

  if (inst.IsArray() && inst.Size() == 2) {
    // Constant value

    const Value &vValue = inst[0u];
    const Value &vDMXChannel = inst[1];

    if (vValue.IsUint() && vDMXChannel.IsUint()) {
      unsigned value = vValue.GetUint();
      unsigned dmxChannel = vDMXChannel.GetUint();

      //setChannel(dmxChannel, value);
      return;
    }
  }

  // Still haven't found a match?
  if (mVerbose) {
    rapidjson::GenericStringBuffer<rapidjson::UTF8<> > buffer;
    rapidjson::Writer<rapidjson::GenericStringBuffer<rapidjson::UTF8<> > > writer(buffer);
    inst.Accept(writer);
    std::clog << "Unsupported JSON mapping instruction: " << buffer.GetString() << "\n";
  }
}
Example #6
0
void FCDevice::opcSetFirmwareConfiguration(const OPC::Message &msg)
{
    /*
     * Raw firmware configuration packet
     */

    memcpy(mFirmwareConfig.data, msg.data + 4, std::min<size_t>(sizeof mFirmwareConfig.data, msg.length() - 4));
    writeFirmwareConfiguration();
}