Can't make replaygain works on DSD files
#1
Hello,

I've been fiddling around ironic_monkey code for dsf tags. So far I wasn't able to apply replaygain even though it seems kodi reads the tag.

Code:
AVDictionaryEntry* avtag=NULL;
  while ((avtag = av_dict_get(fctx->metadata, "", avtag, AV_DICT_IGNORE_SUFFIX)))
  {
    if (StringUtils::EqualsNoCase(URIUtils::GetExtension(strFileName), ".mka") ||
        StringUtils::EqualsNoCase(URIUtils::GetExtension(strFileName), ".dsf"))
    {
      if (strcasecmp(avtag->key, "title") == 0)
        tag.SetTitle(avtag->value);
      else if (strcasecmp(avtag->key, "artist") == 0)
        tag.SetArtist(avtag->value);
      else if (strcasecmp(avtag->key, "album") == 0)
        tag.SetAlbum(avtag->value);
      else if (strcasecmp(avtag->key, "part_number") == 0 ||
               strcasecmp(avtag->key, "track") == 0)
        tag.SetTrackNumber(strtol(avtag->value, NULL, 10));
      else if (strcasecmp(avtag->key, "album_artist") == 0)
        tag.SetAlbumArtist(avtag->value);
      else if (strcasecmp(avtag->key, "genre") == 0)
        tag.SetGenre(avtag->value);  
      else if (strcasecmp(avtag->key, "date") == 0)
        tag.SetYear(strtol(avtag->value, NULL, 10));
      else if (strcasecmp(avtag->key, "replaygain_track_gain") == 0)
    replayGainInfo.ParseGain(ReplayGain::TRACK, avtag->value);
      else if (strcasecmp(avtag->key, "replaygain_album_gain") == 0)
        replayGainInfo.ParseGain(ReplayGain::ALBUM, avtag->value);
      else if (strcasecmp(avtag->key, "replaygain_track_peak") == 0)
        replayGainInfo.ParsePeak(ReplayGain::TRACK, avtag->value);
      else if (strcasecmp(avtag->key, "replaygain_album_peak") == 0)
        replayGainInfo.ParsePeak(ReplayGain::ALBUM, avtag->value);      
    }
  }
  
  if (replayGainInfo.Get(ReplayGain::TRACK).Valid() && replayGainInfo.Get(ReplayGain::ALBUM).Valid())
  {
    tag.SetReplayGain(replayGainInfo);
    myfile << "success";
  }
  else myfile << "failed";

This code read the replaygain info from my dsf tags, but yet replaygain isn't applied. Could I have some guidance on how replaygain works in Kodi? I thought once the replaygain info was passed to the song instance of CmusicInfoTag, that info was picked up by the audioencoder and applied to the stream?

Any help would be welcome since I'm no developper and stuck with this problem.
Reply
#2
Do you get a "AudioDecoder::GetReplayGain - Final Replaygain applied: %f, Track/Album Gain %f, Peak %f" in your debug log ?
Reply
#3
yes, but with the standard value of 1
Reply
#4
what is the ranges of the data you obtain from the tag ?
Reply
#5
I've tried again, and this time it worked, don't know why it didn't before

DEBUG: AudioDecoder::GetReplayGain - Final Replaygain applied: 0.879022, Track/Album Gain 87.879997, Peak 0.459594
Reply
#6
\o/
Reply
#7
Thank you anyway. Smile
Reply
#8
I don't get it, after that last test I've tried again on another file, and it didn't work. Then I've tried again the file that worked and now replaygain isn't applied....
Reply
#9
hard to help from my end. i can look at it (can't promise when) if i have a sample at hand.

i assume you know how to wield a debugger. if not, that's the tool you need to figure this out.
Reply
#10
Any good one on linux?
Reply
#11
nope Wink or well, gdb the backend is okay, it's the frontends.. i use the 'ddd' frontend. it's rather nasty but it does the job.
Reply
#12
making some progress here. I've noticed the replaygain info was sent to the player before it get scanned by my code.
Reply
#13
I've finally got replaygain working.

I've found out that each time a music file is opened for reading, prior to opening the stream, TagLoaderTagLib is called for reading the tags, and MusicInfoTagLoaderFactory is called way after. MusicInfoTagLoaderFactory si calling ironic_monkey code (MusicInfoTagLoaderFFmpeg) that I've modified to scan the replaygain info.

So in order to read the replaygain info for dsf files, I've included a call to MusicInfoTagLoaderFFmpeg within TagLoaderTagLib when it encounters a dsf file

Code:
else if (strExtension == "ogg")
    file = oggVorbisFile = new Ogg::Vorbis::File(stream);
  else if (strExtension == "oga") // Leave this madness until last - oga container can have Vorbis or FLAC
  {
    file = oggFlacFile = new Ogg::FLAC::File(stream);
    if (!file || !file->isValid())
    {
      delete file;
      oggFlacFile = NULL;
      file = oggVorbisFile = new Ogg::Vorbis::File(stream);
    }
  }
  else if (strExtension == "dsf" || strExtension == "mka")
  {
    CMusicInfoTagLoaderFFmpeg dsf;
    if (dsf.Load(strFileName, tag, art))
      CLog::Log(LOGDEBUG, "reading dsf tags");
  }
  
  if (!file || !file->isOpen())
  {
    delete file;
    delete stream;
    if (strExtension != "dsf" && strExtension != "mka")
      CLog::Log(LOGDEBUG, "file could not be opened for tag reading");
    return false;
  }

Now replaygain is applied to my dsf files. Smile
Reply
#14
the why would be interesting, this is ugly general bug.
Reply
#15
I counldn't figure that out, I don't know c++. It's true this fix isn't really elegant.
Reply

Logout Mark Read Team Forum Stats Members Help
Can't make replaygain works on DSD files0