mirror of
https://github.com/italicsjenga/agb.git
synced 2024-12-23 00:01:34 +11:00
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:
commit
c099fc9a61
|
@ -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
|
||||
|
|
|
@ -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,
|
||||
|
|
Loading…
Reference in a new issue