Skip to content

Commit 04327ba

Browse files
authored
Merge pull request #188 from PhysShell/claude/swang-core01-fixed-width-index
SWG-CORE-01: the three canonical index fields are u64 — H3 closed
2 parents d7012f5 + 5705ae8 commit 04327ba

46 files changed

Lines changed: 1195 additions & 171 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

‎cli/src/generation_input.rs‎

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -114,8 +114,8 @@ mod tests {
114114
use griff_core::event::{NoteMarks, Pitch, Tempo, Ticks, TimeSignature, Tuning, Velocity};
115115
use griff_core::midi;
116116
use griff_core::score::{
117-
AtomEvent, AtomNote, EventGroup, EventGroupKind, LossReport, MasterBar, RepeatMarker,
118-
Track, Voice,
117+
index_from_ordinal, AtomEvent, AtomNote, EventGroup, EventGroupKind, LossReport, MasterBar,
118+
RepeatMarker, Track, Voice,
119119
};
120120
use griff_core::slice::TickRange;
121121
use std::cell::Cell;
@@ -137,7 +137,7 @@ mod tests {
137137
.map(|i| {
138138
let start = u32::try_from(i).unwrap().saturating_mul(1920);
139139
MasterBar {
140-
index: i,
140+
index: index_from_ordinal(i),
141141
tick_range: TickRange::new(Ticks(start), Ticks(start.saturating_add(1920)))
142142
.unwrap(),
143143
time_signature: TimeSignature {

‎cli/src/main.rs‎

Lines changed: 16 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ use griff_core::{
2727
ingest,
2828
midi::{self, MidiError},
2929
novelty, rerank,
30-
score::{AtomEvent, LossReport, Score, Track, Voice},
30+
score::{index_from_ordinal, AtomEvent, LossReport, Score, Track, Voice},
3131
scoring,
3232
slice::{self, TickRange},
3333
split, structure, syncopation, technique, unfold,
@@ -860,12 +860,20 @@ fn cmd_phrases(path: &Path) -> Result<(), CliError> {
860860

861861
/// The index of the master bar containing `tick`, or the last bar when the tick
862862
/// falls at or past the end of the timeline.
863-
fn bar_at_tick(score: &Score, tick: u32) -> usize {
863+
///
864+
/// Display only. The two branches are not quite the same kind of number — the
865+
/// hit returns a stored canonical index, the fallback the last *ordinal* — and
866+
/// that pre-existing conflation is left alone here; SWG-CORE-01 only makes
867+
/// both sides the same width so neither has to be narrowed to meet the other.
868+
fn bar_at_tick(score: &Score, tick: u32) -> u64 {
864869
score
865870
.master_bars
866871
.iter()
867872
.find(|mb| tick >= mb.tick_range.start.0 && tick < mb.tick_range.end.0)
868-
.map_or_else(|| score.master_bars.len().saturating_sub(1), |mb| mb.index)
873+
.map_or_else(
874+
|| index_from_ordinal(score.master_bars.len().saturating_sub(1)),
875+
|mb| mb.index,
876+
)
869877
}
870878

871879
/// Renders the heuristic signals that fired at a phrase boundary as a comma
@@ -2328,8 +2336,8 @@ mod tests {
23282336
use griff_core::generate::RhythmTemplate;
23292337
use griff_core::gesture;
23302338
use griff_core::score::{
2331-
AtomEvent, AtomNote, EventGroup, EventGroupKind, LossReport, MasterBar, RepeatMarker,
2332-
Score, SourceMeta, Voice,
2339+
index_from_ordinal, AtomEvent, AtomNote, EventGroup, EventGroupKind, LossReport, MasterBar,
2340+
RepeatMarker, Score, SourceMeta, Voice,
23332341
};
23342342
use griff_core::slice::TickRange;
23352343

@@ -2567,7 +2575,7 @@ mod tests {
25672575
}
25682576

25692577
/// One 4/4 bar with explicit bounds (no arithmetic in the fixture).
2570-
fn mbar(index: usize, start: u32, end: u32) -> MasterBar {
2578+
fn mbar(index: u64, start: u32, end: u32) -> MasterBar {
25712579
MasterBar {
25722580
index,
25732581
tick_range: TickRange::new(Ticks(start), Ticks(end)).expect("ordered"),
@@ -2732,7 +2740,7 @@ mod tests {
27322740
.map(|i| {
27332741
let start = u32::try_from(i).unwrap_or(0).saturating_mul(1920);
27342742
MasterBar {
2735-
index: i,
2743+
index: index_from_ordinal(i),
27362744
tick_range: TickRange::new(Ticks(start), Ticks(start.saturating_add(1920)))
27372745
.expect("ordered"),
27382746
time_signature: TimeSignature {
@@ -3039,7 +3047,7 @@ mod tests {
30393047
.map(|i| {
30403048
let start = u32::try_from(i).expect("small index").saturating_mul(1920);
30413049
MasterBar {
3042-
index: i,
3050+
index: index_from_ordinal(i),
30433051
tick_range: TickRange::new(Ticks(start), Ticks(start.saturating_add(1920)))
30443052
.expect("ordered"),
30453053
time_signature: TimeSignature {

‎cockpit/src/lib.rs‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4044,7 +4044,7 @@ mod tests {
40444044
const BAR: u32 = 3840;
40454045
let master_bars = (0..bars)
40464046
.map(|i| MasterBar {
4047-
index: i as usize,
4047+
index: u64::from(i),
40484048
tick_range: TickRange::new(Ticks(i * BAR), Ticks((i + 1) * BAR)).expect("range"),
40494049
time_signature: TimeSignature::new(4, 4).expect("4/4"),
40504050
tempo: Tempo::from_bpm_integer(120).expect("120"),

‎cockpit/src/swang.rs‎

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -307,8 +307,8 @@ fn line_col(source: &str, offset: u32) -> (u32, u32) {
307307
mod tests {
308308
use griff_core::event::{NoteMarks, Pitch, Tempo, Ticks, TimeSignature, Tuning, Velocity};
309309
use griff_core::score::{
310-
AtomEvent, AtomNote, EventGroup, EventGroupKind, LossReport, MasterBar, RepeatMarker,
311-
Score, Track, Voice,
310+
index_from_ordinal, AtomEvent, AtomNote, EventGroup, EventGroupKind, LossReport, MasterBar,
311+
RepeatMarker, Score, Track, Voice,
312312
};
313313
use griff_core::slice::TickRange;
314314

@@ -321,7 +321,7 @@ mod tests {
321321
.map(|i| {
322322
let start = u32::try_from(i).unwrap() * BAR;
323323
MasterBar {
324-
index: i,
324+
index: index_from_ordinal(i),
325325
tick_range: TickRange::new(Ticks(start), Ticks(start + BAR)).expect("ordered"),
326326
time_signature: TimeSignature {
327327
numerator: 4,

‎core/src/candidate_chain.rs‎

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1028,8 +1028,9 @@ mod tests {
10281028
use crate::layered_path::{PathError, StateId};
10291029
use crate::rerank::SetCandidate;
10301030
use crate::score::{
1031-
AtomEvent, AtomNote, AtomRest, EventGroup, EventGroupKind, ImportWarning, LossReport,
1032-
MasterBar, RepeatMarker, Score, SourceMeta, TechniqueSpan, Track, Voice,
1031+
index_from_ordinal, AtomEvent, AtomNote, AtomRest, EventGroup, EventGroupKind,
1032+
ImportWarning, LossReport, MasterBar, RepeatMarker, Score, SourceMeta, TechniqueSpan,
1033+
Track, Voice,
10331034
};
10341035
use crate::scoring::{Axes, Axis, Scored, WeightPolicy};
10351036
use crate::slice::TickRange;
@@ -1049,7 +1050,7 @@ mod tests {
10491050
for (index, notes) in bars.iter().enumerate() {
10501051
let start = u32::try_from(index).unwrap() * BAR;
10511052
master_bars.push(MasterBar {
1052-
index,
1053+
index: index_from_ordinal(index),
10531054
tick_range: TickRange::new(Ticks(start), Ticks(start + BAR)).unwrap(),
10541055
time_signature: TimeSignature::new(4, 4).unwrap(),
10551056
tempo: Tempo::from_bpm_integer(120).unwrap(),
@@ -1512,7 +1513,7 @@ mod tests {
15121513

15131514
/// Every fact of a master bar, in a comparable form (`MasterBar` is not
15141515
/// `PartialEq`, and `Tempo` holds an `f64`).
1515-
fn bar_facts(bar: &MasterBar) -> (usize, TickRange, TimeSignature, Tempo, RepeatMarker) {
1516+
fn bar_facts(bar: &MasterBar) -> (u64, TickRange, TimeSignature, Tempo, RepeatMarker) {
15161517
(
15171518
bar.index,
15181519
bar.tick_range,

‎core/src/dump.rs‎

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -49,8 +49,12 @@ pub struct NormTrack {
4949
/// A normalized bar: shared transport plus the track's voices in it.
5050
#[derive(Debug, Clone, PartialEq, Serialize)]
5151
pub struct NormBar {
52-
/// Zero-based bar index.
53-
pub index: usize,
52+
/// Zero-based bar index, copied from the stored `MasterBar::index`.
53+
///
54+
/// Carries a canonical value, so it carries the canonical width: reducing
55+
/// it to `usize` here would be a truncating conversion on a 32-bit target,
56+
/// inside a type that is serialized (spec §1.2, SWG-CORE-01).
57+
pub index: u64,
5458
/// Meter as `[numerator, denominator]`.
5559
pub time_sig: [u8; 2],
5660
/// Tempo in BPM at the bar start.

‎core/src/generate.rs‎

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,8 @@ use crate::event::{
55
};
66
use crate::pitch::{PitchClassSet, PitchRange, PitchSelectionError, ScaleLadder};
77
use crate::score::{
8-
AtomEvent, AtomNote, EventGroup, EventGroupKind, LossReport, MasterBar, RepeatMarker, Score,
9-
Track, Voice,
8+
index_from_ordinal, AtomEvent, AtomNote, EventGroup, EventGroupKind, LossReport, MasterBar,
9+
RepeatMarker, Score, Track, Voice,
1010
};
1111
use crate::slice::TickRange;
1212

@@ -447,7 +447,7 @@ fn bars_to_score(
447447
let tick_range =
448448
TickRange::new(bar_start, bar_end).map_err(|_| GenerationError::InvalidConstraints)?;
449449
master_bars.push(MasterBar {
450-
index,
450+
index: index_from_ordinal(index),
451451
tick_range,
452452
time_signature: c.time_signature,
453453
tempo: c.tempo,

‎core/src/generation_input.rs‎

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -521,8 +521,8 @@ mod tests {
521521
use crate::corpus::{ChunkId, ChunkMeta, SourceFormat, SourceRef};
522522
use crate::event::{NoteMarks, Pitch, Tempo, Ticks, TimeSignature, Tuning, Velocity};
523523
use crate::score::{
524-
AtomEvent, AtomNote, EventGroup, EventGroupKind, LossReport, MasterBar, RepeatMarker,
525-
Score, Track, Voice,
524+
index_from_ordinal, AtomEvent, AtomNote, EventGroup, EventGroupKind, LossReport, MasterBar,
525+
RepeatMarker, Score, Track, Voice,
526526
};
527527
use crate::slice::TickRange;
528528

@@ -562,7 +562,7 @@ mod tests {
562562
.map(|i| {
563563
let start = u32::try_from(i).expect("small").saturating_mul(1920);
564564
MasterBar {
565-
index: i,
565+
index: index_from_ordinal(i),
566566
tick_range: TickRange::new(Ticks(start), Ticks(start.saturating_add(1920)))
567567
.expect("ordered"),
568568
time_signature: TimeSignature {

‎core/src/gp.rs‎

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -31,8 +31,9 @@ use crate::{
3131
TechniqueEvidence, Tempo, Ticks, TimeSignature, Tuning, Velocity,
3232
},
3333
score::{
34-
AtomEvent, AtomNote, AtomRest, EventGroup, EventGroupKind, ImportWarning, LossReport,
35-
MasterBar, RepeatMarker, Score, SourceMeta, TechniqueSpan, Track, Voice,
34+
index_from_ordinal, AtomEvent, AtomNote, AtomRest, EventGroup, EventGroupKind,
35+
ImportWarning, LossReport, MasterBar, RepeatMarker, Score, SourceMeta, TechniqueSpan,
36+
Track, Voice,
3637
},
3738
slice::TickRange,
3839
};
@@ -279,7 +280,7 @@ fn build_gp_master_bars(
279280
.unwrap_or(Tempo::FALLBACK_120);
280281

281282
MasterBar {
282-
index: idx,
283+
index: index_from_ordinal(idx),
283284
tick_range: TickRange {
284285
start: Ticks(start),
285286
end: Ticks(end),

‎core/src/midi.rs‎

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -15,8 +15,8 @@ use crate::{
1515
event::{NoteMarks, Pitch, Tempo, Ticks, TimeSignature, Tuning, ValidationError, Velocity},
1616
fretboard::{self, assign_inferred_positions, FingeringWeights},
1717
score::{
18-
AtomEvent, AtomNote, EventGroup, EventGroupKind, ImportWarning, LossReport, MasterBar,
19-
RepeatMarker, Score, SourceMeta, Track as ScoreTrack, Voice,
18+
index_from_ordinal, AtomEvent, AtomNote, EventGroup, EventGroupKind, ImportWarning,
19+
LossReport, MasterBar, RepeatMarker, Score, SourceMeta, Track as ScoreTrack, Voice,
2020
},
2121
slice::TickRange,
2222
};
@@ -345,7 +345,7 @@ fn abs_to_delta(
345345
/// other tempo converts to its nearest in-range value and records a
346346
/// [`ImportWarning::TempoApproximated`] on `loss` (S16 Phase 4-pre A: an
347347
/// approximation is a reported fact, never a silent rounding).
348-
fn tempo_to_micros(tempo: Tempo, bar_index: usize, loss: &mut LossReport) -> u32 {
348+
fn tempo_to_micros(tempo: Tempo, bar_index: u64, loss: &mut LossReport) -> u32 {
349349
let max_u24 = u32::from(u24::max_value());
350350
if let Some(exact) = tempo.to_micros_per_quarter_exact() {
351351
if (1..=max_u24).contains(&exact) {
@@ -513,7 +513,7 @@ fn build_master_bars(
513513
.map_err(|_| MidiError::TickOverflow)?;
514514

515515
master_bars.push(MasterBar {
516-
index,
516+
index: index_from_ordinal(index),
517517
tick_range,
518518
time_signature: sig,
519519
tempo,
@@ -545,7 +545,7 @@ fn build_score_track(
545545
let mut loss = LossReport::new();
546546
let name = name_result.unwrap_or_else(|()| {
547547
loss.add(ImportWarning::TrackNameInvalidUtf8 {
548-
track_index: raw_idx,
548+
track_index: index_from_ordinal(raw_idx),
549549
});
550550
None
551551
});
@@ -829,6 +829,7 @@ mod tests {
829829
bar_ticks, build_master_bars, build_score_meta_track, export_score, import_score,
830830
tempo_to_micros, MidiError, Ppqn,
831831
};
832+
use crate::score::index_from_ordinal;
832833
use crate::{
833834
event::{NoteMarks, Pitch, Tempo, Ticks, TimeSignature, Tuning, Velocity},
834835
score::{
@@ -893,7 +894,7 @@ mod tests {
893894
// different exact tempo — projected again (clean), no second event.
894895
let tempo_same_mpq = Tempo::from_micros_per_quarter(495_868).expect("495 868 µs is valid");
895896
let bar = |index: usize, tempo: Tempo| MasterBar {
896-
index,
897+
index: index_from_ordinal(index),
897898
tick_range: TickRange::new(
898899
Ticks(u32::try_from(index).expect("small") * 1920),
899900
Ticks((u32::try_from(index).expect("small") + 1) * 1920),
@@ -953,7 +954,7 @@ mod tests {
953954
);
954955

955956
let bar = |index: usize, tempo: Tempo| MasterBar {
956-
index,
957+
index: index_from_ordinal(index),
957958
tick_range: TickRange::new(
958959
Ticks(u32::try_from(index).expect("small") * 1920),
959960
Ticks((u32::try_from(index).expect("small") + 1) * 1920),

0 commit comments

Comments
 (0)