Notes are 1 indexed, not 0 indexed (#696)

Versions of xmrs below 0.4.1 (unreleased, 0.4.2 is on crates.io but
0.4.1 is in the repo) have a bug where they swap linear and amiga
frequencies. This caused all old versions of agb (which were using
version 0.3) to use the amiga frequency table rather than the linear
one. Technically it sounds slightly wrong but it is kinda hard to tell.

Since agb 0.20.0, we are now using xmrs 0.5, which correctly reports the
frequency type for the XM file. That pointed out an error in the
note_to_speed method for linear frequencies (since those are now being
used). It turns out that the formula for calculating the frequency
expects a 0 based index for the note, but we were passing a 1 based
index for the note. Moving this down a note fixes the issue where things
were being played at the wrong frequency.

- [x] Changelog updated

We should release 0.20.1 to fix this issue pretty soon.
This commit is contained in:
Gwilym Inzani 2024-05-15 22:02:40 +01:00 committed by GitHub
commit c099fc9a61
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
2 changed files with 11 additions and 7 deletions

View file

@ -7,6 +7,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
## [Unreleased]
### Fixed
- Fixed an issue with agb tracker where XM files with linear frequencies were playing the wrong notes
## [0.20.0] - 2024/05/14
### Added

View file

@ -472,7 +472,7 @@ fn note_to_speed(
FrequencyType::LinearFrequencies => {
note_to_frequency_linear(note, fine_tune, relative_note)
}
FrequencyType::AmigaFrequencies => note_to_frequency_amega(note, fine_tune, relative_note),
FrequencyType::AmigaFrequencies => note_to_frequency_amiga(note, fine_tune, relative_note),
};
let gba_audio_frequency = 32768f64;
@ -482,27 +482,27 @@ fn note_to_speed(
}
fn note_to_frequency_linear(note: Note, fine_tune: f64, relative_note: i8) -> f64 {
let real_note = (note as usize as f64) + (relative_note as f64);
let real_note = (note as usize as f64) + (relative_note as f64) - 1.0; // notes are 1 indexed but below is 0 indexed
let period = 10.0 * 12.0 * 16.0 * 4.0 - real_note * 16.0 * 4.0 - fine_tune / 2.0;
8363.0 * 2.0f64.powf((6.0 * 12.0 * 16.0 * 4.0 - period) / (12.0 * 16.0 * 4.0))
}
fn note_to_frequency_amega(note: Note, fine_tune: f64, relative_note: i8) -> f64 {
fn note_to_frequency_amiga(note: Note, fine_tune: f64, relative_note: i8) -> f64 {
let note = (note as usize)
.checked_add_signed(relative_note as isize)
.expect("Note gone negative");
let pos = ((note % 12) * 8 + (fine_tune / 16.0) as usize).min(AMEGA_FREQUENCIES.len() - 2);
let pos = ((note % 12) * 8 + (fine_tune / 16.0) as usize).min(AMIGA_FREQUENCIES.len() - 2);
let frac = (fine_tune / 16.0) - (fine_tune / 16.0).floor();
let period = ((AMEGA_FREQUENCIES[pos] as f64 * (1.0 - frac))
+ AMEGA_FREQUENCIES[pos + 1] as f64 * frac)
let period = ((AMIGA_FREQUENCIES[pos] as f64 * (1.0 - frac))
+ AMIGA_FREQUENCIES[pos + 1] as f64 * frac)
* 32.0 // docs say 16 here, but for some reason I need 32 :/
/ (1 << ((note as i64) / 12)) as f64;
8363.0 * 1712.0 / period
}
static AMEGA_FREQUENCIES: &[u32] = &[
static AMIGA_FREQUENCIES: &[u32] = &[
907, 900, 894, 887, 881, 875, 868, 862, 856, 850, 844, 838, 832, 826, 820, 814, 808, 802, 796,
791, 785, 779, 774, 768, 762, 757, 752, 746, 741, 736, 730, 725, 720, 715, 709, 704, 699, 694,
689, 684, 678, 675, 670, 665, 660, 655, 651, 646, 640, 636, 632, 628, 623, 619, 614, 610, 604,