~mixxxdevelopers/mixxx/trunk

« back to all changes in this revision

Viewing changes to mixxx/src/midi/midiledhandler.cpp

Merging features_controllerAbstraction. Migration of mappings from .mixxx/midi/ to controllers/ only works on a version upgrade (end-users.)

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
#include "midiledhandler.h"
2
 
#include "widget/wwidget.h"
3
 
#include <QList>
4
 
#include <QDebug>
5
 
 
6
 
QList<MidiLedHandler*> MidiLedHandler::allhandlers = QList<MidiLedHandler*>();
7
 
 
8
 
MidiLedHandler::MidiLedHandler(QString group, QString key, MidiDevice & midi, double min,
9
 
                               double max, unsigned char status, unsigned char midino, unsigned char on, unsigned char off)
10
 
    : m_min(min), m_max(max), m_midi(midi), m_status(status), m_midino(midino), m_on(on), m_off(off) {
11
 
 
12
 
    //OMGWTFBBQ: Massive hack to temporarily fix LP #254564 for the 1.6.0 release.
13
 
    //           Something's funky with our <lights> blocks handling? -- Albert 08/05/2008
14
 
    if (group.isEmpty() || key.isEmpty()) return;
15
 
 
16
 
    m_cobj = ControlObject::getControl(ConfigKey(group, key));
17
 
 
18
 
    //m_cobj should never be null, so Q_ASSERT here to make sure that we hear about it if it is null.
19
 
    //Q_ASSERT(m_cobj);
20
 
    QByteArray err_tmp = QString("Invalid config group: '%1', name: '%2'")
21
 
            .arg(group, key).toAscii();
22
 
    Q_ASSERT_X(m_cobj, "MidiLedHandler", err_tmp);
23
 
 
24
 
    connect(m_cobj, SIGNAL(valueChangedFromEngine(double)), this, SLOT(controlChanged(double)), Qt::DirectConnection);
25
 
    connect(m_cobj, SIGNAL(valueChanged(double)), this, SLOT(controlChanged(double)), Qt::DirectConnection);
26
 
}
27
 
 
28
 
MidiLedHandler::~MidiLedHandler() {
29
 
    ConfigKey cKey = m_cobj->getKey();
30
 
    if (m_midi.midiDebugging()) {
31
 
        qDebug() << QString("Destroying static LED handler on %1 for %2,%3")
32
 
            .arg(m_midi.getName(), cKey.group, cKey.item);
33
 
    }
34
 
}
35
 
 
36
 
void MidiLedHandler::update() {
37
 
    controlChanged(m_cobj->get());
38
 
}
39
 
 
40
 
void MidiLedHandler::controlChanged(double value) {
41
 
    //Guh, the valueChangedFromEngine and valueChanged signals can occur simultaneously because we're
42
 
    //using Qt::DirectConnection. We have to block by hand to prevent re-entrancy. We can't use
43
 
    //Qt::BlockingQueuedConnection because we don't have an event loop in some of the threads that
44
 
    //create MidiLedHandlers. (The underlying code is messy - On first run, the LED handlers get created
45
 
    //in the main thread, and then after you load a new binding, they get created from the Midi thread.)
46
 
    // - Albert 04/19/2009
47
 
    m_reentracyBlock.lock();
48
 
    unsigned char m_byte2 = m_off;
49
 
    if (value >= m_min && value <= m_max) { m_byte2 = m_on; }
50
 
 
51
 
    if (!m_midi.isOpen())
52
 
        qWarning() << "MIDI device" << m_midi.getName() << "not open for output!";
53
 
    else if (m_byte2 != 0xff) {
54
 
//         qDebug() << "MIDI bytes:" << m_status << ", " << m_midino << ", " << m_byte2 ;
55
 
        m_midi.sendShortMsg(m_status, m_midino, m_byte2);
56
 
    }
57
 
    m_reentracyBlock.unlock();
58
 
}
59
 
 
60
 
void MidiLedHandler::createHandlers(QDomNode node, MidiDevice & midi) {
61
 
    if (!node.isNull() && node.isElement()) {
62
 
        QDomNode light = node;
63
 
        while (!light.isNull()) {
64
 
            if(light.nodeName() == "output") {
65
 
                QString group = WWidget::selectNodeQString(light, "group");
66
 
                QString key = WWidget::selectNodeQString(light, "key");
67
 
 
68
 
                unsigned char status = (unsigned char)WWidget::selectNodeInt(light, "status");
69
 
                unsigned char midino = (unsigned char)WWidget::selectNodeInt(light, "midino");
70
 
                unsigned char on = 0x7f;    // Compatible with Hercules and others
71
 
                unsigned char off = 0x00;
72
 
                float min = 0.0f;
73
 
                float max = 1.0f;
74
 
                if (!light.firstChildElement("on").isNull()) {
75
 
                    on = (unsigned char)WWidget::selectNodeInt(light, "on");
76
 
                }
77
 
                if (!light.firstChildElement("off").isNull()) {
78
 
                    off = (unsigned char)WWidget::selectNodeInt(light, "off");
79
 
                }
80
 
                if (!light.firstChildElement("threshold").isNull()) { //Deprecated as of 1.7.0
81
 
                    min = WWidget::selectNodeFloat(light, "threshold");
82
 
                }
83
 
                if (!light.firstChildElement("minimum").isNull()) {
84
 
                    min = WWidget::selectNodeFloat(light, "minimum");
85
 
                }
86
 
                if (!light.firstChildElement("maximum").isNull()) {
87
 
                    max = WWidget::selectNodeFloat(light, "maximum");
88
 
                }
89
 
                if (midi.midiDebugging()) {
90
 
                    qDebug() << QString(
91
 
                        "Creating LED handler for %1,%2 between %3 and %4 to MIDI out: 0x%5 0x%6, on: 0x%7 off: 0x%8")
92
 
                            .arg(group, key,
93
 
                                 QString::number(min), QString::number(max),
94
 
                                 QString::number(status, 16).toUpper(),
95
 
                                 QString::number(midino, 16).toUpper().rightJustified(2,'0'),
96
 
                                 QString::number(on, 16).toUpper().rightJustified(2,'0'),
97
 
                                 QString::number(off, 16).toUpper().rightJustified(2,'0'));
98
 
                }
99
 
 
100
 
                allhandlers.append(new MidiLedHandler(group, key, midi, min, max, status, midino, on, off));
101
 
            }
102
 
            light = light.nextSibling();
103
 
        }
104
 
    }
105
 
}
106
 
 
107
 
void MidiLedHandler::updateAll() {
108
 
    for (int i = 0; i < allhandlers.count(); i++) {
109
 
        allhandlers.at(i)->update();
110
 
    }
111
 
}
112
 
 
113
 
void MidiLedHandler::destroyHandlers(MidiDevice *midi) {
114
 
    for (int i = allhandlers.count()-1; i >= 0; --i) {
115
 
        if (allhandlers.at(i)->getMidiDevice() == midi) {
116
 
            delete allhandlers.takeAt(i);
117
 
        }
118
 
    }
119
 
}