diff mbox

ALSA: dice: add stream format parameters for Mytek devices

Message ID 20632004.ST2tKRhYS0@melvin-pc (mailing list archive)
State New, archived
Headers show

Commit Message

Melvin Vermeeren May 17, 2018, 7 p.m. UTC
Mytek manufactures some equipment with DICE-based firewire ports. These
devices contain old versions of DICE firmware which lacks detailed
stream format reporting for all sampling clock modes.

Building upon the recent work by Takashi Sakamoto, hard-coded parameters
are added for the Stereo 192 DSD-DAC. When the device vendor and model
match the coded parameters are copied into the stream format cache.

Signed-off-by: Melvin Vermeeren <mail@mel.vin>
---
 sound/firewire/dice/Makefile     |  2 +-
 sound/firewire/dice/dice-mytek.c | 46 ++++++++++++++++++++++++++++++++
 sound/firewire/dice/dice.c       |  9 +++++++
 sound/firewire/dice/dice.h       |  1 +
 4 files changed, 57 insertions(+), 1 deletion(-)
 create mode 100644 sound/firewire/dice/dice-mytek.c

Comments

Takashi Sakamoto May 18, 2018, 2:54 a.m. UTC | #1
Hi,

On May 18 2018 04:00, Melvin Vermeeren wrote:
> Mytek manufactures some equipment with DICE-based firewire ports. These
> devices contain old versions of DICE firmware which lacks detailed
> stream format reporting for all sampling clock modes.
> 
> Building upon the recent work by Takashi Sakamoto, hard-coded parameters
> are added for the Stereo 192 DSD-DAC. When the device vendor and model
> match the coded parameters are copied into the stream format cache.
> 
> Signed-off-by: Melvin Vermeeren <mail@mel.vin>
> ---
>   sound/firewire/dice/Makefile     |  2 +-
>   sound/firewire/dice/dice-mytek.c | 46 ++++++++++++++++++++++++++++++++
>   sound/firewire/dice/dice.c       |  9 +++++++
>   sound/firewire/dice/dice.h       |  1 +
>   4 files changed, 57 insertions(+), 1 deletion(-)
>   create mode 100644 sound/firewire/dice/dice-mytek.c

Thanks for this patch.
Reviewed-by: Takashi Sakamoto <o-takashi@sakamocchi.jp>

> diff --git a/sound/firewire/dice/Makefile b/sound/firewire/dice/Makefile
> index 7b7997a5754c..37062a233f6a 100644
> --- a/sound/firewire/dice/Makefile
> +++ b/sound/firewire/dice/Makefile
> @@ -1,4 +1,4 @@
>   snd-dice-objs := dice-transaction.o dice-stream.o dice-proc.o dice-midi.o \
>   		 dice-pcm.o dice-hwdep.o dice.o dice-tcelectronic.o \
> -		 dice-alesis.o dice-extension.o
> +		 dice-alesis.o dice-extension.o dice-mytek.o
>   obj-$(CONFIG_SND_DICE) += snd-dice.o
> diff --git a/sound/firewire/dice/dice-mytek.c b/sound/firewire/dice/dice-mytek.c
> new file mode 100644
> index 000000000000..eb7d5492d10b
> --- /dev/null
> +++ b/sound/firewire/dice/dice-mytek.c
> @@ -0,0 +1,46 @@
> +// SPDX-License-Identifier: GPL-2.0
> +/*
> + * dice-mytek.c - a part of driver for DICE based devices
> + *
> + * Copyright (c) 2018 Melvin Vermeeren
> + */
> +
> +#include "dice.h"
> +
> +struct dice_mytek_spec {
> +	unsigned int tx_pcm_chs[MAX_STREAMS][SND_DICE_RATE_MODE_COUNT];
> +	unsigned int rx_pcm_chs[MAX_STREAMS][SND_DICE_RATE_MODE_COUNT];
> +};
> +
> +static const struct dice_mytek_spec stereo_192_dsd_dac = {
> +	/* AES, TOSLINK, SPDIF, ADAT inputs on device */
> +	.tx_pcm_chs = {{8, 8, 8}, {0, 0, 0} },
> +	/* PCM 44.1-192, native DSD64/DSD128 to device */
> +	.rx_pcm_chs = {{4, 4, 4}, {0, 0, 0} }
> +};
> +
> +/*
> + * Mytek has a few other firewire-capable devices, though newer models appear
> + * to lack the port more often than not. As I don't have access to any of them
> + * they are missing here. An example is the Mytek 8x192 ADDA, which is DICE.
> + */
> +
> +int snd_dice_detect_mytek_formats(struct snd_dice *dice)
> +{
> +	int i;
> +	const struct dice_mytek_spec *dev;
> +
> +	dev = &stereo_192_dsd_dac;
> +
> +	memcpy(dice->tx_pcm_chs, dev->tx_pcm_chs,
> +	       MAX_STREAMS * SND_DICE_RATE_MODE_COUNT * sizeof(unsigned int));
> +	memcpy(dice->rx_pcm_chs, dev->rx_pcm_chs,
> +	       MAX_STREAMS * SND_DICE_RATE_MODE_COUNT * sizeof(unsigned int));
> +
> +	for (i = 0; i < MAX_STREAMS; ++i) {
> +		dice->tx_midi_ports[i] = 0;
> +		dice->rx_midi_ports[i] = 0;
> +	}
> +
> +	return 0;
> +}
> diff --git a/sound/firewire/dice/dice.c b/sound/firewire/dice/dice.c
> index 40f7a32e4893..beeef62581ba 100644
> --- a/sound/firewire/dice/dice.c
> +++ b/sound/firewire/dice/dice.c
> @@ -17,6 +17,7 @@ MODULE_LICENSE("GPL v2");
>   #define OUI_TCELECTRONIC	0x000166
>   #define OUI_ALESIS		0x000595
>   #define OUI_MAUDIO		0x000d6c
> +#define OUI_MYTEK		0x001ee8
>   
>   #define DICE_CATEGORY_ID	0x04
>   #define WEISS_CATEGORY_ID	0x00
> @@ -365,6 +366,14 @@ static const struct ieee1394_device_id dice_id_table[] = {
>   		.model_id	= MODEL_ALESIS_IO_BOTH,
>   		.driver_data = (kernel_ulong_t)snd_dice_detect_alesis_formats,
>   	},
> +	/* Mytek Stereo 192 DSD-DAC. */
> +	{
> +		.match_flags	= IEEE1394_MATCH_VENDOR_ID |
> +				  IEEE1394_MATCH_MODEL_ID,
> +		.vendor_id	= OUI_MYTEK,
> +		.model_id	= 0x000002,
> +		.driver_data = (kernel_ulong_t)snd_dice_detect_mytek_formats,
> +	},
>   	{
>   		.match_flags = IEEE1394_MATCH_VERSION,
>   		.version     = DICE_INTERFACE,
> diff --git a/sound/firewire/dice/dice.h b/sound/firewire/dice/dice.h
> index 505b79fea6d9..83353a3559e8 100644
> --- a/sound/firewire/dice/dice.h
> +++ b/sound/firewire/dice/dice.h
> @@ -226,5 +226,6 @@ int snd_dice_create_midi(struct snd_dice *dice);
>   int snd_dice_detect_tcelectronic_formats(struct snd_dice *dice);
>   int snd_dice_detect_alesis_formats(struct snd_dice *dice);
>   int snd_dice_detect_extension_formats(struct snd_dice *dice);
> +int snd_dice_detect_mytek_formats(struct snd_dice *dice);
>   
>   #endif

 From me, some supplements. In Mytek website, we can get firmwares for
some models with interfaces for IEEE 1394 bus.

* Professional:   https://mytekdigital.com/professional/support/
   * Stereo192-DSD-DAC: 
https://mytekdigital.com/support_docs/Mytek_Stereo192DSD%20DAC_firmware.zip
   * 8x192ADDA DIO FW: 
https://mytekdigital.com/download_library/DioFWDiceMini3001.bin
* HiFi:   https://mytekdigital.com/hifi/support/
   * Manhattan DAC (Original model): 
https://mytekdigital.com/support_docs/Mytek_ManhattanDAC_firmware_v1.1.1.zip
   * Stereo192-DSD-DAC: 
https://mytekdigital.com/support_docs/Mytek_Stereo192DSD%20DAC_firmware.zip

When executing strings(1) to these firmwares, we can see below line:

For Stereo192-DSD-DAC:
```
* Mytek Stereo192DA on DICE Mini (TCD2210)               *
```

For original Manhattan DAC:
```
* Mytek Stereo192DA on DICE Mini (TCD2210)               *
```
(I note that the line includes different name.)

For 8x192ADDA DIO FW:
```
* Mytek 8x192ADDA DioFW on DICE Mini (TCD2210)     *
```

It's reasonable that we judge TCD2210 (a.k.a. Dice mini) ASIC used for
Mytek models. Old firmwares were not released for this ASIC, thus your
patch comment is not proper. The reason for this patch is that this
model doesn't support extended protocol, which I've addressed at a
commit commit 58579c056c1c ('ALSA: dice: use extended protocol to detect
available stream formats').

Furthermore, for 8x192ADDA DIO FW, the firmware includes below
line:

```
* EAP is supported.                                      *
```

I believe ALSA Dice driver can detect stream formats correctly for
this model. Thus, the rest of piece may be for original Manhattan DAC.

I note that all of Dice based devices utilizes Embedded Configurable
Operating System(eCos)[1], and these firmwares are designed for eCos.
IMHO, the firmwares can be parsed by format of eCos but I have never
attempted it,

 From my curious, can you drive your model with DSD samples? If so, what
kind of software do you use?

[1] http://ecos.sourceware.org/


Regards

Takashi Sakamoto
Takashi Iwai May 18, 2018, 6:56 a.m. UTC | #2
On Thu, 17 May 2018 21:00:00 +0200,
Melvin Vermeeren wrote:
> 
> Mytek manufactures some equipment with DICE-based firewire ports. These
> devices contain old versions of DICE firmware which lacks detailed
> stream format reporting for all sampling clock modes.
> 
> Building upon the recent work by Takashi Sakamoto, hard-coded parameters
> are added for the Stereo 192 DSD-DAC. When the device vendor and model
> match the coded parameters are copied into the stream format cache.
> 
> Signed-off-by: Melvin Vermeeren <mail@mel.vin>

Applied, thanks.


Takashi
Melvin Vermeeren May 18, 2018, 8:01 p.m. UTC | #3
On Friday, 18 May 2018 04:54:01 CEST Takashi Sakamoto wrote:
> Hi,
> 
> On May 18 2018 04:00, Melvin Vermeeren wrote:
> > Mytek manufactures some equipment with DICE-based firewire ports. These
> > devices contain old versions of DICE firmware which lacks detailed
> > stream format reporting for all sampling clock modes.
> > 
> > Building upon the recent work by Takashi Sakamoto, hard-coded parameters
> > are added for the Stereo 192 DSD-DAC. When the device vendor and model
> > match the coded parameters are copied into the stream format cache.
> > 
> > Signed-off-by: Melvin Vermeeren <mail@mel.vin>
> > -- SNIP --
> 
>  From me, some supplements. In Mytek website, we can get firmwares for
> some models with interfaces for IEEE 1394 bus.
> 
> * Professional:   https://mytekdigital.com/professional/support/
>    * Stereo192-DSD-DAC:
> https://mytekdigital.com/support_docs/Mytek_Stereo192DSD%20DAC_firmware.zip
>    * 8x192ADDA DIO FW:
> https://mytekdigital.com/download_library/DioFWDiceMini3001.bin
> * HiFi:   https://mytekdigital.com/hifi/support/
>    * Manhattan DAC (Original model):
> https://mytekdigital.com/support_docs/Mytek_ManhattanDAC_firmware_v1.1.1.zip
> * Stereo192-DSD-DAC:
> https://mytekdigital.com/support_docs/Mytek_Stereo192DSD%20DAC_firmware.zip
> 
> When executing strings(1) to these firmwares, we can see below line:
> 
> For Stereo192-DSD-DAC:
> ```
> * Mytek Stereo192DA on DICE Mini (TCD2210)               *
> ```
> 
> For original Manhattan DAC:
> ```
> * Mytek Stereo192DA on DICE Mini (TCD2210)               *
> ```
> (I note that the line includes different name.)
> 
> For 8x192ADDA DIO FW:
> ```
> * Mytek 8x192ADDA DioFW on DICE Mini (TCD2210)     *
> ```
> 
> It's reasonable that we judge TCD2210 (a.k.a. Dice mini) ASIC used for
> Mytek models. Old firmwares were not released for this ASIC, thus your
> patch comment is not proper. The reason for this patch is that this
> model doesn't support extended protocol, which I've addressed at a
> commit commit 58579c056c1c ('ALSA: dice: use extended protocol to detect
> available stream formats').

Thank you for the details, I hadn't looked into the hardware side of things 
with this depth. I had assumed that the lack of reporting would be due to old 
firmware like with other models.

> Furthermore, for 8x192ADDA DIO FW, the firmware includes below
> line:
> 
> ```
> * EAP is supported.                                      *
> ```
> 
> I believe ALSA Dice driver can detect stream formats correctly for
> this model. Thus, the rest of piece may be for original Manhattan DAC.

It could be that the Manhattan does support EAP, it is quite a bit newer than 
the Stereo 192 DSD-DAC. Though at the same time, a lot of the internals are 
the same as in the 192.

> I note that all of Dice based devices utilizes Embedded Configurable
> Operating System(eCos)[1], and these firmwares are designed for eCos.
> IMHO, the firmwares can be parsed by format of eCos but I have never
> attempted it,
> 
>  From my curious, can you drive your model with DSD samples? If so, what
> kind of software do you use?

With lintweaker's out-of-tree USB 2.0 driver[1] it works with DoP. Due to 
latency requirements and reliability I always run over firewire however. I did 
some basic attempts to get it working from userspace, but I think it is not 
possible with the current snd_dice.

As for the player, I believe there are several that support it. So far I have 
been using MPD, which has native DSD playback[2][3].

I did attempt something cheap to see what would happen:

#define AM824_IN_PCM_FORMAT_BITS       SNDRV_PCM_FMTBIT_S32
#define AM824_OUT_PCM_FORMAT_BITS      SNDRV_PCM_FMTBIT_S32

For these two, I appended "| SNDRV_PCM_FMTBIT_DSD_U32_LE" and some other 
variants. MPD then refuses to play because:

alsa_output: opened hw:DAC,0 type=HW
alsa_output: buffer: size=1792..4096 time=10158..23220
alsa_output: period: size=896..2048 time=5079..11610
alsa_output: default period_time = buffer_time/4 = 23219/4 = 5804
alsa_output: format=DSD_U32_LE (Direct Stream Digital, 4-byte (x32), little 
endian, oldest bits in MSB)
alsa_output: buffer_size=4096 period_size=1024
output: opened "mpd_alsa_out" (alsa) audio_format=dsd128:4
exception: Failed to convert for "mpd_alsa_out" (alsa)
exception: nested: PCM conversion from f to dsd is not implemented
output: Retrying without DSD
alsa_output: opened hw:DAC,0 type=HW
alsa_output: buffer: size=1920..4096 time=10000..21334
alsa_output: period: size=960..2048 time=5000..10667
alsa_output: default period_time = buffer_time/4 = 21333/4 = 5333
alsa_output: format=S32_LE (Signed 32 bit Little Endian)
alsa_output: buffer_size=4096 period_size=1024
output: opened "mpd_alsa_out" (alsa) audio_format=192000:32:4
libsamplerate: setting samplerate conversion ratio to 0.27
output: converting in=dsd128:2 -> f=dsd128:2 -> out=192000:32:4

I am pretty sure this happens because the DSD128 file is 2 channels, and MPD 
sees the output in 4 channels. It does exactly the same for DSD64. I am not 
sure how this should be handled since the channels are not actually for 4.0 
audio. Possibly need to expose it is a 2-channel device and in the driver use 
PCM-L,PCM-R or DSD-L,DSD-R depending on the input. Could be the unit works a 
bit differently then this, I will ask Mytek.

In the meanwhile, do you have any suggestions for things I could experiment 
with? I am not very familiar with the ALSA tree (yet). Meanwhile I will try to 
look in MPD source code for a bit, if I could set channel mappings there that 
might solve it too.
 
By the way, it seems that currently native 16-bit and 24-bit PCM formats are 
not supported since it always locks to 32-bit. I remember the "old", 2016, 
DICE driver did support 16-bit to my DAC, not sure about 24-bit. I am curious 
to why the new design is fixed to 32-bit, do you perhaps know?

[1] https://github.com/lintweaker/mytekusb2
[2] https://www.musicpd.org/doc/user/dsd.html
[3] https://github.com/MusicPlayerDaemon/MPD/blob/master/NEWS

Thank you,

Melvin Vermeeren
Takashi Sakamoto May 19, 2018, 8:23 a.m. UTC | #4
Hi,

On May 19 2018 05:01, Melvin Vermeeren wrote:
> With lintweaker's out-of-tree USB 2.0 driver[1] it works with DoP. Due to
> latency requirements and reliability I always run over firewire however. I did
> some basic attempts to get it working from userspace, but I think it is not
> possible with the current snd_dice.
> 
> As for the player, I believe there are several that support it. So far I have
> been using MPD, which has native DSD playback[2][3].
> 
> I did attempt something cheap to see what would happen:
> 
> #define AM824_IN_PCM_FORMAT_BITS       SNDRV_PCM_FMTBIT_S32
> #define AM824_OUT_PCM_FORMAT_BITS      SNDRV_PCM_FMTBIT_S32
> 
> For these two, I appended "| SNDRV_PCM_FMTBIT_DSD_U32_LE" and some other
> variants. MPD then refuses to play because:
> 
> alsa_output: opened hw:DAC,0 type=HW
> alsa_output: buffer: size=1792..4096 time=10158..23220
> alsa_output: period: size=896..2048 time=5079..11610
> alsa_output: default period_time = buffer_time/4 = 23219/4 = 5804
> alsa_output: format=DSD_U32_LE (Direct Stream Digital, 4-byte (x32), little
> endian, oldest bits in MSB)
> alsa_output: buffer_size=4096 period_size=1024
> output: opened "mpd_alsa_out" (alsa) audio_format=dsd128:4
> exception: Failed to convert for "mpd_alsa_out" (alsa)
> exception: nested: PCM conversion from f to dsd is not implemented
> output: Retrying without DSD
> alsa_output: opened hw:DAC,0 type=HW
> alsa_output: buffer: size=1920..4096 time=10000..21334
> alsa_output: period: size=960..2048 time=5000..10667
> alsa_output: default period_time = buffer_time/4 = 21333/4 = 5333
> alsa_output: format=S32_LE (Signed 32 bit Little Endian)
> alsa_output: buffer_size=4096 period_size=1024
> output: opened "mpd_alsa_out" (alsa) audio_format=192000:32:4
> libsamplerate: setting samplerate conversion ratio to 0.27
> output: converting in=dsd128:2 -> f=dsd128:2 -> out=192000:32:4
> 
> I am pretty sure this happens because the DSD128 file is 2 channels, and MPD
> sees the output in 4 channels. It does exactly the same for DSD64. I am not
> sure how this should be handled since the channels are not actually for 4.0
> audio. Possibly need to expose it is a 2-channel device and in the driver use
> PCM-L,PCM-R or DSD-L,DSD-R depending on the input. Could be the unit works a
> bit differently then this, I will ask Mytek.
> 
> In the meanwhile, do you have any suggestions for things I could experiment
> with? I am not very familiar with the ALSA tree (yet). Meanwhile I will try to
> look in MPD source code for a bit, if I could set channel mappings there that
> might solve it too.
>   
> By the way, it seems that currently native 16-bit and 24-bit PCM formats are
> not supported since it always locks to 32-bit. I remember the "old", 2016,
> DICE driver did support 16-bit to my DAC, not sure about 24-bit. I am curious
> to why the new design is fixed to 32-bit, do you perhaps know?
> 
> [1] https://github.com/lintweaker/mytekusb2
> [2] https://www.musicpd.org/doc/user/dsd.html
> [3] https://github.com/MusicPlayerDaemon/MPD/blob/master/NEWS

This is my first time to have discussion about transmission of PDM
sample by IEC 61883-1/6[1][2] via IEEE 1394 bus. You can see details
of this protocol in a document published by 1394TA[3]. For
implementation detail, please refer to my un-upstreamed documents[4][5].

Unfortunately, at present, IEC 61883-1/6 engine in ALSA firewire stack
is designed for PCM samples and MIDI messages with ALSA PCM/MIDI
interface. I removed support 16 bit PCM sample at a commit a02cb8f8def6
('ALSA: firewire: remove support for 16 bit PCM samples in playback
substream')[6] in this point, because as long as I know all of
supported models have no features to switch bit width of
transferred/received PCM samples and my previous implementation for
16 bit sample brings zero-padding 24 bit PCM sample to the device.
(Drivers in ALSA firewire stack support SNDRV_PCM_FMTBIT_S32 with
24 bit constraint[7].)

In my opinion, it's hard to achieve it with quick hack to the engine
and ALSA Dice driver. Especially for your case, one data block for
outgoing packet to target device should include two kind data; PCM
and PDM samples. I can see output from '/proc/asound/DSD/dice' in
your previous message[8] includes below:

```
rx 0:
   iso channel: 1
   sequence start: 0
   audio channels: 4
   midi ports: 0
   names: ANALOG L\ANALOG R\DSD1281\DSD1282\\
   ac3 caps: 00000000
```

If the 'ANALOG L/R' represent data channels for two PCM samples
and the 'DSD1281/2' represent data channels for two PDM samples,
I can assume that one data block includes two kind of samples,
thus two data streams of PCM/PDM samples should be multiplexed into
one data stream of IEC 61883-1/6 packets.

For this case, I need to implement ALSA dice driver to add two PCM
substreams in Linux system; one is for transmission of PCM samples,
another is for transmission of PDM samples for DoP-compliant
application. Unfortunately, current IEC 61883-1/6 engine in ALSA
firewire stack is not designed for this case.

As an another solution, reservation of data transmission of
IEC 61883-1/6 packet either data stream of PCM samples or data
stream of PDM samples. In this case, implementation change can be
smaller than multiplexing/demultiplexing these two data stream for
data stream of IEC 61883-1/6 packets. In this solution, from
userspace applications, two PCM substreams are available exclusively.

[1] IEC 61883-1 Consumer audio/video equipment –
Digital interface - Part 1: General
[2] IEC 61883-6 Consumer audio/video equipment –
Digital interface – Part 6: Audio and music data transmission protocol
[3] Audio and Music Data Transmission Protocol 2.2 Revision 1.1
(1394 Trade Association, Oct 2010)
http://1394ta.org/wp-content/uploads/2015/07/2009013.pdf
[4] Documentation/sound/iec61883-6/protocol.rst
https://github.com/takaswie/sound/blob/topic/iec61883-6-documentation/Documentation/sound/iec61883-6/protocol.rst
[5] Documentation/sound/iec61883-6/timing-on-ieee1394.rst
https://github.com/takaswie/sound/blob/topic/iec61883-6-documentation/Documentation/sound/iec61883-6/timing-on-ieee1394.rst
[6] ALSA: firewire: remove support for 16 bit PCM samples in playback 
substream
https://git.kernel.org/pub/scm/linux/kernel/git/tiwai/sound.git/commit/?id=a02cb8f8def634159b60c3a4d6ba16e471b46e0c
[7] see amdtp_am824_add_pcm_hw_constraints()
https://git.kernel.org/pub/scm/linux/kernel/git/tiwai/sound.git/tree/sound/firewire/amdtp-am824.c#n214
[8] [alsa-devel] DICE Stereo-192-DSD-DAC issues since 2016-02-08 / 
kernel >= ~4.6
http://mailman.alsa-project.org/pipermail/alsa-devel/2017-September/125524.html


Regards

Takashi Sakamoto
Melvin Vermeeren May 21, 2018, 3:09 p.m. UTC | #5
Hello,

Sorry for the wait. Have been busy a bit.

On Saturday, 19 May 2018 10:23:30 CEST Takashi Sakamoto wrote:
> This is my first time to have discussion about transmission of PDM
> sample by IEC 61883-1/6[1][2] via IEEE 1394 bus. You can see details
> of this protocol in a document published by 1394TA[3]. For
> implementation detail, please refer to my un-upstreamed documents[4][5].

Thank you, these help a lot. I just did some quick reading and will read more 
thoroughly in the coming days as time permits. Contact with Mytek is going 
well by the way, I am expecting details from their engineer soon.

> Unfortunately, at present, IEC 61883-1/6 engine in ALSA firewire stack
> is designed for PCM samples and MIDI messages with ALSA PCM/MIDI
> interface. I removed support 16 bit PCM sample at a commit a02cb8f8def6
> ('ALSA: firewire: remove support for 16 bit PCM samples in playback
> substream')[6] in this point, because as long as I know all of
> supported models have no features to switch bit width of
> transferred/received PCM samples and my previous implementation for
> 16 bit sample brings zero-padding 24 bit PCM sample to the device.
> (Drivers in ALSA firewire stack support SNDRV_PCM_FMTBIT_S32 with
> 24 bit constraint[7].)

The commit makes perfect sense, indeed displaying only actual hardware 
capabilities instead of padding in the driver. Curiosity satisfied. :)

> In my opinion, it's hard to achieve it with quick hack to the engine
> and ALSA Dice driver. Especially for your case, one data block for
> outgoing packet to target device should include two kind data; PCM
> and PDM samples. I can see output from '/proc/asound/DSD/dice' in
> your previous message[8] includes below:
> 
> ```
> rx 0:
>    iso channel: 1
>    sequence start: 0
>    audio channels: 4
>    midi ports: 0
>    names: ANALOG L\ANALOG R\DSD1281\DSD1282\\
>    ac3 caps: 00000000
> ```
> 
> If the 'ANALOG L/R' represent data channels for two PCM samples
> and the 'DSD1281/2' represent data channels for two PDM samples,
> I can assume that one data block includes two kind of samples,
> thus two data streams of PCM/PDM samples should be multiplexed into
> one data stream of IEC 61883-1/6 packets.
> 
> For this case, I need to implement ALSA dice driver to add two PCM
> substreams in Linux system; one is for transmission of PCM samples,
> another is for transmission of PDM samples for DoP-compliant
> application. Unfortunately, current IEC 61883-1/6 engine in ALSA
> firewire stack is not designed for this case.
> 
> As an another solution, reservation of data transmission of
> IEC 61883-1/6 packet either data stream of PCM samples or data
> stream of PDM samples. In this case, implementation change can be
> smaller than multiplexing/demultiplexing these two data stream for
> data stream of IEC 61883-1/6 packets. In this solution, from
> userspace applications, two PCM substreams are available exclusively.

As you say, what may help with implementation is that, as far as I have seen 
on the market, all devices are either in PCM or PDM mode. Thus there indeed 
doesn't need to be support for sending PCM and PDM at the same time. Perhaps 
there do exist some really big units which are multiple DAC/ADC in one box 
where some streams are PCM and others are PDM at the same time, but I have not 
yet heard of such a device.

If I understand correctly, the substreams are what show up in "aplay -l" as 
subdevice. Such that "hw:DAC,0" and "hw:DAC,1" would open substream #0 and #1 
respectively. From userspace point of view I think it makes sense to expose a 
single 2-channel substream with both PCM and PDM capabilities which is then 
used in either 2ch PCM or 2ch PDM at any time, but not 1ch PCM + 1ch PDM. This 
is similar to how USB DoP DACs work I believe.

This way a playlist in music software (MPD) containing both PCM and PDM tracks 
will work on the same output. MPD can configure "allowed formats" in the 
output, but it will always convert PDM to PCM for all enabled outputs that do 
not support PDM. In case of two substreams the PCM and PDM substreams will 
then be used at the same time unless the user manually switches active input 
before and after PDM tracks. I suspect many other userspace music software 
have similar behaviour.

Also, I am not yet sure whether this specific DAC supports DoP over IEEE 1394. 
Possibly there is another format in use for PDM playback over IEEE 1394. 
Expect more details on this within the next few days.

I have not yet hacked MPD to attempt to experiment with channel mappings. I 
may still do this in the coming weeks however.

Regards,

Melvin Vermeeren
Melvin Vermeeren June 7, 2018, 2:40 p.m. UTC | #6
Hi,

Over the past weeks I have had some time to do some more research and hacking. 
Thank you for the supplied un-upstreamed documents. Mytek has also been very 
helpful providing some details about the unit. It appears that the assumptions 
so far are largely invalid and there is almost no work to be done on ALSA Dice 
driver.

Although this is good news, I have unfortunately also discovered a problem.

On Monday, 21 May 2018 17:09:37 CEST Melvin Vermeeren wrote:
> On Saturday, 19 May 2018 10:23:30 CEST Takashi Sakamoto wrote:
> > In my opinion, it's hard to achieve it with quick hack to the engine
> > and ALSA Dice driver. Especially for your case, one data block for
> > outgoing packet to target device should include two kind data; PCM
> > and PDM samples. I can see output from '/proc/asound/DSD/dice' in
> > your previous message[8] includes below:
> > 
> > ```
> > 
> > rx 0:
> >    iso channel: 1
> >    sequence start: 0
> >    audio channels: 4
> >    midi ports: 0
> >    names: ANALOG L\ANALOG R\DSD1281\DSD1282\\
> >    ac3 caps: 00000000
> > 
> > ```
> > 
> > If the 'ANALOG L/R' represent data channels for two PCM samples
> > and the 'DSD1281/2' represent data channels for two PDM samples,
> > I can assume that one data block includes two kind of samples,
> > thus two data streams of PCM/PDM samples should be multiplexed into
> > one data stream of IEC 61883-1/6 packets.
>
> Also, I am not yet sure whether this specific DAC supports DoP over IEEE
> 1394. Possibly there is another format in use for PDM playback over IEEE
> 1394. Expect more details on this within the next few days.

It turns out the Mytek Stereo-192-DSD-DAC only supports PDM samples over PCM 
with DoP standard[1]. DoP uses 24-bit PCM frames at 176.4kHz sampling 
frequency to transmit PDM samples.

The "DSD128" channels to my DAC are for DSD128 DoP mode using the method as 
described in 3.2. in the standard. Because this unit does not support 352.8kHz 
four PCM channels are used in 176.4Khz rate to effectively transmit DSD128.

This means the ALSA Dice driver can remain as is, since DoP standard is used 
from userspace applications like MusicPlayerDaemon (MPD). I got DSD64 DoP 
working by hacking the channel mappings. For proper DSD128 DoP with four 
channels some changes are needed in MPD, I'll contact their mailing list soon.

The above proposition might still be needed in the future if we encounter IEEE 
1394 hardware that only supports native PDM formats.

I will submit another patch soon to possibly add support for Mytek Manhattan 
DAC and to correct and update some comments in the dice-mytek.c file.

----

Unfortunately, I have confirmed the existence of some sort of timing or 
transmission issue to the unit. This did not happen when I ran the "old" 
modules out-of-tree for over a year, as described in the initial mail[2]. In 
this mail I also noticed the popping issue.

It comes down to that the transmission is somehow not bit-perfect. In PCM mode 
this causes subtle cracking and popping, which is a lot more notable on higher 
frequencies. The higher the sampling frequency, the more rapid the popping 
sounds become. The PCM stream never fully drops out, sounds do always keep 
playing.

In DSD (DoP) mode this causes complete drop-out of the signal for ~0.2-1.0 
seconds since the DAC leaves DoP mode when the DoP markers are missing. This 
happens consistently every 2 seconds or so. The 2 seconds it does play DSD64 
it does work properly without any artefacts in the produced analog signal. The 
display on DAC keeps saying "dsd DoP" during the dropout.

Currently my kernel is 4.16.12-rt5. I also built 4.17.0-rc2-sound+ from 
Tiwai's repo today, which is commit 3248e54292f93e1bf7b9ff084918d79dd6f655f8. 
The problem is exactly the same in both and was also the same on any kernel I 
used since I switched to the "new" modules.

It should be noted the number of errors is variable. In the best case it is as 
described above. In other cases the number of problematic packets is so high 
the DAC cannot switch into DSD DoP mode at all, staying permanently silent 
while the display flickers between "dsd DoP" and "176.4 PCM" rapidly. For PCM 
streams the number and intensity of cracks and pops increase substantially.

Based upon the above, I think it is likely to be a timing issue. Not sure if 
it occurs during packet transmission or if something goes wrong when starting 
the streams, when the DAC "locks" to the packets.

Do you have a suggestion for anything I could try to either resolve the issue 
or how to provide additional information?

[1] http://dsd-guide.com/sites/default/files/white-papers/
DoP_openStandard_1v1.pdf
[2] http://mailman.alsa-project.org/pipermail/alsa-devel/2017-September/
125524.html

Regards,

Melvin Vermeeren
Melvin Vermeeren June 19, 2018, 6:23 p.m. UTC | #7
Hello Takashi,

Have you discovered any news regarding the timing issue in DICE or anything 
else from my previous email? I noticed in your recent commit 
1ceb506d631f512f8e5b04821c21104b80c15dee, you referred to an email with 
details from 2016[1], leading me to do some experimenting.

On Thursday, 7 June 2018 16:40:21 CEST Melvin Vermeeren wrote:
> Do you have a suggestion for anything I could try to either resolve the
> issue or how to provide additional information?

I have ported the "old modules" from my initial email[2], which is commit:

2eb65d67afbf9364b525b657f1475d1a2cbc27de
ALSA: dice: expand timeout to wait for Dice notification

to my current kernel, 4.16.12-rt5-1-rt. Then I did a quick hack to correctly 
identify the Mytek's channel mapping for this old driver. I found that both 
PCM and DSD over DoP now work perfectly, though sometimes it misses the lock 
as described in the initial mail. I have been playing back DSD over DoP for 
over 30 minutes so far with zero drop-outs or other issues. This is not 
possible with current DICE.

I must conclude that the packet sequence quirk described in your email is not 
the same issue that impacts the Mytek, since that this quirk exists since 
kernel 3.13 and in my initial email there were no problems with kernel 4.4. 
Though I must admit I do not know where the current problem comes from.

Please let me know if there is anything I can do to further diagnose the 
problem with current DICE.

[1] [alsa-devel] Dice packet sequence quirk and ALSA firewire stack in Linux
4.6 http://mailman.alsa-project.org/pipermail/alsa-devel/2016-May/107715.html 
[2] [alsa-devel] DICE Stereo-192-DSD-DAC issues since 2016-02-08 / kernel >= 
~4.6
http://mailman.alsa-project.org/pipermail/alsa-devel/2017-September/
125524.html

Thank you,

Melvin Vermeeren.
diff mbox

Patch

diff --git a/sound/firewire/dice/Makefile b/sound/firewire/dice/Makefile
index 7b7997a5754c..37062a233f6a 100644
--- a/sound/firewire/dice/Makefile
+++ b/sound/firewire/dice/Makefile
@@ -1,4 +1,4 @@ 
 snd-dice-objs := dice-transaction.o dice-stream.o dice-proc.o dice-midi.o \
 		 dice-pcm.o dice-hwdep.o dice.o dice-tcelectronic.o \
-		 dice-alesis.o dice-extension.o
+		 dice-alesis.o dice-extension.o dice-mytek.o
 obj-$(CONFIG_SND_DICE) += snd-dice.o
diff --git a/sound/firewire/dice/dice-mytek.c b/sound/firewire/dice/dice-mytek.c
new file mode 100644
index 000000000000..eb7d5492d10b
--- /dev/null
+++ b/sound/firewire/dice/dice-mytek.c
@@ -0,0 +1,46 @@ 
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * dice-mytek.c - a part of driver for DICE based devices
+ *
+ * Copyright (c) 2018 Melvin Vermeeren
+ */
+
+#include "dice.h"
+
+struct dice_mytek_spec {
+	unsigned int tx_pcm_chs[MAX_STREAMS][SND_DICE_RATE_MODE_COUNT];
+	unsigned int rx_pcm_chs[MAX_STREAMS][SND_DICE_RATE_MODE_COUNT];
+};
+
+static const struct dice_mytek_spec stereo_192_dsd_dac = {
+	/* AES, TOSLINK, SPDIF, ADAT inputs on device */
+	.tx_pcm_chs = {{8, 8, 8}, {0, 0, 0} },
+	/* PCM 44.1-192, native DSD64/DSD128 to device */
+	.rx_pcm_chs = {{4, 4, 4}, {0, 0, 0} }
+};
+
+/*
+ * Mytek has a few other firewire-capable devices, though newer models appear
+ * to lack the port more often than not. As I don't have access to any of them
+ * they are missing here. An example is the Mytek 8x192 ADDA, which is DICE.
+ */
+
+int snd_dice_detect_mytek_formats(struct snd_dice *dice)
+{
+	int i;
+	const struct dice_mytek_spec *dev;
+
+	dev = &stereo_192_dsd_dac;
+
+	memcpy(dice->tx_pcm_chs, dev->tx_pcm_chs,
+	       MAX_STREAMS * SND_DICE_RATE_MODE_COUNT * sizeof(unsigned int));
+	memcpy(dice->rx_pcm_chs, dev->rx_pcm_chs,
+	       MAX_STREAMS * SND_DICE_RATE_MODE_COUNT * sizeof(unsigned int));
+
+	for (i = 0; i < MAX_STREAMS; ++i) {
+		dice->tx_midi_ports[i] = 0;
+		dice->rx_midi_ports[i] = 0;
+	}
+
+	return 0;
+}
diff --git a/sound/firewire/dice/dice.c b/sound/firewire/dice/dice.c
index 40f7a32e4893..beeef62581ba 100644
--- a/sound/firewire/dice/dice.c
+++ b/sound/firewire/dice/dice.c
@@ -17,6 +17,7 @@  MODULE_LICENSE("GPL v2");
 #define OUI_TCELECTRONIC	0x000166
 #define OUI_ALESIS		0x000595
 #define OUI_MAUDIO		0x000d6c
+#define OUI_MYTEK		0x001ee8
 
 #define DICE_CATEGORY_ID	0x04
 #define WEISS_CATEGORY_ID	0x00
@@ -365,6 +366,14 @@  static const struct ieee1394_device_id dice_id_table[] = {
 		.model_id	= MODEL_ALESIS_IO_BOTH,
 		.driver_data = (kernel_ulong_t)snd_dice_detect_alesis_formats,
 	},
+	/* Mytek Stereo 192 DSD-DAC. */
+	{
+		.match_flags	= IEEE1394_MATCH_VENDOR_ID |
+				  IEEE1394_MATCH_MODEL_ID,
+		.vendor_id	= OUI_MYTEK,
+		.model_id	= 0x000002,
+		.driver_data = (kernel_ulong_t)snd_dice_detect_mytek_formats,
+	},
 	{
 		.match_flags = IEEE1394_MATCH_VERSION,
 		.version     = DICE_INTERFACE,
diff --git a/sound/firewire/dice/dice.h b/sound/firewire/dice/dice.h
index 505b79fea6d9..83353a3559e8 100644
--- a/sound/firewire/dice/dice.h
+++ b/sound/firewire/dice/dice.h
@@ -226,5 +226,6 @@  int snd_dice_create_midi(struct snd_dice *dice);
 int snd_dice_detect_tcelectronic_formats(struct snd_dice *dice);
 int snd_dice_detect_alesis_formats(struct snd_dice *dice);
 int snd_dice_detect_extension_formats(struct snd_dice *dice);
+int snd_dice_detect_mytek_formats(struct snd_dice *dice);
 
 #endif