Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

DSD Native #260

Open
antonellocaroli opened this issue Feb 8, 2023 · 6 comments
Open

DSD Native #260

antonellocaroli opened this issue Feb 8, 2023 · 6 comments

Comments

@antonellocaroli
Copy link

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

@mill1000
Copy link
Contributor

mill1000 commented Feb 8, 2023

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

@antonellocaroli
Copy link
Author

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

@mill1000
Copy link
Contributor

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

@antonellocaroli
Copy link
Author

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.

@MMinga
Copy link

MMinga commented Feb 28, 2024

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 '"

@cometdom
Copy link

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."

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants