xmrsplayer 0.14.4

Safe, no_std SoundTracker music player — plays MOD/XM/S3M/IT/DW with cycle-accurate SID and OPL/AdLib FM synthesis.
Documentation
// This example is a scratch pad that was used to reverse-engineer the FT2
// historical arpeggio table. Only `step2` is called from `main` today;
// `step1`, `step3`, the intermediate constants and the `historical_ft2_tick`
// reference implementation are kept for archaeological purposes.
#![allow(dead_code, unused_assignments)]

/*
   Try to optimize stupid historical FT2 arbeggio bug
*/
const HISTORICAL_FT2_ARPEGGIO_TAB_STEP1: [u8; 256] = [
    0, 1, 2, 0, 1, 2, 0, 1, 2, 0, 1, 2, 0, 1, 2, 0,
    /* The following are overflown bytes from FT2's binary.
    	** (confirmed to be the same on FT2.08 and FT2.09)
     * --> stolen from ft2-clone <--
    	*/
    0x00, 0x18, 0x31, 0x4A, 0x61, 0x78, 0x8D, 0xA1, 0xB4, 0xC5, 0xD4, 0xE0, 0xEB, 0xF4, 0xFA, 0xFD,
    0xFF, 0xFD, 0xFA, 0xF4, 0xEB, 0xE0, 0xD4, 0xC5, 0xB4, 0xA1, 0x8D, 0x78, 0x61, 0x4A, 0x31, 0x18,
    0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x03, 0x00, 0x02, 0x00, 0x04, 0x00, 0x00,
    0x00, 0x05, 0x06, 0x00, 0x00, 0x07, 0x00, 0x01, 0x00, 0x02, 0x00, 0x03, 0x04, 0x05, 0x00, 0x00,
    0x0B, 0x00, 0x0A, 0x02, 0x01, 0x03, 0x04, 0x07, 0x00, 0x05, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x79, 0x02, 0x00, 0x00, 0x8F, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46, 0x4F, 0x52, 0x4D, 0x49, 0x4C, 0x42, 0x4D, 0x42, 0x4D,
];

const HISTORICAL_FT2_ARPEGGIO_TAB_STEP2: [u8; 256] = [
    0, 1, 2, 0, 1, 2, 0, 1, 2, 0, 1, 2, 0, 1, 2, 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
    2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 0, 2, 2, 0, 2, 2, 2, 2, 2, 0, 2, 2, 0,
    2, 2, 2, 2, 2, 2, 2, 2, 0, 2, 2, 2, 2, 2, 0, 2, 2, 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 0, 2, 2,
    2, 2, 2, 0, 2, 2, 2, 2, 2, 0, 2, 2, 0, 2, 2, 0, 2, 2, 0, 2, 2, 0, 2, 2, 0, 2, 2, 0, 2, 2, 0, 2,
    2, 0, 2, 2, 0, 2, 2, 0, 2, 2, 0, 2, 2, 0, 2, 2, 0, 2, 2, 0, 2, 2, 0, 2, 2, 0, 2, 2, 0, 2, 2, 0,
    2, 2, 2, 2, 2, 0, 2, 2, 0, 2, 2, 0, 2, 2, 0, 2, 2, 0, 2, 2, 0, 2, 2, 0, 2, 2, 0, 2, 2, 0, 2, 2,
    0, 2, 2, 0, 2, 2, 0, 2, 2, 0, 2, 2, 0, 2, 2, 0, 2, 2, 0, 2, 2, 2, 2, 2, 0, 2, 2, 0, 2, 2, 0, 2,
    2, 0, 2, 2, 0, 2, 2, 0, 2, 2, 0, 2, 2, 0, 2, 2, 0, 2, 2, 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
];

fn step1() {
    println!("const HISTORICAL_FT2_ARPEGGIO_TAB_STEP2: [u8; 256] = [");
    for (i, v) in HISTORICAL_FT2_ARPEGGIO_TAB_STEP1.iter().enumerate() {
        if *v as usize != (i % 3) {
            print!("2,");
        } else {
            print!("{},", (i % 3));
        }

        if (i % 32) == 31 {
            println!();
        }
    }
    println!("];");
}

fn step2() {
    let mut old_i: usize = 0;
    let mut old_v: usize = 0;
    println!("let note = match tick {{");
    for (i, v) in HISTORICAL_FT2_ARPEGGIO_TAB_STEP2.iter().enumerate() {
        if old_v != *v as usize {
            if i - old_i > 1 {
                println!("    {}..={} => {},", old_i, i - 1, old_v);
                old_i = i;
                old_v = *v as usize;
            } else {
                println!("    {} => {},", old_i, old_v);
            }
            old_i = i;
            old_v = *v as usize;
        }
    }
    // manual end
    println!("    244..=256 => 2,\n}};")
}

// step3 ask an AI LLM to reorganise code :-)
fn step3(tick: u8) -> u8 {
    match tick {
        0 => 0,
        1 => 1,
        2 => 2,
        3 => 0,
        4 => 1,
        5 => 2,
        6 => 0,
        7 => 1,
        8 => 2,
        9 => 0,
        10 => 1,
        11 => 2,
        12 => 0,
        13 => 1,
        14 => 2,
        15 => 0,
        16..=50 => 2,
        51 => 0,
        52..=53 => 2,
        54 => 0,
        55..=59 => 2,
        60 => 0,
        61..=62 => 2,
        63 => 0,
        64..=71 => 2,
        72 => 0,
        73..=77 => 2,
        78 => 0,
        79..=80 => 2,
        81 => 0,
        82..=92 => 2,
        93 => 0,
        94..=98 => 2,
        99 => 0,
        100..=104 => 2,
        105 => 0,
        106..=107 => 2,
        108 => 0,
        109..=110 => 2,
        111 => 0,
        112..=113 => 2,
        114 => 0,
        115..=116 => 2,
        117 => 0,
        118..=119 => 2,
        120 => 0,
        121..=122 => 2,
        123 => 0,
        124..=125 => 2,
        126 => 0,
        127..=128 => 2,
        129 => 0,
        130..=131 => 2,
        132 => 0,
        133..=134 => 2,
        135 => 0,
        136..=137 => 2,
        138 => 0,
        139..=140 => 2,
        141 => 0,
        142..=143 => 2,
        144 => 0,
        145..=146 => 2,
        147 => 0,
        148..=149 => 2,
        150 => 0,
        151..=152 => 2,
        153 => 0,
        154..=155 => 2,
        156 => 0,
        157..=158 => 2,
        159 => 0,
        160..=164 => 2,
        165 => 0,
        166..=167 => 2,
        168 => 0,
        169..=170 => 2,
        171 => 0,
        172..=173 => 2,
        174 => 0,
        175..=176 => 2,
        177 => 0,
        178..=179 => 2,
        180 => 0,
        181..=182 => 2,
        183 => 0,
        184..=185 => 2,
        186 => 0,
        187..=188 => 2,
        189 => 0,
        190..=191 => 2,
        192 => 0,
        193..=194 => 2,
        195 => 0,
        196..=197 => 2,
        198 => 0,
        199..=200 => 2,
        201 => 0,
        202..=203 => 2,
        204 => 0,
        205..=206 => 2,
        207 => 0,
        208..=209 => 2,
        210 => 0,
        211..=215 => 2,
        216 => 0,
        217..=218 => 2,
        219 => 0,
        220..=221 => 2,
        222 => 0,
        223..=224 => 2,
        225 => 0,
        226..=227 => 2,
        228 => 0,
        229..=230 => 2,
        231 => 0,
        232..=233 => 2,
        234 => 0,
        235..=236 => 2,
        237 => 0,
        238..=239 => 2,
        240 => 0,
        241..=242 => 2,
        243 => 0,
        244..=255 => 2,
    }
}

// here, is the solution...
fn historical_ft2_tick(tick: u8) -> u8 {
    match tick {
        0..=15 => tick % 3,
        51 | 54 | 60 | 63 | 72 | 78 | 81 | 93 | 99 | 105 | 108 | 111 | 114 | 117 | 120 | 123
        | 126 | 129 | 132 | 135 | 138 | 141 | 144 | 147 | 150 | 153 | 156 | 159 | 165 | 168
        | 171 | 174 | 177 | 180 | 183 | 186 | 189 | 192 | 195 | 198 | 201 | 204 | 207 | 210
        | 216 | 219 | 222 | 225 | 228 | 231 | 234 | 237 | 240 | 243 => 0,
        _ => 2,
    }
}

fn main() {
    // step1();
    step2();
    println!("See final manual `historical_ft2_tick()` for a cleaner version.");
}