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