(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

We use bms-renderer to render songs into WAV format. We use wavegain to analyze the loudness of each song. 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 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

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.

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!

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*} $$

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.