# A study of loudness in BMS files

More than 1 year has passed since last update.

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

## 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
35. [nmk]Childie _A.bms
37. [nora2r]Newworld _newworld_spa.bme
38. [Omnipotenx]PEACE_BREAKER _pb_A.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

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

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.

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! ## 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. In the audio settings, set normalize to “Peak Normalization” Convert your BMS file using BMX2WAV. Take note of the amplification scale (0.496192). Use WaveGain to find the ReplayGain of your wave file. You can download Windows Version of WaveGain from RareWares.org 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*} Wherek\$ 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.