* Performs some general consolidations of inconsistencies on the given score like * missing bars, beats, duplicated midi channels etc
(score: Score)
| 555 | * missing bars, beats, duplicated midi channels etc |
| 556 | */ |
| 557 | public static consolidate(score: Score) { |
| 558 | // empty score? |
| 559 | if (score.masterBars.length === 0) { |
| 560 | const master: MasterBar = new MasterBar(); |
| 561 | score.addMasterBar(master); |
| 562 | |
| 563 | const tempoAutomation = new Automation(); |
| 564 | tempoAutomation.isLinear = false; |
| 565 | tempoAutomation.type = AutomationType.Tempo; |
| 566 | tempoAutomation.value = score.tempo; |
| 567 | master.tempoAutomations.push(tempoAutomation); |
| 568 | |
| 569 | const bar: Bar = new Bar(); |
| 570 | score.tracks[0].staves[0].addBar(bar); |
| 571 | |
| 572 | const v = new Voice(); |
| 573 | bar.addVoice(v); |
| 574 | |
| 575 | const emptyBeat: Beat = new Beat(); |
| 576 | emptyBeat.isEmpty = true; |
| 577 | v.addBeat(emptyBeat); |
| 578 | return; |
| 579 | } |
| 580 | |
| 581 | const usedChannels = new Set<number>([SynthConstants.PercussionChannel]); |
| 582 | for (const track of score.tracks) { |
| 583 | // ensure percussion channel |
| 584 | if (track.staves.length === 1 && track.staves[0].isPercussion) { |
| 585 | track.playbackInfo.primaryChannel = SynthConstants.PercussionChannel; |
| 586 | track.playbackInfo.secondaryChannel = SynthConstants.PercussionChannel; |
| 587 | } else { |
| 588 | // unique midi channels and generate secondary channels |
| 589 | if (track.playbackInfo.primaryChannel !== SynthConstants.PercussionChannel) { |
| 590 | while (usedChannels.has(track.playbackInfo.primaryChannel)) { |
| 591 | track.playbackInfo.primaryChannel++; |
| 592 | } |
| 593 | } |
| 594 | usedChannels.add(track.playbackInfo.primaryChannel); |
| 595 | |
| 596 | if (track.playbackInfo.secondaryChannel !== SynthConstants.PercussionChannel) { |
| 597 | while (usedChannels.has(track.playbackInfo.secondaryChannel)) { |
| 598 | track.playbackInfo.secondaryChannel++; |
| 599 | } |
| 600 | } |
| 601 | usedChannels.add(track.playbackInfo.secondaryChannel); |
| 602 | } |
| 603 | |
| 604 | for (const staff of track.staves) { |
| 605 | // fill empty beats |
| 606 | for (const b of staff.bars) { |
| 607 | for (const v of b.voices) { |
| 608 | if (v.isEmpty && v.beats.length === 0) { |
| 609 | const emptyBeat: Beat = new Beat(); |
| 610 | emptyBeat.isEmpty = true; |
| 611 | v.addBeat(emptyBeat); |
| 612 | } |
| 613 | } |
| 614 | } |