Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -468,6 +468,8 @@ add_library(mixxx-lib STATIC EXCLUDE_FROM_ALL
src/controllers/learningutils.cpp
src/controllers/midi/legacymidicontrollermapping.cpp
src/controllers/midi/legacymidicontrollermappingfilehandler.cpp
src/controllers/midi/midibeatclock.cpp
src/controllers/midi/midibeatclockreceiver.cpp
src/controllers/midi/midicontroller.cpp
src/controllers/midi/midienumerator.cpp
src/controllers/midi/midimessage.cpp
Expand Down Expand Up @@ -585,6 +587,7 @@ add_library(mixxx-lib STATIC EXCLUDE_FROM_ALL
src/engine/sidechain/networkinputstreamworker.cpp
src/engine/sidechain/networkoutputstreamworker.cpp
src/engine/sync/basesyncablelistener.cpp
src/engine/sync/controllersyncable.cpp
src/engine/sync/enginesync.cpp
src/engine/sync/internalclock.cpp
src/engine/sync/synccontrol.cpp
Expand Down Expand Up @@ -1493,6 +1496,7 @@ add_executable(mixxx-test
src/test/metadatatest.cpp
src/test/metaknob_link_test.cpp
src/test/midicontrollertest.cpp
src/test/midibeatclockreceivertest.cpp
src/test/mixxxtest.cpp
src/test/movinginterquartilemean_test.cpp
src/test/nativeeffects_test.cpp
Expand Down
4 changes: 3 additions & 1 deletion src/controllers/bulk/bulkcontroller.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -65,10 +65,12 @@ static QString get_string(libusb_device_handle *handle, u_int8_t id) {
}

BulkController::BulkController(
const QString& group,
libusb_context* context,
libusb_device_handle* handle,
struct libusb_device_descriptor* desc)
: m_context(context),
: Controller(group),
m_context(context),
m_phandle(handle),
in_epaddr(0),
out_epaddr(0) {
Expand Down
1 change: 1 addition & 0 deletions src/controllers/bulk/bulkcontroller.h
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ class BulkController : public Controller {
Q_OBJECT
public:
BulkController(
const QString& group,
libusb_context* context,
libusb_device_handle* handle,
struct libusb_device_descriptor* desc);
Expand Down
8 changes: 7 additions & 1 deletion src/controllers/bulk/bulkenumerator.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ QList<Controller*> BulkEnumerator::queryDevices() {
ssize_t i = 0;
int err = 0;

int index = 1;
for (i = 0; i < cnt; i++) {
libusb_device *device = list[i];
struct libusb_device_descriptor desc;
Expand All @@ -49,8 +50,13 @@ QList<Controller*> BulkEnumerator::queryDevices() {
continue;
}

// Generate a group for this controller
QString group = QStringLiteral("[BulkController") +
QString::number(index) + QChar(']');
index++;

BulkController* currentDevice =
new BulkController(m_context, handle, &desc);
new BulkController(group, m_context, handle, &desc);
m_devices.push_back(currentDevice);
}
}
Expand Down
5 changes: 3 additions & 2 deletions src/controllers/controller.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,9 @@
#include "moc_controller.cpp"
#include "util/screensaver.h"

Controller::Controller()
: m_pScriptEngineLegacy(nullptr),
Controller::Controller(const QString& group)
: m_group(group),
m_pScriptEngineLegacy(nullptr),
m_bIsOutputDevice(false),
m_bIsInputDevice(false),
m_bIsOpen(false),
Expand Down
15 changes: 14 additions & 1 deletion src/controllers/controller.h
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,13 @@

#include <QElapsedTimer>
#include <QTimerEvent>
#include <memory>

#include "controllers/controllermappinginfo.h"
#include "controllers/legacycontrollermapping.h"
#include "controllers/legacycontrollermappingfilehandler.h"
#include "controllers/scripting/legacy/controllerscriptenginelegacy.h"
#include "engine/sync/controllersyncable.h"
#include "util/duration.h"

class ControllerJSProxy;
Expand All @@ -17,7 +19,7 @@ class ControllerJSProxy;
class Controller : public QObject {
Q_OBJECT
public:
explicit Controller();
explicit Controller(const QString& group);
~Controller() override; // Subclass should call close() at minimum.

/// The object that is exposed to the JS scripts as the "controller" object.
Expand Down Expand Up @@ -50,6 +52,10 @@ class Controller : public QObject {
inline const QString& getCategory() const {
return m_sDeviceCategory;
}
const QString& getGroup() const {
return m_group;
}

virtual bool isMappable() const = 0;
inline bool isLearning() const {
return m_bLearning;
Expand Down Expand Up @@ -112,6 +118,10 @@ class Controller : public QObject {
// polling/processing but before closing the device.
virtual void stopEngine();

virtual std::shared_ptr<ControllerSyncable> syncable() const {
return nullptr;
}

// To be called when receiving events
void triggerActivity();

Expand Down Expand Up @@ -150,6 +160,9 @@ class Controller : public QObject {
}

private:
/// Group name for control objects
const QString m_group;

ControllerScriptEngineLegacy* m_pScriptEngineLegacy;

// Verbose and unique device name suitable for display.
Expand Down
24 changes: 23 additions & 1 deletion src/controllers/controllermanager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@
#include "controllers/controllerlearningeventfilter.h"
#include "controllers/defs_controllers.h"
#include "controllers/midi/portmidienumerator.h"
#include "engine/enginemaster.h"
#include "engine/sync/enginesync.h"
#include "moc_controllermanager.cpp"
#include "util/cmdlineargs.h"
#include "util/time.h"
Expand Down Expand Up @@ -78,9 +80,10 @@ bool controllerCompare(Controller *a,Controller *b) {
return a->getName() < b->getName();
}

ControllerManager::ControllerManager(UserSettingsPointer pConfig)
ControllerManager::ControllerManager(UserSettingsPointer pConfig, EngineMaster* pMixingEngine)
: QObject(),
m_pConfig(pConfig),
m_pMixingEngine(pMixingEngine),
// WARNING: Do not parent m_pControllerLearningEventFilter to
// ControllerManager because the CM is moved to its own thread and runs
// its own event loop.
Expand Down Expand Up @@ -192,12 +195,31 @@ void ControllerManager::updateControllerList() {

locker.relock();
if (newDeviceList != m_controllers) {
m_pMixingEngine->getEngineSync()->setControllerSyncables({});
m_controllers = newDeviceList;

QList<std::shared_ptr<Syncable>> controllerSyncables;
for (const auto* pController : qAsConst(m_controllers)) {
const std::shared_ptr<ControllerSyncable> pSyncable = pController->syncable();
if (pSyncable != nullptr) {
connect(pSyncable.get(),
&ControllerSyncable::syncModeRequested,
this,
&ControllerManager::slotControllerRequestSyncMode);
controllerSyncables.append(pSyncable);
}
}
m_pMixingEngine->getEngineSync()->setControllerSyncables(controllerSyncables);
locker.unlock();
emit devicesChanged();
}
}

void ControllerManager::slotControllerRequestSyncMode(SyncMode mode) {
ControllerSyncable* pSyncable = qobject_cast<ControllerSyncable*>(QObject::sender());
m_pMixingEngine->getEngineSync()->requestSyncMode(pSyncable, mode);
}

QList<Controller*> ControllerManager::getControllers() const {
QMutexLocker locker(&m_mutex);
return m_controllers;
Expand Down
6 changes: 5 additions & 1 deletion src/controllers/controllermanager.h
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
// Forward declaration(s)
class Controller;
class ControllerLearningEventFilter;
class EngineMaster;

/// Function to sort controllers by name
bool controllerCompare(Controller *a, Controller *b);
Expand All @@ -20,7 +21,7 @@ bool controllerCompare(Controller *a, Controller *b);
class ControllerManager : public QObject {
Q_OBJECT
public:
ControllerManager(UserSettingsPointer pConfig);
ControllerManager(UserSettingsPointer pConfig, EngineMaster* pMixingEngine);
virtual ~ControllerManager();

static const mixxx::Duration kPollInterval;
Expand Down Expand Up @@ -71,8 +72,11 @@ class ControllerManager : public QObject {
void stopPolling();
void maybeStartOrStopPolling();

void slotControllerRequestSyncMode(SyncMode mode);

private:
UserSettingsPointer m_pConfig;
EngineMaster* m_pMixingEngine;
ControllerLearningEventFilter* m_pControllerLearningEventFilter;
QTimer m_pollTimer;
mutable QMutex m_mutex;
Expand Down
4 changes: 3 additions & 1 deletion src/controllers/hid/hidcontroller.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,10 @@ constexpr int kMaxHidErrorMessageSize = 512;
} // namespace

HidController::HidController(
const QString& group,
mixxx::hid::DeviceInfo&& deviceInfo)
: m_deviceInfo(std::move(deviceInfo)),
: Controller(group),
m_deviceInfo(std::move(deviceInfo)),
m_pHidDevice(nullptr),
m_pollingBufferIndex(0) {
setDeviceCategory(mixxx::hid::DeviceCategory::guessFromDeviceInfo(m_deviceInfo));
Expand Down
1 change: 1 addition & 0 deletions src/controllers/hid/hidcontroller.h
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ class HidController final : public Controller {
Q_OBJECT
public:
explicit HidController(
const QString& group,
mixxx::hid::DeviceInfo&& deviceInfo);
~HidController() override;

Expand Down
8 changes: 7 additions & 1 deletion src/controllers/hid/hidenumerator.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,7 @@ HidEnumerator::~HidEnumerator() {
QList<Controller*> HidEnumerator::queryDevices() {
qInfo() << "Scanning USB HID devices";

int index = 1;
hid_device_info* device_info_list = hid_enumerate(0x0, 0x0);
for (const auto* device_info = device_info_list;
device_info;
Expand All @@ -85,8 +86,13 @@ QList<Controller*> HidEnumerator::queryDevices() {
continue;
}

HidController* newDevice = new HidController(std::move(deviceInfo));
// Generate a group for this controller
QString group = QStringLiteral("[HidController") +
QString::number(index) + QChar(']');

HidController* newDevice = new HidController(group, std::move(deviceInfo));
m_devices.push_back(newDevice);
index++;
}
hid_free_enumeration(device_info_list);

Expand Down
3 changes: 2 additions & 1 deletion src/controllers/midi/hss1394controller.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -60,10 +60,11 @@ void DeviceChannelListener::Reconnected() {
}

Hss1394Controller::Hss1394Controller(
const QString& group,
const hss1394::TNodeInfo& deviceInfo,
int deviceIndex,
UserSettingsPointer pConfig)
: MidiController(),
: MidiController(group),
m_deviceInfo(deviceInfo),
m_iDeviceIndex(deviceIndex) {
// Note: We prepend the input stream's index to the device's name to prevent
Expand Down
1 change: 1 addition & 0 deletions src/controllers/midi/hss1394controller.h
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ class Hss1394Controller : public MidiController {
Q_OBJECT
public:
Hss1394Controller(
const QString& group,
const hss1394::TNodeInfo& deviceInfo,
int deviceIndex,
UserSettingsPointer pConfig);
Expand Down
9 changes: 8 additions & 1 deletion src/controllers/midi/hss1394enumerator.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ QList<Controller*> Hss1394Enumerator::queryDevices() {
hss1394::uint uNodes = Node::Instance()->GetNodeCount();
qDebug() << " Nodes detected:" << uNodes;

int index = 1;
for(hss1394::uint i=0; i<40; i++) {
TNodeInfo tNodeInfo;
bool bInstalled;
Expand All @@ -40,8 +41,14 @@ QList<Controller*> Hss1394Enumerator::queryDevices() {
QString("%1").arg(tNodeInfo.uGUID.mu32Low, 0, 16),
QString("%1").arg(tNodeInfo.uProtocolVersion, 0, 16));
qDebug() << " " << message;

// Generate a group for this controller
QString group = QStringLiteral("[Hss1374Controller") +
QString::number(index) + QChar(']');
index++;

Hss1394Controller* currentDevice = new Hss1394Controller(
tNodeInfo, i, m_pConfig);
group, tNodeInfo, i, m_pConfig);
m_devices.push_back(currentDevice);
}
}
Expand Down
43 changes: 43 additions & 0 deletions src/controllers/midi/midibeatclock.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
#include "controllers/midi/midibeatclock.h"

namespace mixxx {

MidiBeatClock::MidiBeatClock(const QString& group)
: ControllerSyncable(group) {
// Pick a wide range (1 to 200) and allow out of bounds sets. This lets you
// map a soft-takeover MIDI knob to the master BPM. This also creates bpm_up
// and bpm_down controls.
// bpm_up / bpm_down steps by 1
// bpm_up_small / bpm_down_small steps by 0.1
m_pClockBpm.reset(new ControlObject(ConfigKey(m_group, "bpm")));
m_pClockBpm->setReadOnly();
// The relative position between two beats in the range 0.0 ... 1.0
m_pClockBeatDistance.reset(new ControlObject(ConfigKey(m_group, "beat_distance")));
m_pClockBeatDistance->setReadOnly();
}

void MidiBeatClock::receive(unsigned char status, Duration timestamp) {
MidiBeatClockReceiver::receive(status, timestamp);
m_pClockBpm->setAndConfirm(bpm().getValue());
m_pClockBeatDistance->setAndConfirm(beatDistance());
}

void MidiBeatClock::setMasterBeatDistance(double beatDistance) {
Q_UNUSED(beatDistance);
};

void MidiBeatClock::setMasterBpm(double bpm) {
Q_UNUSED(bpm);
};

void MidiBeatClock::setMasterParams(double beatDistance, double baseBpm, double bpm) {
Q_UNUSED(beatDistance);
Q_UNUSED(baseBpm);
Q_UNUSED(bpm);
};

void MidiBeatClock::setInstantaneousBpm(double bpm) {
Q_UNUSED(bpm);
};

} // namespace mixxx
Loading