diff -r 1c74985d4c4e -r 63154f9d24a2 djm-fix.cpp --- a/djm-fix.cpp Tue Apr 15 22:44:31 2025 +0200 +++ b/djm-fix.cpp Tue Apr 15 22:45:25 2025 +0200 @@ -1,6 +1,6 @@ /** * DJM-Fix - * Copyright © 2020 František Kučera (Frantovo.cz, GlobalCode.info) + * Copyright © 2025 František Kučera (Frantovo.cz, GlobalCode.info) * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -33,69 +33,86 @@ } /** - * The support for Pioneer DJ DJM-250MK2 (an external USB sound card / mixer) was added to the Linux (kernel) by these patches: + * The support for Pioneer DJ DJM-250MK2 (an external USB sound card / mixer) + * was added to the Linux (kernel) by these patches: * - * - https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/sound/usb?id=73d8c94084341e2895169a0462dbc18167f01683 (playback) - * - https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/sound/usb?id=14335d8b9e1a2bf006f9d969a103f9731cabb210 (recording) - * - https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/sound/usb?id=cdc01a1558dedcee3daee7e1802d0349a07edb87 (mixer setup) + * https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/... + * - ...sound/usb?id=73d8c94084341e2895169a0462dbc18167f01683 (playback) + * - ...sound/usb?id=14335d8b9e1a2bf006f9d969a103f9731cabb210 (recording) + * - ...sound/usb?id=cdc01a1558dedcee3daee7e1802d0349a07edb87 (mixer setup) * - * These patches are enough for playback and for recording from post CH faders. + * These patches are enough for playback and for recording from post CH faders. * - * However this mixer is somehow incapacitated and if we want to record the raw signal from the PHONO or LINE channels, - * we only get silence. This feature is important for DVS (Digital Vinyl Systems) setups where - * the timecode signal from special control vinyls flows from mixer to the computer - * where it is interpreted in a software like MIXXX and used for controlling the playback of files on our computer. - * The signal (usually music) from these files flows back to the mixer and then to speakers and headphones. + * However this mixer is somehow incapacitated and if we want to record the raw + * signal from the PHONO or LINE channels, we only get silence. This feature is + * important for DVS (Digital Vinyl Systems) setups where the timecode signal + * from special control vinyls flows from mixer to the computer where it is + * interpreted in a software like MIXXX and used for controlling the playback of + * files on our computer. The signal (usually music) from these files flows back + * to the mixer and then to speakers and headphones. * - * To make this work and enjoy all the features of the device we have bought, we need to tell the mixer that we - * want the signal instead of silence on given channels. And this is the purpose of the djm-fix utility and - * it is done by sending some magic packet to the mixer. + * To make this work and enjoy all the features of the device we have bought, we + * need to tell the mixer that we want the signal instead of silence on given + * channels. And this is the purpose of the djm-fix utility and it is done by + * sending some magic packet to the mixer. * - * Implementation of this magic in the AlsaBridge.cpp file is based on publicly available documentation - * that can be found at . - * 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) - * and some magic bits. I wrote this standalone C++ program that talks with the mixer over MIDI SysEx messages and does the magic. + * Implementation of this magic in the AlsaBridge.cpp file is based on publicly + * available documentation that can be found at: + * - https://swiftb0y.github.io/CDJHidProtocol/hid-analysis/handshake.html + * - https://mixb.me/CDJHidProtocol/hid-analysis/handshake.html (formerly). + * 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) and + * some magic bits. I wrote this standalone C++ program that talks with the + * mixer over MIDI SysEx messages and does the magic. * - * When this program is started, it finds the mixer and makes it fully working. - * It needs to be running all the time, otherwise we will get silence on the PHONO/LINE channels again. + * When this program is started, it finds the mixer and makes it fully working. + * It needs to be running all the time, otherwise we will get silence + * on the PHONO/LINE channels again. * * Install dependencies: - * apt install mercurial make pkg-config g++ libasound2-dev # in Debian or Ubuntu (it will be similar in other distributions) + * apt install mercurial make pkg-config g++ libasound2-dev + * (in Debian or Ubuntu - it will be similar in other distributions) * * Download djm-fix: - * hg clone https://hg.frantovo.cz/midi/djm-fix/ # primary source - * hg clone https://hg.globalcode.info/midi/djm-fix/ # or we can use this mirror + * hg clone https://hg.frantovo.cz/midi/djm-fix/ # primary source + * hg clone https://hg.globalcode.info/midi/djm-fix/ # mirror * * Compile: - * make # we can skip this step, it will be compiled on the first run + * make # can be skipped * * Run: - * make run # in most cases - * build/djm-fix 'Pioneer DJ.*' # or provide custom name pattern (regular expression) to select the proper card + * make run # in most cases + * build/djm-fix 'Pioneer DJ.*' # with custom name + * ^ regular expression to select desired card * * Stop: * press Ctrl+C * - * Look for updates in the Mercurial repositories and at . + * Look for updates in the Mercurial repositories and at: + * - https://blog.frantovo.cz/c/387/ */ int main(int argc, char**argv) { using L = djmfix::logging::Level; - std::unique_ptr logger(djmfix::logging::create(std::cerr, L::INFO)); + std::unique_ptr + logger(djmfix::logging::create(std::cerr, L::INFO)); try { logger->log(L::INFO, "DJM-Fix started."); std::string cardNamePattern = argc == 2 ? argv[1] : "Pioneer DJ.*"; signal(SIGINT, interrupt); std::unique_ptr djmFix(djmfix::create(logger.get())); - std::unique_ptr alsaBridge(djmfix::alsa::create(djmFix.get(), cardNamePattern, logger.get())); + std::unique_ptr alsaBridge( + djmfix::alsa::create(djmFix.get(), + cardNamePattern, + logger.get())); alsaBridge->start(); while (run) std::this_thread::sleep_for(std::chrono::milliseconds(100)); - + std::cerr << std::endl; logger->log(L::INFO, "DJM-Fix stopping."); - + alsaBridge->stop(); return 0;