Skip to main content

acorde_core/
lib.rs

1//! Platform-agnostic music score data model and command engine (undo/redo), with zero I/O
2//! and zero rendering. Pairs with [`acorde-io`](https://docs.rs/acorde-io) for MusicXML/MIDI/ABC
3//! parsing and [`acorde-layout`](https://docs.rs/acorde-layout) for logical score layout.
4
5pub mod model;
6
7pub use model::arrange::{
8    AccordionAnalysis, AccordionBassMode, AccordionInversion, AccordionLossPolicy,
9    AccordionMelodicVoice, AccordionPattern, AccordionReductionDiagnostic,
10    AccordionReductionOptions, AccordionReductionResult, AccordionSourceMapping,
11    AccordionSwingPolicy, ArrangeResult, GuidedAccordionOptions, GuidedAccordionResult,
12    GuidedArrangeDiagnostic, LayeredAccordionOptions, LayeredAccordionResult, PartCandidate,
13    PositionedAccordionChord, analyze_for_accordion, arrange_for_accordion,
14    arrange_for_accordion_with_options, arrange_with_explicit_chords, arrange_with_layers,
15};
16pub use model::arrange_presets::{
17    AccordionPresetCapabilities, AccordionPresetConfig, AccordionPresetDescription,
18    AccordionPresetResult, AccordionPresetSelection, AccordionShuffleOptions,
19    accordion_preset_capabilities, arrange_accordion_preset, arrange_from_resolved_preset,
20    shuffle_accordion_preset,
21};
22pub use model::authored_chords::{
23    AuthoredChordAnnotation, AuthoredChordDiagnostic, AuthoredChordOptions, AuthoredChordResult,
24    annotate_from_authored_chords,
25};
26pub use model::change_hint::{ChangeHint, ChangeScope};
27pub use model::chord_plan::{
28    BeatFraction, CHORD_PLAN_CONTRACT_VERSION, ChordPlan, ChordPlanCoverage, ChordPlanDiagnostic,
29    ChordPlanEntry, ChordPlanExtractionMode, ChordPlanExtractionOptions, ChordPlanExtractionResult,
30    ChordPlanOrigin, ChordPlanPosition, ChordPlanPresetResult, ChordPlanSource,
31    chord_plan_to_preset_selection, extract_chord_plan,
32};
33pub use model::chord_proposals::{
34    CHORD_PROPOSAL_CONTRACT_VERSION, ChordChangedSpan, ChordProposalArrangementResult,
35    ChordProposalCandidate, ChordProposalDiagnostic, ChordProposalRequest, ChordProposalResult,
36    ResolvedChordProposal, arrange_from_chord_proposal, suggest_chord_plans,
37};
38pub use model::commands::{
39    AddHairpinCmd, AddMeasureCmd, AddNoteCmd, AddPartCmd, AddPedalCmd, AddPitchCmd, AddSpannerCmd,
40    AddStaffCmd, BatchCmd, Command, CommandStack, CycleEnharmonicSpellingCmd, DeleteMeasureCmd,
41    DeleteNoteCmd, DeletePartCmd, DeleteStaffCmd, DurationScale, ExchangeVoicesCmd,
42    ExplodeChordPitchesCmd, ExplodeVoicesCmd, ImplodeStavesCmd, JoinMeasuresCmd,
43    MoveOrCopyVoiceRangeCmd, NewScoreCmd, PasteRangeCmd, PasteScoreFragmentCmd, PasteVoiceCmd,
44    RealizeChordSymbolsCmd, RemoveScoreViewCmd, RemoveSpannerCmd, RemoveTrailingEmptyMeasuresCmd,
45    ReorderPartsCmd, ResequenceRehearsalMarksCmd, RespellScoreCmd, RespellScoreToKeyCmd,
46    RespellStaffRegionCmd, ScaleVoiceRangeCmd, ScoreFragmentPastePolicy, SetArpeggioCmd,
47    SetBarlineCmd, SetChordSymbolCmd, SetClefCmd, SetCrossStaffCmd, SetCueCmd, SetDurationCmd,
48    SetDynamicCmd, SetExpressionTextCmd, SetFiguredBassCmd, SetFingeringCmd, SetFingeringsCmd,
49    SetGlissandoCmd, SetGraceCmd, SetGuitarBendAlterCmd, SetGuitarBendCurveCmd,
50    SetGuitarTechniqueCmd, SetHarmonyRangeCmd, SetHarpPedalDiagramsCmd, SetHiddenCmd,
51    SetInstrumentDefinitionCmd, SetInstrumentIdCmd, SetKeySignatureCmd, SetLyricCmd,
52    SetMeasureInstrumentChangeCmd, SetMeasureTablatureChangeCmd, SetMeasureTextCmd, SetMetadataCmd,
53    SetMidMeasureClefsCmd, SetMidiInstrumentCmd, SetMultiRestCmd, SetNavigationMarkCmd,
54    SetNoteHeadCmd, SetNotePlacementCmd, SetObjectStyleOverridesCmd, SetOttavaCmd, SetPageBreakCmd,
55    SetPartGroupCmd, SetPartNameCmd, SetPercussionKitCmd, SetRehearsalMarkCmd,
56    SetScoreStyleOverridesCmd, SetScoreTextCmd, SetSectionBreakCmd, SetStaffPresentationCmd,
57    SetStemCmd, SetStringNumberCmd, SetSystemBreakCmd, SetSystemBreakIntervalCmd,
58    SetTabPositionCmd, SetTablatureConfigCmd, SetTechniqueTextCmd, SetTempoAtMeasureCmd,
59    SetTempoCmd, SetTimeSignatureCmd, SetTransposeCmd, SetTupletCmd, SetUnpitchedCmd, SetVoltaCmd,
60    SplitMeasureCmd, ToggleArticulationCmd, ToggleSlurCmd, ToggleTieCmd, ToggleTrillLineCmd,
61    TransposeStaffRegionCmd, TupletScalePolicy, UnrollRepeatsCmd, UpdateSpannerCmd,
62    UpsertScoreViewCmd, command_key, command_label,
63};
64pub use model::duration::Duration;
65pub use model::engine::{EngineHistory, HistoryConflict, HistoryRelation, ScoreEngine};
66pub use model::fragment::{
67    MIN_SUPPORTED_SCORE_FRAGMENT_CONTRACT_VERSION, SCORE_FRAGMENT_CONTRACT_VERSION, ScoreFragment,
68    ScoreFragmentCrossStaffTarget, ScoreFragmentDiagnostic, ScoreFragmentMeasure,
69    ScoreFragmentMeasureAttributes, ScoreFragmentSelection, ScoreFragmentVoice,
70    extract_score_fragment,
71};
72pub use model::gm::{drum_name, program_name};
73pub use model::harmony::{detect_chord, roman_numeral};
74pub use model::interval::{Interval, IntervalQuality};
75pub use model::musical_diff::{
76    MusicalChange, MusicalChangeKind, MusicalComparisonDiagnostic, MusicalComparisonOptions,
77    MusicalComparisonResult, NoteCorrespondence, StructurePolicy, VoiceAddr, VoiceCorrespondence,
78    compare_musical_positions,
79};
80pub use model::notation::{
81    AccidentalDisplay, Articulation, Barline, BeamState, ChordBarre, ChordDefinition,
82    ChordDefinitionMember, ChordDegree, ChordSymbol, Clef, CrossStaff, Dynamic, FiguredBassFigure,
83    FingeringSelectionPolicy, GuitarTechnique, HairpinKind, KeySignature, Lyric, NoteHead,
84    OttavaKind, StyledText, TabPosition, TablatureConfig, TextStyle, TimeSignature, TupletBoundary,
85    TupletInfo, VerseLyric,
86};
87pub use model::omr::{
88    MAX_OMR_ANNOTATIONS, MAX_OMR_EVENTS_PER_MEASURE, MAX_OMR_MEASURES, MAX_OMR_PAGES,
89    OMR_PROPOSAL_CONTRACT_VERSION, OmrCommandPlan, OmrDiagnostic, OmrDiagnosticKind,
90    OmrMeasureProposal, OmrMeasureTarget, OmrNoteAnnotation, OmrNoteAnnotationProposal,
91    OmrNoteTarget, OmrPage, OmrProposal, OmrRegion, OmrRhythmicEvent, OmrUnresolvedItem,
92};
93pub use model::pitch::{Pitch, Step};
94pub use model::playback::{
95    DynamicTimeline, MAX_PLAYBACK_COMPARISON_EVENTS, MAX_TAB_PERFORMANCE_EVENTS, MetronomeConfig,
96    OFFLINE_RENDER_CONTRACT_VERSION, OfflineRenderDiagnostic, OfflineRenderDiagnosticKind,
97    OfflineRenderFormat, OfflineRenderFrameEvent, OfflineRenderManifest,
98    OfflineRenderMeasureAddress, OfflineRenderNavigationPolicy, OfflineRenderRequest,
99    OfflineRenderResult, OfflineRenderScope, OfflineRenderSemanticEventKind,
100    OfflineRenderSemanticFrameEvent, PLAYBACK_COMPARISON_CONTRACT_VERSION,
101    PLAYBACK_ROUTING_CONTRACT_VERSION, PLAYBACK_TIMING_CORPUS_CONTRACT_VERSION, PlaybackAuxSend,
102    PlaybackBusRoute, PlaybackEffectRoute, PlaybackEvent, PlaybackOptions, PlaybackPosition,
103    PlaybackRealizationProfile, PlaybackRoutingConfig, PlaybackRoutingManifest, PlaybackTimingCase,
104    PlaybackTimingCaseReport, PlaybackTimingCorpusReport, PlaybackTimingMismatch,
105    PlaybackTimingReport, PlaybackTimingTolerance, TAB_PERFORMANCE_CONTRACT_VERSION,
106    TAB_ROUND_TRIP_CONTRACT_VERSION, TablaturePerformanceDiagnostic, TablaturePerformanceEvent,
107    TablaturePerformanceReport, TablatureRoundTripDiagnostic, TablatureRoundTripReport,
108    build_offline_render_manifest, build_playback_routing_manifest, compare_playback_timing,
109    compute_playback_position, evaluate_playback_timing_corpus, project_tablature_performance,
110    tablature_round_trip_report, to_playback_events, to_playback_events_bounded,
111};
112pub use model::repeat::measure_sequence;
113pub use model::scale::{Scale, ScaleKind};
114pub use model::score::{
115    GuitarBendPoint, HarpPedalDiagram, HarpPedalPosition, InstrumentDefinition, InstrumentRange,
116    Measure, MeasureLength, MidMeasureClef, MidiAftertouch, MidiControlChange, MidiPitchBend,
117    MidiProgramChange, NotationSpanner, NotationSpannerKind, Note, NoteAddr, ObjectStyleOverride,
118    ObjectStyleTarget, Part, PartGroup, PartGroupSymbol, PercussionInstrument,
119    RegionalTranspositionTarget, RespellPolicy, Score, ScoreChange, ScoreMetadata, ScorePatch,
120    ScoreSettings, ScoreStats, ScoreTemplate, ScoreView, ScoreViewLayoutOverrides, Staff,
121    StaffGroup, StaffKind, StaffNoteheadScheme, StaffPresentation, StyleImportProvenance,
122    TablatureFretMarkStyle, TablatureRhythmDisplay, ViewStaffKindOverride, ViewStaffRef, ViewStyle,
123    ViewStyleOverride, ViewStyleProperty, ViewTranspositionPolicy, VoltaBracket, apply_patch,
124    assign_tablature_positions, compute_beams, diff, measure_beats_remaining,
125    optimize_tablature_positions, respell_score, respell_score_to_key, respell_staff_region,
126    score_duration_secs, score_duration_secs_region, score_patch, suggested_stem_up, transpose,
127    transpose_checked, transpose_staff_region_checked, tuplet_group_ranges, voice_duration_beats,
128};
129pub use model::structural_plan::{
130    STRUCTURAL_CHANGE_PLAN_CONTRACT_VERSION, StructuralChangeDiagnostic,
131    StructuralChangeDiagnosticKind, StructuralChangePlan, StructuralMeasureStructure,
132    plan_structural_change,
133};
134pub use model::validate::{
135    GuitarBendCurveValidationReason, InstrumentDefinitionValidationReason, InstrumentRangeKind,
136    ObjectStyleValidationReason, PercussionInstrumentValidationReason, ScoreViewValidationReason,
137    SpannerEndpoint, StaffPresentationValidationReason, TablatureValidationReason, ValidationError,
138    ValidationReport, ValidationWarning, validate,
139};
140
141/// Current Score JSON schema version produced by this crate.
142pub const SCORE_SCHEMA_VERSION: u32 = 1;
143
144#[derive(Debug, thiserror::Error)]
145pub enum Error {
146    #[error("part index {0} out of range")]
147    PartNotFound(usize),
148    #[error("staff index {0} out of range")]
149    StaffNotFound(usize),
150    #[error("measure index {0} out of range")]
151    MeasureNotFound(usize),
152    #[error("note index {0} out of range")]
153    NoteNotFound(usize),
154    #[error("voice index {0} out of range")]
155    VoiceOutOfRange(usize),
156    #[error("{0}")]
157    InvalidCommand(String),
158    #[error("nothing to undo")]
159    NothingToUndo,
160    #[error("nothing to redo")]
161    NothingToRedo,
162    #[error("clipboard is empty")]
163    ClipboardEmpty,
164    #[error("cannot delete the last staff of a part")]
165    CannotDeleteLastStaff,
166    #[error("invalid patch: {0}")]
167    InvalidPatch(String),
168    #[error("score failed structural validation")]
169    InvalidScore,
170    #[error("engine history base score does not match the supplied score")]
171    HistoryBaseMismatch,
172    #[error("engine history is not a safe append-only extension")]
173    HistoryNotAppendable,
174    #[error("invalid playback comparison tolerance")]
175    InvalidPlaybackComparison,
176    #[error("invalid offline render request")]
177    InvalidOfflineRenderRequest,
178    #[error("invalid playback routing configuration")]
179    InvalidPlaybackRouting,
180    #[error("invalid playback timing corpus")]
181    InvalidPlaybackTimingCorpus,
182    #[error("playback comparison contains too many events ({0})")]
183    PlaybackComparisonTooLarge(usize),
184    #[error("tablature performance projection contains too many events ({0})")]
185    TabPerformanceTooLarge(usize),
186    #[error("tablature round-trip serialization failed: {0}")]
187    TabRoundTripSerialization(String),
188}