Skip to content

Carry the preview time to and from .osu files - #320

Open
MAX-WiRED wants to merge 1 commit into
uvcat7:betafrom
MAX-WiRED:fix/osu-preview-time
Open

MAX-WiRED wants to merge 1 commit into
uvcat7:betafrom
MAX-WiRED:fix/osu-preview-time

Conversation

@MAX-WiRED

Copy link
Copy Markdown
Contributor

The point a song previews from is lost in both directions when a .osu file is
involved.

Why

PreviewTime is the same value as #SAMPLESTART, counted in milliseconds
rather than seconds. The writer emits a constant:

Write(out, "PreviewTime", "-1");

so a simfile that has a preview loses it on export, and ParseGeneral reads
only AudioFilename and Mode, so a .osu that has one loses it on import.
osu! itself sets the field from its editor, and most ranked maps carry a real
value.

The change

The loader reads it into previewStart, and the writer emits what is stored:

} else if (IsProp(prop, "PreviewTime")) {
    out.previewTime = Str::readInt(PropVal(prop)) * 0.001;
}
Write(out, "PreviewTime",
      sim->previewStart > 0.0 ? ToMilliseconds(sim->previewStart) : -1);

osu! writes -1 for a song with no preview, so that value is left alone on the
way in and still written on the way out when there is nothing to write.

Neither osu! nor a simfile agree on the length: osu! records only where the
preview starts. #SAMPLELENGTH therefore stays at zero on import, which is
what the games fall back to their own default on - the same thing that already
happens today, since nothing was imported at all.

Reproducing

osu file format v14

[General]
AudioFilename: audio.mp3
PreviewTime: 60819
Mode: 3

[Metadata]
Title:Preview
Artist:Test
Version:Normal

[Difficulty]
CircleSize:4

[TimingPoints]
0,500,4,1,0,100,1,0

[HitObjects]
64,192,0,1,0,0:0:0:0:
192,192,500,1,0,0:0:0:0:

Open it and look at File -> Properties: the preview fields are empty. Save it
as .sm and #SAMPLESTART is 0.000000.

Testing

Built on Windows with clang-tidy and clang-format enforced, as the build does.

With the change, that file gives #SAMPLESTART:60.819000;, and saving back to
.osu gives PreviewTime:60819. The same file with PreviewTime: -1 still
gives #SAMPLESTART:0.000000; and is written back as PreviewTime:-1, so a
map with no preview does not gain one at the start of the song.

`PreviewTime` was written as -1 on every save and never read on load, so
the point a song previews from was lost in both directions. It is the
same value as `#SAMPLESTART`, counted in milliseconds rather than
seconds.

The loader now reads it into `previewStart`, treating osu!'s -1 as "no
preview", and the writer emits the stored value, still writing -1 when
there is none.

Neither format records how long the preview runs, so only the start
carries over.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant