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

ReplayGain Support?

Open drewofdoom opened this issue 11 years ago • 16 comments

This may already be implemented, but I can't find any reference to it in the issue tracker or the code. Granted, my coding skills are pretty subpar...

Nevertheless, Gstreamer has support for replaygain via its "Good" plugin. Could replaygain be implemented on client-side, as most servers (especially linux-based) lack this functionality, and those that do support it require transcoding?

  • 0.10: https://developer.gnome.org/gst-plugins-libs/0.10/gst-plugins-good-plugins-plugin-replaygain.html
  • 1.0: http://gstreamer.freedesktop.org/data/doc/gstreamer/head/gst-plugins-good-plugins/html/gst-plugins-good-plugins-plugin-replaygain.html

Looks like all that needs to happen is to call the "rgvolume" plugin when launching the stream. Album mode can be toggled with the "album-mode" flag (default TRUE).

drewofdoom avatar Sep 05 '13 19:09 drewofdoom

Sounds interesting. I never use replay-gain, so this is not implemented. If you can figure out the details what to do, fork the code and send me a pull-request, I am happy to integrate that.

hzeller avatar Sep 07 '13 17:09 hzeller

I'll certainly do that as soon as I have some time.

drewofdoom avatar Sep 07 '13 20:09 drewofdoom

So I've been looking over the code with my rather limited knowledge of coding. It seems as if the relevant code should go somewhere in the elements section of output_gstreamer.c, but I'm not entirely certain how to accomplish that. I can certainly go through and figure it out, but I feel like I've hit a roadblock while looking at the gstreamer code.

Apparently, gstreamer only reads tags calculated with its own replaygain analyzer (rganalyze element). This is problematic, as the de-facto standard for replaygain tag support is the foobar method.

Basically, gstreamer looks for:

GST_TAG_TRACK_GAIN
GST_TAG_TRACK_PEAK
GST_TAG_ALBUM_GAIN
GST_TAG_ALBUM_PEAK
GST_TAG_REFERENCE_LEVEL

while most replaygain software outputs tags like this:

replaygain_track_gain
replaygain_track_peak
replaygain_album_gain
replaygain_album_peak
replaygain_reference_level

So, without some sort of tag mapping, this is relatively useless after all. The analysis could be done during the stream, but that would result in gapped tracks and would not scale well to embedded devices (which is probably 80% of the use case for this project, if not more).

I haven't seen any sort of tag-mapping references in the code, which leads me to believe that there is none and this feature is probably more trouble than it's worth. I might look into trying my hand at creating a tag-mapping module, but likelihood that I'll get it working is admittedly low.

I'm sure you're busy enough with everything you've got going on, HZeller, but if anyone with more coding experience thinks this is worth doing, please drop me a line at (drew at hovel dot la) and we'll see about getting this going.

drewofdoom avatar Sep 20 '13 19:09 drewofdoom

Important for implementing is to be able to test. Since I don't use replaygain, can you produce a file (based on a public license, e.g. creative commons) with these tags set ? Or can tell me a tool with which I can add the replay-gain under Linux ? I found this site, it looks promising http://www.bobulous.org.uk/misc/Replay-Gain-in-Linux.html .

hzeller avatar Sep 21 '13 18:09 hzeller

Sorry, didn't get notified about your response. Thought I was tracking this issue.

I'll source a creatie commons ogg track and try to insert these tags.

drewofdoom avatar Oct 24 '13 21:10 drewofdoom

Bringing this old issue up, almost seven years old. minimstreamer uses a simple value to manage replaygain. https://forum.minimserver.com/showthread.php?tid=1365&page=5&highlight=replaygain For me as user, I want to decide which of the both tags should be used, so it is not optimal to go always to the configuration side. Currently, I use the app Bubble UPnP where I can select the replaygain and convert the stream to wav. My wish is to use it from every playing device, PC and so on.

I would kindly ask, is it possible to make the gsstreamer accessable by two ways – replaygain-track and replaygain-album – by selecting the player – maybe as two virtual renderer? In most cases, I want to play in replaygain-album, to use the dynamic of it, in other reasons, when playing random, I want the replaygain-track tag, to avoid loudness-jumps.

In cases when the tag(s) are not set, the plugin would play as usual, until today, for those users it makes no difference to now.

Attached, you will find two examples, one flac and one mp3 whit both written tags. (Removed)

MMinga avatar May 04 '20 20:05 MMinga

Just a quick analysis.

It looks like Gstreamer has support for ReplayGain in it's "Good" plugins repo. Of most interest would be this element: https://gstreamer.freedesktop.org/documentation/replaygain/rgvolume.html?gi-language=c#rgvolume

You could manually construct a pipeline using the --gstout-audiopipe to feed audio data through a rgvolume element. One instance should set album-mode to FALSE, the other instance should set album-mode to TRUE. The first renderer would be for random playback, the second for album playback.

This is a total guess on the pipeline

--gstout-audiopipe 'audioconvert ! rgvolume pre-amp=6.0 headroom=10.0 album-mode=TRUE ! rglimiter ! audioconvert ! audioresample ! autoaudiosink'

To run two separate instances of gmrender on a single machine just make sure to change the UUID of one of them. I would also recommend changing the friendly name. I use this to have an unbuffered and buffered renderer on a single device.

mill1000 avatar May 04 '20 20:05 mill1000

Dear mill, thanks for the fast reply, Í gave the information to the developer of my renderer. with regards Michael

MMinga avatar May 04 '20 21:05 MMinga

Sure thing. As a note: I am not certain if these values pre-amp=6.0 headroom=10.0 are appropriate. It may be better to use the default values.

mill1000 avatar May 04 '20 21:05 mill1000

Dear Mill, I tried it now on my own. How to get a second instance running? Should it be done in the configuration file? If Yes how? Attached my current configuration: gstreamer_configuration.txt

MMinga avatar Sep 04 '23 20:09 MMinga

To create a second instance I would setup a second systemd service with the desired options for replaygain.

A rough example. Adjust the -f and --uuid parameters as necessary

[Unit]
Description=GMediaRender - ReplayGain
After=syslog.service network.target

[Service]
ExecStart=/usr/local/bin/gmediarender -f %H ReplayGain --uuid %m_1 --gstout-audiopipe 'audioconvert ! rgvolume pre-amp=0 headroom=0 album-mode=TRUE ! rglimiter ! audioconvert ! audioresample ! autoaudiosink  --uuid 666 
StandardOutput=syslog
StandardError=syslog
SyslogIdentifier=GMediaRender - ReplayGain
User=pi
Group=audio

[Install]
WantedBy=multi-user.target

mill1000 avatar Sep 05 '23 16:09 mill1000

Dear Mill, I tried it and it results into the second one running but the first one not. The second one has a standard name "Pi" it runs with "replay-gain = track" as expected. Where is the fault, why the first one in "/etc/default/gmrender" is now not working? Where is the possibilty to set an own name for the second one?

Thanks in advance for your support.

gmediarender_configuration.txt gmrenderertrack.servcie_configuration.txt Screenshot_20230905-222128

MMinga avatar Sep 05 '23 20:09 MMinga

-f %H ReplayGain controls the name. The %H inserts the hostname which must be 'Pi'. You can customize it. e.g. -f 'Track Mode'

Looking at your configurations, both instances are configured with the same uuid (--uuid 666), you need to have a unique UUID for each instance.

mill1000 avatar Sep 05 '23 21:09 mill1000

You have --uuid and -f listed twice in the ExecStart commands.

I don't think you need to specify -p on the second service.

Hint: Use triple backticks ``` to format a code block.

mill1000 avatar Sep 12 '23 16:09 mill1000

Dear Mill, I tried to enter the friendly name and uuid several times, without a success. Also I tried the second service without changing the port without success. The code above is now running and never change a running system. IMHO the issue can be closed.

Update: The friendly name and --uuid is true. The port not: ERROR [2023-09-13 17:49:58.450493 | upnp] UpnpInit2(interface=(null), port=49494) Error: UPNP_E_SOCKET_BIND (-203). Retrying... (0s)

MMinga avatar Sep 12 '23 20:09 MMinga

Additional explanation: In my current setup I started new: https://github.com/hzeller/gmrender-resurrect/blob/master/INSTALL.md Then I did not run the rederer, I created two systems /etc/systemd/system, gmediarendereralbum.service and gmediarenderertrack.service settings: These are runnig perfect

Description=GMediaRender - ReplayGainAlbum
After=syslog.service network.target

[Service]
ExecStartPre=/bin/sleep 30
ExecStart=/usr/local/bin/gmediarender --gstout-initial-volume-db=-15 --gstout-audiopipe 'audioconvert ! rgvolume pre-amp=0 headroom=0 album-mode=TRUE ! rglimiter ! audioconvert ! audioresample ! autoaudiosink ' --uuid 666 -f 'Album Mode'
StandardOutput=syslog
StandardError=syslog
SyslogIdentifier=GMediaRender - ReplayGainAlbum
User=Pi User
Group=audio

[Install]
WantedBy=multi-user.target 

[Unit]
Description=GMediaRender - ReplayGainTrack
After=syslog.service network.target

[Service]
ExecStartPre=/bin/sleep 30
ExecStart=/usr/local/bin/gmediarender  --gstout-initial-volume-db=-15 --gstout-audiopipe 'audioconvert ! rgvolume pre-amp=0 headroom=0 album-mode=FALSE ! rglimiter ! audioconvert ! audioresample ! autoaudiosink ' --uuid 6661 -f 'Track Mode' -p 49152
StandardOutput=syslog
StandardError=syslog
SyslogIdentifier=GMediaRender - ReplayGainTrack
User=Pi User
Group=audio

[Install]
WantedBy=multi-user.target

MMinga avatar Sep 16 '23 14:09 MMinga