use sim_lib_pitch_core::PitchClass;
use sim_lib_pitch_set::PitchClassMask;
use crate::{
AggregateCoverageReport, BlockOrder, RowPartition, ToneRow, analyze_aggregate_coverage,
};
#[derive(Clone, Debug, PartialEq, Eq)]
pub struct MosaicBlock {
pub partition_index: usize,
pub block_index: usize,
pub order: BlockOrder,
pub ordinals: Vec<u8>,
pub pitch_classes: Vec<PitchClass>,
pub mask: PitchClassMask,
}
#[derive(Clone, Debug, PartialEq, Eq)]
pub struct MosaicReport {
pub blocks: Vec<MosaicBlock>,
pub aggregate_coverage: AggregateCoverageReport,
}
pub fn analyze_mosaic(row: &ToneRow, partitions: &[RowPartition]) -> MosaicReport {
let mut blocks = Vec::new();
let mut masks = Vec::new();
for (partition_index, partition) in partitions.iter().enumerate() {
for (block_index, block) in partition.blocks().iter().enumerate() {
let pitch_classes = block.pitch_classes(row);
let mask = PitchClassMask::from_pitch_classes(&pitch_classes);
masks.push(mask);
blocks.push(MosaicBlock {
partition_index,
block_index,
order: partition.order(),
ordinals: block.ordinals().to_vec(),
pitch_classes,
mask,
});
}
}
MosaicReport {
blocks,
aggregate_coverage: analyze_aggregate_coverage(
PitchClassMask::from_pitch_classes(row.classes()),
&masks,
),
}
}