1.1 --- a/djm-fix.cpp Tue Apr 15 22:44:31 2025 +0200
1.2 +++ b/djm-fix.cpp Tue Apr 15 22:45:25 2025 +0200
1.3 @@ -1,6 +1,6 @@
1.4 /**
1.5 * DJM-Fix
1.6 - * Copyright © 2020 František Kučera (Frantovo.cz, GlobalCode.info)
1.7 + * Copyright © 2025 František Kučera (Frantovo.cz, GlobalCode.info)
1.8 *
1.9 * This program is free software: you can redistribute it and/or modify
1.10 * it under the terms of the GNU General Public License as published by
1.11 @@ -33,69 +33,86 @@
1.12 }
1.13
1.14 /**
1.15 - * The support for Pioneer DJ DJM-250MK2 (an external USB sound card / mixer) was added to the Linux (kernel) by these patches:
1.16 + * The support for Pioneer DJ DJM-250MK2 (an external USB sound card / mixer)
1.17 + * was added to the Linux (kernel) by these patches:
1.18 *
1.19 - * - https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/sound/usb?id=73d8c94084341e2895169a0462dbc18167f01683 (playback)
1.20 - * - https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/sound/usb?id=14335d8b9e1a2bf006f9d969a103f9731cabb210 (recording)
1.21 - * - https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/sound/usb?id=cdc01a1558dedcee3daee7e1802d0349a07edb87 (mixer setup)
1.22 + * https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/...
1.23 + * - ...sound/usb?id=73d8c94084341e2895169a0462dbc18167f01683 (playback)
1.24 + * - ...sound/usb?id=14335d8b9e1a2bf006f9d969a103f9731cabb210 (recording)
1.25 + * - ...sound/usb?id=cdc01a1558dedcee3daee7e1802d0349a07edb87 (mixer setup)
1.26 *
1.27 - * These patches are enough for playback and for recording from post CH faders.
1.28 + * These patches are enough for playback and for recording from post CH faders.
1.29 *
1.30 - * However this mixer is somehow incapacitated and if we want to record the raw signal from the PHONO or LINE channels,
1.31 - * we only get silence. This feature is important for DVS (Digital Vinyl Systems) setups where
1.32 - * the timecode signal from special control vinyls flows from mixer to the computer
1.33 - * where it is interpreted in a software like MIXXX and used for controlling the playback of files on our computer.
1.34 - * The signal (usually music) from these files flows back to the mixer and then to speakers and headphones.
1.35 + * However this mixer is somehow incapacitated and if we want to record the raw
1.36 + * signal from the PHONO or LINE channels, we only get silence. This feature is
1.37 + * important for DVS (Digital Vinyl Systems) setups where the timecode signal
1.38 + * from special control vinyls flows from mixer to the computer where it is
1.39 + * interpreted in a software like MIXXX and used for controlling the playback of
1.40 + * files on our computer. The signal (usually music) from these files flows back
1.41 + * to the mixer and then to speakers and headphones.
1.42 *
1.43 - * To make this work and enjoy all the features of the device we have bought, we need to tell the mixer that we
1.44 - * want the signal instead of silence on given channels. And this is the purpose of the djm-fix utility and
1.45 - * it is done by sending some magic packet to the mixer.
1.46 + * To make this work and enjoy all the features of the device we have bought, we
1.47 + * need to tell the mixer that we want the signal instead of silence on given
1.48 + * channels. And this is the purpose of the djm-fix utility and it is done by
1.49 + * sending some magic packet to the mixer.
1.50 *
1.51 - * Implementation of this magic in the AlsaBridge.cpp file is based on publicly available documentation
1.52 - * that can be found at <https://mixb.me/CDJHidProtocol/hid-analysis/handshake.html>.
1.53 - * This page pointed me to the proper hash function (according to the constants, it is bit uncommon but publicly known Fowler–Noll–Vo hash function, FNV)
1.54 - * and some magic bits. I wrote this standalone C++ program that talks with the mixer over MIDI SysEx messages and does the magic.
1.55 + * Implementation of this magic in the AlsaBridge.cpp file is based on publicly
1.56 + * available documentation that can be found at:
1.57 + * - https://swiftb0y.github.io/CDJHidProtocol/hid-analysis/handshake.html
1.58 + * - https://mixb.me/CDJHidProtocol/hid-analysis/handshake.html (formerly).
1.59 + * This page pointed me to the proper hash function (according to the constants,
1.60 + * it is bit uncommon but publicly known Fowler–Noll–Vo hash function, FNV) and
1.61 + * some magic bits. I wrote this standalone C++ program that talks with the
1.62 + * mixer over MIDI SysEx messages and does the magic.
1.63 *
1.64 - * When this program is started, it finds the mixer and makes it fully working.
1.65 - * It needs to be running all the time, otherwise we will get silence on the PHONO/LINE channels again.
1.66 + * When this program is started, it finds the mixer and makes it fully working.
1.67 + * It needs to be running all the time, otherwise we will get silence
1.68 + * on the PHONO/LINE channels again.
1.69 *
1.70 * Install dependencies:
1.71 - * apt install mercurial make pkg-config g++ libasound2-dev # in Debian or Ubuntu (it will be similar in other distributions)
1.72 + * apt install mercurial make pkg-config g++ libasound2-dev
1.73 + * (in Debian or Ubuntu - it will be similar in other distributions)
1.74 *
1.75 * Download djm-fix:
1.76 - * hg clone https://hg.frantovo.cz/midi/djm-fix/ # primary source
1.77 - * hg clone https://hg.globalcode.info/midi/djm-fix/ # or we can use this mirror
1.78 + * hg clone https://hg.frantovo.cz/midi/djm-fix/ # primary source
1.79 + * hg clone https://hg.globalcode.info/midi/djm-fix/ # mirror
1.80 *
1.81 * Compile:
1.82 - * make # we can skip this step, it will be compiled on the first run
1.83 + * make # can be skipped
1.84 *
1.85 * Run:
1.86 - * make run # in most cases
1.87 - * build/djm-fix 'Pioneer DJ.*' # or provide custom name pattern (regular expression) to select the proper card
1.88 + * make run # in most cases
1.89 + * build/djm-fix 'Pioneer DJ.*' # with custom name
1.90 + * ^ regular expression to select desired card
1.91 *
1.92 * Stop:
1.93 * press Ctrl+C
1.94 *
1.95 - * Look for updates in the Mercurial repositories and at <https://blog.frantovo.cz/c/387/>.
1.96 + * Look for updates in the Mercurial repositories and at:
1.97 + * - https://blog.frantovo.cz/c/387/
1.98 */
1.99
1.100 int main(int argc, char**argv) {
1.101 using L = djmfix::logging::Level;
1.102 - std::unique_ptr<djmfix::logging::Logger> logger(djmfix::logging::create(std::cerr, L::INFO));
1.103 + std::unique_ptr<djmfix::logging::Logger>
1.104 + logger(djmfix::logging::create(std::cerr, L::INFO));
1.105 try {
1.106 logger->log(L::INFO, "DJM-Fix started.");
1.107 std::string cardNamePattern = argc == 2 ? argv[1] : "Pioneer DJ.*";
1.108
1.109 signal(SIGINT, interrupt);
1.110 std::unique_ptr<djmfix::DJMFix> djmFix(djmfix::create(logger.get()));
1.111 - std::unique_ptr<djmfix::alsa::AlsaBridge> alsaBridge(djmfix::alsa::create(djmFix.get(), cardNamePattern, logger.get()));
1.112 + std::unique_ptr<djmfix::alsa::AlsaBridge> alsaBridge(
1.113 + djmfix::alsa::create(djmFix.get(),
1.114 + cardNamePattern,
1.115 + logger.get()));
1.116
1.117 alsaBridge->start();
1.118 while (run) std::this_thread::sleep_for(std::chrono::milliseconds(100));
1.119 -
1.120 +
1.121 std::cerr << std::endl;
1.122 logger->log(L::INFO, "DJM-Fix stopping.");
1.123 -
1.124 +
1.125 alsaBridge->stop();
1.126
1.127 return 0;