Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Format voices across staves and parts #183

Merged
merged 71 commits into from
Dec 27, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
71 commits
Select commit Hold shift + click to select a range
2c3d851
Prototype the new Part rendering object
jaredjj3 Dec 16, 2023
06abf70
Add PartMeasure type
jaredjj3 Dec 17, 2023
4c74870
Update address with the new hierarchy
jaredjj3 Dec 17, 2023
b34042b
Scaffold new seed class
jaredjj3 Dec 18, 2023
6308f00
Scaffold new Measure class
jaredjj3 Dec 18, 2023
a5a7365
Add PartMap type
jaredjj3 Dec 18, 2023
3b0e62d
Use PartMap in Measure
jaredjj3 Dec 18, 2023
1a914de
Implement partial measure creation in seed2
jaredjj3 Dec 18, 2023
6e5e2a5
Scaffold new system class
jaredjj3 Dec 18, 2023
c9f0d96
Implement rough version of seed splitting
jaredjj3 Dec 18, 2023
d98c27e
Pipe address to measure
jaredjj3 Dec 18, 2023
10030c9
Scaffold measure fragment
jaredjj3 Dec 18, 2023
c9de1c4
Scaffold bar style calculations
jaredjj3 Dec 18, 2023
3a2831b
Replace PartMap with PartScoped types
jaredjj3 Dec 19, 2023
a878cb5
Calculate measure fragment data
jaredjj3 Dec 20, 2023
40a3a56
Create measure fragments containing all parts
jaredjj3 Dec 21, 2023
30c80fb
Create parts in measure fragment
jaredjj3 Dec 21, 2023
46b9b48
Handle backup and forward directions
jaredjj3 Dec 21, 2023
fb82aef
Create staves in new Part
jaredjj3 Dec 21, 2023
d16ac6a
Flesh out measure fragment min required width calculation
jaredjj3 Dec 21, 2023
5bd846e
Render stave entries directly for justification measurement
jaredjj3 Dec 21, 2023
739d00d
Flesh out MeasureFragment min required width calculationsgst
jaredjj3 Dec 21, 2023
e0bc1ff
Wire in new seed and temporarily remove part name rendering feature
jaredjj3 Dec 21, 2023
886bde1
Precalculate measure widths at seed time
jaredjj3 Dec 22, 2023
302e066
Implement system rendering
jaredjj3 Dec 22, 2023
929066f
Use currentMeasure instead of going through data
jaredjj3 Dec 22, 2023
b2f369b
Setup measure rendering
jaredjj3 Dec 22, 2023
4ac5730
Pipe prescribed measure fragment widths from seed to measure fragments
jaredjj3 Dec 22, 2023
0e53fe2
Position system renderings
jaredjj3 Dec 22, 2023
fe335e0
Account for stave connector braces when calculating width
jaredjj3 Dec 22, 2023
2970914
Remove stave connector renderings from measure
jaredjj3 Dec 22, 2023
07008ee
Move MeasureFragmentWidth from types to measurefragment
jaredjj3 Dec 22, 2023
7cb69ef
Wire part rendering to stave
jaredjj3 Dec 22, 2023
8f6009d
Add stave distance when rendering parts
jaredjj3 Dec 22, 2023
c893469
Wire up measure fragment to parts
jaredjj3 Dec 22, 2023
f34c422
Remove legacy code
jaredjj3 Dec 22, 2023
85b7b6e
Rename part2 to part
jaredjj3 Dec 22, 2023
cf02f68
Fix part.ts reference
jaredjj3 Dec 22, 2023
30791b9
Fix system measure index
jaredjj3 Dec 22, 2023
6ba8e30
Do not stretch the last system
jaredjj3 Dec 22, 2023
3b07454
Conditionally stretch the last system
jaredjj3 Dec 22, 2023
53cafd6
Fix measure fragment event calculation
jaredjj3 Dec 22, 2023
6a5359b
Fix system measure index assignment at seed split time
jaredjj3 Dec 22, 2023
66bc90c
Account for the end barline when measuring widths
jaredjj3 Dec 22, 2023
3aabf20
Render part names
jaredjj3 Dec 23, 2023
851e3e4
Rename staveOffset to staveOffsetX
jaredjj3 Dec 23, 2023
969c7a8
Update snapshots and render stave connectors
jaredjj3 Dec 23, 2023
3034bcf
Prevent Backup from being negative and update snapshots
jaredjj3 Dec 23, 2023
bdb40f8
Update snapshot
jaredjj3 Dec 23, 2023
d38d78e
Add stave signature helpers for clef changes
jaredjj3 Dec 23, 2023
0f4a5c0
Add measure boundary detection to stave signature
jaredjj3 Dec 23, 2023
c24f472
Render measure boundary clef changes at the end of the measure
jaredjj3 Dec 23, 2023
cec5398
Remove unused import
jaredjj3 Dec 23, 2023
4943090
Account for end clef widths
jaredjj3 Dec 23, 2023
c9599f0
Update snapshot
jaredjj3 Dec 23, 2023
23b0016
Render part stave connector and update snapshots
jaredjj3 Dec 23, 2023
e53594d
Update multi system spanner snapshot
jaredjj3 Dec 23, 2023
2345e01
Fix measure fragment positioning
jaredjj3 Dec 24, 2023
fa17de3
Remove TODO and add clarifying comment
jaredjj3 Dec 24, 2023
3c622b5
Fix measure allocation and account for endbarlines more accurately
jaredjj3 Dec 24, 2023
e49fca8
Account for stave offset and end barline correctly when splitting mea…
jaredjj3 Dec 24, 2023
c4b8c36
Fix measure fragment creation
jaredjj3 Dec 25, 2023
5220fc4
Fix extra stave connectors being added
jaredjj3 Dec 25, 2023
b170007
Fix measure fragmentation
jaredjj3 Dec 26, 2023
0804a4b
Account for measure width for multirest measures
jaredjj3 Dec 26, 2023
9d9b8e7
Fix measure fragmentation
jaredjj3 Dec 26, 2023
0a4a6ae
Add padding to complex time signatures
jaredjj3 Dec 27, 2023
33db8d4
Do not unconditionally add stave signatures during measure fragmentation
jaredjj3 Dec 27, 2023
b93b8e0
Update snapshots
jaredjj3 Dec 27, 2023
741e496
Render multi_stave_single_part_formatting.musicxml
jaredjj3 Dec 27, 2023
31507a2
Render multi_part_formatting.musicxml
jaredjj3 Dec 27, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 9 additions & 0 deletions src/musicxml/types.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
import { Measure } from './measure';
import { Part } from './part';

/**
* StaveLayout describes how a stave is positioned.
*
Expand All @@ -19,3 +22,9 @@ export type SystemLayout = {
topSystemDistance: number | null;
systemDistance: number | null;
};

/** A part and measure. */
export type PartMeasure = {
part: Part;
measure: Measure;
};
19 changes: 8 additions & 11 deletions src/rendering/address.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,15 +25,13 @@ export class Address<T extends AddressType = AddressType> {
private type: T;
private id: symbol;
private parent: Address | null;
private children: Address[];
private context: AddressContext<T>;

private constructor(opts: { type: T; id: symbol; parent: Address | null; context: AddressContext<T> }) {
this.type = opts.type;
this.id = opts.id;
this.parent = opts.parent;
this.context = opts.context;
this.children = [];
}

/** Creates an address for a system. */
Expand All @@ -48,7 +46,6 @@ export class Address<T extends AddressType = AddressType> {
): Address<T> {
const id = Symbol(type);
const address = new Address({ type, id, parent, context });
parent?.children.push(address);
return address;
}

Expand Down Expand Up @@ -101,15 +98,9 @@ export class Address<T extends AddressType = AddressType> {
return voiceAddress.context?.voiceIndex;
}

/** Creates an address for a part. */
part(context: AddressContext<'part'>): Address<'part'> {
this.assertThisIsA('system');
return Address.create('part', this, context);
}

/** Creates an address for a measure. */
measure(context: AddressContext<'measure'>): Address<'measure'> {
this.assertThisIsA('part');
this.assertThisIsA('system');
return Address.create('measure', this, context);
}

Expand All @@ -119,9 +110,15 @@ export class Address<T extends AddressType = AddressType> {
return Address.create('measurefragment', this, context);
}

/** Creates an address for a part. */
part(context: AddressContext<'part'>): Address<'part'> {
this.assertThisIsA('measurefragment');
return Address.create('part', this, context);
}

/** Creates an address for a stave. */
stave(context: AddressContext<'stave'>): Address<'stave'> {
this.assertThisIsA('measurefragment');
this.assertThisIsA('part');
return Address.create('stave', this, context);
}

Expand Down
30 changes: 30 additions & 0 deletions src/rendering/division.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,16 @@ import { Fraction } from '@/util';
export class Division {
private constructor(private fraction: Fraction) {}

/** Creates an empty division. */
static zero() {
return new Division(new Fraction(0));
}

/** Creates a division with the maximum safe value. */
static max() {
return new Division(new Fraction(Number.MAX_SAFE_INTEGER));
}

/**
* Creates a Division.
*
Expand All @@ -28,6 +38,26 @@ export class Division {
return this.fraction.isEquivalent(value.fraction);
}

/** Returns if the other divisions is less than this. */
isLessThan(value: Division): boolean {
return this.toBeats() < value.toBeats();
}

/** Returns if the other divisions is greater than this. */
isGreaterThan(value: Division): boolean {
return this.toBeats() > value.toBeats();
}

/** Returns if the other divisions is less than or equal to this. */
isLessThanOrEqualTo(value: Division): boolean {
return this.isLessThan(value) || this.isEqual(value);
}

/** Returns if the other divisions is greater than or equal to this. */
isGreaterThanOrEqualTo(value: Division): boolean {
return this.isGreaterThan(value) || this.isEqual(value);
}

/** Returns the sum as a new Division. */
add(value: Division) {
const fraction = this.fraction.add(value.fraction);
Expand Down
Loading