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