Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

added xm #68

Merged
merged 1 commit into from
Aug 10, 2018
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
303 changes: 303 additions & 0 deletions media/tracker_modules/xm.ksy
Original file line number Diff line number Diff line change
@@ -0,0 +1,303 @@
meta:
id: xm
title: Extended Module
application:
- FastTracker 2
- Protracker
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please list only applications that originated the format, not all applications that support it. It's like you list only "Adobe Photoshop" for .psd, not all possible viewers / raster image editors with kind of support .psd.

- MilkyTracker
- libmodplug
- Mikmod
file-extension: xm
license: Unlicense
endian: le
encoding: utf-8
doc-ref: |
http://sid.ethz.ch/debian/milkytracker/milkytracker-0.90.85%2Bdfsg/resources/reference/xm-form.txt
ftp://ftp.modland.com/pub/documents/format_documentation/FastTracker%202%20v2.04%20(.xm).html
seq:
- id: preheader
type: preheader
- id: header
size: preheader.header_size - 4
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You don't like prefixes proposed in the style guide that much (i.e. len_, num_, ofs_, etc)?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, I really don't like them:
1 it is a bit weird to put low-level details first and high-level last
2 combining verbose words with non-verbose ones also looks weird

Copy link
Member

@GreyCat GreyCat Oct 17, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Well, could you raise your concerns in kaitai-io/kaitai_struct#140? Current "silent protest" won't get us anywhere — I still think that any standard at all is better than no standard, and until we'll discuss your objections, I would just take time to enforce it manually, i.e. by fixing your contributions. This will, in turn, will probably just annoy you, because:

  • It takes longer time to get your ksys into this repository
  • After that, "that guy" comes and mangles it in a way you don't like it

I see that you do a lot of interesting stuff here, and it would be bad if all that would go to waste just because we couldn't agree on some basic stuff.

I actually have an idea. Can I contact you using your mail.ru address?

Copy link
Contributor Author

@KOLANICH KOLANICH Oct 18, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I actually have an idea. Can I contact you using your mail.ru address?

Of course you can, but why not to discuss it on GH? Have I made you angry? If you contact by email, please leave a comment on GH about that.

After that, "that guy" comes and mangles it in a way you don't like

Completely OK: it's your repo, it's OK to do what you want in it, even completely wiping it.

Also
kaitai-io/kaitai_struct_doc#7

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If you contact by email, please leave a comment on GH about that.

Confirming, I've sent you the e-mail.

type: header
- id: patterns
type: pattern
repeat: expr
repeat-expr: header.number_of_patterns
- id: instruments
type: instrument
repeat: expr
repeat-expr: header.number_of_instruments
types:
preheader:
seq:
- id: signature0
contents: 'Extended Module: '
- id: module_name
size: 20
type: strz
doc: Module name, padded with zeroes
- id: signature1
contents: [0x1a]
- id: tracker_name
size: 20
type: strz
doc: Tracker name
- id: version_number
type: version
doc: "Format versions below [0x01, 0x04] have a LOT of differences. Check this field!"
- id: header_size
type: u4
doc: Header size << Calculated FROM THIS OFFSET, not from the beginning of the file! >>
types:
version:
seq:
- id: minor
type: u1
doc: currently 0x04
- id: major
type: u1
doc: currently 0x01
instances:
value:
value: (major<<8) | minor
header:
seq:
- id: song_length
type: u2
doc: Song length (in pattern order table)
- id: restart_position
type: u2
- id: number_of_channels
type: u2
doc: "(2,4,6,8,10,...,32)"
- id: number_of_patterns
type: u2
doc: "(max 256)"
- id: number_of_instruments
type: u2
doc: "(max 128)"
- id: flags
type: flags
- id: default_tempo
type: u2
- id: default_bpm
type: u2
- id: pattern_order_table
type: u1
doc: "max 256"
repeat: expr
#repeat-expr: song_length
repeat-expr: 256
flags:
seq:
- id: reserved
type: b15
- id: freq_table_type
type: b1
doc: "0 = Amiga frequency table (see below); 1 = Linear frequency table"
pattern:
seq:
- id: header
type: header
- id: packed_data
size: header.main.packed_pattern_data_size
types:
header:
seq:
- id: header_length
type: u4
doc: Pattern header length
- id: main
type: header_main
size: header_length - 4
types:
header_main:
seq:
- id: packing_type
type: u1
doc: Packing type (always 0)
- id: number_of_rows_raw
type:
switch-on: _root.preheader.version_number.value
cases:
0x0102: u1
_: u2
doc: Number of rows in pattern (1..256)
- id: packed_pattern_data_size
type: u2
doc: Packed pattern data size
instances:
number_of_rows:
value: number_of_rows_raw + (_root.preheader.version_number.value==0x0102?1:0)
instrument:
seq:
- id: header_size
type: u4
doc: |
Instrument size << header that is >>
<< "Instrument Size" field tends to be more than the actual size of the structure documented here (it includes also the extended instrument sample header above). So remember to check it and skip the additional bytes before the first sample header >>
- id: header
size: header_size - 4
type: header
- id: samples_headers
type: sample_header
repeat: expr
repeat-expr: header.number_of_samples
- id: samples
type: samples_data(_index)
repeat: expr
repeat-expr: header.number_of_samples
types:
header:
seq:
- id: name
size: 22
type: strz
- id: type
type: u1
doc: Usually zero, but this seems pretty random, don't assume it's zero
- id: number_of_samples
type: u2
- id: extra_header
type: extra_header
if: number_of_samples > 0
extra_header:
seq:
- id: sample_header_size
type: u4
- id: sample_number_for_all_notes
type: u1
repeat: expr
repeat-expr: 96
- id: points_for_volume_envelope
type: envelope_point
repeat: expr
repeat-expr: 12
- id: points_for_panning_envelope
type: envelope_point
repeat: expr
repeat-expr: 12
- id: number_of_volume_points
type: u1
- id: number_of_panning_points
type: u1

- id: volume_sustain_point
type: u1
- id: volume_loop_start_point
type: u1
- id: volume_loop_end_point
type: u1

- id: panning_sustain_point
type: u1
- id: panning_loop_start_point
type: u1
- id: panning_loop_end_point
type: u1

- id: volume_type
type: u1
enum: type
- id: panning_type
type: u1
enum: type

- id: vibrato_type
type: u1
- id: vibrato_sweep
type: u1
- id: vibrato_depth
type: u1
- id: vibrato_rate
type: u1
- id: volume_fadeout
type: u2
- id: reserved
type: u2
types:
envelope_point:
doc: |
Envelope frame-counters work in range 0..FFFFh (0..65535 dec).
BUT! FT2 only itself supports only range 0..FFh (0..255 dec).
Some other trackers (like SoundTracker for Unix), however, can use the full range 0..FFFF, so it should be supported.
!!TIP: This is also a good way to detect if the module has been made with FT2 or not. (In case the tracker name is brain- deadly left unchanged!)
Of course it does not help if all instruments have the values inside FT2 supported range.
The value-field of the envelope point is ranged between 00..3Fh (0..64 dec).
seq:
- id: x
type: u2
doc: Frame number of the point
- id: y
type: u2
doc: Value of the point
enums:
type:
0: on
1: sustain
2: loop
samples_data:
doc: |
The saved data uses simple delta-encoding to achieve better compression ratios (when compressed with pkzip, etc.)
Pseudocode for converting the delta-coded data to normal data,
old = 0;
for i in range(data_len):
new = sample[i] + old;
sample[i] = new;
old = new;
params:
- id: index
type: u2
seq:
- id: samples_data
type:
switch-on: _parent.samples_headers[index].type.is_sample_data_16_bit
cases:
true: u2
false: u1
repeat: expr
repeat-expr: _parent.samples_headers[index].sample_length
sample_header:
seq:
- id: sample_length
type: u4
- id: sample_loop_start
type: u4
- id: sample_loop_length
type: u4

- id: volume
type: u1
- id: fine_tune
type: s1
doc: -16..+15
- id: type
type: loop_type
- id: panning
type: u1
doc: (0-255)
- id: relative_note_number
type: s1
- id: reserved
type: u1
- id: name
size: 22
type: strz
types:
loop_type:
seq:
- id: reserved0
type: b3
- id: is_sample_data_16_bit
type: b1
- id: reserved1
type: b2
- id: loop_type
type: b2
enum: loop_type
enums:
loop_type:
0: none
1: forward
2: ping_pong