music21_rs/figuredbass/rules.rs
1//! What a figured-bass realization is held to: music21's
2//! `figuredBass.rules`.
3
4use crate::defaults::IntegerType;
5use crate::pitch::Pitch;
6
7/// The rules a realization keeps, each on or off: which voicings of one
8/// chord are acceptable, which moves from one chord to the next are, and
9/// how the chords that must resolve a particular way are resolved.
10///
11/// Every rule starts out as music21's does.
12#[derive(Clone, Debug, PartialEq)]
13#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
14pub struct Rules {
15 /// Refuse a voicing that leaves out a note of its chord.
16 pub forbid_incomplete_possibilities: bool,
17 /// How far apart, in semitones, the upper parts may lie; `None` lets
18 /// them lie anywhere.
19 pub upper_parts_max_semitone_separation: Option<IntegerType>,
20 /// Refuse a voicing where a part sings above a part over it.
21 pub forbid_voice_crossing: bool,
22 /// Refuse parallel fifths.
23 pub forbid_parallel_fifths: bool,
24 /// Refuse parallel octaves.
25 pub forbid_parallel_octaves: bool,
26 /// Refuse hidden fifths between the outer parts.
27 pub forbid_hidden_fifths: bool,
28 /// Refuse hidden octaves between the outer parts.
29 pub forbid_hidden_octaves: bool,
30 /// Refuse a part moving past where a neighbouring part was.
31 pub forbid_voice_overlap: bool,
32 /// How far each part named may move, in semitones: `(part, semitones)`,
33 /// counting the highest part as one.
34 pub part_movement_limits: Vec<(usize, IntegerType)>,
35 /// Resolve a dominant seventh as a dominant seventh resolves.
36 pub resolve_dominant_seventh_properly: bool,
37 /// Resolve a diminished seventh as a diminished seventh resolves.
38 pub resolve_diminished_seventh_properly: bool,
39 /// Resolve an augmented sixth as an augmented sixth resolves.
40 pub resolve_augmented_sixth_properly: bool,
41 /// Resolve a diminished seventh to the tonic with its root doubled,
42 /// rather than its third, where the inversions do not decide it.
43 pub doubled_root_in_dim7: bool,
44 /// Hold a special resolution to the rules for single voicings too.
45 pub apply_single_possib_rules_to_resolution: bool,
46 /// Hold a special resolution to the rules for moving between voicings
47 /// too.
48 pub apply_consecutive_possib_rules_to_resolution: bool,
49 /// In resolving an Italian sixth, let the root resolve only once and
50 /// the third not be doubled.
51 pub restrict_doublings_in_italian_a6_resolution: bool,
52 /// Keep every part but the bass where it was: music21's
53 /// `_upperPartsRemainSame`, which a realizer sets for a bass note that
54 /// only moves.
55 pub upper_parts_remain_same: bool,
56 /// Hold each part named to a pitch: `(part, pitch)`, counting the
57 /// highest part as one. music21's `_partPitchLimits`.
58 pub part_pitch_limits: Vec<(usize, Pitch)>,
59 /// The parts that must keep their pitch from one voicing to the next:
60 /// music21's `_partsToCheck`.
61 pub parts_to_check: Vec<usize>,
62}
63
64impl Default for Rules {
65 fn default() -> Self {
66 Self {
67 forbid_incomplete_possibilities: true,
68 upper_parts_max_semitone_separation: Some(12),
69 forbid_voice_crossing: true,
70 forbid_parallel_fifths: true,
71 forbid_parallel_octaves: true,
72 forbid_hidden_fifths: true,
73 forbid_hidden_octaves: true,
74 forbid_voice_overlap: true,
75 part_movement_limits: Vec::new(),
76 resolve_dominant_seventh_properly: true,
77 resolve_diminished_seventh_properly: true,
78 resolve_augmented_sixth_properly: true,
79 doubled_root_in_dim7: false,
80 apply_single_possib_rules_to_resolution: false,
81 apply_consecutive_possib_rules_to_resolution: false,
82 restrict_doublings_in_italian_a6_resolution: true,
83 upper_parts_remain_same: false,
84 part_pitch_limits: Vec::new(),
85 parts_to_check: Vec::new(),
86 }
87 }
88}