gmrender-resurrect icon indicating copy to clipboard operation
gmrender-resurrect copied to clipboard

DSD Native

Open antonellocaroli opened this issue 2 years ago • 6 comments

It seems that someone is working on dsd integration in gstreamer, with already some results

https://gitlab.freedesktop.org/gstreamer/gst-plugins-base/-/issues/972#note_1759303

Do you think that when it is merged with the main branch, it can be supported by gmediarender? I assume you would need to add a dsd option that would call up

--audiosink="dsdconvert ! alsasink device=........"

https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/3901

antonellocaroli avatar Feb 08 '23 06:02 antonellocaroli

The MR specifies that auto-plugging works. If we're lucky gmrender won't have to do anything at all.

mill1000 avatar Feb 08 '23 20:02 mill1000

gmediarender -f "PCx86" --gstout-audiopipe dsdconvert ! alsasink device=hw:CARD=Audio,DEV=0
gmediarender 0.1 started [ gmediarender 0.1_git2023-01-03_c455d13 (libupnp-1.14.15; glib-2.74.3; gstreamer-1.20.4) ].
Logging switched off. Enable with --logfile=<filename> (or --logfile=stdout for console)
Ready for rendering.
ERROR [2023-02-09 06:59:34.881789 | gstreamer] avdemux_dsf0: Error: Internal data stream error. (Debug: ../gst-libav-1.20.4/ext/libav/gstavdemux.c(1663): gst_ffmpegdemux_loop (): /GstPlayBin:play/GstURIDecodeBin:uridecodebin0/GstDecodeBin:decodebin0/avdemux_dsf:avdemux_dsf0:
streaming stopped, reason not-linked (-1))
ERROR [2023-02-09 06:59:34.882001 | gstreamer] aqueue: Error: Internal data stream error. (Debug: ../gstreamer-1.20.4/plugins/elements/gstqueue.c(992): gst_queue_handle_sink_event (): /GstPlayBin:play/GstPlaySink:playsink/GstBin:abin/GstQueue:aqueue:
streaming stopped, reason not-linked (-1))
ERROR [2023-02-09 06:59:35.129100 | gstreamer] Failed to get track duration.
ERROR [2023-02-09 06:59:35.129172 | gstreamer] Failed to get track pos
ERROR [2023-02-09 06:59:35.629323 | gstreamer] Failed to get track duration.
ERROR [2023-02-09 06:59:35.629382 | gstreamer] Failed to get track pos
ERROR [2023-02-09 06:59:36.129531 | gstreamer] Failed to get track duration.
ERROR [2023-02-09 06:59:36.129592 | gstreamer] Failed to get track pos
ERROR [2023-02-09 06:59:36.629751 | gstreamer] Failed to get track duration.
ERROR [2023-02-09 06:59:36.629808 | gstreamer] Failed to get track pos
ERROR [2023-02-09 06:59:37.129953 | gstreamer] Failed to get track duration.
ERROR [2023-02-09 06:59:37.130010 | gstreamer] Failed to get track pos
ERROR [2023-02-09 06:59:37.630154 | gstreamer] Failed to get track duration.
ERROR [2023-02-09 06:59:37.630209 | gstreamer] Failed to get track pos
ERROR [2023-02-09 06:59:38.130365 | gstreamer] Failed to get track duration.
ERROR [2023-02-09 06:59:38.130427 | gstreamer] Failed to get track pos

antonellocaroli avatar Feb 09 '23 06:02 antonellocaroli

Did you build the referenced merge request? Is that what we're seeing?

Can you try the commands they MR used as example? e.g.

gst-play-1.0 --audiosink="dsdconvert ! alsasink device=hw:3,0" test-dsd-128.dsf

mill1000 avatar Feb 10 '23 16:02 mill1000

Did you build the referenced merge request? Is that what we're seeing?

Yes

Can you try the commands they MR used as example? e.g.

gst-play-1.0 --audiosink="dsdconvert ! alsasink device=hw:3,0" test-dsd-128.dsf

yes it works.

gst-play-1.0 --verbose --gapless --audiosink="dsdconvert ! alsasink device=hw:2,0" /tmp/01\ -\ David\ Elias\ -\ The\ Window\ -\ Vision\ of\ Her\ \(DSD64\).dsf 
Press 'k' to see a list of keyboard shortcuts.
Now playing /tmp/01 - David Elias - The Window - Vision of Her (DSD64).dsf
/GstPlayBin:playbin/GstURIDecodeBin:uridecodebin0: ring-buffer-max-size = 0
/GstPlayBin:playbin/GstURIDecodeBin:uridecodebin0: buffer-size = -1
/GstPlayBin:playbin/GstURIDecodeBin:uridecodebin0: buffer-duration = -1
/GstPlayBin:playbin/GstURIDecodeBin:uridecodebin0: force-sw-decoders = false
/GstPlayBin:playbin/GstURIDecodeBin:uridecodebin0: use-buffering = false
/GstPlayBin:playbin/GstURIDecodeBin:uridecodebin0: download = false
/GstPlayBin:playbin/GstURIDecodeBin:uridecodebin0: uri = file:///tmp/01%20-%20David%20Elias%20-%20The%20Window%20-%20Vision%20of%20Her%20(DSD64).dsf
/GstPlayBin:playbin/GstURIDecodeBin:uridecodebin0: connection-speed = 0
/GstPlayBin:playbin/GstURIDecodeBin:uridecodebin0: source = "\(GstFileSrc\)\ source"
/GstPlayBin:playbin/GstURIDecodeBin:uridecodebin0/GstDecodeBin:decodebin0/GstTypeFindElement:typefind.GstPad:src: caps = application/x-gst-av-dsf
/GstPlayBin:playbin/GstURIDecodeBin:uridecodebin0/GstDecodeBin:decodebin0/GstTypeFindElement:typefind.GstPad:src: caps = NULL
/GstPlayBin:playbin/GstURIDecodeBin:uridecodebin0/GstDecodeBin:decodebin0/GstMultiQueue:multiqueue0: max-size-buffers = 5
/GstPlayBin:playbin/GstURIDecodeBin:uridecodebin0/GstDecodeBin:decodebin0/GstMultiQueue:multiqueue0: max-size-time = 0
/GstPlayBin:playbin/GstURIDecodeBin:uridecodebin0/GstDecodeBin:decodebin0/GstMultiQueue:multiqueue0: max-size-bytes = 8388608
/GstPlayBin:playbin/GstURIDecodeBin:uridecodebin0/GstDecodeBin:decodebin0/GstMultiQueue:multiqueue0.GstMultiQueuePad:sink_0: caps = audio/x-dsd, rate=(int)352800, channels=(int)2, channel-mask=(bitmask)0x0000000000000003, format=(string)DSDU8, reversed-bytes=(boolean)true, layout=(string)non-interleaved
/GstPlayBin:playbin/GstURIDecodeBin:uridecodebin0/GstDecodeBin:decodebin0/GstMultiQueue:multiqueue0.GstMultiQueuePad:src_0: caps = audio/x-dsd, rate=(int)352800, channels=(int)2, channel-mask=(bitmask)0x0000000000000003, format=(string)DSDU8, reversed-bytes=(boolean)true, layout=(string)non-interleaved
/GstPlayBin:playbin/GstInputSelector:inputselector0.GstSelectorPad:sink_0: always-ok = false
/GstPlayBin:playbin/GstInputSelector:inputselector0.GstSelectorPad:sink_0: active = true
/GstPlayBin:playbin/GstInputSelector:inputselector0: active-pad = "\(GstSelectorPad\)\ sink_0"
/GstPlayBin:playbin/GstPlaySink:playsink: volume = 1
/GstPlayBin:playbin/GstPlaySink:playsink: mute = false
/GstPlayBin:playbin/GstInputSelector:inputselector0.GstPad:src: caps = audio/x-dsd, rate=(int)352800, channels=(int)2, channel-mask=(bitmask)0x0000000000000003, format=(string)DSDU8, reversed-bytes=(boolean)true, layout=(string)non-interleaved
/GstPlayBin:playbin/GstPlaySink:playsink.GstGhostPad:audio_sink.GstProxyPad:proxypad5: caps = audio/x-dsd, rate=(int)352800, channels=(int)2, channel-mask=(bitmask)0x0000000000000003, format=(string)DSDU8, reversed-bytes=(boolean)true, layout=(string)non-interleaved
/GstPlayBin:playbin/GstPlaySink:playsink/GstTee:audiotee.GstTeePad:src_0: caps = audio/x-dsd, rate=(int)352800, channels=(int)2, channel-mask=(bitmask)0x0000000000000003, format=(string)DSDU8, reversed-bytes=(boolean)true, layout=(string)non-interleaved
/GstPlayBin:playbin/GstPlaySink:playsink/GstStreamSynchronizer:streamsynchronizer0.GstStreamSyncPad:src_0: caps = audio/x-dsd, rate=(int)352800, channels=(int)2, channel-mask=(bitmask)0x0000000000000003, format=(string)DSDU8, reversed-bytes=(boolean)true, layout=(string)non-interleaved
/GstPlayBin:playbin/GstPlaySink:playsink/GstBin:abin.GstGhostPad:sink.GstProxyPad:proxypad8: caps = audio/x-dsd, rate=(int)352800, channels=(int)2, channel-mask=(bitmask)0x0000000000000003, format=(string)DSDU8, reversed-bytes=(boolean)true, layout=(string)non-interleaved
/GstPlayBin:playbin/GstPlaySink:playsink/GstBin:abin/GstQueue:aqueue.GstPad:sink: caps = audio/x-dsd, rate=(int)352800, channels=(int)2, channel-mask=(bitmask)0x0000000000000003, format=(string)DSDU8, reversed-bytes=(boolean)true, layout=(string)non-interleaved
/GstPlayBin:playbin/GstPlaySink:playsink/GstBin:abin/GstQueue:aqueue.GstPad:src: caps = audio/x-dsd, rate=(int)352800, channels=(int)2, channel-mask=(bitmask)0x0000000000000003, format=(string)DSDU8, reversed-bytes=(boolean)true, layout=(string)non-interleaved
/GstPlayBin:playbin/GstPlaySink:playsink/GstBin:abin/GstQueue:aqueue.GstPad:src: caps = audio/x-dsd, rate=(int)352800, channels=(int)2, channel-mask=(bitmask)0x0000000000000003, format=(string)DSDU8, reversed-bytes=(boolean)true, layout=(string)non-interleaved
/GstPlayBin:playbin/GstPlaySink:playsink/GstBin:abin/GstQueue:aqueue.GstPad:src: caps = audio/x-dsd, rate=(int)352800, channels=(int)2, channel-mask=(bitmask)0x0000000000000003, format=(string)DSDU8, reversed-bytes=(boolean)true, layout=(string)non-interleaved
/GstPlayBin:playbin/GstPlaySink:playsink.GstGhostPad:audio_sink: caps = audio/x-dsd, rate=(int)352800, channels=(int)2, channel-mask=(bitmask)0x0000000000000003, format=(string)DSDU8, reversed-bytes=(boolean)true, layout=(string)non-interleaved
/GstPlayBin:playbin/GstInputSelector:inputselector0.GstSelectorPad:sink_0: caps = audio/x-dsd, rate=(int)352800, channels=(int)2, channel-mask=(bitmask)0x0000000000000003, format=(string)DSDU8, reversed-bytes=(boolean)true, layout=(string)non-interleaved
/GstPlayBin:playbin/GstURIDecodeBin:uridecodebin0.GstGhostPad:src_0.GstProxyPad:proxypad4: caps = audio/x-dsd, rate=(int)352800, channels=(int)2, channel-mask=(bitmask)0x0000000000000003, format=(string)DSDU8, reversed-bytes=(boolean)true, layout=(string)non-interleaved
/GstPlayBin:playbin/GstURIDecodeBin:uridecodebin0/GstDecodeBin:decodebin0.GstDecodePad:src_0.GstProxyPad:proxypad3: caps = audio/x-dsd, rate=(int)352800, channels=(int)2, channel-mask=(bitmask)0x0000000000000003, format=(string)DSDU8, reversed-bytes=(boolean)true, layout=(string)non-interleaved
/GstPlayBin:playbin/GstPlaySink:playsink/GstBin:abin/GstPlaySinkAudioConvert:aconv.GstGhostPad:sink.GstProxyPad:proxypad6: caps = audio/x-dsd, rate=(int)352800, channels=(int)2, channel-mask=(bitmask)0x0000000000000003, format=(string)DSDU8, reversed-bytes=(boolean)true, layout=(string)non-interleaved
/GstPlayBin:playbin/GstInputSelector:inputselector0.GstSelectorPad:sink_0: tags = taglist, title=(string)"Vision\ of\ Her", artist=(string)"David\ Elias", genre=(string)Folk, encoder=(string)"KORG\ AudioGate\ ver.1.5.0", datetime=(datetime)2007-11-20T22:52Z;
/GstPlayBin:playbin/GstPlaySink:playsink/GstBin:abin/GstPlaySinkAudioConvert:aconv/GstIdentity:identity.GstPad:src: caps = audio/x-dsd, rate=(int)352800, channels=(int)2, channel-mask=(bitmask)0x0000000000000003, format=(string)DSDU8, reversed-bytes=(boolean)true, layout=(string)non-interleaved
/GstPlayBin:playbin/GstInputSelector:inputselector0.GstSelectorPad:sink_0: tags = taglist, title=(string)"Vision\ of\ Her", artist=(string)"David\ Elias", genre=(string)Folk, encoder=(string)"KORG\ AudioGate\ ver.1.5.0", datetime=(datetime)2007-11-20T22:52Z, audio-codec=(string)"DSD\ \(Direct\ Stream\ Digital\)\,\ least\ significant\ bit\ first\,\ planar";
/GstPlayBin:playbin/GstPlaySink:playsink/GstBin:abin/GstPlaySinkAudioConvert:aconv.GstGhostPad:src: caps = audio/x-dsd, rate=(int)352800, channels=(int)2, channel-mask=(bitmask)0x0000000000000003, format=(string)DSDU8, reversed-bytes=(boolean)true, layout=(string)non-interleaved
/GstPlayBin:playbin/GstPlaySink:playsink/GstBin:abin/GstBin:bin0.GstGhostPad:sink.GstProxyPad:proxypad0: caps = audio/x-dsd, rate=(int)352800, channels=(int)2, channel-mask=(bitmask)0x0000000000000003, format=(string)DSDU8, reversed-bytes=(boolean)true, layout=(string)non-interleaved
/GstPlayBin:playbin/GstPlaySink:playsink/GstBin:abin/GstBin:bin0/GstDsdConvert:dsdconvert0.GstPad:src: caps = audio/x-dsd, rate=(int)352800, channels=(int)2, channel-mask=(bitmask)0x0000000000000003, format=(string)DSDU32BE, layout=(string)interleaved, reversed-bytes=(boolean)false
Redistribute latency...
/GstPlayBin:playbin/GstPlaySink:playsink/GstBin:abin/GstBin:bin0/GstAlsaSink:alsasink0.GstPad:sink: caps = audio/x-dsd, rate=(int)352800, channels=(int)2, channel-mask=(bitmask)0x0000000000000003, format=(string)DSDU32BE, layout=(string)interleaved, reversed-bytes=(boolean)false
/GstPlayBin:playbin/GstPlaySink:playsink/GstBin:abin/GstBin:bin0/GstDsdConvert:dsdconvert0.GstPad:sink: caps = audio/x-dsd, rate=(int)352800, channels=(int)2, channel-mask=(bitmask)0x0000000000000003, format=(string)DSDU8, reversed-bytes=(boolean)true, layout=(string)non-interleaved
/GstPlayBin:playbin/GstPlaySink:playsink/GstBin:abin/GstBin:bin0.GstGhostPad:sink: caps = audio/x-dsd, rate=(int)352800, channels=(int)2, channel-mask=(bitmask)0x0000000000000003, format=(string)DSDU8, reversed-bytes=(boolean)true, layout=(string)non-interleaved
/GstPlayBin:playbin/GstPlaySink:playsink/GstBin:abin/GstPlaySinkAudioConvert:aconv.GstGhostPad:src.GstProxyPad:proxypad7: caps = audio/x-dsd, rate=(int)352800, channels=(int)2, channel-mask=(bitmask)0x0000000000000003, format=(string)DSDU8, reversed-bytes=(boolean)true, layout=(string)non-interleaved
/GstPlayBin:playbin/GstPlaySink:playsink/GstBin:abin/GstPlaySinkAudioConvert:aconv/GstIdentity:identity.GstPad:sink: caps = audio/x-dsd, rate=(int)352800, channels=(int)2, channel-mask=(bitmask)0x0000000000000003, format=(string)DSDU8, reversed-bytes=(boolean)true, layout=(string)non-interleaved
/GstPlayBin:playbin/GstPlaySink:playsink/GstBin:abin/GstPlaySinkAudioConvert:aconv.GstGhostPad:sink: caps = audio/x-dsd, rate=(int)352800, channels=(int)2, channel-mask=(bitmask)0x0000000000000003, format=(string)DSDU8, reversed-bytes=(boolean)true, layout=(string)non-interleaved
Redistribute latency...
0:01:48.3 / 0:05:07.1

But it is probably best to wait for the full integration....see todo

TODO: It is currently unclear if DSD conversion should be done automatically inside alsasink / audioringbuffer / audiobasesink. On one hand, from what I gather, such conversions are generally preferred to exist as separate elements, so integrated converters are less "gstreamer-like". On the other hand, you pretty much always have to insert a dsdconvert element in real world use cases that may involve DSD. This gets especially tricky if the same pipeline shall handle both PCM and DSD. That's because dsdconvert only handles DSD, and audioconvert does not handle DSD.
Perhaps one option would be to integrate the DSD converter into audioconvert. But - this would allow for DSD <-> PCM cases, which are covered by neither the DSD conversion functions nor the GstAudioConverter. (DSD -> PCM is covered by the avdec_dsd_ decoders; PCM -> DSD currently does not exist.)
Another option would be to add the gst_dsd_convert function (from the public gstdsd.h API) inside audioringbuffer. But, as said above, it is unclear if this is considered OK.
This MR is marked as a draft because of this open TODO.

antonellocaroli avatar Feb 10 '23 17:02 antonellocaroli

I tried it on my system, Armibian. But I cannot hear sound, other formats work, where is my fault? bash -c "sleep 10 && /home/minganoise/gmrender-resurrect/./src/gmediarender -f 'Volumio Album Mode' --uuid 666666 -p 49157 -d --gstout-initial-volume-db=-15 --gstout-audiopipe ' rgvolume pre-amp=0 headroom=0 album-mode=TRUE ! rglimiter ! dsdconvert ! autoaudiosink '"

MMinga avatar Feb 28 '24 21:02 MMinga

Hi, apparently, DSD is supported since GStreamer version 1.24. "DSD audio support

  1. DSD audio is a non-PCM raw audio format representation and the GstAudio library gained support for this in form of new GstDsdInfo and GstDsdFormat API.
  2. Support for DSD audio has been implemented in alsasink as well as the GstAudioSink and GstAudioRingBuffer base classes, and the gst-libav plugin to enable FFmpeg-based DSD elements and functionality."

cometdom avatar Mar 24 '24 10:03 cometdom