-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathspec.md
950 lines (719 loc) · 32.8 KB
/
spec.md
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
# The UltraStar File Format
The UltraStar file format is a timed text format for describing karaoke songs where singing performance is scored by the karaoke software.
## Status of this Document
This document aims to describe the UltraStar File Format in its most recent version 2.0.0.
> [!IMPORTANT]
>
> This document is currently a work-in-progress.
> Parts of the final specification may change significantly from the current state of this document.
GitHub Issues are preferred for discussion of this specification.
Alternatively, you can discuss comments on our Discord server.
## 1. Introduction
The UltraStar file format provides a standardized representation of karaoke songs.
The format has been used for a long time by numerous karaoke games such as [UltraStar Deluxe](https://github.com/UltraStar-Deluxe/USDX), [Performous](https://github.com/performous/performous), or [Vocaluxe](https://github.com/Vocaluxe/Vocaluxe).
There exists an ecosystem of supporting applications for hosting, editing, and managing songs.
However, due to the lack of an official file format specification implementations differ and new features cannot be added consistently.
This document aims to fix this problem by providing a formal specification for the syntax and semantics of the UltraStar file format.
The UltraStar file format is designed to be edited by machines and humans alike
and is intended to be easily understood and edited by technical and non-technical users.
This guiding principle is influential for many decisions made during the design process.
### 1.1. Conventions in this Document
The keywords "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this document are to be interpreted as described in [RFC 2119](https://datatracker.ietf.org/doc/html/rfc2119).
The grammatical rules in this document are to be interpreted as described in [RFC 5234](https://datatracker.ietf.org/doc/html/rfc5234).
We are using the following core rules:
```abnf
CR = %x0D ; carriage return
LF = %x0A ; line feed
CRLF = CR LF
DIGIT = %x30-39 ; 0-9
```
### 1.2. Terminology
The following terminology is used throughout this document:
**Song**: A song refers to a file in the UltraStar file format.
In some contexts **song** can refer to linked media files as well. In those cases **textfile** is used to disambiguate individual files.
**Medley**: A medley is a short, recognizable excerpt from a song.
Many games include a designated medley mode.
**Implementation**: An implementation is any program or software that interacts with the file format.
**Game Implementation**: A game implementation is an implementation that allows users to sing karaoke songs
and potentially scores singing performance.
> [!CAUTION]
>
> The exact terminology has not been decided yet.
## 2. General Structure
Songs are plain text files
The UTF-8 encoding MUST be used.
Implementations MUST NOT add a byte order mark to the beginning of a file.
In the interests of interoperability, implementations MAY ignore the presence of a byte order mark rather than treating it as an error.
> [!CAUTION]
>
> Whether files with a BOM may be accepted is an open discussion ([#46](https://github.com/UltraStar-Deluxe/format/issues/46)).
The canonical file extension for textfiles is `.txt`.
Songs consist of a header and a body.
The header contains metadata about the song.
The body contains the musical data.
A file SHOULD end with an `E` on a single line.
Everything after a trailing `E` MUST be ignored.
> [!CAUTION]
>
> Whether the trailing `E` is optional or not is open for discussion ([#44](https://github.com/UltraStar-Deluxe/format/issues/44)).
```abnf
song = file-header
file-body
[ %x45 *char ] ; E
char = %x00-10FFFF
```
### 2.1. Line Endings and Whitespace
Both the header and the body of a file are defined in terms of lines.
A line is a string of text that is terminated with an end-of-line sequence.
```abnf
end-of-line = ( CR / LF / CRLF )
empty-line = end-of-line
```
Implementations SHOULD use a single Line Feed (`%x0A`) as line terminator.
Implementations MUST accept the end of input (`EOF`) as a valid line terminator.
Empty lines are ignored throughout the entire file.
> [!CAUTION]
>
> Whether empty lines are allowed or not is currently open for discussion ([#50](https://github.com/UltraStar-Deluxe/format/issues/50)).
> Whether a line that consists only of whitespace is recognized as an empty line has not been decided yet.
Whitespace is used as a separator in many places of the format.
Any unicode character with the property `White_Space=yes` is a valid whitespace character (except for the carriage return `%x0D` and line feed `%x0A` both of which are considered line breaks). See [Wikipedia](https://en.wikipedia.org/wiki/Whitespace_character) for a list of whitespace characters.
In the interests of interoperability implementations SHOULD use ASCII spaces (`%x20`) as whitespace.
```abnf
WSP = <any unicode character with White_Space=yes>
```
## 2. The File Header
The header of a song consists of a sequence of key-value pairs.
Each line in the header section starts with a hash.
The key and value of a header are separated by a colon.
Whitespace around key and value is ignored.
> [!CAUTION]
>
> The terminology “header” is not decided yet.
> Other terms used for the same concept are “tag”, “attribute” or “field”.
```abnf
file-header = *( header-line / empty-line )
header-line = hash *WSP header-key *WSP colon *WSP header-value *WSP line-break
header-key = 1*header-char
header-value = single-value / multi-value
multi-value = single-value *( comma single-value ) [ comma ]
single-value = *( header-char / colon )
header-char = %x00-09 / ; exclude line feed
%x0B-0C / ; exclude carriage return
%x0E-39 / ; exclude colon
%x3B-10FFFF
hash = %x23 ; #
colon = %x3A ; :
comma = %x2C ; ,
period = %x2E ; .
```
> [!CAUTION]
>
> The use of trailing commas in comma-separated header lists has not been decided yet.
> [!CAUTION]
>
> The allowed character sets for header keys and values have not been decided yet.
Comparisons of header keys is case-insensitive.
For the sake of consistency header keys SHOULD use only capital letters.
Header values are generally case-sensitive unless otherwise specified.
An empty value is equivalent to the header being absent.
Implementations MAY remove leading and trailing whitespace in header keys and values without changing semantics.
Header values may not exceed 255 characters.
Implementations MAY define application-specific headers
but SHOULD prefix those headers with the application name to avoid conflicts with future standardized headers.
Implementations MUST ignore headers they do not recognize.
The order of headers is irrelevant (note the exception in section 3.1.)
although standardized headers should precede any application-specific headers.
> [!CAUTION]
>
> Handling of application-specific headers has not been decided yet.
The following sections describe the standardized headers that have been defined.
If a syntax for a header is specified it applies to the `single-value`.
If no syntax is specified any valid `single-value` is valid.
Some headers are marked as deprecated or removed from a certain version onward.
Implementations MUST continue to apply the defined semantics to a header if it is deprecated in the file format version indicated by the file.
Implementations MUST NOT apply semantics to a header if a file indicates a version where the header has been removed.
### 3.1. Single-Valued and Multi-Valued Headers
Headers can be single-valued or multi-valued.
Single-valued headers can only be specified once and can only contain a single value.
For the sake of robustness implementations SHOULD ignore multiple occurrences of single-valued headers (which value is chosen in such a case is an implementation detail).
Multi-valued headers can contain multiple values separated by a comma (`%x2C`).
Additionally, multiple occurrences of a multi-valued header are semantically equivalent to a single occurrence
where all values are concatenated by commas in order of occurrence.
In this way the order of multi-valued headers is significant.
Implementations MAY remove leading and trailing whitespace of individual values of a multi-valued header without changing sematics. Implementations MAY also remove empty values in a multi-valued header without changing semantics.
> [!WARNING]
>
> **Backwards-Compatible Change** in version 1.1.0
>
> Multi-Valued Headers were introduced in version 1.1.0 of the format.
> Headers indicated as multi-valued were single-valued in previous versions.
> [!WARNING]
>
> **Backwards-Compatible Change** in version ???
>
> Concatenating multiple occurrences of multi-valued headers was introduced in version ??? of the format.
> Previously handling of repeated headers was not covered by this specification.
> [!CAUTION]
>
> The use of multi-valued headers has not been decided yet ([#22](https://github.com/UltraStar-Deluxe/format/issues/22)).
### 3.2. File References
Some headers reference other files, most notably `AUDIO`, `VIDEO`, `COVER`, and `BACKGROUND`.
These file references are always relative to the textfile from which they are referenced.
As a security measure file references MUST NOT use absolute paths.
Implementations SHOULD refuse to load absolutely referenced files.
> [!CAUTION]
>
> Whether absolute paths are allowed or not hasn't been decided yet.
> [!IMPORTANT]
>
> In Windows file names are case-insensitive (i.e. there cannot be two files in a folder that differ only by their case).
> Linux and macOS however, use fully case-sensitive file systems.
> Implementations might need to pay special attention to this fact to ensure that files are compatible across all systems.
### 3.3. The `VERSION` Header
```
Required: Yes
Multi-Valued: No
Syntax: 1*DIGIT period 1*DIGIT period 1*DIGIT
Since: 1.0.0
```
The `VERSION` header indicates the version of this specification that a file complies to.
The value of the header is a triplet of numbers separated by periods.
Similar to [semantic versioning ´](https://semver.org) the version number implicates a certain level of compatibility.
In particular an implementation supporting version 1.0.0 of this spec should be able to process files using a version of 1.1.0 without any changes (although new features might not be supported).
Implementations SHOULD NOT attempt to process files with a higher major version than they were designed to work with.
In absence of the `VERSION` header implementations SHOULD assume the version 0.3.0.
Implementations SHOULD reject a file based on the value of the `VERSION` header,
in particular if the value is syntactically invalid.
The `VERSION` header SHOULD be the first header in a file.
### 3.4. The `BPM` Header
```
Required: Yes
Multi-Valued: No
Syntax: 1*DIGIT [ period 1*DIGIT ]
Since: 0.1.0
```
The `BPM` header indicates the number of beats per minute as a decimal value.
The notes in a song are quantized in beats.
A single beat is the smallest unit of time that can be present in a song.
The value of this tag is arbitrary in the sense that it is usually 4 to 8 times higher than the actual BPM of a song.
> [!WARNING]
>
> **Breaking Change** in version 2.0.0
>
> In versions 0.x and 1.x the value of the `BPM` header was implicitly quadrupled.
> This is **not** the case for version 2.0.0 and above.
> [!CAUTION]
>
> The removal of the implicit quadrupling has not been decided yet.
> [!WARNING]
>
> **Breaking Change** in version 2.0.0
>
> In versions 0.x and 1.x the comma was allowed as decimal separator in addition to the period.
> This feature has been removed in version 2.0.0 and above.
> [!CAUTION]
>
> The removal of the comma as a valid decimal separator has not been decided yet.
### 3.5. The `AUDIO` Header
```
Required: Yes
Multi-Valued: No
Since: 1.1.0
```
The `AUDIO` header contains a file reference (as defined in section 3.2.) to an audio file.
This file contains the full version of a song (including instrumentals and vocals).
Supported audio formats are an implementation detail.
Implementations MUST disregard the [`MP3`](#36-the-mp3-header) header if an `AUDIO` header is present (even if the specified file cannot be found or processed).
> [!CAUTION]
>
> If media files should follow a specific naming scheme has not been decided yet.
### 3.6. The `MP3` Header
```
Required: Yes (Versions 0.x and 1.x)
Multi-Valued: No
Since: 0.1.0
Deprecated: 1.1.0
Removed: 2.0.0
```
The `MP3` header contains a file reference (as defined in section 3.2.) to an audio file.
This header has been replaced by the `AUDIO` header.
### 3.7. The `TITLE` Header
```
Required: Yes
Multi-Valued: No
Since: 0.1.0
```
The `TITLE` header contains the title of the song.
### 3.8. The `ARTIST` Header
```
Required: Yes
Multi-Valued: No
Since: 0.1.0
```
The `ARTIST` header contains the artist of the song.
### 3.9. The `COVER`, `BACKGROUND`, and `VIDEO` Headers
```
Required: No
Multi-Valued: No
Since: 0.2.0
```
The headers `COVER`, `BACKGROUND`, and `VIDEO` contain file references to image files or in case of `VIDEO` video files.
Implementations MAY use these files to display cover artwork and background graphics during gameplay.
Supported image and video formats are an implementation detail.
> [!CAUTION]
>
> If a minimum requirement concerning media types should be part of the spec has not been decided yet.
> [!CAUTION]
>
> If media files should follow a specific naming scheme has not been decided yet.
### 3.10. The `VOCALS` and `INSTRUMENTAL` Headers
```
Required: No
Multi-Valued: No
Since: 1.1.0
```
The `VOCALS` and `INSTRUMENTAL` header contain file references to audio files.
These files contain the a cappella and instrumental versions of the song respectively.
Implementations MAY use these instead of [`AUDIO`](#35-the-audio-header)
to give users the option of changing the volume of vocal and instrumental tracks separately.
> [!CAUTION]
>
> Whether the inclusion of `VOCALS` requires the inclusion of `INSTRUMENTAL` is currently not decided.
### 3.11. The `GAP` Header
```
Required: No
Multi-Valued: No
Syntax: 1*DIGIT
Since: 0.2.0
```
The `GAP` header indicates an amount of time in milliseconds from the beginning of the audio track until beat 0.
This effectively offsets all notes in a song by this amount of time relative to the audio track.
The `GAP` value is an integer.
> [!CAUTION]
>
> Whether negative `GAP` values are allowed or disallowed is not decided yet.
> [!WARNING]
>
> **Breaking Change** in version 2.0.0
>
> In versions 0.x and 1.x the value of `GAP` could also be a decimal value.
> Since version 2.0.0 this is not allowed anymore.
### 3.12. The `VIDEOGAP` Header
```
Required: No
Multi-Valued: No
Syntax: [ minus ] 1*DIGIT
Since: 0.2.0
```
The `VIDEOGAP` header indicates an amount of time in milliseconds that the background video will be delayed relative to the audio of a song.
The `VIDEOGAP` value is an integer.
> [!WARNING]
>
> **Breaking Change** in version 2.0.0
>
> In versions 0.x and 1.x the value of `VIDEOGAP` was specified in seconds as a decimal value.
> Version 2.0.0 changes this to an integer and milliseconds.
### 3.13. The `NOTESGAP` Header
```
Required: No
Multi-Valued: No
Syntax: [ minus ] 1*DIGIT
Since: 0.2.0
Deprecated: 0.3.0
Removed: 1.0.0
```
The `NOTESGAP` header is deprecated and MUST NOT be used.
Implementations MUST ignore the field if present.
> [!NOTE]
>
> The `NOTESGAP` header was defined in version 0.1.0 But its semantics were never fully specified.
### 3.14. The `START` and `END` Headers
```
Required: No
Multi-Valued: No
Syntax: 1*DIGIT
Since: 0.2.0
```
The `START` and `END` header specify two time points in milliseconds relative to the start of the audio data that indicate a start and end point for the song.
Game implementations SHOULD start and end the song at the specified points and scale scoring accordingly.
Both `START` and `END` values are integers.
> [!NOTE]
>
> The `START` and `END` values do not affect the placement of notes nor any other time codes relative to the audio.
> They simply indicate that a song should be started or stopped a certain amount of time into the audio file.
> [!WARNING]
>
> **Breaking Change** in version 2.0.0
>
> In versions 0.x and 1.x `START` was specified in seconds as a decimal value.
> Version 2.0.0 changes this to an integer and milliseconds.
### 3.15. The `PREVIEWSTART` Header
```
Required: No
Multi-Valued: No
Syntax: 1*DIGIT
Since: 0.2.0
```
The `PREVIEWSTART` header indicates a time offset in milliseconds relative to the start of the audio where the preview starts.
Implementations MAY use this value when playing a song in a preview setting (e.g. during song selection).
In its absence implementations SHOULD default to the start of the medley section (if available).
> [!WARNING]
>
> **Breaking Change** in version 2.0.0
>
> In versions 0.x and 1.x `PREVIEWSTART` was specified in seconds as a decimal value.
> Version 2.0.0 of this specification changes this to an integer and milliseconds.
### 3.16. The `MEDLEYSTART` and `MEDLEYEND` Headers
```
Required: No
Multi-Valued: No
Syntax: 1*DIGIT
Since: 2.0.0
```
The `MEDLEYSTART` and `MEDLEYEND` headers indicate in milliseconds the start and end of the medley section of a song relative to the start of the audio.
These tags replace `MEDLEYSTARTBEAT` and `MEDLEYENDBEAT` in version 2.0.0 of this specification.
### 3.17. The `MEDLEYSTARTBEAT` and `MEDLEYENDBEAT` Headers
```
Required: No
Multi-Valued: No
Syntax: 1*DIGIT
Since: 0.2.0
Removed: 2.0.0
```
The `MEDLEYSTARTBEAT` and `MEDLEYENDBEAT` headers indicate in beats the start and end of the medley section of a song.
Implementations MUST respect the `GAP` value when calculating the medley start and end times.
> [!WARNING]
>
> **Breaking Change** in version 2.0.0
>
> The headers `MEDLEYSTARTBEAT` and `MEDLEYENDBEAT` have been replaced by `MEDLEYSTART` and `MEDLEYEND` in version 2.0.0 of this specification.
### 3.18. The `CALCMEDLEY` Header
```
Required: No
Multi-Valued: No
Syntax: "on" / "off"
Since: 0.2.0
```
If [`MEDLEYSTART`](#316-the-medleystart-and-medleyend-headers) or [`MEDLEYEND`](#316-the-medleystart-and-medleyend-headers) ([`MEDLEYSTARTBEAT`](#317-the-medleystartbeat-and-medleyendbeat-headers) or [`MEDLEYENDBEAT`](#317-the-medleystartbeat-and-medleyendbeat-headers) for versions before 2.0.0) are not specified,
the `CALCMEDLEY` header indicates whether an implementation is supposed to determine the start and end of the medley section automatically.
The value of this header is compared case-insensitively.
> [!CAUTION]
>
> The exact semantics of the `CALCMEDLEY` header have not been defined yet.
### 3.19. The `YEAR` Header
```
Required: No
Multi-Valued: No
Syntax: 4DIGIT
Since: 0.2.0
```
The `YEAR` indicates the year in which the song was released.
The value must be a positive integer.
> [!CAUTION]
>
> The exact syntax of the `YEAR` header has not been decided yet.
### 3.20. The `GENRE` Header
```
Required: No
Multi-Valued: Yes
Since: 0.2.0
```
The `GENRE` defines the genre(s) of the song.
Individual genre values MUST be compared case-insensitively.
For consistency, it is usually best to capitalize genres.
> [!CAUTION]
>
> Whether genres should be compared case-insensitively or not hasn't been decided yet.
### 3.21. The `LANGUAGE` Header
```
Required: No
Multi-Valued: Yes
Since: 0.2.0
```
The `LANGUAGE` header indicates the spoken or sung language(s) of a song.
Valid values for this header are the english language names according to [ISO 639-2](https://www.loc.gov/standards/iso639-2/php/code_list.php). `LANGUAGE` values are compared case-insensitively.
> [!CAUTION]
>
> The set of valid values for the `LANGUAGE` header has not been decided yet.
### 3.22. The `EDITION` Header
```
Required: No
Multi-Valued: Yes
Since: 0.2.0
```
The `EDITION` indicates what edition of games a song belongs to.
While this header is intended to hold commercially available editions (e.g. SingStar Pop Hits, GuitarHero Live) implementations MUST NOT reject a file based on the value of this header.
A list of SingStar editions is available [here](https://github.com/bohning/usdb_syncer/wiki/SingStar-Editions).
For arbitrary keywords see the [`TAGS`](#323-the-tags-header) header.
### 3.23. The `TAGS` Header
```
Required: No
Multi-Valued: Yes
Since: 1.1.0
```
The `TAGS` allow association of any reasonable keyword with a song.
Implementations SHOULD compare tags in a case-insensitive manner.
> [!CAUTION]
>
> Whether tags should be compared case-insensitively or not hasn't been decided yet.
### 3.24. The `P1` thru `P9` Headers
```
Required: Yes for multi-voice songs
Multi-Valued: No
Since: 0.2.0
```
The headers `P1`, `P2`, …, `P9` indicate the names of the voices of a song.
These names correspond to the voices indicated by the `P1`, `P2`, …, `P9` voice changes (see [section 3.3](#33-voice-changes)).
If the voices correspond to different singers in the original song, the header values often indicate the names of the original singers.
The association of header values to voices is defined by the numerical value after each `P` respectively,
i.e. the header `P2` indicates the name of the voice whose notes are introduced by the `P2` voice change.
If a song uses the voice change `Pn` the corresponding `Pn` header is required.
> [!NOTE]
>
> As `P0` is not a valid voice change, the header `P0` is not specified.
> [!CAUTION]
>
> The exact semantics of the `P` headers have not been decided yet.
### 3.25. The `DUETSINGER1` thru `DUETSINGER9` Headers
```
Required: No
Multi-Valued: No
Since: 0.2.0
Deprecated: 0.3.0
Removed: 1.0.0
```
The headers `DUETSINGER1`, `DUETSINGER2`, …, `DUETSINGER9` are aliases for [`P1`](#324-the-p1-thru-p9-headers) thru [`P9`](#324-the-p1-thru-p9-headers), etc.
If both are specified [`P1`](#324-the-p1-thru-p9-headers) thru [`P9`](#324-the-p1-thru-p9-headers), headers take precedence.
### 3.26. The `CREATOR` Header
```
Required: No
Multi-Valued: Yes
Since: 0.2.0
```
The `CREATOR` indicates who created the textfile.
Values are usually usernames or gamer tags.
> [!NOTE]
>
> Some implementations are known to use an application-specific header `AUTHOR` in place of `CREATOR`.
> The semantics of the `AUTHOR` header are not part of this specification.
### 3.27. The `PROVIDEDBY` Header
```
Required: No
Multi-Valued: No
Since: 1.1.0
```
The `PROVIDEDBY` header indicates the source of a particular textfile.
Implementations concerned with providing textfiles to many users (sometimes referred to as "hosters") SHOULD set this value automatically.
Values SHOULD be valid URLs according to [RFC 1738](https://datatracker.ietf.org/doc/html/rfc1738) using the HTTP or HTTPS scheme.
### 3.28. The `COMMENT` Header
```
Required: No
Multi-Valued: No
Since: 0.2.0
```
The `COMMENT` header can include arbitrary text.
Implementations MUST NOT assign semantics to the value of this header.
### 3.29. The `ENCODING` Header
```
Required: No
Multi-Valued: No
Syntax: "UTF-8" / "CP1252" / "CP1250"
Since: 0.2.0
Deprecated: 0.3.0
Removed: 1.0.0
```
The `ENCODING` header specifies the encoding used for text values in a textfile.
If present implementations MUST apply this encoding to all header values and all note texts.
Implementations MAY support additional encodings.
Names of encodings are compared in a case-insensitive manner.
> [!IMPORTANT]
>
> Many implementations only apply the specified encoding to **subsequent** headers and note texts.
> Although this is technically not spec-compliant it is usually best to put the `ENCODING` header first.
> [!WARNING]
>
> The use of the `ENCODING` tag is highly discouraged.
> Songs must always use the UTF-8 encoding.
### 3.30. The `RELATIVE` Header
```
Required: No
Multi-Valued: No
Syntax: "yes" / "no"
Since: 0.2.0
Deprecated: 0.3.0
Removed: 1.0.0
```
The `RELATIVE` header enables [Relative Mode](#a-relative-mode) (see Appendix A).
## 3. The File Body
The body of a file consists of a sequence of notes, end-of-phrase markers, and voice changes.
```abnf
body = *( note /
end-of-phrase /
voice-change /
empty-line )
```
The sequence of notes and end-of-phrase markers SHOULD appear in ascending order by their start beats.
> [!CAUTION]
>
> Whether the body of a file must or may be sorted is not decided yet.
### 3.1. Notes
A note is a musical element in a song.
Each note is defined by its type, start beat, duration, pitch, and text.
```abnf
note = note-type
WSP start-beat
WSP duration
WSP pitch
WSP note-text
line-break
note-type = %x21-22 / %x24-7E ; Visible ASCII-characters except space and #
start-beat = 1*DIGIT
duration = 1*DIGIT
pitch = [ minus ] 1*DIGIT
note-text = 1*( %x20-10FFFF )
minus = %x2D ; -
```
> [!CAUTION]
>
> Whether only a single or multiple whitespace character in a row are allowed is currently up for discussion ([#46](https://github.com/UltraStar-Deluxe/format/issues/46)).
The note type indicates how singing the correct or wrong note should affect scoring.
The following sections define standard note types.
Implementations MAY substitute unknown note types with freestyle notes (`F`).
Implementations MUST NOT attach semantics to note types not covered by this specification.
The start beat and duration define the time when a note appears in a song.
Both are indicated in beats (see section 3.3.) relative to offset indicated by the `GAP` header.
The end beat of a note is calculated as its start beat plus its duration.
Notes SHOULD NOT overlap, i.e. the start beat of a note being between the start beat (inclusive) and end beat (exclusive) of another note.
> [!CAUTION]
>
> Whether and how applications may define custom note types hasn't been decided yet.
> [!CAUTION]
>
> Whether negative note starts and/or durations are valid is, hasn't been decided yet.
The pitch of a note is encoded as the number of half-steps relative to `C4` (also referred to as middle C).
So a pitch of `5` represent an `F4` and a pitch of `-2` represents an `A#3`.
> [!NOTE]
>
> The pitches in this paragraph use [scientific pitch notation](https://en.wikipedia.org/wiki/Scientific_pitch_notation).
#### 3.1.1. Regular Notes `:`
A regular note is indicated by the note type `:` (colon, `%x3A`).
A regular note indicates that a certain pitch is to be held for a certain duration.
Game implementations MAY decide to compare pitches independently of the octave (i.e. compare pitches module 12).
#### 3.1.2. Golden Notes `*`
A golden note is indicated by the note type `*` (asterisk, `%x2A`).
Golden note have the same semantics as regular notes.
However, during scoring game implementations SHOULD award more points for golden notes.
The exact scoring behavior is an implementation detail.
#### 3.1.3. Rap Notes `R`
> [!WARNING]
>
> Rap notes are standardized in version 0.2.0 of this specification.
A rap note is indicated by the note type `R` (the letter R, `%x52`).
Rap notes have the same timing semantics as regular notes but are intended or spoken phrases that do not have a defined pitch.
Implementations MUST ignore pitch information on rap notes.
#### 3.1.4. Golden Rap Notes `G`
> [!WARNING]
>
> Golden rap notes are standardized in version 0.2.0 of this specification.
A golden rap note is indicated by the note type `G` (the letter G, `%x47`).
Golden rap notes have the same semantics as rap notes.
However, during scoring game implementations SHOULD award more points for golden rap notes.
The exact scoring behavior is an implementation detail.
#### 3.1.5. Freestyle Notes `F`
> [!WARNING]
>
> Freestyle notes are standardized in version 0.2.0 of this specification.
A freestyle note is indicated by the note type `F` (the letter F, `%x46`).
Similar to rap notes, freestyle notes do not carry pitch information.
Additionally, game implementations MUST NOT award points for freestyle notes.
### 3.2. End-of-Phrase Markers
End-of-Phrase markers are indicated by a `-` character (hyphen/minus, `%x2D`).
```abnf
end-of-phrase = dash
WSP start-beat
*WSP line-break
```
An end-of-phrase marker carries no musical information but indicates the end of a phrase in the song.
This is usually interpreted as a line break in the lyrics.
An end-of-phrase SHOULD NOT appear between the start beat (inclusive) of a note and its end beat (exclusive).
An end-of-phrase marker SHOULD NOT appear before the start time of the first note or after the start time of the last note.
> [!CAUTION]
>
> Whether leading or trailing end-of-phrase markers are allowed is currently up for discussion ([#44](https://github.com/UltraStar-Deluxe/format/issues/44)).
> [!CAUTION]
>
> Whether there can be non-whitespace text following an end-of-phrase indicator has not been decided yet.
### 3.3. Voice Changes
> [!WARNING]
>
> **Breaking Change** in version 0.2.0
>
> In version 0.1.0 only single-voice songs were defined.
> Voice changes are specified since version 0.2.0.
A voice change (also referred to as a “player change”) is indicated by a `P` (the letter P, `%x50`), immediately followed by a single digit.
```abnf
voice-change = p voice-numer
*WSP line-break
p = %x50 ; P
voice-number = DIGIT
```
A voice change indicates that all notes and end-of-phrase markers following this line belong to the voice indicated by the `voice-number`.
Implementations MAY choose to limit the number of voices.
If the body of a song does not start with a voice change, `P1` is assumed implicitly.
To improve readability notes for different voices should not be interlaced.
> [!NOTE]
>
> A voice change does NOT implicitly add an end-of-phrase indicator.
Voice changes SHOULD appear in ascending order of `voice-number` and there SHOULD be no gaps (i.e. a song having notes for `P1` and `P3`, but not `P2`).
The exact `voice-number` carries no semantics other than its relative order with other `voice-number` and its association with the corresponding header (see [section 3.25](#325-the-p1-and-p2-headers)).
In particular a file that uses `P3` and `P5` can be rewritten using `P1` and `P2` with no change in semantics.
> [!TIP]
>
> A song that makes use of voice changes is referred to as a “duet”.
> [!NOTE]
>
> There exists a legacy behavior where an indicated `P3` would start a sequence of notes that apply to both voices.
> This behavior is explicitly NOT compliant with this specification.
A song that uses voice changes MUST also include the appropriate [`P1`](#324-the-p1-thru-p9-headers) thru [`P9`](#324-the-p1-thru-p9-headers) headers indicating the names of the voices.
> [!CAUTION]
>
> Whether songs that make use of voice changes need to start their body with a voice change has not been decided yet.
> [!CAUTION]
>
> Whether single-voice songs can have voice changes (only `P1`) has not been decided yet.
> [!CAUTION]
>
> Whether gaps in `voice-number`s are allowed has not been decided yet.
> [!CAUTION]
>
> Whether there may be a whitespace between the `P` and the indicated voice is currently open for discussion ([#46](https://github.com/UltraStar-Deluxe/format/issues/46)).
## Appendix
### A. Relative Mode
> [!WARNING]
>
> Relative mode is deprecated and has been removed in version 1.0.0 of this specification.
Relative mode is a special input mode that affects parsing and interpreting songs significantly.
Relative mode is enabled by the [`RELATIVE`](#330-the-relative-header) header being set to `yes` (case-insensitive).
#### Syntax
When relative mode is enabled, the syntax of end-of-phrase markers changes:
```abnf
end-of-phrase =/ dash
WSP start-beat
WSP rel-offset
*WSP line-break
rel-offset = 1*DIGIT
```
Note that the syntax in relative mode is incompatible with the normal syntax.
Implementations MUST NOT try to rectify a missing `RELATIVE` header based on the end-of-phrase markers encountered.
#### Semantics
In relative mode the semantics of start times changes for notes and end-of-phrase markers.
- At the start of the body a relative offset `rel` is initialized to the value of the `GAP` header (or `0` if no `GAP` header exists).
- The start times of notes and end-of-phrase markers are relative to the current `rel` value. The absolute start time is calculated as `rel + start-beat`.
- End-of-phrase markers in relative mode include a `rel-offset`.
After the start time of the end-of-phrase marker has been interpreted, the `rel-offset` value is added to `rel` for subsequent lines.
> [!IMPORTANT]
>
> In relative mode the order of notes and end-of-phrase markers within a file is significant.
In files with multiple voices each voice has its own `rel` value which is independent of other voices.
The `rel` value for a voice does not reset when a voice change is encountered.