Edited at

A study of loudness in BMS files

More than 3 years have passed since last update.

A study of loudness in BMS files

(Re;gats& さんからの日本語訳はこちらです。本当にありがとうございました!

https://www.dropbox.com/s/s8hc8hw9ausqdqc/BMSの音の大きさに関する研究.docx?dl=0)

Hi! In this article, I analyzed 67 BMS files from the GENOSIDE BMS Starter Package to determine the trends in the loudness of songs, in terms of ReplayGain value. The resulting ReplayGain value, on average, is at -12.2 dB. By measuring your BMS’s loudness, and applying gain to your keysound files, so that the ReplayGain value is -12.2 dB, you can make your BMS sound as loud as most other songs in this study. Instructions for bms-renderer (Mac / Unix) and for BMX2WAV are also provided in this article.


Introduction

BMS files are mostly created by the community. Novice, amateur, experts and professionals alike can all create BMS files, and share them with the community. As a result, differences in song loudness arise. Some songs are very quiet, while some songs are very loud.

This article studies about the loudness of songs found in a sample of BMS files, specifically, those found in the GENOSIDE BMS Starter Package.

The results from this study may be used in various applications, for example:


  • BMS players can automatically analyze BMS files to normalize the loudness of every song, so that we can end the loudness war.

  • BMS authors can perform analysis on their own BMS songs, and adjust their songs so that that they are as loud as others.


Overview


  1. We use bms-renderer to render songs into WAV format.

  2. We use wavegain to analyze the loudness of each song.

  3. We analyze the results.

Screen Shot 2015-09-15 at 23.10.01.png


BMS → WAV Rendering

There are existing tools that converts BMS to WAV. Lunatic Rave 2 has a feature to convert BMS to MP3. BMX2WAV also exists, and is the most popular tool to do this.

However, it only supports Windows (I use a Mac). Also, they outputs as 16-bit WAV files. In 16-bit files, the sound is limited at 0 dBFS. Therefore, it is necessary to normalize the volume to avoid clipping. The original loudness information is lost.

Rendering to a 32-bit float format is more desirable because there are no clipping in these kind of files. The original loudness is preserved.

bms-renderer is a small command-line script that renders BMS files into 32-bit floating-point WAV format (less than 200 lines of code as of writing). It is written in JavaScript, leveraging the Node.js platform. It uses bms-js (the same engine used in Bemuse) to parse BMS files and libsndfile to read and write wave files. Communication between JavaScript code and libsndfile is done through the node-ffi module.

I used bms-renderer to render the BMS files in this study, but it is also possible to use BMX2WAV. I added the instructions further below.


※ Note that while 32-bit float file format doesn’t have clipping problem (samples are not limited to [-1, 1] range), you may hear clipping when you try to play that file because of the limit in your DAC.



ReplayGain

ReplayGain is a standard to normalize loudness of songs (similar to Apple’s sound check).

It measures the perceived loudness of a song. It then calculate the volume (gain) adjustment that needs to be applied to the song when it is played, so that every song plays at the same volume. This is called the “replay gain value.”

wavegain is a command-line tool that analyzes ReplayGain for wave files.


The Experiment


Songs Used

I used the songs from the GENOSIDE BMS Starter Package as input data for analysis. I select one BMS file from each song.

However, bms-renderer only supports keysound files that have a sample rate of 44,100 and have 2 channels. If a song contains a keysound file that does not meet this criteria, then it cannot be rendered.

In the end, these 67 BMS files are used in this study.

#
Folder
File

1.
[ABE3]Ereshkigal_N
ereshkigal_A7.bme

2.
[anubasu-anubasu]TIOA
0.tioa_7a.bms

3.
[BACO]Love&justice
_03_flonne_spa.bml

4.
[celas]crystal-world_r
_crystal-world_r_7a.bme

5.
[csp]hujin_raijin
hujin_a.bme

6.
[daisan]Polis_Ruin
PR_A.bml

7.
[DCF]disco the ground
Disco the ground(A).bms

8.
[est]angelic_snow
as_a7.bme

9.
[ETIA.]Love_Blood
_3_spa.bme

10.
[ETIA.]wudaohongye
_73.bme

11.
[FALL]cosmowanderer
_cosmowanderer.bml

12.
[FALL]stillaliveinlove
_still.bml

13.
[gmtn.(witch's slave)]furioso_melodia
_carage_furioso_melodia[7another].bme

14.
[gmtn.]solitary_melody_remix
_carage_solitary_melody_remix_7another.bme

15.
[Grandthaw]ERIS
ERIS[A].bms

16.
[Grandthaw]Flesvelka
flesvelka[A].bms

17.
[Hate]duty
duty_sp03.bme

18.
[HatexRitsuxSalita]YRKG
YRKG_0710_SPA.bme

19.
[I-sm]MooN
_38_13.bme

20.
[incinerate]Purgatorium
rengoku[ANOTHER].bme

21.
[Junk]elegante
03_another.bme

22.
[Junk]Ling_Child
03_another.bme

23.
[Junk]Once_in_my_life
01_another.bme

24.
[kanone]Cross_Galaxy
crossgalaxy_A.bms

25.
[kaomirin]DoS_Maid
_DoS_Maid_03_another7.bml

26.
[klamnop]lights
_prog_a.bme

27.
[knot]cold_planet
another.bms

28.
[Kucchi]yakumo
yakumo_a.bms

29.
[Lime]Ophelia
_ophelia_another7.bme

30.
[Lime]sambaland
_sambaland_7normal.bme

31.
[Lime]stargazer
lime_stargazer_7h.bme

32.
[luze]dtd_emperor
dtd_emperor_a_bga.bme

33.
[maki]yumenikki
subcons_a7.bme

34.
[nekomirin]Durandal_radioedit
_durandal_radio_02_hyper7.bme

35.
[nmk]Childie
_A.bms

36.
[nmk]Serenade
_A.bms

37.
[nora2r]Newworld
_newworld_spa.bme

38.
[Omnipotenx]PEACE_BREAKER
_pb_A.bme

39.
[Orange_Strophe]neps_paradox
neps_7_3.bme

40.
[orgt]DestinySalmon_stage1
_stage1_a.bme

41.
[Papyrus]Papyrus
papy_a.bml

42.
[PLight]poppin'_shower
ps_another.bme

43.
[Queen P.A.L.]JULIAN
_13 [ HARD 7 ] JULIAN.bme

44.
[Ras]PrayStation
PrayStation_7a.bme

45.
[rider]freja
03_freja_another.bms

46.
[rilym]Black_Rainbow
03-Black_Rainbow-7A.bms

47.
[ruby.g]candy_n_baguette
sp_cnb_3_span.bml

48.
[sa10]banana_man
_7ka.bme

49.
[sakuzyo]Axion
axion_A.bms

50.
[sakuzyo]Black_Lair
Black_Lair_A.bms

51.
[sakuzyo]Vallista
vallista_another.bms

52.
[sany-on]minimal_satorin
20100121_703_hard.bml

53.
[Shiraishi]sinSQ
_sinSQ_A.bms

54.
[siromaru+cranky]conflict
_03_conflict.bme

55.
[sun3 vs EXCALIpUR BGA-Johnny]Cross breed
crossbreed(ANOTHER7).bme

56.
[sun3]Messier_333
Messier 333(ANOTHER7).bme

57.
[void]Name of oath
[[24]]Name of oath[SPA].bml

58.
[void]zenithalize
+074 ZENITHALIZE [SPA].bme

59.
[void_feat.Salita]Act_Beloved
__spa.bme

60.
[wa.]morion
_morion_7a.bme

61.
[xenothium]nutstoyou
_nutstoyou_7a.bms

62.
[xi]ascension_to_heaven
ath_A.bme

63.
[xi]freedom_dive
dive_h7.bme

64.
[xi]halcyon
_hal_A.bml

65.
[xi]parousia
_parousia_A.bme

66.
[Ym1024_feat.lamie]rePrayer
rePrayer_[7-A_Another].bme

67.
[Ym1024_feat.lamie]started
start_[7-9_Another].bme


Finding ReplayGain

The command:

wavegain -nc *.wav

analyzes all the .wav files and prints a report. The results can be viewed here.


Results


ReplayGain

Screen Shot 2015-09-16 at 0.23.41.png

In this chart, you can see the trends in the amount of gain to be applied to the music file.

According to the ReplayGain 1.0 Specification, the ReplayGain algorithm will calculate the amount of gain that needs to be applied, so that its perceived loudness matches the loudness of pink noise at -14 dBFS. In other words, it will adjust the volume so that each song has about 14 dB of headroom.

This means that the lower is the ReplayGain value, the louder is the song. On average, the songs received a ReplayGain value of -12dB.


Peak Volume

Screen Shot 2015-09-16 at 0.24.10.png

As can be seen in the chart above, every song here has the peak level of more than 160%, at an average of 240%. Playing at full volume, there will be a lot of clipping.

From this chart, it seemed evident, that we don’t need to worry too much whether the BMS will sound too loud.


Note: This does not mean that they don’t clip: they do, but most of them still sound quite good.



Application: Adjusting loudness in your BMS song

When I participated in 第12回自称無名BMS作家が物申す!, I received a comment on the BMS entry 「Exargon」 that the BMS version does not sound as intense as it should be.

Although this event is over, let’s try to fix it as an example for future BMS work. First, I need to find the ReplayGain value of this song.

First, I rendered the BMS file into a wave file.

$ bms-renderer exargon_7another.bms exargon_render.wav

Next, I ran WaveGain on the BMS file.

$ wavegain -nc exargon_render.wav

Analyzing...

Gain | Peak | Scale | New Peak |Left DC|Right DC| Track
| | | |Offset | Offset |
--------------------------------------------------------------
-6.41 dB | 66036 | 0.48 | 31570 | -51 | -61 | exargon_render.wav

Notice the gain correction of -6.41 dB.

Even the quietest song in GENOSIDE package had a ReplayGain of -8.02 dB. This means that this song is really, really quiet!

To make it as loud as the other songs, we find the amount of gain that needs to be applied so that it matches the average value (-12.2 dB).

$$ \begin{align*} -6.41\text{ dB} - (\text{extra gain}) & = -12.2\text{ dB} \\ \text{extra gain} & = -6.41\text{ dB} + 12.2\text{ dB} \\ & = +5.79\text{ dB} \end{align*} $$

This means we need to apply 5.79 dB of amplification to every keysound to make it as loud as most songs.

How to do this depends on which audio editing program you use. As for me, I use SoX to apply this gain adjustment to every file at once:

$ for I in *.ogg

do
sox "$I" "../exargon_louder/$I" gain 5.79
done


Warning: Be aware of clipping and audio distortion! For certain kind of songs and instruments, some clipping is fine. But for songs with lots of heavy kick drums and bass, clipping sounds very bad (unless intentional). Always test within a BMS player, and use your ears to judge, not these numbers! :smile:



Appendix: Instructions on Windows using BMX2WAV

You can also use BMX2WAV to render your BMS, and afterwards find the ReplayGain of your BMS song.

In the conversion settings, enable the option 「WAV が鳴り終わる前に同じ WAV が鳴った場合、前の WAV を消す」 to closely match the behavior of multiplex WAV definition as implemented in most BMS players.

01_ConvertOptions.PNG

In the audio settings, set normalize to “Peak Normalization”

02_Normalize.PNG

Convert your BMS file using BMX2WAV. Take note of the amplification scale (0.496192).

03_BMX2Wav_Result.PNG

Use WaveGain to find the ReplayGain of your wave file. You can download Windows Version of WaveGain from RareWares.org

04_WaveGain.PNG

Here, the ReplayGain is -0.43 dB. Take note of it.

Next, find the amount of volume adjustment applied during the normalization in BMX2WAV using this formula:

$$ \begin{align*} \text{gain in dB} = 20 \log_{10} k \end{align*} $$

Where $k$ is the value from BMX2WAV. In this example:

$$ \begin{align*} \text{gain in dB} & = 20 \log_{10} (0.496192) \\ & = -6.087005 \text{ dB} \end{align*} $$

Finally, add in the value from WaveGain to obtain the actual ReplayGain:

$$ (-6.09\text{ dB}) + (-0.43\text{ dB}) = (-6.52\text{ dB}) $$

The resulting number obtained from files rendered using BMX2WAV (-6.52 dB) is very close to that obtained by bms-renderer (-6.41 dB). I have tested this with few other BMS files and the results are also very close.

To make it as loud as the other songs, we find the amount of gain that needs to be applied so that it matches the average value (-12.2 dB).

$$ \begin{align*} -6.52\text{ dB} - (\text{extra gain}) & = -12.2\text{ dB} \\ \text{extra gain} & = -6.52\text{ dB} + 12.2\text{ dB} \\ & = +5.68\text{ dB} \end{align*} $$

This means we need to apply 5.68 dB of amplification to every keysound to make it as loud as most songs.

To convert decibel value to amplification factor, use this formula:

$$ \text{amplification factor} = 10^{\left(\frac{\text{gain}}{20}\right)} $$

For example:

$$ \text{amplification factor} = 10^{\left(\frac{+5.68}{20}\right)} = 10^{0.284} = 1.923 $$

This means you have to amplify by 1.923x to make your song loudness match the average loudness of songs in this study.


Conclusions

This article presented a survey of the 67 BMS files and found that they are VERY LOUD. Sound clipping is not much problematic, and we found that some songs even reached a peak volume of 490%.

The methods I presented in this article is quite more complicated to do on Windows systems than on Mac/Linux systems. It would be really cool if someone could build a tool that works on Windows.

I hope that this article would be useful to BMS authors and creators of other BMS players.


About Me

I am flicknote. I am the creator of Bemuse, a BMS simulator that runs in your browser.