sim_lib_music_core/
freeze.rs1use sim_kernel::Symbol;
2
3use crate::{ChainPlacementPlan, ChainTraceRecord, PlayContext, PlayEvent};
4
5#[derive(Clone, Debug, PartialEq, Eq)]
10pub struct FreezeMeta {
11 pub source_id: Symbol,
13 pub chain_hash: String,
15 pub context_hash: String,
17 pub seed: u64,
19 pub placement: ChainPlacementPlan,
21 pub output_hash: String,
23}
24
25#[derive(Clone, Debug, PartialEq, Eq)]
27pub struct SourceRecording {
28 pub source_id: Symbol,
30 pub chain_hash: String,
32 pub context_hash: String,
34 pub seed: u64,
36 pub placement: ChainPlacementPlan,
38}
39
40#[derive(Clone, Debug, PartialEq, Eq)]
42pub struct DirectRecording {
43 pub meta: FreezeMeta,
45 pub events: Vec<PlayEvent>,
47 pub traces: Vec<ChainTraceRecord>,
49}
50
51#[derive(Clone, Debug, PartialEq, Eq)]
53pub struct FrozenPlayerChain {
54 pub meta: FreezeMeta,
56 pub events: Vec<PlayEvent>,
58 pub traces: Vec<ChainTraceRecord>,
60}
61
62impl SourceRecording {
63 pub(crate) fn new(
64 source_id: Symbol,
65 chain_hash: String,
66 context_hash: String,
67 seed: u64,
68 placement: ChainPlacementPlan,
69 ) -> Self {
70 Self {
71 source_id,
72 chain_hash,
73 context_hash,
74 seed,
75 placement,
76 }
77 }
78}
79
80pub(crate) fn freeze_meta(
81 source_id: Symbol,
82 chain_hash: String,
83 cx: &PlayContext,
84 placement: ChainPlacementPlan,
85 events: &[PlayEvent],
86 traces: &[ChainTraceRecord],
87) -> FreezeMeta {
88 FreezeMeta {
89 source_id,
90 chain_hash,
91 context_hash: context_hash(cx),
92 seed: cx.seed,
93 placement,
94 output_hash: stable_hash("player-output", &(events, traces)),
95 }
96}
97
98pub(crate) fn context_hash(cx: &PlayContext) -> String {
99 stable_hash(
100 "play-context",
101 &(
102 &cx.transport,
103 &cx.tempo,
104 cx.sample_rate,
105 cx.ppq,
106 cx.range,
107 cx.seed,
108 &cx.capabilities,
109 cx.site,
110 ),
111 )
112}
113
114pub(crate) fn stable_hash<T: core::fmt::Debug>(label: &str, value: &T) -> String {
115 let mut hash = 0xcbf29ce484222325u64;
116 for byte in format!("{label}:{value:?}").bytes() {
117 hash ^= u64::from(byte);
118 hash = hash.wrapping_mul(0x100000001b3);
119 }
120 format!("fnv1a64:{hash:016x}")
121}