Esempio n. 1
0
int HidController::close() {
    if (!isOpen()) {
        qDebug() << "HID device" << getName() << "already closed";
        return -1;
    }

    qDebug() << "Shutting down HID device" << getName();

    // Stop the reading thread
    if (m_pReader == NULL) {
        qWarning() << "HidReader not present for" << getName()
                   << "yet the device is open!";
    } else {
        disconnect(m_pReader, SIGNAL(incomingData(QByteArray, mixxx::Duration)),
                   this, SLOT(receive(QByteArray, mixxx::Duration)));
        m_pReader->stop();
        hid_set_nonblocking(m_pHidDevice, 1);   // Quit blocking
        controllerDebug("  Waiting on reader to finish");
        m_pReader->wait();
        delete m_pReader;
        m_pReader = NULL;
    }

    // Stop controller engine here to ensure it's done before the device is closed
    //  incase it has any final parting messages
    stopEngine();

    // Close device
    controllerDebug("  Closing device");
    hid_close(m_pHidDevice);
    setOpen(false);
    return 0;
}
Esempio n. 2
0
int BulkController::close() {
    if (!isOpen()) {
        qDebug() << " device" << getName() << "already closed";
        return -1;
    }

    qDebug() << "Shutting down USB Bulk device" << getName();

    // Stop the reading thread
    if (m_pReader == NULL) {
        qWarning() << "BulkReader not present for" << getName()
                   << "yet the device is open!";
    } else {
        disconnect(m_pReader, SIGNAL(incomingData(QByteArray, mixxx::Duration)),
                   this, SLOT(receive(QByteArray, mixxx::Duration)));
        m_pReader->stop();
        controllerDebug("  Waiting on reader to finish");
        m_pReader->wait();
        delete m_pReader;
        m_pReader = NULL;
    }

    // Stop controller engine here to ensure it's done before the device is
    // closed incase it has any final parting messages
    stopEngine();

    // Close device
    controllerDebug("  Closing device");
    libusb_close(m_phandle);
    m_phandle = NULL;
    setOpen(false);
    return 0;
}
Esempio n. 3
0
int HidController::open() {
    if (isOpen()) {
        qDebug() << "HID device" << getName() << "already open";
        return -1;
    }

    // Open device by path
    controllerDebug("Opening HID device" << getName() << "by HID path" << hid_path);

    m_pHidDevice = hid_open_path(hid_path);

    // If that fails, try to open device with vendor/product/serial #
    if (m_pHidDevice == NULL) {
        controllerDebug("Failed. Trying to open with make, model & serial no:"
                << hid_vendor_id << hid_product_id << hid_serial);
        m_pHidDevice = hid_open(hid_vendor_id, hid_product_id, hid_serial_raw);
    }

    // If it does fail, try without serial number WARNING: This will only open
    // one of multiple identical devices
    if (m_pHidDevice == NULL) {
        qWarning() << "Unable to open specific HID device" << getName()
                   << "Trying now with just make and model."
                   << "(This may only open the first of multiple identical devices.)";
        m_pHidDevice = hid_open(hid_vendor_id, hid_product_id, NULL);
    }

    // If that fails, we give up!
    if (m_pHidDevice == NULL) {
        qWarning()  << "Unable to open HID device" << getName();
        return -1;
    }

    setConnected(true);

    setOpen(true);
    startEngine();

    if (m_pReader != NULL) {
        qWarning() << "HidReader already present for" << getName();
    } else {
        m_pReader = new HidReader(m_pHidDevice);
        m_pReader->setObjectName(QString("HidReader %1").arg(getName()));

        connect(m_pReader, SIGNAL(incomingData(QByteArray, mixxx::Duration)),
                this, SLOT(receive(QByteArray, mixxx::Duration)));

        // Controller input needs to be prioritized since it can affect the
        // audio directly, like when scratching
        m_pReader->start(QThread::HighPriority);
    }

    return 0;
}
Esempio n. 4
0
void MidiOutputHandler::controlChanged(double value) {
    // Don't update with out of date messages.
    value = m_cos.get();

    unsigned char byte3 = m_mapping.output.off;
    if (value >= m_mapping.output.min && value <= m_mapping.output.max) {
        byte3 = m_mapping.output.on;
    }

    if (static_cast<int>(byte3) == m_lastVal) {
        // Don't send redundant messages.
        return;
    }

    if (!m_pController->isOpen()) {
        qWarning() << "MIDI device" << m_pController->getName() << "not open for output!";
    } else if (byte3 != 0xFF) {
        controllerDebug("sending MIDI bytes:" << m_mapping.output.status
                     << "," << m_mapping.output.control << ","
                     << byte3);
        m_pController->sendShortMsg(m_mapping.output.status,
                                    m_mapping.output.control, byte3);
        m_lastVal = static_cast<int>(byte3);
    }
}
Esempio n. 5
0
void MidiController::createOutputHandlers() {
    if (m_preset.outputMappings.isEmpty()) {
        return;
    }

    QHashIterator<ConfigKey, MidiOutputMapping> outIt(m_preset.outputMappings);
    QStringList failures;
    while (outIt.hasNext()) {
        outIt.next();

        const MidiOutputMapping& mapping = outIt.value();

        QString group = mapping.control.group;
        QString key = mapping.control.item;

        unsigned char status = mapping.output.status;
        unsigned char control = mapping.output.control;
        unsigned char on = mapping.output.on;
        unsigned char off = mapping.output.off;
        double min = mapping.output.min;
        double max = mapping.output.max;

        controllerDebug(QString(
                "Creating output handler for %1,%2 between %3 and %4 to MIDI out: 0x%5 0x%6, on: 0x%7 off: 0x%8")
                        .arg(group, key,
                                QString::number(min), QString::number(max),
                                QString::number(status, 16).toUpper(),
                                QString::number(control, 16).toUpper().rightJustified(2,'0'),
                                QString::number(on, 16).toUpper().rightJustified(2,'0'),
                                QString::number(off, 16).toUpper().rightJustified(2,'0')));

        MidiOutputHandler* moh = new MidiOutputHandler(this, mapping);
        if (!moh->validate()) {
            QString errorLog =
                QString("MIDI output message 0x%1 0x%2 has invalid MixxxControl %3, %4")
                        .arg(QString::number(status, 16).toUpper(),
                             QString::number(control, 16).toUpper().rightJustified(2,'0'))
                        .arg(group, key).toUtf8();
            qWarning() << errorLog;

            int deckNum = 0;
            if (ControllerDebug::enabled()) {
                failures.append(errorLog);
            } else if (PlayerManager::isDeckGroup(group, &deckNum)) {
                int numDecks = PlayerManager::numDecks();
                if (deckNum <= numDecks) {
                    failures.append(errorLog);
                }
            }

            delete moh;
            continue;
        }
        m_outputs.append(moh);
    }

    if (!failures.isEmpty()) {
        ErrorDialogProperties* props = ErrorDialogHandler::instance()->newDialogProperties();
        props->setType(DLG_WARNING);
        props->setTitle(tr("MixxxControl(s) not found"));
        props->setText(tr("One or more MixxxControls specified in the "
                          "outputs section of the loaded preset were invalid."));
        props->setInfoText(tr("Some LEDs or other feedback may not work correctly."));
        QString detailsText = tr("* Check to see that the MixxxControl "
                                 "names are spelled correctly in the mapping "
                                 "file (.xml)\n");
        detailsText += tr("* Make sure the MixxxControls in question actually exist."
                          " Visit this wiki page for a complete list: ");
        detailsText += "http://mixxx.org/wiki/doku.php/mixxxcontrols\n\n";
        detailsText += failures.join("\n");
        props->setDetails(detailsText);
        ErrorDialogHandler::instance()->requestErrorDialog(props);
    }
}
Esempio n. 6
0
MidiOutputHandler::~MidiOutputHandler() {
    ConfigKey cKey = m_cos.getKey();
    controllerDebug(QString("Destroying static MIDI output handler on %1 for %2,%3")
                .arg(m_pController->getName(), cKey.group, cKey.item));
}