diff mbox series

Add basic capture support for Pioneer DJ DJM-250MK2

Message ID 20200825153113.6352-1-konference@frantovo.cz (mailing list archive)
State New, archived
Headers show
Series Add basic capture support for Pioneer DJ DJM-250MK2 | expand

Commit Message

František Kučera Aug. 25, 2020, 3:31 p.m. UTC
From: František Kučera <franta-linux@frantovo.cz>

This patch extends support for DJM-250MK2 and allows recording.
However, DVS is not possible yet (see the comment in code).

Signed-off-by: František Kučera <franta-linux@frantovo.cz>
---
 sound/usb/pcm.c          |  1 +
 sound/usb/quirks-table.h | 62 ++++++++++++++++++++++++++++++++++------
 sound/usb/quirks.c       |  1 +
 3 files changed, 56 insertions(+), 8 deletions(-)

Comments

František Kučera Aug. 25, 2020, 3:36 p.m. UTC | #1
Hello,

in February I added playback support for Pioneer DJ DJM-250MK2 (commit 73d8c94084341e2895169a0462dbc18167f01683).
Then I gave up being disgusted by Pioneer's quality and support...

Now I returned back to the unfinished work and added basic support for recording.
It is now possible to record from MIC, AUX and PHONO/LINE (but just post fader).
Thanks Dmitry Panchenko and Fabian Lesniak for inspiration.

There are two remaining open questions/issues:

1) The direct (before fader) PHONO/LINE recording channels are silent until some (yet unknown) special command is send to the mixer. There is quite a lot communication over USB in both directions and I have to dig through the dumps. This would be a separate commit and I do not know, how long it could take.

2) The channels 1-2, 2-3 and 3-5, both recording and playback, can be configured/mapped (by an USB URB command) to various sources. I wrote some userspace C code for testing purposes that uses libusb-1.0/libusb.h, so I can switch the channels. How this feature should be provided to the user? Should the USB commands be issued from the kernel driver or from userspace? Is there any existing similar example?

Franta
Takashi Iwai Aug. 25, 2020, 3:45 p.m. UTC | #2
On Tue, 25 Aug 2020 17:36:09 +0200,
František Kučera wrote:
> 
> Hello,
> 
> in February I added playback support for Pioneer DJ DJM-250MK2 (commit 73d8c94084341e2895169a0462dbc18167f01683).
> Then I gave up being disgusted by Pioneer's quality and support...
> 
> Now I returned back to the unfinished work and added basic support for recording.
> It is now possible to record from MIC, AUX and PHONO/LINE (but just post fader).
> Thanks Dmitry Panchenko and Fabian Lesniak for inspiration.
> 
> There are two remaining open questions/issues:
> 
> 1) The direct (before fader) PHONO/LINE recording channels are silent until some (yet unknown) special command is send to the mixer. There is quite a lot communication over USB in both directions and I have to dig through the dumps. This would be a separate commit and I do not know, how long it could take.
> 
> 2) The channels 1-2, 2-3 and 3-5, both recording and playback, can be configured/mapped (by an USB URB command) to various sources. I wrote some userspace C code for testing purposes that uses libusb-1.0/libusb.h, so I can switch the channels. How this feature should be provided to the user? Should the USB commands be issued from the kernel driver or from userspace? Is there any existing similar example?

At best implement a mixer element (probably with enumerated type) to
perform the switching.  You can find quite a lot of examples in
mixer_quirks.c.


Takashi
Fabian Lesniak Aug. 25, 2020, 3:49 p.m. UTC | #3
Hello Franta,
> 2) The channels 1-2, 2-3 and 3-5, both recording and playback, can be configured/mapped (by an USB URB command) to various sources. I wrote some userspace C code for testing purposes that uses libusb-1.0/libusb.h, so I can switch the channels. How this feature should be provided to the user? Should the USB commands be issued from the kernel driver or from userspace? Is there any existing similar example?

I have implemented these controls in mixer_quirks.c back when I fought
with these mixers. As I have not tested them against the current master
and your changes yet, I'll just drop a gist with the old patches from
last September if you want to have a look (patch 0003 is the one with
the mixer controls):

https://gist.github.com/flesniak/074ab23bbc833663b782f44174eae6a4

I will try to test that single patch together with your patches and
submit them if it works. I remember faintly that alsamixer did not show
the TLV dB range correctly, probably I was using DECLARE_TLV_DB_RANGE
incorrectly.

Cheers

Fabian
Takashi Iwai Aug. 26, 2020, 8:22 a.m. UTC | #4
On Tue, 25 Aug 2020 17:31:13 +0200,
František Kučera wrote:
> 
> From: František Kučera <franta-linux@frantovo.cz>
> 
> This patch extends support for DJM-250MK2 and allows recording.
> However, DVS is not possible yet (see the comment in code).
> 
> Signed-off-by: František Kučera <franta-linux@frantovo.cz>

Applied now.  Thanks.


Takashi
František Kučera Jan. 18, 2021, 10:41 p.m. UTC | #5
Dne 25. 08. 20 v 17:36 František Kučera napsal(a):
> 1) The direct (before fader) PHONO/LINE recording channels are silent until some (yet unknown) special command is send to the mixer. There is quite a lot communication over USB in both directions and I have to dig through the dumps. This would be a separate commit and I do not know, how long it could take.

As mentioned earlier, the Pioneer DJM devices are somehow broken and by default they produce only silence on LINE/PHONO recording channels.

It was really challenging but it is no more hopeless – in the meantime, someone described, how it works inside, and I wrote a standalone program called djm-fix that fixes the device and enables the LINE/PHONO channels (so the mixer is usable e.g. for DVS). Details are described here: <https://blog.frantovo.cz/c/387/>. The djm-fix tool is still a bit raw, but it works for me and at least one more DJM-250MK2 owner confirmed, that it works.

Is it possible to move this fix to the kernel level? Or should it stay rather as a standalone tool? I think that it would be nice to have Pioneer DJM devices fully working out of the box without additional tools.

The fix consists of a MIDI handshake – we need to send and receive some messages, compute some hash and then periodically send a keep-alive message (when we stop, the LINE/PHONO channels become silent again).

Franta
Takashi Iwai Jan. 19, 2021, 8:54 a.m. UTC | #6
On Mon, 18 Jan 2021 23:41:35 +0100,
František Kučera wrote:
> 
> Dne 25. 08. 20 v 17:36 František Kučera napsal(a):
> > 1) The direct (before fader) PHONO/LINE recording channels are silent until some (yet unknown) special command is send to the mixer. There is quite a lot communication over USB in both directions and I have to dig through the dumps. This would be a separate commit and I do not know, how long it could take.
> 
> As mentioned earlier, the Pioneer DJM devices are somehow broken and by default they produce only silence on LINE/PHONO recording channels.
> 
> It was really challenging but it is no more hopeless – in the meantime, someone described, how it works inside, and I wrote a standalone program called djm-fix that fixes the device and enables the LINE/PHONO channels (so the mixer is usable e.g. for DVS). Details are described here: <https://blog.frantovo.cz/c/387/>. The djm-fix tool is still a bit raw, but it works for me and at least one more DJM-250MK2 owner confirmed, that it works.
> 
> Is it possible to move this fix to the kernel level? Or should it stay rather as a standalone tool? I think that it would be nice to have Pioneer DJM devices fully working out of the box without additional tools.
> 
> The fix consists of a MIDI handshake – we need to send and receive some messages, compute some hash and then periodically send a keep-alive message (when we stop, the LINE/PHONO channels become silent again).

I haven't looked closely, but if it's about MIDI messaging, it can be
implemented in the kernel, too (only if it fits better than
user-space), yes.  If it's over HID, it's a different story, though.


Takashi
František Kučera Jan. 19, 2021, 2:26 p.m. UTC | #7
Dne 19. 01. 21 v 9:54 Takashi Iwai napsal(a):
> I haven't looked closely, but if it's about MIDI messaging, it can be
> implemented in the kernel, too (only if it fits better than
> user-space), yes.  If it's over HID, it's a different story, though.

Yes, it is only MIDI. The scenario is:

1) send a greeting message to the mixer

2) receive a greeting message

3) send another constant message

4) receive the response

5) compute something and send it back

6) receive the confirmation message

7) start sending a keep-alive message each 200 ms

Specific received messages might be consumed by kernel (invisible for user-space), but others should flow undisturbed to the user-space. The sent messages should be injected and intermixed with normal messages coming from user-space. The kernel should not claim exclusive access to the MIDI device, because user-space tools might want to use it too.

Is there already anything similar, for inspiration?

Franta
Be Jan. 20, 2021, 2:46 a.m. UTC | #8
I discourage doing this in the kernel. If Pioneer did this in their drivers on Windows and macOS, I would recommend doing it in the kernel. But they do not; Rekordbox does it at the application level. Mixxx users are currently unable to use the phono inputs of these devices regardless of OS (see https://mixxx.discourse.group/t/pioneer-djm-250-mk2/17001/29 ). The best way to implement this would be through Mixxx's MIDI controller mapping system so that it works across Linux, Windows, and macOS.

I am CCing Olivia Mackintosh because the Pioneer DJM 750 likely uses the same or very similar MIDI signals. They could probably share one MIDI script in Mixxx. The Pioneer DJM 900 NXS2 probably uses the same or very similar signals too.

If you're interested in implementing this in Mixxx, let's continue the discussion in Mixxx's Zulip chat: https://mixxx.zulipchat.com/

> Dne 19. 01. 21 v 9:54 Takashi Iwai napsal(a):
> >/I haven't looked closely, but if it's about MIDI messaging, it can be /> >/implemented in the kernel, too (only if it fits better than /> >/user-space), yes. If it's over HID, it's a different story, though. />
> Yes, it is only MIDI. The scenario is:
>
> 1) send a greeting message to the mixer
>
> 2) receive a greeting message
>
> 3) send another constant message
>
> 4) receive the response
>
> 5) compute something and send it back
>
> 6) receive the confirmation message
>
> 7) start sending a keep-alive message each 200 ms
>
> Specific received messages might be consumed by kernel (invisible for user-space), but others should flow undisturbed to the user-space. The sent messages should be injected and intermixed with normal messages coming from user-space. The kernel should not claim exclusive access to the MIDI device, because user-space tools might want to use it too.
> 
> Is there already anything similar, for inspiration?
>
> Franta


------------------------------------------------------------------------
Olivia Mackintosh Jan. 20, 2021, 8:36 a.m. UTC | #9
Thank you for copying me in.

I would love to support Pioneer devices under Linux ("fully"). I.e:
	for DJM mixers: the ability to use audio and midi IO with ALSA
	and by extension pulse/pipewire/JACK and so on. This is my bias.

I'm partial to things just working™ so would prefer it to be a kernel
module but the inclusion in-tree is not for me to say.

Lets continue this discussion on the Mixxx chat for now.

Kind regards,
Olivia


On Tue, Jan 19, 2021 at 08:46:03PM -0600, Be wrote:
> I discourage doing this in the kernel. If Pioneer did this in their drivers on Windows and macOS, I would recommend doing it in the kernel. But they do not; Rekordbox does it at the application level. Mixxx users are currently unable to use the phono inputs of these devices regardless of OS (see https://mixxx.discourse.group/t/pioneer-djm-250-mk2/17001/29 ). The best way to implement this would be through Mixxx's MIDI controller mapping system so that it works across Linux, Windows, and macOS.
> 
> I am CCing Olivia Mackintosh because the Pioneer DJM 750 likely uses the same or very similar MIDI signals. They could probably share one MIDI script in Mixxx. The Pioneer DJM 900 NXS2 probably uses the same or very similar signals too.
> 
> If you're interested in implementing this in Mixxx, let's continue the discussion in Mixxx's Zulip chat: https://mixxx.zulipchat.com/
> 
> > Dne 19. 01. 21 v 9:54 Takashi Iwai napsal(a):
> > >/I haven't looked closely, but if it's about MIDI messaging, it can be /> >/implemented in the kernel, too (only if it fits better than /> >/user-space), yes. If it's over HID, it's a different story, though. />
> > Yes, it is only MIDI. The scenario is:
> > 
> > 1) send a greeting message to the mixer
> > 
> > 2) receive a greeting message
> > 
> > 3) send another constant message
> > 
> > 4) receive the response
> > 
> > 5) compute something and send it back
> > 
> > 6) receive the confirmation message
> > 
> > 7) start sending a keep-alive message each 200 ms
> > 
> > Specific received messages might be consumed by kernel (invisible for user-space), but others should flow undisturbed to the user-space. The sent messages should be injected and intermixed with normal messages coming from user-space. The kernel should not claim exclusive access to the MIDI device, because user-space tools might want to use it too.
> > 
> > Is there already anything similar, for inspiration?
> > 
> > Franta
> 
> 
> ------------------------------------------------------------------------
diff mbox series

Patch

diff --git a/sound/usb/pcm.c b/sound/usb/pcm.c
index 5600751803cf..f5fa11deea4d 100644
--- a/sound/usb/pcm.c
+++ b/sound/usb/pcm.c
@@ -374,6 +374,7 @@  static int set_sync_ep_implicit_fb_quirk(struct snd_usb_substream *subs,
 		ifnum = 2;
 		goto add_sync_ep_from_ifnum;
 	case USB_ID(0x2b73, 0x000a): /* Pioneer DJ DJM-900NXS2 */
+	case USB_ID(0x2b73, 0x0017): /* Pioneer DJ DJM-250MK2 */
 		ep = 0x82;
 		ifnum = 0;
 		goto add_sync_ep_from_ifnum;
diff --git a/sound/usb/quirks-table.h b/sound/usb/quirks-table.h
index f4fb002e3ef4..c6b2f0b8d3e2 100644
--- a/sound/usb/quirks-table.h
+++ b/sound/usb/quirks-table.h
@@ -3549,14 +3549,40 @@  AU0828_DEVICE(0x2040, 0x7270, "Hauppauge", "HVR-950Q"),
 {
 	/*
 	 * Pioneer DJ DJM-250MK2
-	 * PCM is 8 channels out @ 48 fixed (endpoints 0x01).
-	 * The output from computer to the mixer is usable.
-	 *
-	 * The input (phono or line to computer) is not working.
-	 * It should be at endpoint 0x82 and probably also 8 channels,
-	 * but it seems that it works only with Pioneer proprietary software.
-	 * Even on officially supported OS, the Audacity was unable to record
-	 * and Mixxx to recognize the control vinyls.
+	 * PCM is 8 channels out @ 48 fixed (endpoint 0x01)
+	 * and 8 channels in @ 48 fixed (endpoint 0x82).
+	 * 
+	 * Both playback and recording is working, even simultaneously.
+	 * 
+	 * Playback channels could be mapped to:
+	 *  - CH1
+	 *  - CH2
+	 *  - AUX
+	 * 
+	 * Recording channels could be mapped to:
+	 *  - Post CH1 Fader
+	 *  - Post CH2 Fader
+	 *  - Cross Fader A
+	 *  - Cross Fader B
+	 *  - MIC
+	 *  - AUX
+	 *  - REC OUT
+	 * 
+	 * There is remaining problem with recording directly from PHONO/LINE.
+	 * If we map a channel to:
+	 *  - CH1 Control Tone PHONO
+	 *  - CH1 Control Tone LINE
+	 *  - CH2 Control Tone PHONO
+	 *  - CH2 Control Tone LINE
+	 * it is silent.
+	 * There is no signal even on other operating systems with official drivers.
+	 * The signal appears only when a supported application is started.
+	 * This needs to be investigated yet...
+	 * (there is quite a lot communication on the USB in both directions)
+	 * 
+	 * In current version this mixer could be used for playback
+	 * and for recording from vinyls (through Post CH* Fader)
+	 * but not for DVS (Digital Vinyl Systems) like in Mixxx.
 	 */
 	USB_DEVICE_VENDOR_SPEC(0x2b73, 0x0017),
 	.driver_info = (unsigned long) &(const struct snd_usb_audio_quirk) {
@@ -3580,6 +3606,26 @@  AU0828_DEVICE(0x2040, 0x7270, "Hauppauge", "HVR-950Q"),
 					.rate_max = 48000,
 					.nr_rates = 1,
 					.rate_table = (unsigned int[]) { 48000 }
+					}
+			},
+			{
+				.ifnum = 0,
+				.type = QUIRK_AUDIO_FIXED_ENDPOINT,
+				.data = &(const struct audioformat) {
+					.formats = SNDRV_PCM_FMTBIT_S24_3LE,
+					.channels = 8, // inputs
+					.iface = 0,
+					.altsetting = 1,
+					.altset_idx = 1,
+					.endpoint = 0x82,
+					.ep_attr = USB_ENDPOINT_XFER_ISOC|
+						USB_ENDPOINT_SYNC_ASYNC|
+						USB_ENDPOINT_USAGE_IMPLICIT_FB,
+					.rates = SNDRV_PCM_RATE_48000,
+					.rate_min = 48000,
+					.rate_max = 48000,
+					.nr_rates = 1,
+					.rate_table = (unsigned int[]) { 48000 }
 				}
 			},
 			{
diff --git a/sound/usb/quirks.c b/sound/usb/quirks.c
index abf99b814a0f..6a0be7e7f4fe 100644
--- a/sound/usb/quirks.c
+++ b/sound/usb/quirks.c
@@ -1493,6 +1493,7 @@  void snd_usb_set_format_quirk(struct snd_usb_substream *subs,
 		set_format_emu_quirk(subs, fmt);
 		break;
 	case USB_ID(0x2b73, 0x000a): /* Pioneer DJ DJM-900NXS2 */
+	case USB_ID(0x2b73, 0x0017): /* Pioneer DJ DJM-250MK2 */
 		pioneer_djm_set_format_quirk(subs);
 		break;
 	case USB_ID(0x534d, 0x2109): /* MacroSilicon MS2109 */