Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Full Ableton Link support #10999

Open
wants to merge 97 commits into
base: main
Choose a base branch
from

Conversation

JoergAtGithub
Copy link
Member

@JoergAtGithub JoergAtGithub commented Oct 24, 2022

Based on the old PR #3783 from @spensbot, I created a new PR with Ableton Link support for Main.
Currently the GUI controls exist only for Latenight:
grafik
The LINK-Button enables/disables the Link session. The number right to it shows the number of connected Link peers.
It syncronizes Tempo and Beat-Position (Phase). In Ableton Link all peers are equal, there is no leader. Therefore syncronization is always bidirectional.

In this Implementation, it syncs the Mixxx-Sync-Leader with the other peers. Means, it works only if the Crown-Button for a deck and the new LINK-Button are active.

I tested this with the official LinkHut-App of the Ableton Link package and with the Android App "G-Stomper Rythm", which is a free Drummachine, but with advertizing. A very cool Ableton Link software is also the music visualisation and lighting software from spensbot: https://captivatesynth.com/

Test Plan
Any Ableton Link software, should pass the following test plan:
https://github.com/Ableton/link/blob/master/TEST-PLAN.md

  • TEMPO-1: Tempo changes should be transmitted between connected apps.
  • TEMPO-2: Opening an app with Link enabled should not change the tempo of an existing Link session.
  • TEMPO-3: When connected, loading a new document should not change the Link session tempo.
  • TEMPO-4: Tempo range handling.
  • TEMPO-5: Enabling Link does not change app's tempo if there is no Link session to join.
  • BEATTIME-1: Enabling Link does not change app's beat time if there is no Link session to join.
  • BEATTIME-2: App's beat time does not change if another participant joins its session.
  • STARTSTOPSTATE-1: Listening to start/stop commands from other peers.
  • STARTSTOPSTATE-2: Sending start/stop commands to other peers.
  • AUDIOENGINE-1: Correct alignment of app audio with shared session

To install the official Linkhut reference tools used in the test plan, you can use VCPKG: ./vcpkg install ableton[hut,hutsilent]

Closes #8650

spensbot and others added 30 commits April 11, 2021 23:08
On startup, Mixxx will enable link and join the active link session
We have much to do for Mixxx to become a link-compatible app
Basically, Mixxx needs to respond to & update the active link session
to synchronize bpm & phase
Remove the ableton link submodule
Change logging to standard Qt commands
Use Doxygen style comments in abletonlink.h
…rsion of 3.05

Disabled system AbletonLink for Debian, because this package is broken in Ubuntu 20.04
Moved debug code from header to cpp
src/engine/sync/abletonlink.h Outdated Show resolved Hide resolved
src/engine/sync/abletonlink.h Show resolved Hide resolved
@JoergAtGithub JoergAtGithub force-pushed the abletonlink branch 5 times, most recently from 262642c to 30b8374 Compare August 18, 2024 13:55
Refactored various methods in `AbletonLink` to use `auto` and `const auto` for improved readability and simplicity. Updated floating-point literals to use `1.0` instead of `1.` for clarity and consistency.
@jonahclarsen
Copy link

Just want to say I'm super stoked for this and thankful for all your effort!

CMakeLists.txt Outdated Show resolved Hide resolved
Comment on lines +39 to +46
m_pNumLinkPeers->setReadOnly();
m_pNumLinkPeers->forceSet(0);

// The callback is invoked on a Link - managed thread.
// The callback is the only entity, which access m_pNumLinkPeers
m_pLink->setNumPeersCallback([this](std::size_t numPeers) {
m_pNumLinkPeers->forceSet(numPeers);
});
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

then make it a member of the lambda instead.

Suggested change
m_pNumLinkPeers->setReadOnly();
m_pNumLinkPeers->forceSet(0);
// The callback is invoked on a Link - managed thread.
// The callback is the only entity, which access m_pNumLinkPeers
m_pLink->setNumPeersCallback([this](std::size_t numPeers) {
m_pNumLinkPeers->forceSet(numPeers);
});
// The callback is invoked on a Link - managed thread.
m_pLink->setNumPeersCallback([ControlObject numLinkPeers = []{
ControlObject numLinkPeers(ConfigKey(group, numPeers));
numLinkPeers.setReadOnly();
numLinkPeers.forceSet(0);
return numLinkPeers;
}()](std::size_t numPeers) {
numLinkPeers.forceSet(numPeers);
});

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The proposed code does not compile, as it does not match to the declaration in the headers of Link.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

that does not make sense. Can you post the error?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

grafik

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks. looks like a syntax issue. I'll figure it out.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

init captures don't support explicit type declarations. Try this:

Suggested change
m_pNumLinkPeers->setReadOnly();
m_pNumLinkPeers->forceSet(0);
// The callback is invoked on a Link - managed thread.
// The callback is the only entity, which access m_pNumLinkPeers
m_pLink->setNumPeersCallback([this](std::size_t numPeers) {
m_pNumLinkPeers->forceSet(numPeers);
});
// The callback is invoked on a Link - managed thread.
m_pLink->setNumPeersCallback([numLinkPeers = []{
ControlObject numLinkPeers(ConfigKey(group, numPeers));
numLinkPeers.setReadOnly();
numLinkPeers.forceSet(0);
return numLinkPeers;
}()](std::size_t numPeers) {
numLinkPeers.forceSet(numPeers);
});

Copy link
Member Author

@JoergAtGithub JoergAtGithub Sep 8, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This doesn't work too:

  [64/126] Building CXX object CMakeFiles\mixxx-lib.dir\src\engine\sync\abletonlink.cpp.obj
  FAILED: CMakeFiles/mixxx-lib.dir/src/engine/sync/abletonlink.cpp.obj 
  C:\PROGRA~1\MICROS~1\2022\COMMUN~1\VC\Tools\MSVC\1441~1.341\bin\Hostx64\x64\cl.exe  /nologo /TP -DAMD64 -DDJINTEROP_SOURCE -DLINK_PLATFORM_WINDOWS=1 -DMIXXX_BUILD_RELEASE -DMIXXX_DEBUG_ASSERTIONS_ENABLED -DMIXXX_DEBUG_ASSERTIONS_FATAL -DMIXXX_USE_QML -DMIXXX_USE_QOPENGL -DNOMINMAX -DPROTOBUF_USE_DLLS -DQT_CONCURRENT_LIB -DQT_CORE5COMPAT_LIB -DQT_CORE_LIB -DQT_GUI_LIB -DQT_LABSQMLMODELS_LIB -DQT_NETWORK_LIB -DQT_NO_DEBUG -DQT_OPENGL_LIB -DQT_PRINTSUPPORT_LIB -DQT_QMLINTEGRATION_LIB -DQT_QMLMODELS_LIB -DQT_QMLWORKERSCRIPT_LIB -DQT_QML_LIB -DQT_QUICKCONTROLS2IMPL_LIB -DQT_QUICKCONTROLS2_LIB -DQT_QUICKLAYOUTS_LIB -DQT_QUICKSHAPES_LIB -DQT_QUICKTEMPLATES2_LIB -DQT_QUICKWIDGETS_LIB -DQT_QUICK_LIB -DQT_SHADERTOOLS_LIB -DQT_SQL_LIB -DQT_SVGWIDGETS_LIB -DQT_SVG_LIB -DQT_TABLET_SUPPORT -DQT_TESTCASE_BUILDDIR=\"D:/mixxx-main-pr-test/build/x64__portable\" -DQT_TESTCASE_SOURCEDIR=\"D:/mixxx-main-pr-test\" -DQT_TESTLIB_LIB -DQT_USE_QSTRINGBUILDER -DQT_WIDGETS_LIB -DQT_XML_LIB -DSFC_SUPPORTS_SET_COMPRESSION_LEVEL -DUNICODE -DWIN32 -DWIN32_LEAN_AND_MEAN -DWIN64 -DWINVER=0x0601 -D_ATL_MIN_CRT -D_CRT_SECURE_NO_WARNINGS -D_ENABLE_EXTENDED_ALIGNED_STORAGE -D_SILENCE_CXX17_ITERATOR_BASE_CLASS_DEPRECATION_WARNING -D_UNICODE -D_USE_MATH_DEFINES -D_WIN32_WINNT=0x0601 -D_WIN64 -D__BATTERY__ -D__BROADCAST__ -D__BULK__ -D__ENGINEPRIME__ -D__FFMPEG__ -D__HID__ -D__HSS1394__ -D__LILV__ -D__MAD__ -D__MEDIAFOUNDATION__ -D__MODPLUG__ -D__OPUS__ -D__PORTMIDI__ -D__QTKEYCHAIN__ -D__RUBBERBAND__ -D__SNDFILE__ -D__SQLITE3__ -D__SSE2__ -D__SSE__ -D__STDC_CONSTANT_MACROS -D__STDC_FORMAT_MACROS -D__STDC_LIMIT_MACROS -D__STEM__ -D__VINYLCONTROL__ -D__WINDOWS__ -D__WV__ -ID:\mixxx-main-pr-test\build\x64__portable\mixxx-lib_autogen\include -ID:\mixxx-main-pr-test\src -ID:\mixxx-main-pr-test\build\x64__portable\src -external:ID:\mixxx-main-pr-test\lib\fidlib -external:ID:\mixxx-main-pr-test\lib\portaudio -external:ID:\mixxx-main-pr-test\buildenv\mixxx-deps-2.5-x64-windows-06fe9b5\installed\x64-windows\include -external:ID:\mixxx-main-pr-test\lib\rigtorp\SPSCQueue\include -external:ID:\mixxx-main-pr-test\lib\replaygain -external:ID:\mixxx-main-pr-test\lib\reverb -external:ID:\mixxx-main-pr-test\lib\libshout-idjc\include -external:ID:\mixxx-main-pr-test\buildenv\mixxx-deps-2.5-x64-windows-06fe9b5\installed\x64-windows\share\ableton-link\..\..\include\ableton -external:ID:\mixxx-main-pr-test\buildenv\mixxx-deps-2.5-x64-windows-06fe9b5\installed\x64-windows\share\asio\..\..\include -external:ID:\mixxx-main-pr-test\buildenv\mixxx-deps-2.5-x64-windows-06fe9b5\installed\x64-windows\include\djinterop -external:ID:\mixxx-main-pr-test\lib\rekordbox-metadata -external:ID:\mixxx-main-pr-test\lib\kaitai -external:ID:\mixxx-main-pr-test\lib\mp3guessenc-0.27.4 -external:ID:\mixxx-main-pr-test\buildenv\mixxx-deps-2.5-x64-windows-06fe9b5\installed\x64-windows\include\Qt6\QtConcurrent -external:ID:\mixxx-main-pr-test\buildenv\mixxx-deps-2.5-x64-windows-06fe9b5\installed\x64-windows\include\Qt6 -external:ID:\mixxx-main-pr-test\buildenv\mixxx-deps-2.5-x64-windows-06fe9b5\installed\x64-windows\include\Qt6\QtCore -external:ID:\mixxx-main-pr-test\buildenv\mixxx-deps-2.5-x64-windows-06fe9b5\installed\x64-windows\share\Qt6\mkspecs\win32-msvc -external:ID:\mixxx-main-pr-test\buildenv\mixxx-deps-2.5-x64-windows-06fe9b5\installed\x64-windows\include\Qt6\QtGui -external:ID:\mixxx-main-pr-test\buildenv\mixxx-deps-2.5-x64-windows-06fe9b5\installed\x64-windows\include\Qt6\QtNetwork -external:ID:\mixxx-main-pr-test\buildenv\mixxx-deps-2.5-x64-windows-06fe9b5\installed\x64-windows\include\Qt6\QtOpenGL -external:ID:\mixxx-main-pr-test\buildenv\mixxx-deps-2.5-x64-windows-06fe9b5\installed\x64-windows\include\Qt6\QtPrintSupport -external:ID:\mixxx-main-pr-test\buildenv\mixxx-deps-2.5-x64-windows-06fe9b5\installed\x64-windows\include\Qt6\QtWidgets -external:ID:\mixxx-main-pr-test\buildenv\mixxx-deps-2.5-x64-windows-06fe9b5\installed\x64-windows\include\Qt6\QtQml -external:ID:\mixxx-main-pr-test\buildenv\mixxx-deps-2.5-x64-windows-06fe9b5\installed\x64-windows\include\Qt6\QtQmlIntegration -external:ID:\mixxx-main-pr-test\buildenv\mixxx-deps-2.5-x64-windows-06fe9b5\installed\x64-windows\include\Qt6\QtSql -external:ID:\mixxx-main-pr-test\buildenv\mixxx-deps-2.5-x64-windows-06fe9b5\installed\x64-windows\include\Qt6\QtSvg -external:ID:\mixxx-main-pr-test\buildenv\mixxx-deps-2.5-x64-windows-06fe9b5\installed\x64-windows\include\Qt6\QtTest -external:ID:\mixxx-main-pr-test\buildenv\mixxx-deps-2.5-x64-windows-06fe9b5\installed\x64-windows\include\Qt6\QtXml -external:ID:\mixxx-main-pr-test\buildenv\mixxx-deps-2.5-x64-windows-06fe9b5\installed\x64-windows\include\Qt6\QtShaderTools -external:ID:\mixxx-main-pr-test\buildenv\mixxx-deps-2.5-x64-windows-06fe9b5\installed\x64-windows\include\Qt6\QtSvgWidgets -external:ID:\mixxx-main-pr-test\buildenv\mixxx-deps-2.5-x64-windows-06fe9b5\installed\x64-windows\include\Qt6\QtCore5Compat -external:ID:\mixxx-main-pr-test\buildenv\mixxx-deps-2.5-x64-windows-06fe9b5\installed\x64-windows\include\Qt6\QtQuick -external:ID:\mixxx-main-pr-test\buildenv\mixxx-deps-2.5-x64-windows-06fe9b5\installed\x64-windows\include\Qt6\QtQmlModels -external:ID:\mixxx-main-pr-test\buildenv\mixxx-deps-2.5-x64-windows-06fe9b5\installed\x64-windows\include\Qt6\QtLabsQmlModels -external:ID:\mixxx-main-pr-test\buildenv\mixxx-deps-2.5-x64-windows-06fe9b5\installed\x64-windows\include\Qt6\QtQmlModels\6.5.3 -external:ID:\mixxx-main-pr-test\buildenv\mixxx-deps-2.5-x64-windows-06fe9b5\installed\x64-windows\include\Qt6\QtQmlModels\6.5.3\QtQmlModels -external:ID:\mixxx-main-pr-test\buildenv\mixxx-deps-2.5-x64-windows-06fe9b5\installed\x64-windows\include\Qt6\QtCore\6.5.3 -external:ID:\mixxx-main-pr-test\buildenv\mixxx-deps-2.5-x64-windows-06fe9b5\installed\x64-windows\include\Qt6\QtCore\6.5.3\QtCore -external:ID:\mixxx-main-pr-test\buildenv\mixxx-deps-2.5-x64-windows-06fe9b5\installed\x64-windows\include\Qt6\QtQml\6.5.3 -external:ID:\mixxx-main-pr-test\buildenv\mixxx-deps-2.5-x64-windows-06fe9b5\installed\x64-windows\include\Qt6\QtQml\6.5.3\QtQml -external:ID:\mixxx-main-pr-test\buildenv\mixxx-deps-2.5-x64-windows-06fe9b5\installed\x64-windows\include\Qt6\QtQuickControls2 -external:ID:\mixxx-main-pr-test\buildenv\mixxx-deps-2.5-x64-windows-06fe9b5\installed\x64-windows\include\Qt6\QtQuickControls2Impl -external:ID:\mixxx-main-pr-test\buildenv\mixxx-deps-2.5-x64-windows-06fe9b5\installed\x64-windows\include\Qt6\QtQuickLayouts -external:ID:\mixxx-main-pr-test\buildenv\mixxx-deps-2.5-x64-windows-06fe9b5\installed\x64-windows\include\Qt6\QtGui\6.5.3 -external:ID:\mixxx-main-pr-test\buildenv\mixxx-deps-2.5-x64-windows-06fe9b5\installed\x64-windows\include\Qt6\QtGui\6.5.3\QtGui -external:ID:\mixxx-main-pr-test\buildenv\mixxx-deps-2.5-x64-windows-06fe9b5\installed\x64-windows\include\Qt6\QtQuick\6.5.3 -external:ID:\mixxx-main-pr-test\buildenv\mixxx-deps-2.5-x64-windows-06fe9b5\installed\x64-windows\include\Qt6\QtQuick\6.5.3\QtQuick -external:ID:\mixxx-main-pr-test\buildenv\mixxx-deps-2.5-x64-windows-06fe9b5\installed\x64-windows\include\Qt6\QtQuickShapes -external:ID:\mixxx-main-pr-test\buildenv\mixxx-deps-2.5-x64-windows-06fe9b5\installed\x64-windows\include\Qt6\QtQuickShapes\6.5.3 -external:ID:\mixxx-main-pr-test\buildenv\mixxx-deps-2.5-x64-windows-06fe9b5\installed\x64-windows\include\Qt6\QtQuickShapes\6.5.3\QtQuickShapes -external:ID:\mixxx-main-pr-test\buildenv\mixxx-deps-2.5-x64-windows-06fe9b5\installed\x64-windows\include\Qt6\QtQuickTemplates2 -external:ID:\mixxx-main-pr-test\buildenv\mixxx-deps-2.5-x64-windows-06fe9b5\installed\x64-windows\include\Qt6\QtQuickWidgets -external:ID:\mixxx-main-pr-test\buildenv\mixxx-deps-2.5-x64-windows-06fe9b5\installed\x64-windows\include\Qt6\QtQmlWorkerScript -external:ID:\mixxx-main-pr-test\buildenv\mixxx-deps-2.5-x64-windows-06fe9b5\installed\x64-windows\include\taglib -external:ID:\mixxx-main-pr-test\lib\qm-dsp -external:ID:\mixxx-main-pr-test\lib\qm-dsp\include -external:ID:\mixxx-main-pr-test\buildenv\mixxx-deps-2.5-x64-windows-06fe9b5\installed\x64-windows\include\opus -external:ID:\mixxx-main-pr-test\buildenv\mixxx-deps-2.5-x64-windows-06fe9b5\installed\x64-windows\include\hidapi -external:ID:\mixxx-main-pr-test\buildenv\mixxx-deps-2.5-x64-windows-06fe9b5\installed\x64-windows\include\libusb-1.0 -external:ID:\mixxx-main-pr-test\lib\xwax -external:ID:\mixxx-main-pr-test\buildenv\mixxx-deps-2.5-x64-windows-06fe9b5\installed\x64-windows\include\wavpack -external:W0 /DWIN32 /D_WINDOWS /EHsc /Zc:__cplusplus /Zc:inline /Z7 /O2  /DNDEBUG -std:c++20 -MD /UTF8 /fp:fast /Gy /W3 /wd4200 -DPA_USE_JACK=1 -DPA_USE_ASIO=1 -DPA_USE_DS=1 -DPA_USE_WMME=1 -DPA_USE_WASAPI=1 -DPA_USE_WDMKS=1 -Zc:__cplusplus -permissive- -utf-8 /YuD:/mixxx-main-pr-test/build/x64__portable/CMakeFiles/mixxx-lib.dir/cmake_pch.hxx /FpD:/mixxx-main-pr-test/build/x64__portable/CMakeFiles/mixxx-lib.dir/./cmake_pch.cxx.pch /FID:/mixxx-main-pr-test/build/x64__portable/CMakeFiles/mixxx-lib.dir/cmake_pch.hxx /showIncludes /FoCMakeFiles\mixxx-lib.dir\src\engine\sync\abletonlink.cpp.obj /Fdmixxx-lib.dir\mixxx-lib.pdb /FS -c D:\mixxx-main-pr-test\src\engine\sync\abletonlink.cpp
D:\mixxx-main-pr-test\src\engine\sync\abletonlink.cpp(40): error C3493: 'group' cannot be implicitly captured because no default capture mode has been specified
D:\mixxx-main-pr-test\src\engine\sync\abletonlink.cpp(40): error C2065: 'numPeers': undeclared identifier
D:\mixxx-main-pr-test\src\engine\sync\abletonlink.cpp(45): error C2662: 'void ControlObject::forceSet(double)': cannot convert 'this' pointer from 'const ControlObject' to 'ControlObject &'
  D:\mixxx-main-pr-test\src\engine\sync\abletonlink.cpp(45): note: Conversion loses qualifiers
  D:\mixxx-main-pr-test\src\control/controlobject.h(112): note: see declaration of 'ControlObject::forceSet'
  D:\mixxx-main-pr-test\src\engine\sync\abletonlink.cpp(45): note: while trying to match the argument list '(unsigned __int64)'

Copy link
Member

@Swiftb0y Swiftb0y Sep 9, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ah, need captures in the IILE and the new lambda needs mutable so it can access the numLinkPeers mutably. I wonder why the original lambda didn't need mutable

Suggested change
m_pNumLinkPeers->setReadOnly();
m_pNumLinkPeers->forceSet(0);
// The callback is invoked on a Link - managed thread.
// The callback is the only entity, which access m_pNumLinkPeers
m_pLink->setNumPeersCallback([this](std::size_t numPeers) {
m_pNumLinkPeers->forceSet(numPeers);
});
// The callback is invoked on a Link - managed thread.
m_pLink->setNumPeersCallback([numLinkPeers = [&]{
ControlObject numLinkPeers(ConfigKey(group, numPeers));
numLinkPeers.setReadOnly();
numLinkPeers.forceSet(0);
return numLinkPeers;
}()](std::size_t numPeers) mutable {
numLinkPeers.forceSet(numPeers);
});

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Doesn't work:

  FAILED: CMakeFiles/mixxx-lib.dir/src/engine/sync/abletonlink.cpp.obj 
  C:\PROGRA~1\MICROS~1\2022\COMMUN~1\VC\Tools\MSVC\1441~1.341\bin\Hostx64\x64\cl.exe  /nologo /TP -DAMD64 -DDJINTEROP_SOURCE -DLINK_PLATFORM_WINDOWS=1 -DMIXXX_BUILD_RELEASE -DMIXXX_DEBUG_ASSERTIONS_ENABLED -DMIXXX_DEBUG_ASSERTIONS_FATAL -DMIXXX_USE_QML -DMIXXX_USE_QOPENGL -DNOMINMAX -DPROTOBUF_USE_DLLS -DQT_CONCURRENT_LIB -DQT_CORE5COMPAT_LIB -DQT_CORE_LIB -DQT_GUI_LIB -DQT_LABSQMLMODELS_LIB -DQT_NETWORK_LIB -DQT_NO_DEBUG -DQT_OPENGL_LIB -DQT_PRINTSUPPORT_LIB -DQT_QMLINTEGRATION_LIB -DQT_QMLMODELS_LIB -DQT_QMLWORKERSCRIPT_LIB -DQT_QML_LIB -DQT_QUICKCONTROLS2IMPL_LIB -DQT_QUICKCONTROLS2_LIB -DQT_QUICKLAYOUTS_LIB -DQT_QUICKSHAPES_LIB -DQT_QUICKTEMPLATES2_LIB -DQT_QUICKWIDGETS_LIB -DQT_QUICK_LIB -DQT_SHADERTOOLS_LIB -DQT_SQL_LIB -DQT_SVGWIDGETS_LIB -DQT_SVG_LIB -DQT_TABLET_SUPPORT -DQT_TESTCASE_BUILDDIR=\"D:/mixxx/build/x64__portable\" -DQT_TESTCASE_SOURCEDIR=\"D:/mixxx\" -DQT_TESTLIB_LIB -DQT_USE_QSTRINGBUILDER -DQT_WIDGETS_LIB -DQT_XML_LIB -DSFC_SUPPORTS_SET_COMPRESSION_LEVEL -DUNICODE -DWIN32 -DWIN32_LEAN_AND_MEAN -DWIN64 -DWINVER=0x0601 -D_ATL_MIN_CRT -D_CRT_SECURE_NO_WARNINGS -D_ENABLE_EXTENDED_ALIGNED_STORAGE -D_SILENCE_CXX17_ITERATOR_BASE_CLASS_DEPRECATION_WARNING -D_UNICODE -D_USE_MATH_DEFINES -D_WIN32_WINNT=0x0601 -D_WIN64 -D__BATTERY__ -D__BROADCAST__ -D__BULK__ -D__ENGINEPRIME__ -D__FFMPEG__ -D__HID__ -D__HSS1394__ -D__LILV__ -D__MAD__ -D__MEDIAFOUNDATION__ -D__MODPLUG__ -D__OPUS__ -D__PORTMIDI__ -D__QTKEYCHAIN__ -D__RUBBERBAND__ -D__SNDFILE__ -D__SQLITE3__ -D__SSE2__ -D__SSE__ -D__STDC_CONSTANT_MACROS -D__STDC_FORMAT_MACROS -D__STDC_LIMIT_MACROS -D__STEM__ -D__VINYLCONTROL__ -D__WINDOWS__ -D__WV__ -ID:\mixxx\build\x64__portable\mixxx-lib_autogen\include -ID:\mixxx\src -ID:\mixxx\build\x64__portable\src -external:ID:\mixxx\lib\fidlib -external:ID:\mixxx\lib\portaudio -external:ID:\mixxx\buildenv\mixxx-deps-2.5-x64-windows-06fe9b5\installed\x64-windows\include -external:ID:\mixxx\lib\rigtorp\SPSCQueue\include -external:ID:\mixxx\lib\replaygain -external:ID:\mixxx\lib\reverb -external:ID:\mixxx\lib\libshout-idjc\include -external:ID:\mixxx\buildenv\mixxx-deps-2.5-x64-windows-06fe9b5\installed\x64-windows\share\ableton-link\..\..\include\ableton -external:ID:\mixxx\buildenv\mixxx-deps-2.5-x64-windows-06fe9b5\installed\x64-windows\share\asio\..\..\include -external:ID:\mixxx\buildenv\mixxx-deps-2.5-x64-windows-06fe9b5\installed\x64-windows\include\djinterop -external:ID:\mixxx\lib\rekordbox-metadata -external:ID:\mixxx\lib\kaitai -external:ID:\mixxx\lib\mp3guessenc-0.27.4 -external:ID:\mixxx\buildenv\mixxx-deps-2.5-x64-windows-06fe9b5\installed\x64-windows\include\Qt6\QtConcurrent -external:ID:\mixxx\buildenv\mixxx-deps-2.5-x64-windows-06fe9b5\installed\x64-windows\include\Qt6 -external:ID:\mixxx\buildenv\mixxx-deps-2.5-x64-windows-06fe9b5\installed\x64-windows\include\Qt6\QtCore -external:ID:\mixxx\buildenv\mixxx-deps-2.5-x64-windows-06fe9b5\installed\x64-windows\share\Qt6\mkspecs\win32-msvc -external:ID:\mixxx\buildenv\mixxx-deps-2.5-x64-windows-06fe9b5\installed\x64-windows\include\Qt6\QtGui -external:ID:\mixxx\buildenv\mixxx-deps-2.5-x64-windows-06fe9b5\installed\x64-windows\include\Qt6\QtNetwork -external:ID:\mixxx\buildenv\mixxx-deps-2.5-x64-windows-06fe9b5\installed\x64-windows\include\Qt6\QtOpenGL -external:ID:\mixxx\buildenv\mixxx-deps-2.5-x64-windows-06fe9b5\installed\x64-windows\include\Qt6\QtPrintSupport -external:ID:\mixxx\buildenv\mixxx-deps-2.5-x64-windows-06fe9b5\installed\x64-windows\include\Qt6\QtWidgets -external:ID:\mixxx\buildenv\mixxx-deps-2.5-x64-windows-06fe9b5\installed\x64-windows\include\Qt6\QtQml -external:ID:\mixxx\buildenv\mixxx-deps-2.5-x64-windows-06fe9b5\installed\x64-windows\include\Qt6\QtQmlIntegration -external:ID:\mixxx\buildenv\mixxx-deps-2.5-x64-windows-06fe9b5\installed\x64-windows\include\Qt6\QtSql -external:ID:\mixxx\buildenv\mixxx-deps-2.5-x64-windows-06fe9b5\installed\x64-windows\include\Qt6\QtSvg -external:ID:\mixxx\buildenv\mixxx-deps-2.5-x64-windows-06fe9b5\installed\x64-windows\include\Qt6\QtTest -external:ID:\mixxx\buildenv\mixxx-deps-2.5-x64-windows-06fe9b5\installed\x64-windows\include\Qt6\QtXml -external:ID:\mixxx\buildenv\mixxx-deps-2.5-x64-windows-06fe9b5\installed\x64-windows\include\Qt6\QtShaderTools -external:ID:\mixxx\buildenv\mixxx-deps-2.5-x64-windows-06fe9b5\installed\x64-windows\include\Qt6\QtSvgWidgets -external:ID:\mixxx\buildenv\mixxx-deps-2.5-x64-windows-06fe9b5\installed\x64-windows\include\Qt6\QtCore5Compat -external:ID:\mixxx\buildenv\mixxx-deps-2.5-x64-windows-06fe9b5\installed\x64-windows\include\Qt6\QtQuick -external:ID:\mixxx\buildenv\mixxx-deps-2.5-x64-windows-06fe9b5\installed\x64-windows\include\Qt6\QtQmlModels -external:ID:\mixxx\buildenv\mixxx-deps-2.5-x64-windows-06fe9b5\installed\x64-windows\include\Qt6\QtLabsQmlModels -external:ID:\mixxx\buildenv\mixxx-deps-2.5-x64-windows-06fe9b5\installed\x64-windows\include\Qt6\QtQmlModels\6.5.3 -external:ID:\mixxx\buildenv\mixxx-deps-2.5-x64-windows-06fe9b5\installed\x64-windows\include\Qt6\QtQmlModels\6.5.3\QtQmlModels -external:ID:\mixxx\buildenv\mixxx-deps-2.5-x64-windows-06fe9b5\installed\x64-windows\include\Qt6\QtCore\6.5.3 -external:ID:\mixxx\buildenv\mixxx-deps-2.5-x64-windows-06fe9b5\installed\x64-windows\include\Qt6\QtCore\6.5.3\QtCore -external:ID:\mixxx\buildenv\mixxx-deps-2.5-x64-windows-06fe9b5\installed\x64-windows\include\Qt6\QtQml\6.5.3 -external:ID:\mixxx\buildenv\mixxx-deps-2.5-x64-windows-06fe9b5\installed\x64-windows\include\Qt6\QtQml\6.5.3\QtQml -external:ID:\mixxx\buildenv\mixxx-deps-2.5-x64-windows-06fe9b5\installed\x64-windows\include\Qt6\QtQuickControls2 -external:ID:\mixxx\buildenv\mixxx-deps-2.5-x64-windows-06fe9b5\installed\x64-windows\include\Qt6\QtQuickControls2Impl -external:ID:\mixxx\buildenv\mixxx-deps-2.5-x64-windows-06fe9b5\installed\x64-windows\include\Qt6\QtQuickLayouts -external:ID:\mixxx\buildenv\mixxx-deps-2.5-x64-windows-06fe9b5\installed\x64-windows\include\Qt6\QtGui\6.5.3 -external:ID:\mixxx\buildenv\mixxx-deps-2.5-x64-windows-06fe9b5\installed\x64-windows\include\Qt6\QtGui\6.5.3\QtGui -external:ID:\mixxx\buildenv\mixxx-deps-2.5-x64-windows-06fe9b5\installed\x64-windows\include\Qt6\QtQuick\6.5.3 -external:ID:\mixxx\buildenv\mixxx-deps-2.5-x64-windows-06fe9b5\installed\x64-windows\include\Qt6\QtQuick\6.5.3\QtQuick -external:ID:\mixxx\buildenv\mixxx-deps-2.5-x64-windows-06fe9b5\installed\x64-windows\include\Qt6\QtQuickShapes -external:ID:\mixxx\buildenv\mixxx-deps-2.5-x64-windows-06fe9b5\installed\x64-windows\include\Qt6\QtQuickShapes\6.5.3 -external:ID:\mixxx\buildenv\mixxx-deps-2.5-x64-windows-06fe9b5\installed\x64-windows\include\Qt6\QtQuickShapes\6.5.3\QtQuickShapes -external:ID:\mixxx\buildenv\mixxx-deps-2.5-x64-windows-06fe9b5\installed\x64-windows\include\Qt6\QtQuickTemplates2 -external:ID:\mixxx\buildenv\mixxx-deps-2.5-x64-windows-06fe9b5\installed\x64-windows\include\Qt6\QtQuickWidgets -external:ID:\mixxx\buildenv\mixxx-deps-2.5-x64-windows-06fe9b5\installed\x64-windows\include\Qt6\QtQmlWorkerScript -external:ID:\mixxx\buildenv\mixxx-deps-2.5-x64-windows-06fe9b5\installed\x64-windows\include\taglib -external:ID:\mixxx\lib\qm-dsp -external:ID:\mixxx\lib\qm-dsp\include -external:ID:\mixxx\buildenv\mixxx-deps-2.5-x64-windows-06fe9b5\installed\x64-windows\include\opus -external:ID:\mixxx\buildenv\mixxx-deps-2.5-x64-windows-06fe9b5\installed\x64-windows\include\hidapi -external:ID:\mixxx\buildenv\mixxx-deps-2.5-x64-windows-06fe9b5\installed\x64-windows\include\libusb-1.0 -external:ID:\mixxx\lib\xwax -external:ID:\mixxx\buildenv\mixxx-deps-2.5-x64-windows-06fe9b5\installed\x64-windows\include\wavpack -external:W0 /DWIN32 /D_WINDOWS /EHsc /Zc:__cplusplus /Zc:inline /Z7 /O2  /DNDEBUG -std:c++20 -MD /UTF8 /fp:fast /Gy /W3 /wd4200 -DPA_USE_JACK=1 -DPA_USE_ASIO=1 -DPA_USE_DS=1 -DPA_USE_WMME=1 -DPA_USE_WASAPI=1 -DPA_USE_WDMKS=1 -Zc:__cplusplus -permissive- -utf-8 /YuD:/mixxx/build/x64__portable/CMakeFiles/mixxx-lib.dir/cmake_pch.hxx /FpD:/mixxx/build/x64__portable/CMakeFiles/mixxx-lib.dir/./cmake_pch.cxx.pch /FID:/mixxx/build/x64__portable/CMakeFiles/mixxx-lib.dir/cmake_pch.hxx /showIncludes /FoCMakeFiles\mixxx-lib.dir\src\engine\sync\abletonlink.cpp.obj /Fdmixxx-lib.dir\mixxx-lib.pdb /FS -c D:\mixxx\src\engine\sync\abletonlink.cpp
D:\mixxx\src\engine\sync\abletonlink.cpp(27): error C2614: 'AbletonLink': illegal member initialization: 'm_pNumLinkPeers' is not a base or member
D:\mixxx\src\engine\sync\abletonlink.cpp(47): error C2280: 'ControlObject::ControlObject(ControlObject &&)': attempting to reference a deleted function
  D:\mixxx\src\control/controlobject.h(189): note: see declaration of 'ControlObject::ControlObject'

I suggest you compile it yourself first, because this two person trial and error development seems not very efficient to me.

Copy link
Member

@Swiftb0y Swiftb0y Sep 10, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Okay, I've investigated and my conclusion is that moving this into the lambda is infeasible because link requires the lambda to be copy-able. This would require making the member of the lambda a std::shared_ptr<ControlObject> which has unnecessary overhead. They also don't allow mutable which is another oversight in the link API. (not that that is required because TIL that you can still call mutable member functions of a pointer managed by a const unique_ptr, which seems dangerous).

The only recommendation I would make then is moving the m_pNumLinkPeers above m_pLink in the class definition so it doesn't get destroyed while m_pLink still references it.

src/engine/sync/abletonlink.cpp Outdated Show resolved Hide resolved
Comment on lines +168 to +170
m_audioBufferTimeMicros = std::chrono::microseconds(
bufferSize / mixxx::audio::ChannelCount::stereo() /
sampleRate * 1000000);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this seems unused.

Comment on lines +113 to +116
std::chrono::microseconds m_audioBufferTimeMicros;
std::chrono::microseconds m_absTimeWhenPrevOutputBufferReachesDac;
std::chrono::microseconds m_sampleTimeAtStartCallback;
std::chrono::microseconds m_timeAtStartCallback;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

can be simplified

  • m_audioBufferTimeMicros is only set, never read
  • m_sampleTimeAtStartCallback is only initialized, never changed nor read
  • m_timeAtStartCallback is only set, never read
Suggested change
std::chrono::microseconds m_audioBufferTimeMicros;
std::chrono::microseconds m_absTimeWhenPrevOutputBufferReachesDac;
std::chrono::microseconds m_sampleTimeAtStartCallback;
std::chrono::microseconds m_timeAtStartCallback;
std::chrono::microseconds m_absTimeWhenPrevOutputBufferReachesDac;

src/engine/sync/abletonlink.h Outdated Show resolved Hide resolved
src/engine/sync/abletonlink.cpp Outdated Show resolved Hide resolved
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Add a Ableton Link interface