Logo

How to best handle Offset and BPM in official simfiles?

Register Log In Back To Forums

Post #1 · Posted at 2015-06-08 01:25:39pm 8.8 years ago

Offline dbk2
dbk2 Avatar Member
332 Posts
Not Set
Reg. 2012-04-30


Last updated: 2015-07-07 03:10am
Hi everyone,

I don't normally venture outside the Simulation Discussion subforum, but I have some questions pertaining to "official" simfiles as they are made for StepMania. I'm going to use Possession from DDR X2 to illustrate the topic at hand, but I can assure you that this issue is endemic with official simfiles curated here at Z-i-V.

- - - - - - - - - - - - - - - - - -

Regarding #BPMs and #OFFSET

If a user downloads Possession from DDR X2 today, the .sm and .ssc files will contain the following values for the BPMs tag.

Quote: "Possession.ssc"
#BPMS:
0.000=371.134,
5.000=369.978,
137.000=185.013,
168.000=370.061,
296.000=184.886,
324.000=183.673,
325.000=369.969;

If you are not familiar with the format, it follows a pattern of:

(measure number)=(BPM)

Note that the very first BPM established, at beat 0, is 371.134
The data then goes back and forth between values close to, but not quite, 370 and 185 for the remainder of the song.

In the comments section for the simfile page, you can find:

Quote: "Other Information: Comments"
Audio, jacket & sm files: Official data.

What is Official data? I am left to assume the interpretation that the values were extracted from a data-dump of arcade software. Can anyone actually confirm this to be true?

I personally find it hard to believe that those are the BPM values used. Why not integers? And why start with 371.134, when the song is advertised to be 185-370? I suspect this is simply error introduced by the individual who transcribed the steps.

Going on that hunch, I investigated further by converting the Possession.ogg to uncompressed WAV using Audacity, and then importing that into Logic, my DAW of choice. I trimmed off the appropriate quantity of silence from the start of the file so that the first beat of the song lined up with measure #2 in Logic's waveform editor:

http://i.imgur.com/7aBH5qpl.png

Lining up the waveform at the level of zoom shown above should yield accuracy within ~10µs if Apple's software is to be trusted.

From there, I set the project BPM to 185.000 and scrolled to the end of the song (the last visibly clean beat, actually, which took place at measure 81) and found, curiously, that it didn't quite line up. With some fine-tuning, I was able to get beat 81 to line up with the measure tick:

http://i.imgur.com/MvvZQ68l.png

The BPM I finally settled on was 184.9979. For the sake of StepMania, then, the values I would personally recommend with the existing song file are:

Quote: "Possession.ssc according to the song"
#BPMS:
0.000=369.9958,
137.000=184.9979,
168.000=369.9958,
296.000=184.9979,
325.000=369.9958;

But, to be honest, I find non-integer BPM values like this to be highly suspect and more likely the result of a poor audio rip or bad transcoding. If anyone has Possession in a lossless or high-quality format (flac, 320 mp3, etc.), I would be curious to do a comparison.

- - - - - - - - - - - - - - - - - -

Summary of what I found:

1. Setting the simfile's #OFFSET value to 0.000 when the music file's actual offset isn't 0 is incorrect. Doing so leads to bizarre workarounds like temporarily setting a faster/slower BPM at beat 0 and changing it sometime before the first step occurs.
2. The BPM values in the .sm/.ssc files here do not necessarily reflect the BPMs found in the song files.
3. It is possible that the existing song files here contain drift or other errors not intended.


Resulting questions:

1. What is "official data" and how is information (BPMs, offset, etc.) for StepMania purposes derived from it?
2. If "official data" is indeed some sort of arcade data-dump, are the values truly as found in Z-i-V's various official simfiles?
3. If the answer to question #2 is "yes," is it worth retaining these artifacts for the purposes of StepMania emulation?

This is not how StepMania was designed to be used. I can attest that the #OFFSET value exists for people who don't want to cut their song file to actually have an offset of precisely 0. Furthermore, the correct BPMs of the provided song files are very frequently not what the corresponding .sm/.ssc files specify.

- - - - - - - - - - - - - - - - - -

I'm not sure if a standard Z-i-V policy exists for handling this sort of issue for the sake of consistency. If not, I suggest that one should be enacted. Smile

Cheers,
dbk2

Post #2 · Posted at 2015-06-08 03:25:25pm 8.8 years ago

Offline razorblade
razorblade Avatar Member
1,099 Posts
Not Set
Reg. 2011-03-01


Last updated: 2015-06-08 03:37pm
Usually, the first measure isn't always the same length as the other measures next to it, so the starting bpm seems to be weird. You don't actually need to convert ogg to other lossless format because ogg is already enough to view their exact waveforms. Although their quality is considered a lossy format like mp3, their song offset remain intact after conversion from raw file unlike mp3s.

I'm in behind of these official DDR AC simfile updates and I think you gotta ask Saxxonspike about it since he's the only creator of bemani2sm program I used to produce sm files from raw ssq files and wav from raw xwb files. It is packaged in his Scharfrichter tools.

All oggs and sm files were produced directly from their raw files and didn't made any alteration to the output other than supplying all required metadatas and step difficulties.

I just noticed that the #BPMs beat number between sm and ssc files are different. The sm file is the legit one.

Here is the bm2sm program I used (it's my custom build from Saxxonspike's original one) and I included a raw ssq and xwb files for POSSESSION (source from DDR 2013 AC data, since songs are separated now unlike in before DDR 2013 where they were combined as a group inside an xwb) . After you extracted all contents, drag the ssq and xwb files to the exe and supply the required infos. Open the output sm and a new folder and you'll see the contents inside.

----> download link here <----

EDIT: I updated the bm2sm link to include a raw xwb audio file for POSSESSION for you to check.

I hope this will answer your questions now.

Post #3 · Posted at 2015-06-08 07:58:05pm 8.8 years ago

Offline hooky
hooky Avatar Member
2,683 Posts
United States
Reg. 2007-07-28

If you put these lines of code in an SM5 theme:

MinSecondsToStep=2
MinSecondsToMusic=0


then the simfiles will start as soon as they do in DDR. MinSecondsToStep=2 is to prevent user/beta simfiles that have the first step on the first bar from starting as soon as ScreenGameplay starts. Just imagine if Over the "Period" did that... *shudders*

So I guess in DDR, ScreenGameplay always starts at beat 0.

Post #4 · Posted at 2015-06-08 08:49:44pm 8.8 years ago

Offline dbk2
dbk2 Avatar Member
332 Posts
Not Set
Reg. 2012-04-30


Last updated: 2015-06-08 09:18pm
Thank you for the helpful response, razorblade.

I was able to export a .wav file using the utility you linked to, and I spent some time analyzing it in Logic. I noticed immediately that the waveform was much cleaner and more well-defined in this file than in Z-i-V's ogg file.

- - - - - - - - - - - - - - - - - -

In my post above, I had hypothesized that the ogg file from Z-i-V contained drift or other, similar errors not found in the source audio.
Quote
3. It is possible that the existing song files here contain drift or other errors not intended.

I have concluded that this was an incorrect hypothesis on my part. I cut + aligned the new .wav file using the same procedure described above and ultimately arrived at the same BPM, 184.9979.

- - - - - - - - - - - - - - - - - -
Possession as currently provided by Z-i-V


With that out of the way, I then wanted to see how accurate the provided BPM values were in keeping the waveform aligned with the measure ticks. As I mentioned in my original post, the BPM changes found in Z-i-V's .sm file look like this:

Quote: "Possession.sm"
#BPMS:
0.000=371.134,
5.000=369.978,
137.000=185.013,
168.000=370.061,
296.000=184.886,
324.000=183.673,
325.000=369.969;

I implemented these BPM changes in Logic using the original .wav file (not trimmed at the start) with 0 offset applied.



I made (tried to make) some diagrams to illustrate what I found by marking up screenshots too include the discrepancies I found between where the arrows would be (a particular measure) and where the waveform actually was.

Note that you won't be able to get the same numbers I found just by looking at a single screenshot (I was too lazy to mark up so many screenshots), so you'll have to trust the numbers I got.

This is the beginning of Possession, as found on Z-i-V:
http://i.imgur.com/kpuCPw9l.png

This is the ending of Possession, as found on Z-i-V:
http://i.imgur.com/UpXi5Kul.png

So, the steps begin 8ms early and finish 12ms late, which means that they gradually shift a total of 20ms over the duration of the song. This sort of sync issue is definitely noticeable when playing StepMania with good hardware. I would care less about it, but making it drift this much via erratic BPM values seems like more effort than just assuming integer BPMs. (Also, I really like the song and find it a shame that it drifts like this.)

- - - - - - - - - - - - - - - - - -
Possession with Integer BPMs

So, what happens if we just assume that the BPMs are integers, then?

Well, we can line up the starting measure with the start of the music quite cleanly.
http://i.imgur.com/i4GKJ6bl.png

And, by the end, the steps have become 3ms early. Not perfect, but certainly better.
http://i.imgur.com/QxFXjJil.png

- - - - - - - - - - - - - - - - - -

Result Summary

This is what Z-i-V currently provides:
Quote: "20ms drift"
#BPMS:
0.000=371.134,
5.000=369.978,
137.000=185.013,
168.000=370.061,
296.000=184.886,
324.000=183.673,
325.000=369.969;

This would have been easier, more straightforward, and an improvement for sync:
Quote: "3ms drift"
#BPMS:
0.000=370,
137.000=185,
168.000=370,
296.000=185,
325.000=370;

And this is as close to perfect as I could manually find:
Quote: "0ms drift"
#BPMS:
0.000=369.9958,
137.000=184.9979,
168.000=369.9958,
296.000=184.9979,
325.000=369.9958;

- - - - - - - - - - - - - - - - - -

I need to take a break from writing + making diagrams + staring at waveform, but I'll try to collect my thoughts more later and follow up with some recommendations. Feel free to discuss in the meantime.

Post #5 · Posted at 2015-06-08 09:09:54pm 8.8 years ago

Offline razorblade
razorblade Avatar Member
1,099 Posts
Not Set
Reg. 2011-03-01


Last updated: 2015-06-08 09:43pm
Quote: dbk2
This is what Z-i-V currently provides:
Quote: "20ms drift"
#BPMS:
0.000=371.134,
5.000=369.978,
137.000=185.013,
168.000=370.061,
296.000=184.886,
324.000=183.673,
325.000=369.969;

I dunno where you got this and used as a basis which is obviously has noticeable drift. Yours is one beat advance every bpm change. Correction, the official data is actually:

Quote
#BPMS:
0=371.134,
4=369.978,
136=185.013,
167=370.061,
295=184.886,
323=183.673,
324=369.969;

Notice the difference in their beat number. I told it earlier:

Quote: razorblade

I just noticed that the #BPMs beat number between sm and ssc files are different. The sm file is the legit one.

Post #6 · Posted at 2015-06-08 09:12:46pm 8.8 years ago

Offline hooky
hooky Avatar Member
2,683 Posts
United States
Reg. 2007-07-28

There aren't even any SSCs in the official files I'm pretty sure.

Post #7 · Posted at 2015-06-08 09:14:13pm 8.8 years ago

Offline razorblade
razorblade Avatar Member
1,099 Posts
Not Set
Reg. 2011-03-01

Yeah, and I never added one eversince.

Post #8 · Posted at 2015-06-09 12:10:18am 8.8 years ago

Offline dbk2
dbk2 Avatar Member
332 Posts
Not Set
Reg. 2012-04-30

Quote: razorblade

I dunno where you got this and used as a basis which is obviously has noticeable drift. Yours is one beat advance every bpm change. Correction, the official data is actually:

Quote
#BPMS:
0=371.134,
4=369.978,
136=185.013,
167=370.061,
295=184.886,
323=183.673,
324=369.969;

Notice the difference in their beat number. I told it earlier:

Quote: razorblade

I just noticed that the #BPMs beat number between sm and ssc files are different. The sm file is the legit one.

I apologize for not understanding you earlier. You bring up an interesting point.

I'm not sure where my Possession.ssc file came from. Perhaps it is from a beta version of Possession from Z-i-V. Regardless, thank you for pointing out my mistake there; I will certainly own up to it.

I should also apologize for not being more clear in my second post.

The measure number ticks in Logic will not match 1:1 with the measure markers in StepMania due to the chart's two stops. Where StepMaina's measure counter literally stops for a moment and then continues, Logic continues counting measures, and the two become off. Complicating matters further, StepMania starts at beat 0 while Logic starts at beat 1.

It's messy and ultimately unimportant, as I'll get to..

- - - - - - - - - - - - - - - - - - - - - - - -
It's still the same song
Using an unaltered .wav file + the correct BPM values you linked to, I double- and then triple-checked the results in Logic.

The initial offset issue remains (steps start 8ms ahead of the music) and the song+chart still drift ~20ms from there by the end of the song.

- - - - - - - - - - - - - - - - - - - - - - - -
The stops don't add up

Also worth pointing out, the two stops in the .sm file don't make sense, mathematically.

While I generally recommend using StepMania's "Convert Selection to Stop" feature to handle the math for you, the calculation isn't too bad.

A stop lasting n beats = (( 60 / CurrentBPM ) * n)

If I use the BPM provided in Z-i-V's .sm file to calculate the appropriate length of the first stop (2 beats)

((60 / 370.061) * 2) ~= 0.324270

The .sm file sets the stop to 0.327, however, which would introduce ~3ms drift. The second stop is similarly strange, introducing ~12ms drift given the BPM when it occurs.

To summarize, even if we accept the kind-of-wonky BPMs provided by BemaniToSM.exe as truth, the stops don't make sense.

- - - - - - - - - - - - - - - - - - - - - - - -
Summary

Anyway.

Sadly, this all adds up to tell us that the music file provided by Z-i-V and the .sm file provided by Z-i-V for Possession still factually have sync issues. If this was by design on Konami's part and truly part of the arcade data, so be it. I can still reliably demonstrate that the steps start ~8ms ahead of the music and finish ~12ms behind it.

- - - - - - - - - - - - - - - - - - - - - - - -
Thoughts

I personally do not feel, in my rhythm gamer heart, that knowingly maintaining such error for the sake of "accurate emulation" sticks with the spirit of rhythm gaming. I would opt to have on-sync charts and music, as hopefully intended.

Discuss if you want to. I'll get back to SM5 theming, albeit slightly discouraged.

Post #9 · Posted at 2015-06-09 08:02:33am 8.8 years ago

Offline Arcorann
Arcorann Avatar Member
59 Posts
Not Set
Reg. 2015-01-29


Last updated: 2015-06-09 09:04am
I've read the SSQ file and the corresponding code, and I think I have a rough idea of what's going on in the file. Basically, the BPM data is stored as a list of tick counts, followed by a list of times, in units of 1/150 second. Specifically, the header looks like this:

Quote

5C 00 00 00 // length of data = 92 bytes
01 00 96 00 // 0x01 = timing block; 0x96 = 150 = time unit frequency in Hz
0A 00 00 00 // 0x0A = 10 = number of timing points
00 00 00 00
00 10 00 00 // 0x001000 = 4 beats - offset-related?
00 20 02 00 // 0x022000 = 136 beats
00 9C 02 00 // 0x029C00 = 167 beats
00 9C 02 00 // 0x029C00 = 167 beats
00 9C 04 00 // 0x049C00 = 295 beats
00 0C 05 00 // 0x050C00 = 323 beats
00 0C 05 00 // 0x050C00 = 323 beats
00 10 05 00 // 0x051000 = 324 beats
00 90 09 00 // 0x099000 = 612 beats
00 00 00 00
61 00 00 00 // 0x0061 = 97 ticks = 0.647 seconds - offset-related?
EC 0C 00 00 // 0x0CEC = 3308 ticks = 22.053 seconds
D0 12 00 00 // 0x12D0 = 4816 ticks = 32.107
01 13 00 00 // 0x1301 = 4865 ticks = 32.433
2A 1F 00 00 // 0x1F2A = 7978 ticks = 53.187
7D 24 00 00 // 0x247D = 9341 ticks = 62.273
0E 25 00 00 // 0x250E = 9486 ticks = 63.240
3F 25 00 00 // 0x253F = 9535 ticks = 63.567
9D 40 00 00 // 0x409D = 16541 ticks = 110.273 seconds

I suspect that the conversion program may be misinterpreting the first few entries (the one that are related to the lead-in time and the offset) - it shouldn't be too hard to rewrite the code. Apart from that, if synced correctly there shouldn't be more than 3ms error at any point in either direction. I have yet to double-check the times, mind.

Post #10 · Posted at 2015-06-10 02:20:25pm 8.8 years ago

Offline dbk2
dbk2 Avatar Member
332 Posts
Not Set
Reg. 2012-04-30

I have heard that DDR (and all Bemani games, I think?) handle timing via frames. I'm (very) curious as to where the 150Hz value comes from. I've never heard of any display outputting at 150hz.

Thank you for looking into the matter. Please let us know if you find anything more!

Post #11 · Posted at 2015-06-11 08:57:02am 8.8 years ago

Offline Arcorann
Arcorann Avatar Member
59 Posts
Not Set
Reg. 2015-01-29

Did some more investigation by comparing Training Mode charts with the .sm files and it seems that, as I suspected, the second timing point corresponds to HERE WE GO appearing, and as we know the point where HERE WE GO appears is the actual point of the offset.

And so, all those people who complained about it back here seem to be at least partially vindicated - the songs don't actually have zero offset at all. The other half is whether the BPM changes caused by rounding are "real", which should be confirmed by checking the CHAOS value of a song with lots of BPM changes - say, deltaMAX?

Post #12 · Posted at 2015-06-14 04:25:14am 8.7 years ago

Offline Kyzentun
Kyzentun Avatar Member
3,209 Posts
United States
Reg. 2008-02-20

"I'm honestly pissed off."
The BPM values in the simfile for deltaMAX actually convey everything anybody needs to know about ZIV's policy on sync errors.
deltaMAX is well known to have been created with the specific gimmick of starting out at 100 bpm and increasing by 1 bpm every beat. So here's a snippet from the bpm list in the official simfile on ZIV:
Quote
98=180,
101=183.673,
105=187.5,
106=183.673,
107=191.489,
108=187.5,
109=191.489,
110=187.5,
111=195.652,
112=191.489,
113=195.652,
114=191.489,
115=195.652,
116=200,
117=195.652,
118=200,

That should close any discussion about fixing sync errors in ZIV's official simfiles.
silenttype01: Kyzentun is never harsh. He says it how it is.

GENERATION 24: The first time you see this, copy it into your sig on any forum and add 1 to the generation. Social experiment.

Post #13 · Posted at 2015-07-04 02:41:55pm 8.7 years ago

Offline Arcorann
Arcorann Avatar Member
59 Posts
Not Set
Reg. 2015-01-29

Back, apologies for necropost.

Firstly, I went and checked the Chaos values for deltaMAX (CSP):

Official Chaos value: 100

Irregularity value: 1144
Song length (HERE WE GO to CLEARED): ~120 s

Assuming total BPM changes of 572 (original): CHAOS = 56.8
Assuming total BPM changes of 3452.357 (calculated): CHAOS = 100.2

Actually, I went to the spreadsheet for verification and my figures don't match those there. Not sure what the difference is.

Anyway, I was about to reiterate my recommendation that the official simfiles be corrected to have the first non-zero timing point as offset, but then it occurred to me to check if there were any songs where this happened mid-measure. Sure enough, Valkyrie Dimension has it two beats after the start; of course, Over The "Period" is suspected to have it on an 8th note. What do we do in these cases?

Post #14 · Posted at 2015-07-04 05:52:51pm 8.7 years ago

Offline SM MaxX
SM MaxX Avatar Member+
910 Posts
United States
Reg. 2012-08-30

Nintendo Switch Friend Code: SW-1495-0040-1058
"I play too much touhou"
Man it's almost like a ton of syncing problems are caused because ignoring the fact that you can change the song offset now requires different bpms to even get the song back on sync and now the whole file just ends up offsync

Weird
http://i.imgur.com/EvGgqSs.png

Post #15 · Posted at 2015-07-05 01:43:16am 8.7 years ago

Offline Arcorann
Arcorann Avatar Member
59 Posts
Not Set
Reg. 2015-01-29


Last updated: 2015-07-05 01:43am
Actually, the conversion ensures that all beats are off by 3ms at most - I verified this myself for POSSESSION; I suspect dbk2 converted the stops incorrectly. The only issue here is that the start of the song is at the wrong place.

Post #16 · Posted at 2015-07-05 07:12:04pm 8.7 years ago

Offline dbk2
dbk2 Avatar Member
332 Posts
Not Set
Reg. 2012-04-30


Last updated: 2015-07-05 07:19pm
Quote: Arcorann
Official Chaos value: 100

Irregularity value: 1144
Song length (HERE WE GO to CLEARED): ~120 s

Assuming total BPM changes of 572 (original): CHAOS = 56.8
Assuming total BPM changes of 3452.357 (calculated): CHAOS = 100.2

Quote: Arcorann
The only issue here is that the start of the song is at the wrong place.

I'm admittedly confused, actually. What do arbitrarily calculated Chaos Values have to do with objectively reproducible timing error and accumulated sync drift?

To clarify, I am arguing in favor of the BPM changes in .sm and .ssc data files matching the music as closely as possible with minimal drift as the top priority. This is what StepMania, as a piece of software, was ideally built to allow.

If the DDR software enforces a 0ms offset due to programming oversight, I consider that a shortcoming of that software and not worth intentionally reproducing in StepMania.

Post #17 · Posted at 2015-07-05 08:16:01pm 8.7 years ago

Offline Silverhawke
Silverhawke Avatar Member+
4,606 Posts
Indonesia
Reg. 2009-01-27

3DS Friend Code: 3496-9710-9426
"highwind fluffdragon"
it means that the chart, as it appears in game, do actually has those weird bpm changes; the official data used in the games has the same weird bpms instead of increasing bpm by 1 every beat. so, it's not wrong to use those values and call it official data, though you're welcome to use your own more accurate sync.

arguably superior, but the policy is to preserve data as is, so yeah.

if you're going to change the offset, that introduces sort of a.. variable into the process. if we just use data the conversion program and the game gave us, that lessens the arbitrary choices.

i dunno what I'm going at here, it's just easier to use the data as is (it works anyway) instead of adding another step (potentially arbitrary) into the process.
my homepage → silverhawke.xyz

Post #18 · Posted at 2015-07-07 03:00:25am 8.7 years ago

Offline Zowayix
Zowayix Avatar Member
1,144 Posts
Not Set
Reg. 2009-09-19


Last updated: 2015-07-07 03:03am
I agree with sticking to the game data, even if it's "wrong". One of the things these simfiles are used for is to practice real DDR songs, and if the real song would drift off-sync on an arcade cabinet, then so should the official simfile.

Post #19 · Posted at 2015-07-08 01:25:18am 8.7 years ago

Offline Arcorann
Arcorann Avatar Member
59 Posts
Not Set
Reg. 2015-01-29

Let me make my opinion on this issue clear: I support fixing the offset but not fixing BPMs. The incorrect offset is clearly player-visible; one sees songs such as CHAOS starting several seconds early and with a BPM that doesn't match the rest of the song before reaching the proper start point. By contrast, I already demonstrated that the BPMs from conversion result in a timing error of at most 3ms at any point, and if we were to start fixing BPMs people wouldn't be able to agree on the correct sync (already we have POSSESSION being either 370 or 369.996).

No-one has addressed my previous question, by the way.

Post #20 · Posted at 2015-07-08 02:14:49am 8.7 years ago

Offline SM MaxX
SM MaxX Avatar Member+
910 Posts
United States
Reg. 2012-08-30

Nintendo Switch Friend Code: SW-1495-0040-1058
"I play too much touhou"

Last updated: 2015-07-08 02:15am
The thing is, the data was made because of the system DDR uses with it's offsets. Stepmania is not the same system; I hardly call it preserving official data when it's essentially mangling it by not adjusting for the fact that's it doesn't use the data the same way as DDR does.

Quote
Let me make my opinion on this issue clear: I support fixing the offset but not fixing BPMs.

I know this wouldn't be the case for every song, but if an offset is horribly off chances are bpms would have to be changed if you want to keep the sync consistent (you'd only be adjusting where the drift is by avoiding that).

Quote
and if we were to start fixing BPMs people wouldn't be able to agree on the correct sync

If the second value to a waveform doesn't match the corresponding second value for a simfile, then it isn't correct. There isn't like any subjectivity to this, it's hard math that's has either a correct value or a wrong value. "Feel" of the sync by muscle memory is completely irrelevant and really shouldn't be considered.
http://i.imgur.com/EvGgqSs.png
Register Log In Back To Forums

0 User(s) Viewing This Thread (Past 15 Minutes)

©2006-2024 Zenius -I- vanisher.com -5th style- IIPrivacy Policy
Web Server: 6% · Database: 4% · Server Time: 2024-03-29 07:58:46
This page took 0.017 seconds to execute.
Theme: starlight · Language: englishuk
Reset Theme & Language