Hello,
for the longest time, Google Play Music has been without any kind of loudness normalization. Many songs are too quit in comparison to others, which is in part due to the loudness war of the past and some recording label's recent departure from it. Especially songs uploaded by oneself are plagued by this issue, and Google themselves have ignored this problem for years.
Loudness normalization, or even better - Replaygain - will fix this issue once and for all, if it can be implemented. AFAIK standard normalization can work on the fly, but is faulty at times. Replaygain will need to quickly scan a song (a matter of mere seconds nowadays) before adjusting the volume. Information on the process can be found on the hydrogenaudio wiki:
http://wiki.hydrogenaud.io/index.php?title=ReplayGain
Implementing the output sound device selection was a great improvement to your software and supplied a much-needed feature that Google Play itself did not provide. Once again, the situation looks grim without your help!
@Silun This is one of those things that is nice to think of but is rather tricky to implement.
Basic volume normalization can be achieved with a DynamicsCompressorNode
However I don't think this is true "normalization".
The major problem behind any implementation though is that in order to transform the audio it needs to pass through an AudioContext. When it passes through an AudioContext the method we use to change the audio output device setSinkId(id) no longer works and audio is reverted back to the default device.
This is an underlying implementation flaw in Chromium and has prevented the equalizer from being enabled for a long time.
The best i can do for now is mark this has _Blocked_ and wait for Chromium to implement the setSinkId method on AudioContext elements
For those wondering you can track the sequence of Chromium WebAudio issues over at
https://bugs.chromium.org/p/chromium/issues/detail?id=595635
That is just one of the bugs but it appears to be the one where discussion has happened recently
@MarshallOfSound Using a compressor is nowhere near normalization. Proper normalization would mean looking through the whole file, detecting the highest peak, and setting it to 0 dBFS. A compressor however, looks through a timeframe, usually through a moving average, and ducks volume past a certain threshold.
As an electronic music producer, I know my way around compressors and limiters, and using a compressor isn't the way to go here. The attack and release parameters would need to be handpicked for each song manually to not completely destroy the track's dynamics, and even then it could still lead to compression artifacts (hearing the sound "pump" on sudden loud noises, for example).
That being said, I do not know what kind of algorithm Chrominium uses for its dynamics compressor, and there are transparent compressing and RMS-triggered algorithms, which greatly help with the artifacts, however there is still the need to tweak the attack and release values for each song.
ReplayGain would be the nice implementation, however it requires analyzing each file to determine its loudness and change the volume according to that. So, it falls back to Google's responsibility to implement such a feature.
OK, first up thanks @SolarLiner for the in depth explanation of the magic of normalization. I've actually done a lot of research into this over the last few weeks and I basically learnt exactly what @SolarLiner said.
TLDR: True normalization requires some kind of "look ahead" algorithm
Unfortunately due to how GPM works and how it streams audio we can't perform any "look-ahead" analysis of the audio.
I've tried making the audio play at 1000x and then sending it back to the beginning and capturing the waveform but this caused some epic sounds which I shall never play again for my own ear safety.
So as a final thingy.
Yes, it's possible in theory. But no it's not possible in practice. Closing as wontfix
A daft question. If you've got a song list, couldn't you play them ahead to generate volume data?
Unfortunately not.
Unfortunately due to how GPM works and how it streams audio we can't perform any "look-ahead" analysis of the audio.
We don't actually have any way of playing future songs without Google playing it in the player.
With ReplayGain, there is no need for lookahead -- all the analysis is done ahead of time and the results are stored in the music file itself. The player just needs to read the computed values and adjust the volume accordingly.
@eykamp So then wouldn't you have to reupload every single song to Google so the file on the server contains the data needed by ReplayGain?
I believe Google processed the sent tracks for cataloging and other purposes - stripping unnecessary data along the way. Even if you passed your entire catalog for ReplayGain - EBU normalization, you would still not get the ReplayGain data - and All Access users can't even do it anyway.
Actually majority of your songs will not be uploaded at all. The upload app generates a hash and then you get a matching song from Google library when you play it. Even worse, if you try to be sneaky and recompress the song with normalization applied it STILL gets replaced by the standard version from the library. I guess theoretically you could complain about individual songs being too quiet but that's about it.
So clearly that it not the way to go, but if we could get ReplayGain to store results in a local file, normalization could theoretically be achieved? The only problem in that case is how to generate those results. I can imagine 3 possibilities:
Generate the data from local versions of your music. This is good for people like me that have local versions of all music. However this doesn't help for people that don't have local versions and it doesn't help for radio. Plus, there is the problem of trying to find the correct volume data for the streaming song once its been generated from local files. I dunno how easy that would be exactly.
Generate data from a stream. Obviously you would have to stream the song at least once before you could normalize, but that wouldn't bother me too much. Judging by the previous comments, this looks to be a tricky hack.
Use google play's download feature to download the actual music file and generate it from that. I don't know if this has been implemented yet, but seeing as its present on the web app, it shouldn't be too bad. Presumably (correct me if I'm wrong), the file downloaded is identical to the one in Google's library (and therefore the one you stream), and not necessarily the one you uploaded so it should be easy to match generated data.
Personally 3 seems like the best option to me. Of course, this entire discussion would be moot if Google would normalize all their versions of the songs but if they haven't done it yet, I doubt they will. I've encountered songs on the same album that have wildly different equalizations though, so it is really Google's fault.
You can only ever download a single song twice. However you can download the entire catalog as often as you like.
But this only applies to user-uploaded music. All Access tracks and radios can't profit from solution 3.
I'm not familiar with ReplayGain, does it always generate the same data for each file? Could we maintain a community version of the generated volume data (lets call it volume-data.json) for the Google library?
ReplayGain attributes should be deterministic, so if you run it with the
same settings on the same file, you should get the same results. But
you would have to be able to determine which copy of "Come on Eileen"
you were streaming to make sure you had the proper ReplayGain settings
for that particular copy. Maybe fingerprint the first 1K of the song,
and combine that with metadata such as title and artist? That might
make for a large database, but it could work.
On 5/20/2017 10:10 AM, griest024 wrote:
>
I'm not familiar with ReplayGain, does it always generate the same
data for each file? Could we maintain a community version of the
generated volume data (lets call it |volume-data.json|) for the Google
library?—
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
https://github.com/MarshallOfSound/Google-Play-Music-Desktop-Player-UNOFFICIAL-/issues/1099#issuecomment-302886176,
or mute the thread
https://github.com/notifications/unsubscribe-auth/ABFLC38ojPgtDvSr9EKRyN1tlBuZBDl8ks5r7x5ugaJpZM4IjY0T.
well the benefit of generating volume-data.json from the Google version of the song is that it should be easy to match it later when streaming because the file is identical.
I should rephrase my previous comment. If we were to have a community volume-data.json it would be hard to decide what options to use while generating it. Is it possible to generate a "master file" that holds all the data needed to satisfy all, or at least most, of the options? So each user can decide exactly how the volume normalizer uses volume-data.json.
I used to wrestle with this in my personal music collection, but then concluded the default ReplayGain settings are fine.
So I would suggest that the default settings would work well for most folks, and that the main benefit is consistency across tracks.
If there was a reason why this wouldn't work, perhaps users could have a local "adjustments" file that would let them further modify the default settings at playback time... But this would probably be total overkill.
On May 20, 2017, 12:14, at 12:14, griest024 notifications@github.com wrote:
well the benefit of generating
volume-data.jsonfrom the Google
version of the song is that it should be easy to match it later when
streaming because the file is identical.I should rephrase my previous comment. If we were to have a community
volume-data.jsonit would be hard to decide what options to use while
generating it. Is it possible to generate a "master file" that holds
all the data needed to satisfy all, or at least most, of the options?
So each user can decide exactly how the volume normalizer uses
volume-data.json.--
You are receiving this because you were mentioned.
Reply to this email directly or view it on GitHub:
https://github.com/MarshallOfSound/Google-Play-Music-Desktop-Player-UNOFFICIAL-/issues/1099#issuecomment-302892916
We have to consider that some songs are simply meant to be louder than others. Especially when you consider the larger range of audio than this feature could be applied to: spoken word etc.
From wikipedia:
ReplayGain analysis can be performed on individual tracks, so that all tracks will be of equal volume on playback. Analysis can also be performed on a per-album basis. In album-gain analysis an additional peak-value and gain-value, which will be shared by the whole album, is calculated. Using the album-gain values during playback will preserve the volume differences among tracks on an album.
On playback, listeners may decide if they want all tracks to sound equally loud or if they want all albums to sound equally loud with different tracks having different loudness. In album-gain mode, when album-gain data is missing, players should use track-gain data instead.
It looks as though ReplayGain has this covered; loudness is decided at playback, rather than at analysis. Am I understanding that correctly?
I am fine with the default settings, at least for now. The feature can always be improved later and something is better than nothing.
ReplayGain is never processed at playback because it needs to whole track at once to define a loudness value. It simply can't be used on this application unless Google implants it.
There are other techniques like auto gain staging which are used in real time mixing.
Maybe something could be done with EBU128 specifications which have real-time implementations.
How feasible is it to generate extra data so that a user could use either track or album-based normalization at playback?
EBU128 is a kinda of ReplayGain successor for broadcasting: the idea is the same, the specifics are different but the goal is to level out differences between programs on radio and TV. It is also used for live broadcasting, so I think something can be leveraged from that. Doing so would require no pre-processing and no extra metadata, however I'm pretty sure it won't sound as natural.
You are correct that, without prior information, you cannot compute a
loudness value on a stream.
However, we are discussing pre-computing the loudness value and storing
it for subsequent playback, and sharing that value between users.
I think it would be hard to do an album-based computation if we only
have data for one track at a time. I think it would be best to simply
store the computed loudness for each track, and let the player make what
adjustments the user wants based on that data.
Sad to say, but the definition of an "album" is getting more and more
hazy as time passes.
On 5/20/2017 2:51 PM, Nathan Graule wrote:
>
ReplayGain is never processed at playback because it needs to whole
track at once to define a loudness value. It simply can't be used on
this application unless Google implants it.There are other techniques like auto gain staging which are used in
real time mixing.Maybe something could be done with EBU128 specifications which have
real-time implementations.—
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
https://github.com/MarshallOfSound/Google-Play-Music-Desktop-Player-UNOFFICIAL-/issues/1099#issuecomment-302900900,
or mute the thread
https://github.com/notifications/unsubscribe-auth/ABFLC3U_nc-5VCRI6fCiYcSIhkc6GiHjks5r72BPgaJpZM4IjY0T.
The proof of concept must come first and for that, all default settings and track-based normalization is perfectly fine.
Google needs to implement this, its only adding metadata for the file, its not like the audio data itself is changed at all. And they wouldn't even have to add it as metadata, the volume data could be served through a separate API call.
This issue has been long closed already, so I don't know if anyone will see this comment, but I'm not sure where else to put this comment =P
I have an idea for an implementation. What if GPMDP maintains its own database of ReplayGain values? For a song that doesn't have a ReplayGain value, the first time you _completely_ play through that song, GDMDP could calculate the song's ReplayGain value and store it in GPMDP's database of ReplayGain values. So the first playthrough of a song would not have any normalization, but subsequent playthroughs would benefit from the ReplayGain value calculated during the first playthrough. Your music library would slowly and eventually become normalized, with the set of music you listen to most frequently becoming normalized most quickly.
I can imagine that this might be non-trivial to implement, so I would understand if the idea is rejected =P
@ceryen I suggested this earlier in this thread:
Could we maintain a community version of the generated volume data
@griest024 Sorry, I missed that you already expressed the idea of generating ReplayGain values after a track has been played through once. I would like to also say that it wouldn't bother me either that the first playthrough wouldn't have normalization.
Having a community-generated database of ReplayGain values is tricky though. The database would be fairly large since there is quite a lot of music available on Google Play Music. It would require much more infrastructure and resources from MarshallOfSound, he would need to pay for that database to be hosted somewhere. A locally generated and maintained database might be more appealing to MarshallOfSound since it wouldn't require extra infrastructure, only resources on the user's computer.
Replaygain is just 8 bit signed value (I think) so the space required is
neglible. Basically it's just "play this song, adjusted by xx dB".
On Sun, 27 Aug 2017, 03:16 ceryen, notifications@github.com wrote:
@griest024 https://github.com/griest024 Sorry, I missed that you
already expressed the idea of generating ReplayGain values after a track
has been played through once. I would like to also say that it wouldn't
bother me either that the first playthrough wouldn't have normalization.Having a community-generated database of ReplayGain values is tricky
though. The database would be fairly large since there is quite a lot of
music available on Google Play Music. It would require much more
infrastructure and resources from MarshallOfSound, he would need to pay for
that database to be hosted somewhere. A locally generated and maintained
database might be more appealing to MarshallOfSound since it wouldn't
require extra infrastructure, only resources on the user's computer.—
You are receiving this because you commented.
Reply to this email directly, view it on GitHub
https://github.com/MarshallOfSound/Google-Play-Music-Desktop-Player-UNOFFICIAL-/issues/1099#issuecomment-325172876,
or mute the thread
https://github.com/notifications/unsubscribe-auth/AAqUkHfjjWmEyAnZ37R-S0kBkqFTX-bfks5scNF3gaJpZM4IjY0T
.
An 8 bit number, and a 56 byte song fingerprint (just a guess at how
tracks are tracked, so to speak) would mean 57 bytes per song; I have no
idea how many tracks are in the Google universe, but 57 bytes * 10
million tracks is a 570MB database. That's not much.
On 8/26/2017 8:40 PM, Barleyman wrote:
Replaygain is just 8 bit signed value (I think) so the space required is
neglible. Basically it's just "play this song, adjusted by xx dB".On Sun, 27 Aug 2017, 03:16 ceryen, notifications@github.com wrote:
@griest024 https://github.com/griest024 Sorry, I missed that you
already expressed the idea of generating ReplayGain values after a track
has been played through once. I would like to also say that it wouldn't
bother me either that the first playthrough wouldn't have normalization.Having a community-generated database of ReplayGain values is tricky
though. The database would be fairly large since there is quite a lot of
music available on Google Play Music. It would require much more
infrastructure and resources from MarshallOfSound, he would need to
pay for
that database to be hosted somewhere. A locally generated and maintained
database might be more appealing to MarshallOfSound since it wouldn't
require extra infrastructure, only resources on the user's computer.—
You are receiving this because you commented.
Reply to this email directly, view it on GitHubhttps://github.com/MarshallOfSound/Google-Play-Music-Desktop-Player-UNOFFICIAL-/issues/1099#issuecomment-325172876,
or mute the thread—
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
https://github.com/MarshallOfSound/Google-Play-Music-Desktop-Player-UNOFFICIAL-/issues/1099#issuecomment-325175170,
or mute the thread
https://github.com/notifications/unsubscribe-auth/ABFLC5P5T_cnCkTRpaeT6GXCZegDqit6ks5scOUUgaJpZM4IjY0T.
I'm not sure using a song fingerprint would be possible if you have to be able to identify the song before it even starts playing. There are also 40 million songs in Google Play Music.
The size of the database was more of an ancillary point. Even if the database is not very large, it needs to be hosted somewhere that is accessible to all users and hosted in a way such that user clients can submit updates. That will have some hosting costs. There is also development costs in terms of setting that infrastructure up. It would be up to MarshallOfSound to decide whether those costs would be worth it. My only point is that a locally generated database would avoid those costs without significant detriment to the user.
Another challenge with a global database is that it can get polluted with music that people have themselves uploaded to Google Play Music. You would need to filter those user-uploaded songs out or else the database would be polluted with music that most people cannot even access.
Even if the database is not very large, it needs to be hosted somewhere that is accessible to all users and hosted in a way such that user clients can submit updates
Uh..github? LOOT does something similar.
Edit: @ceryen for the record, I think a locally generated version of the file is fine but a community version wouldn't require the song to be played through once first. As for the size issue, it could possibly get quite large but I doubt that data would end up being generated for even 10% of the play database.
GitHub does not allow files larger than 100MB to be checked in. GitHub does have GIT LFS, which will allow larger files, but with the restriction of 1GB of free storage and only 1GB of bandwidth per month.
Furthermore, using Git to store binary files is a terrible idea, it will cause your repository size to explode. To quote GitHub: "If you push a 500 MB file to Git LFS, you'll use 500 MB of your allotted storage and none of your bandwidth. If you make a 1 byte change and push the file again, you'll use another 500 MB of storage and no bandwidth, bringing your total usage for these two pushes to 1 GB of storage and zero bandwidth."
LOOT does something similar.
Their file is 788KB, nowhere near the same magnitude in size.
Furthermore, using Git to store binary files is a terrible idea
I thought ReplayGain can store data in json format (at least mp3gain can).
GitHub does not allow files larger than 100MB to be checked in.
Fair enough, use gitlab.
I thought ReplayGain stores data in json format.
Then you're talking about more than 8 bits per song for ReplayGain, although I don't see why GPMDP would need to store things in JSON, it could just store the bare value.
But fair enough, let's say the file is text rather than binary.
Fair enough, use gitlab.
If you do store the database in GitHub/GitLab, what is the plan for receiving updates from users? Make them register GitHub/GitLab accounts and submit pull requests? Seems more annoying than just adjusting the playback volume by hand.
Replaygain is just a value in the mp3 headers, if you wanted to make your
own database you could obviously use whatever format you wanted. Bare
minimum is a 8 bit signed integer plus another 8 bit fraction value. In the
tags it's probably a text string so something like 5 characters including
the sign and the dot.
If you actually get some kind of song ID (32bit? 64?) from Google play
music, you already have everything you need. You want to have an actual
online database so you can just query changes.
I think from earlier discussion you don't actually have access to much,
desktop player is not an actual player so it does not know about the song
volume.. So a simple exercise becomes much more convoluted as you'd have to
intercept the player audio stream and adjust/analyze it on the fly.
On Sun, 27 Aug 2017, 12:53 ceryen, notifications@github.com wrote:
I thought ReplayGain stores data in json format.
Then you're talking about way, way more than 8 bits per song for ReplayGain
Fair enough, use gitlab.
GitLab has a 10GB repository size limit. If you check in a 500 MB file
just 20 times, you're out of space.If you do store the database in GitHub/GitLab, what is the plan for
receiving updates from users? Make them register GitHub/GitLab accounts and
submit pull requests? Seems more annoying than just adjusting the playback
volume by hand.—
You are receiving this because you commented.
Reply to this email directly, view it on GitHub
https://github.com/MarshallOfSound/Google-Play-Music-Desktop-Player-UNOFFICIAL-/issues/1099#issuecomment-325193656,
or mute the thread
https://github.com/notifications/unsubscribe-auth/AAqUkF_9me2BIKbVjRpHhcJoMgHOk9Anks5scVijgaJpZM4IjY0T
.
So a simple exercise becomes much more convoluted as you'd have to
intercept the player audio stream and adjust/analyze it on the fly.
It seems like adjusting the volume wouldn't be too difficult, but getting enough data to actually do a replaygain analysis might be tricky; it would probably require writing our own implementation of replaygain.
Google Play Music and Android Auto is a match made in Heaven.
But it appears Google sometimes uses it's own library files and sometimes the file I uploaded.
Because of volume variations, I deleted all my Google Play Music personal library uploads, and ran Replay Gain on all my files, then uploaded them again (yes, it took a LONG time).
I can play an album and my preset replay gain set volume of -10dBFS plays fine (I like to leave a bit of headroom as playback sounds better on lower quality DACs). Then the occasional 0dBFS track plays - which must be from Google's own copy of the file. Blasting through the only ear drums I have and will ever have. Or worse, a file someone else compressed to +-0dB dynamic range and uploaded at 0dbFS (it'll be like some 20dB louder).
Arrrrrrrrrr!!
If I can Replay Gain all my files on my crap home PC, Google you can automatically do so for anything being uploaded. And reduce space by 'sharing' files so only 1 copy of a file need be on your servers. A simple switch to have tracks replayed in Track mode or Album mode is all it takes to keep audiophile purists happy. And hey, while you are at it, have an option to playback the file in full dynamic range or compressed as some listeners like it. Hey, a $30 DVD player from a supermarket has the ability (some call it Night mode and Normal mode), and Google Play doesn't??
Common Google, you can do better than this. Do it NOW!
Just because you can do it doesn't mean that Google wants to, or even
legally can.
YouTube does normalize to -14 dBFS (check in the "stats for nerds" panel),
so it seems YouTube Music will have ReplayGain or at least some form of
normalization. And with Play Music being discontinued in the relatively far
future, all that remains will be normalized audio.
--
Nathan Graule
+33 6 79 58 29 83
Nice. But not everyone can cannot afford to pay for YouTube Music without adverts.
If Google can legally play a track on my Google Play Music downloads that is clearly not the track I uploaded, they can offer the option to use the ReplayGain metadata already in the files we uploaded.
Most helpful comment
@MarshallOfSound Using a compressor is nowhere near normalization. Proper normalization would mean looking through the whole file, detecting the highest peak, and setting it to 0 dBFS. A compressor however, looks through a timeframe, usually through a moving average, and ducks volume past a certain threshold.
As an electronic music producer, I know my way around compressors and limiters, and using a compressor isn't the way to go here. The attack and release parameters would need to be handpicked for each song manually to not completely destroy the track's dynamics, and even then it could still lead to compression artifacts (hearing the sound "pump" on sudden loud noises, for example).
That being said, I do not know what kind of algorithm Chrominium uses for its dynamics compressor, and there are transparent compressing and RMS-triggered algorithms, which greatly help with the artifacts, however there is still the need to tweak the attack and release values for each song.
ReplayGain would be the nice implementation, however it requires analyzing each file to determine its loudness and change the volume according to that. So, it falls back to Google's responsibility to implement such a feature.