GioF71 / tidal-connect

Simple script for configuring Tidal Connect with Docker (also on Volumio, MoodeAudio, OSMC)
MIT License
64 stars 6 forks source link

Apple USB-C to 3.5mm Headphone Jack on Moode with softvol #187

Open zamiere opened 3 days ago

zamiere commented 3 days ago

MoOde Release: 8.3.9 2024-02-23 RaspiOS: 11.9 Bullseye 32-bit

cat /proc/asound/cards
 1 [A              ]: USB-Audio - USB-C to 3.5mm Headphone Jack A
                      Apple, Inc. USB-C to 3.5mm Headphone Jack A at usb-3f980000.usb-1.5, full speed

.env:

MQA_PASSTHROUGH=true
FRIENDLY_NAME=Tidal Connect
ENABLE_GENERATED_TONE=no
CARD_NAME=DAC
CARD_FORMAT=S24_3LE
ENABLE_SOFTVOL=yes
ASOUND_FILE_PREFIX=applejack

userconfig/applejack.asound.conf:

pcm.softvol {
    type            softvol
    slave {
        pcm         "hw:CARD=A,DEV=0"
    }
    control {
        name        "SoftMaster"
        card        "A"
    }
}

pcm.!default {
    type             plug
    slave {
        pcm         "softvol"
    }
}

ctl.!default {
    type hw
    card "A"
}
GioF71 commented 3 days ago

Hello try

CARD_NAME=A

alone... Then we see if CARD_FORMAT is needed!

zamiere commented 3 days ago

Thanks, it seems only the .asound.conf is necessary and defining it in .env file of course. It's turning on softvolume, so it's resample unavailable formats (96/24) to card compatible with ALSA resample, because I enabled default ALSA mode in moOde: Default: Use ALSA "plughw" plugin which performs format conversions if needed to match audio device requirements. Direct: Use ALSA "hw" plugin which does not preform any format conversions. The audio device must accept the given format.

I think that explicit format and freq limiting to hw capabilities helps in direct mode, I didn't tried it yet. It's possible that softvol only works with plughw mode.

GioF71 commented 2 days ago

Hello again, sorry for my previous reply, I was away for the weekend and I didn't actually understand your post. I see now that you are already using a custom asound.conf with "A" as the device. Forgive the wrong suggestion, but when you define your asound.conf, the variables CARD_NAME, CARD_INDEX, CARD_DEVICE and CARD_FORMAT become irrelevant. Anyway, since you are using moode, we might want to check the device capabilities with their utility. Can you run:

moodeutl -F

and post the output.

I was thinking of buying one device like this, actually the fact that it does not support hires kind of made me change idea. Not because I would notice the difference but because I would need, like you, to avoid conversions when possible.

zamiere commented 2 days ago

Thanks for clarifying that asound.conf make unnecessary those variables. Now I reinstalled the latest 64 bit version of moode, moodeutl -F output is

Error opening sound device for card 1, device 0: Unknown error 524.  Skipping.
*** Scanning for playback devices ***
Card 0, ID `A', name `USB-C to 3.5mm Headphone Jack A'
  Device 0, ID `USB Audio', name `USB Audio', 1 subdevices (1 available)
    2 channels, sampling rate 48000..48000 Hz
    Sample formats: S16_LE, S24_3LE
    Buffer size range from 96 to 96000
    Period size range from 48 to 48000

      Subdevice 0, name `subdevice #0'
Card 1, ID `vc4hdmi', name `vc4-hdmi'
  Device 0, ID `MAI PCM i2s-hifi-0', name `MAI PCM i2s-hifi-0', 1 subdevices (1 available)

It's not as bad as cheap, you can see measurements and review on head-fi. It's a little bit light and not as analoguish like r2r DACs but not bad for the price. For high-res tracks I've dropped a line into asound.conf for better quality resample: defaults.pcm.rate_converter "speexrate_best"

The samplerate_best is too slow for resampling 88200 tracks. For these alsa plugins install libasound2-plugins: docker exec -i tidal-connect bash -c "echo 'deb http://legacy.raspbian.org/raspbian/ stretch main contrib non-free rpi firmware' > /etc/apt/sources.list && apt update && apt install libasound2-plugins -y"

I have collected some scripts from here and put into a fork of your repo here

Thank you for your work and giving information about the details!

GioF71 commented 2 days ago

Hello, thank you. That output provide some good information. Let me ask you a question: did you had to set ENABLE_SOFTVOL=yes because the generated tone would not play, preventing the container to start, didn't you? If this is confirmed, considering that from the moodeutl output, it seems that only 48000 is supported, it starts to make sense that plughw works and hw doesn't. "hw" would work only when the source sampling rate is 48000 I suppose. I was about to suggest you to configure the tidal app to "High" and not "Max" so Tidal would always use 44.1kHz, so you would avoid resampling. Anyway for your case, even if the device only supports 48kHz, I believe this configuration would still make sense, because you would avoid resampling down from 88.2 and 96kHz. It is probably better to let tidal select the 44.1kHz stream (which should be always available) and let alsa resample to 48kHz. Maybe you will be able to use the higher quality sample rate converter.

In the end, if you want to contribute the asound.conf, I will gladly accept the pull request. Or if you prefer, I will add it using the information in this issue.

zamiere commented 2 days ago

I just wanted to use the volume control in android app, and hw volume doesn't change with default settings. So I set the softvol parameter and found a working asound.conf. The device supports 44.1 and 48k, it's a good idea to use professionally downsampled streams. I will happy if you find it useful and include the config in your repo, I've made too much changes in the fork, I don't want to pull over your code.

GioF71 commented 2 days ago

Thank you, but about this:

The device supports 44.1 and 48k

are you sure? Moodeutl says otherwise. But OTOH if I look at the windows image here in yuriv's, it seems 44.1kHz is supported. Can you try this from the repository?

aplay -D hw:A assets/audio/short-low-tone.wav

and maybe:

aplay -D plughw:A assets/audio/short-low-tone.wav

I am preparing a 48kHz version of the tones :-)

GioF71 commented 2 days ago

The tone will be unaudible unless you crank up the volume, I have attenuated it as much as I can. The purpose is to verify it does not fail to play.

zamiere commented 2 days ago

If I remove the "ENABLE_GENERATED_TONE=no" line from the .env, the tidal-connect doesn't load.

Another strange thing is strong clipping distortion in this track: https://tidal.com/browse/track/89414123?u Doesn't help if I change the quality to HiFi. Maybe it's a softvol resample bug, not enough headroom to convert overdriven waveforms, I don't know how can I decrease the volume to prevent clipping.

GioF71 commented 2 days ago

Hello, you can maybe try alsamixer and lower down the volume a bit. That would be hardware volume, and softvolume won't raise over that limit hopefully!

GioF71 commented 1 day ago

If I remove the "ENABLE_GENERATED_TONE=no" line from the .env, the tidal-connect doesn't load.

This should not happen anymore with the latest revision, I have added a 48kHz tone, so now the condition is that just of the tones don't fail to play. Would you try with the latest updates?

zamiere commented 1 day ago

Lowering the volume with alsamixer doesn't change the issue.

zamiere commented 1 day ago

Now merged the changes from upstream, removed the "ENABLE_GENERATED_TONE=no" line from my .env and... no luck.

tidal-connect | Trying a short tone @ 48kHz ... tidal-connect | ALSA lib pcm.c:2495:(snd_pcm_open_noupdate) Unknown PCM custom tidal-connect | aplay: main:788: audio open error: No such file or directory tidal-connect | Failed with 48 kHz tone, trying 44.1 kHz ... tidal-connect | ALSA lib pcm.c:2495:(snd_pcm_open_noupdate) Unknown PCM custom tidal-connect | aplay: main:788: audio open error: No such file or directory tidal-connect | tone_played=[0] tidal-connect | Device locked/invalid, won't start the application ... tidal-connect | Sleeping 10 seconds before restarting ...

zamiere commented 1 day ago

The clipping problem is an issue with speex. It's resolved when I disabled the resample so it's not affect your code. (Just for fun, with "samplerate_best" the sound is stuttering because Pi 3B+ too weak for converting 88200/24 sources, it's require more CPU computing power than "samplerate_medium", the latter is works.)

GioF71 commented 1 day ago

Now merged the changes from upstream, removed the "ENABLE_GENERATED_TONE=no" line from my .env and... no luck.

tidal-connect | Trying a short tone @ 48kHz ... tidal-connect | ALSA lib pcm.c:2495:(snd_pcm_open_noupdate) Unknown PCM custom tidal-connect | aplay: main:788: audio open error: No such file or directory tidal-connect | Failed with 48 kHz tone, trying 44.1 kHz ... tidal-connect | ALSA lib pcm.c:2495:(snd_pcm_open_noupdate) Unknown PCM custom tidal-connect | aplay: main:788: audio open error: No such file or directory tidal-connect | tone_played=[0] tidal-connect | Device locked/invalid, won't start the application ... tidal-connect | Sleeping 10 seconds before restarting ...

maybe I made some mistake writing the file applejack.asound.conf... can you verify it? Looks like the "custom" audio card is somehow invalid! Maybe we should set "custom" instead of "!default", or give a different name and then set FORCE_PLAYBACK_DEVICE accordingly. In any case I might find a moment to try your file (with a alsa device as the target of course) as soon as possible.

GioF71 commented 1 day ago

I pushed a changed setting "custom" but it's done in the dark as I cannot test in the dark. But anyway I believe that a simple change allowing to use plughw instead of hw might work, without the need for a custom asound.conf. I will try that when possible.

GioF71 commented 1 day ago

Maybe try this as applejack.asound.conf:

pcm.tidal-audio-device {
  type plug
  slave.pcm {
    type plughw
    card A
    device 0
  }
}

pcm.custom {
    type            softvol
    slave {
        pcm         "tidal-audio-device"
    }
    control {
        name        "Master"
        card        0
    }
}

If this works, it would confirm the hypothesis...

zamiere commented 1 day ago

Maybe we should set "custom" instead of "!default"...

Yes, it's load with changed asound.conf. I didn't tried the last config yet.

zamiere commented 1 day ago
tidal-connect    | Sleeping 10 seconds before restarting ...
tidal-connect    | Trying a short tone @ 48kHz ...
tidal-connect    | ALSA lib dlmisc.c:254:(snd1_dlobj_cache_get) Cannot open shared library /usr/lib/arm-linux-gnueabihf/alsa-lib/libasound_module_pcm_plughw.so
tidal-connect    | aplay: main:788: audio open error: No such device or address
tidal-connect    | Failed with 48 kHz tone, trying 44.1 kHz ...
tidal-connect    | ALSA lib dlmisc.c:254:(snd1_dlobj_cache_get) Cannot open shared library /usr/lib/arm-linux-gnueabihf/alsa-lib/libasound_module_pcm_plughw.so
tidal-connect    | aplay: main:788: audio open error: No such device or address
tidal-connect    | tone_played=[0]
tidal-connect    | Device locked/invalid, won't start the application ...
tidal-connect    | Sleeping 10 seconds before restarting ...
GioF71 commented 1 day ago

ok so it's a wrong config. I cannot test now with an actual container... I will try asap. I hope you can revert to a working config!

zamiere commented 1 day ago

Yes, the latest committed config works without any glitch! Thank you!

GioF71 commented 1 day ago

Yes, the latest committed config works without any glitch! Thank you!

Good! But just to be clear, what are the contents of the working .env and applejack.asound.conf ?

zamiere commented 1 day ago

My .env is:

FRIENDLY_NAME=Tidal Connect
ASOUND_FILE_PREFIX=applejack

applejack.asound.conf:

pcm.softvol {
    type            softvol
    slave {
        pcm         "hw:CARD=A,DEV=0"
    }
    control {
        name        "SoftMaster"
        card        "A"
    }
}

pcm.custom {
    type             plug
    slave {
        pcm         "softvol"
    }
}

ctl.custom {
    type hw
    card "A"
}

I think we can close this issue. :)

GioF71 commented 1 day ago

glad it works. Keep the working config safe... but can you try this now:

.env

FRIENDLY_NAME=Tidal Connect
CARD_NAME=A

and recreate? With the changes in the tone test, it might go through. The generated file should not be very different. The missing part is the "ctl.custom" and the slave is defined in a different way but it should be equivalent. I'd like to see what can be done in order to avoid the need of a custom asound.conf.

Thank you in advance!

GioF71 commented 1 day ago

Can you also execute this:

amixer -c A controls | grep \'Master\'

and post the output?

zamiere commented 1 day ago

I decided to testing it with clean environment with removing everything.

docker rm -vf $(docker ps -aq)
docker rmi -f $(docker images -aq)

And now the volume control on Windows change the volume on Master device, not the Headphone channel that really change the output level.

dac

zamiere commented 1 day ago
#amixer -c A controls
numid=5,iface=MIXER,name='Master'
numid=2,iface=MIXER,name='Headphone Playback Switch'
numid=3,iface=MIXER,name='Headphone Playback Volume'
numid=4,iface=MIXER,name='SoftMaster'
numid=1,iface=PCM,name='Playback Channel Map'
zamiere commented 1 day ago

I lost the path, after clean install the working configs doesn't work anymore, no working volume control from app.

GioF71 commented 1 day ago

hello, isn't the master set too low in alsamixer?

GioF71 commented 1 day ago

your custom asound.conf should still work... you can reset your main branch to a few commits ago (to last week roughly) if you want to be sure to restore the working configuration

zamiere commented 1 day ago

I need a full reset before testing a config to see if it works.

zamiere commented 1 day ago

Removed the HDMI with "dtoverlay=vc4-kms-v3d,nohdmi" line in /boot/config.txt.

cat /proc/asound/cards
 0 [A              ]: USB-Audio - USB-C to 3.5mm Headphone Jack A
                      Apple, Inc. USB-C to 3.5mm Headphone Jack A at usb-3f980000.usb-1.5, full speed
zamiere commented 23 hours ago

When it worked, app volume slider changed the headphone out level. There was only two sliders in alsamixer, headphone and softvol, now three, the new slider master is the first and app slider change this mixer and nothing is change in output level.

zamiere commented 18 hours ago

In othet words, it's the same as the issue here.

zamiere commented 17 hours ago

And the path is maybe here.

zamiere commented 17 hours ago

I accidentally ran "alsactl clean" and it's removed all sliders, only the "headphone" remained. And now it works! Not softvol, but i can control the hardware output level. I will try the softvol now.

zamiere commented 16 hours ago

I entered the CARD_NAME=A line in the env, after I ran alsactl clean and now I have a Master volume and it works! Maybe it will work with my other DAC without hardware volume control too. I beginning to see the light!

GioF71 commented 13 hours ago

Good... did you have to change the custom asound.conf?

zamiere commented 11 hours ago

Sometimes it works, sometimes not, I leave it as is, works with hw volume, I will be careful when changing it.

GioF71 commented 11 hours ago

Sometimes it works, sometimes not, I leave it as is, works with hw volume, I will be careful when changing it.

So if I understand correctly, with your custom asound.conf, the tidal app move an additional slider for Software volume, while without that asound.conf, the tidal app ends up moving the master volume, is that right?

zamiere commented 4 hours ago

Without asound.conf, after alsactl clean with rebuilt config only one slider appear in alsamixer, with "Headphone" label. That's a hardware volume slider I think.

GioF71 commented 4 hours ago

Ok good to know. The interesting thing is that your asound.conf can make softvol work even with your device, which already has a "Master" device defined. So there is hope for those other users who could not enable softvol. I will have a look at the old issues and maybe implement the changes in an experimental branch

zamiere commented 4 hours ago

I have an another usb/toslink adapter (and DAC) with optical output which drive a cheap R2R DAC. I want a softvol on that to control the volume, because the adapter builtin hw volume change the onboard dac volume, the coaxial output level is constant. If we can put the softvol before the hardware card/device, Tidal will change that. I don't know if it's possible, only angry neighbours can tell about loud test results until now... 😅

GioF71 commented 4 hours ago

doesn't a variant of your applejack.asound.conf (with the other card name other than "A") work?

zamiere commented 4 hours ago

Not tried yet. But when I tried the committed conf with current (apple) card, it doesn't work with audio file check enabled. Now I reinstalled the TonyTromp repo and it's generated an .env file with: PLAYBACK_DEVICE=USB-C to 3.5mm Headphone Jack A: Audio (hw:0,0)

I will try it with a clean install.

zamiere commented 4 hours ago

I think I wrongly concluded that it works, I was wrong all along.

GioF71 commented 4 hours ago

image

I just tried over a pi4 "Headphones", which has an existing "Master" control so generally softvol doesn't work with this repository. However if I use your asound.conf (just adapted with Headphones instead of A), softvol works, but the Master slider goes up and down.

So, this confirms the behavior of your apple usb c device I believe.

I suppose your other setup (the R2R dac with usb to spdif adapter) should behave similarly. EDIT: It probably won't because with this config the tidal app volume operates on the hardware volume unfortunately.

GioF71 commented 4 hours ago

I think I wrongly concluded that it works, I was wrong all along.

what do you mean? :-o

zamiere commented 4 hours ago

I'm just not sure how long it worked this way because after that only the hardware one worked and I didn't watch the sliders... I hope the other dac will show what is the correct way for a working config.

GioF71 commented 4 hours ago

I'm just not sure how long it worked this way because after that only the hardware one worked and I didn't watch the sliders... I hope the other dac will show what is the correct way for a working config.

the problem is that that custom asound.conf creates the SoftMaster control. But the tidal app will use the "Master" control anyway. On the other hand, without that SoftMaster control, the Tidal app volume doesn't work at all for reasons beyond my knowledge. I suppose on your usb-to-spdif that if you should move that SoftMaster slider from alsamixer, the volume attenuation will be reflected on the dac coax output as well. But it would be very inconvenient because the app moves the "Master" slider, so the hw volume, while you would want the Softmaster volume to be moved