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