rewrite unsafe code in voice allocator
This commit is contained in:
parent
72f10db64d
commit
06c5342724
|
|
@ -1531,12 +1531,8 @@ impl Engine {
|
||||||
|
|
||||||
// Get the VoiceAllocator node and serialize its template
|
// Get the VoiceAllocator node and serialize its template
|
||||||
if let Some(node) = graph.get_node(va_idx) {
|
if let Some(node) = graph.get_node(va_idx) {
|
||||||
// Downcast to VoiceAllocatorNode
|
// Downcast to VoiceAllocatorNode using safe Any trait
|
||||||
let node_ptr = node as *const dyn crate::audio::node_graph::AudioNode;
|
if let Some(va_node) = node.as_any().downcast_ref::<VoiceAllocatorNode>() {
|
||||||
let node_ptr = node_ptr as *const VoiceAllocatorNode;
|
|
||||||
|
|
||||||
unsafe {
|
|
||||||
let va_node = &*node_ptr;
|
|
||||||
let template_preset = va_node.template_graph().to_preset(&preset_name);
|
let template_preset = va_node.template_graph().to_preset(&preset_name);
|
||||||
|
|
||||||
// Write to file
|
// Write to file
|
||||||
|
|
@ -1558,12 +1554,8 @@ impl Engine {
|
||||||
let node_idx = NodeIndex::new(node_id as usize);
|
let node_idx = NodeIndex::new(node_id as usize);
|
||||||
|
|
||||||
if let Some(graph_node) = graph.get_graph_node_mut(node_idx) {
|
if let Some(graph_node) = graph.get_graph_node_mut(node_idx) {
|
||||||
// Downcast to SimpleSamplerNode
|
// Downcast to SimpleSamplerNode using safe Any trait
|
||||||
let node_ptr = &mut *graph_node.node as *mut dyn crate::audio::node_graph::AudioNode;
|
if let Some(sampler_node) = graph_node.node.as_any_mut().downcast_mut::<SimpleSamplerNode>() {
|
||||||
let node_ptr = node_ptr as *mut SimpleSamplerNode;
|
|
||||||
|
|
||||||
unsafe {
|
|
||||||
let sampler_node = &mut *node_ptr;
|
|
||||||
if let Err(e) = sampler_node.load_sample_from_file(&file_path) {
|
if let Err(e) = sampler_node.load_sample_from_file(&file_path) {
|
||||||
eprintln!("Failed to load sample: {}", e);
|
eprintln!("Failed to load sample: {}", e);
|
||||||
}
|
}
|
||||||
|
|
@ -1580,12 +1572,8 @@ impl Engine {
|
||||||
let node_idx = NodeIndex::new(node_id as usize);
|
let node_idx = NodeIndex::new(node_id as usize);
|
||||||
|
|
||||||
if let Some(graph_node) = graph.get_graph_node_mut(node_idx) {
|
if let Some(graph_node) = graph.get_graph_node_mut(node_idx) {
|
||||||
// Downcast to MultiSamplerNode
|
// Downcast to MultiSamplerNode using safe Any trait
|
||||||
let node_ptr = &mut *graph_node.node as *mut dyn crate::audio::node_graph::AudioNode;
|
if let Some(multi_sampler_node) = graph_node.node.as_any_mut().downcast_mut::<MultiSamplerNode>() {
|
||||||
let node_ptr = node_ptr as *mut MultiSamplerNode;
|
|
||||||
|
|
||||||
unsafe {
|
|
||||||
let multi_sampler_node = &mut *node_ptr;
|
|
||||||
if let Err(e) = multi_sampler_node.load_layer_from_file(&file_path, key_min, key_max, root_key, velocity_min, velocity_max, loop_start, loop_end, loop_mode) {
|
if let Err(e) = multi_sampler_node.load_layer_from_file(&file_path, key_min, key_max, root_key, velocity_min, velocity_max, loop_start, loop_end, loop_mode) {
|
||||||
eprintln!("Failed to add sample layer: {}", e);
|
eprintln!("Failed to add sample layer: {}", e);
|
||||||
}
|
}
|
||||||
|
|
@ -1602,12 +1590,8 @@ impl Engine {
|
||||||
let node_idx = NodeIndex::new(node_id as usize);
|
let node_idx = NodeIndex::new(node_id as usize);
|
||||||
|
|
||||||
if let Some(graph_node) = graph.get_graph_node_mut(node_idx) {
|
if let Some(graph_node) = graph.get_graph_node_mut(node_idx) {
|
||||||
// Downcast to MultiSamplerNode
|
// Downcast to MultiSamplerNode using safe Any trait
|
||||||
let node_ptr = &mut *graph_node.node as *mut dyn crate::audio::node_graph::AudioNode;
|
if let Some(multi_sampler_node) = graph_node.node.as_any_mut().downcast_mut::<MultiSamplerNode>() {
|
||||||
let node_ptr = node_ptr as *mut MultiSamplerNode;
|
|
||||||
|
|
||||||
unsafe {
|
|
||||||
let multi_sampler_node = &mut *node_ptr;
|
|
||||||
if let Err(e) = multi_sampler_node.update_layer(layer_index, key_min, key_max, root_key, velocity_min, velocity_max, loop_start, loop_end, loop_mode) {
|
if let Err(e) = multi_sampler_node.update_layer(layer_index, key_min, key_max, root_key, velocity_min, velocity_max, loop_start, loop_end, loop_mode) {
|
||||||
eprintln!("Failed to update sample layer: {}", e);
|
eprintln!("Failed to update sample layer: {}", e);
|
||||||
}
|
}
|
||||||
|
|
@ -1624,12 +1608,8 @@ impl Engine {
|
||||||
let node_idx = NodeIndex::new(node_id as usize);
|
let node_idx = NodeIndex::new(node_id as usize);
|
||||||
|
|
||||||
if let Some(graph_node) = graph.get_graph_node_mut(node_idx) {
|
if let Some(graph_node) = graph.get_graph_node_mut(node_idx) {
|
||||||
// Downcast to MultiSamplerNode
|
// Downcast to MultiSamplerNode using safe Any trait
|
||||||
let node_ptr = &mut *graph_node.node as *mut dyn crate::audio::node_graph::AudioNode;
|
if let Some(multi_sampler_node) = graph_node.node.as_any_mut().downcast_mut::<MultiSamplerNode>() {
|
||||||
let node_ptr = node_ptr as *mut MultiSamplerNode;
|
|
||||||
|
|
||||||
unsafe {
|
|
||||||
let multi_sampler_node = &mut *node_ptr;
|
|
||||||
if let Err(e) = multi_sampler_node.remove_layer(layer_index) {
|
if let Err(e) = multi_sampler_node.remove_layer(layer_index) {
|
||||||
eprintln!("Failed to remove sample layer: {}", e);
|
eprintln!("Failed to remove sample layer: {}", e);
|
||||||
}
|
}
|
||||||
|
|
@ -1939,16 +1919,15 @@ impl Engine {
|
||||||
let graph = &mut track.instrument_graph;
|
let graph = &mut track.instrument_graph;
|
||||||
let node_idx = NodeIndex::new(voice_allocator_id as usize);
|
let node_idx = NodeIndex::new(voice_allocator_id as usize);
|
||||||
if let Some(graph_node) = graph.get_graph_node_mut(node_idx) {
|
if let Some(graph_node) = graph.get_graph_node_mut(node_idx) {
|
||||||
// Downcast to VoiceAllocatorNode
|
// Downcast to VoiceAllocatorNode using safe Any trait
|
||||||
let node_ptr = &*graph_node.node as *const dyn crate::audio::node_graph::AudioNode;
|
if let Some(va_node) = graph_node.node.as_any().downcast_ref::<VoiceAllocatorNode>() {
|
||||||
let node_ptr = node_ptr as *const VoiceAllocatorNode;
|
|
||||||
unsafe {
|
|
||||||
let va_node = &*node_ptr;
|
|
||||||
let template_preset = va_node.template_graph().to_preset("template");
|
let template_preset = va_node.template_graph().to_preset("template");
|
||||||
match template_preset.to_json() {
|
match template_preset.to_json() {
|
||||||
Ok(json) => QueryResponse::GraphState(Ok(json)),
|
Ok(json) => QueryResponse::GraphState(Ok(json)),
|
||||||
Err(e) => QueryResponse::GraphState(Err(format!("Failed to serialize template: {:?}", e))),
|
Err(e) => QueryResponse::GraphState(Err(format!("Failed to serialize template: {:?}", e))),
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
QueryResponse::GraphState(Err("Node is not a VoiceAllocatorNode".to_string()))
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
QueryResponse::GraphState(Err("Voice allocator node not found".to_string()))
|
QueryResponse::GraphState(Err("Voice allocator node not found".to_string()))
|
||||||
|
|
|
||||||
|
|
@ -281,19 +281,10 @@ impl AudioGraph {
|
||||||
// This is tricky with trait objects, so we'll need to use Any
|
// This is tricky with trait objects, so we'll need to use Any
|
||||||
// For now, let's use a different approach - store the node pointer temporarily
|
// For now, let's use a different approach - store the node pointer temporarily
|
||||||
|
|
||||||
// Check node type first
|
// Downcast to VoiceAllocatorNode using safe Any trait
|
||||||
if graph_node.node.node_type() != "VoiceAllocator" {
|
let va = graph_node.node.as_any_mut()
|
||||||
return Err("Node is not a VoiceAllocator".to_string());
|
.downcast_mut::<VoiceAllocatorNode>()
|
||||||
}
|
.ok_or_else(|| "Node is not a VoiceAllocator".to_string())?;
|
||||||
|
|
||||||
// Get mutable reference and downcast using raw pointers
|
|
||||||
let node_ptr = &mut *graph_node.node as *mut dyn AudioNode;
|
|
||||||
|
|
||||||
// SAFETY: We just checked that this is a VoiceAllocator
|
|
||||||
// This is safe because we know the concrete type
|
|
||||||
unsafe {
|
|
||||||
let va_ptr = node_ptr as *mut VoiceAllocatorNode;
|
|
||||||
let va = &mut *va_ptr;
|
|
||||||
|
|
||||||
// Add node to template graph
|
// Add node to template graph
|
||||||
let node_idx = va.template_graph_mut().add_node(node);
|
let node_idx = va.template_graph_mut().add_node(node);
|
||||||
|
|
@ -304,7 +295,6 @@ impl AudioGraph {
|
||||||
|
|
||||||
return Ok(node_id);
|
return Ok(node_id);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
Err("VoiceAllocator node not found".to_string())
|
Err("VoiceAllocator node not found".to_string())
|
||||||
}
|
}
|
||||||
|
|
@ -322,18 +312,10 @@ impl AudioGraph {
|
||||||
|
|
||||||
// Get the VoiceAllocator node
|
// Get the VoiceAllocator node
|
||||||
if let Some(graph_node) = self.graph.node_weight_mut(voice_allocator_idx) {
|
if let Some(graph_node) = self.graph.node_weight_mut(voice_allocator_idx) {
|
||||||
// Check node type first
|
// Downcast to VoiceAllocatorNode using safe Any trait
|
||||||
if graph_node.node.node_type() != "VoiceAllocator" {
|
let va = graph_node.node.as_any_mut()
|
||||||
return Err("Node is not a VoiceAllocator".to_string());
|
.downcast_mut::<VoiceAllocatorNode>()
|
||||||
}
|
.ok_or_else(|| "Node is not a VoiceAllocator".to_string())?;
|
||||||
|
|
||||||
// Get mutable reference and downcast using raw pointers
|
|
||||||
let node_ptr = &mut *graph_node.node as *mut dyn AudioNode;
|
|
||||||
|
|
||||||
// SAFETY: We just checked that this is a VoiceAllocator
|
|
||||||
unsafe {
|
|
||||||
let va_ptr = node_ptr as *mut VoiceAllocatorNode;
|
|
||||||
let va = &mut *va_ptr;
|
|
||||||
|
|
||||||
// Connect in template graph
|
// Connect in template graph
|
||||||
let from_idx = NodeIndex::new(from_node as usize);
|
let from_idx = NodeIndex::new(from_node as usize);
|
||||||
|
|
@ -347,7 +329,6 @@ impl AudioGraph {
|
||||||
|
|
||||||
return Ok(());
|
return Ok(());
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
Err("VoiceAllocator node not found".to_string())
|
Err("VoiceAllocator node not found".to_string())
|
||||||
}
|
}
|
||||||
|
|
@ -364,16 +345,10 @@ impl AudioGraph {
|
||||||
use crate::audio::node_graph::nodes::VoiceAllocatorNode;
|
use crate::audio::node_graph::nodes::VoiceAllocatorNode;
|
||||||
|
|
||||||
if let Some(graph_node) = self.graph.node_weight_mut(voice_allocator_idx) {
|
if let Some(graph_node) = self.graph.node_weight_mut(voice_allocator_idx) {
|
||||||
if graph_node.node.node_type() != "VoiceAllocator" {
|
// Downcast to VoiceAllocatorNode using safe Any trait
|
||||||
return Err("Node is not a VoiceAllocator".to_string());
|
let va = graph_node.node.as_any_mut()
|
||||||
}
|
.downcast_mut::<VoiceAllocatorNode>()
|
||||||
|
.ok_or_else(|| "Node is not a VoiceAllocator".to_string())?;
|
||||||
let node_ptr = &mut *graph_node.node as *mut dyn AudioNode;
|
|
||||||
|
|
||||||
// SAFETY: We just checked that this is a VoiceAllocator
|
|
||||||
unsafe {
|
|
||||||
let va_ptr = node_ptr as *mut VoiceAllocatorNode;
|
|
||||||
let va = &mut *va_ptr;
|
|
||||||
|
|
||||||
let from_idx = NodeIndex::new(from_node as usize);
|
let from_idx = NodeIndex::new(from_node as usize);
|
||||||
let to_idx = NodeIndex::new(to_node as usize);
|
let to_idx = NodeIndex::new(to_node as usize);
|
||||||
|
|
@ -383,7 +358,6 @@ impl AudioGraph {
|
||||||
|
|
||||||
return Ok(());
|
return Ok(());
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
Err("VoiceAllocator node not found".to_string())
|
Err("VoiceAllocator node not found".to_string())
|
||||||
}
|
}
|
||||||
|
|
@ -397,16 +371,10 @@ impl AudioGraph {
|
||||||
use crate::audio::node_graph::nodes::VoiceAllocatorNode;
|
use crate::audio::node_graph::nodes::VoiceAllocatorNode;
|
||||||
|
|
||||||
if let Some(graph_node) = self.graph.node_weight_mut(voice_allocator_idx) {
|
if let Some(graph_node) = self.graph.node_weight_mut(voice_allocator_idx) {
|
||||||
if graph_node.node.node_type() != "VoiceAllocator" {
|
// Downcast to VoiceAllocatorNode using safe Any trait
|
||||||
return Err("Node is not a VoiceAllocator".to_string());
|
let va = graph_node.node.as_any_mut()
|
||||||
}
|
.downcast_mut::<VoiceAllocatorNode>()
|
||||||
|
.ok_or_else(|| "Node is not a VoiceAllocator".to_string())?;
|
||||||
let node_ptr = &mut *graph_node.node as *mut dyn AudioNode;
|
|
||||||
|
|
||||||
// SAFETY: We just checked that this is a VoiceAllocator
|
|
||||||
unsafe {
|
|
||||||
let va_ptr = node_ptr as *mut VoiceAllocatorNode;
|
|
||||||
let va = &mut *va_ptr;
|
|
||||||
|
|
||||||
let node_idx = NodeIndex::new(node_id as usize);
|
let node_idx = NodeIndex::new(node_id as usize);
|
||||||
va.template_graph_mut().remove_node(node_idx);
|
va.template_graph_mut().remove_node(node_idx);
|
||||||
|
|
@ -414,7 +382,6 @@ impl AudioGraph {
|
||||||
|
|
||||||
return Ok(());
|
return Ok(());
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
Err("VoiceAllocator node not found".to_string())
|
Err("VoiceAllocator node not found".to_string())
|
||||||
}
|
}
|
||||||
|
|
@ -430,16 +397,10 @@ impl AudioGraph {
|
||||||
use crate::audio::node_graph::nodes::VoiceAllocatorNode;
|
use crate::audio::node_graph::nodes::VoiceAllocatorNode;
|
||||||
|
|
||||||
if let Some(graph_node) = self.graph.node_weight_mut(voice_allocator_idx) {
|
if let Some(graph_node) = self.graph.node_weight_mut(voice_allocator_idx) {
|
||||||
if graph_node.node.node_type() != "VoiceAllocator" {
|
// Downcast to VoiceAllocatorNode using safe Any trait
|
||||||
return Err("Node is not a VoiceAllocator".to_string());
|
let va = graph_node.node.as_any_mut()
|
||||||
}
|
.downcast_mut::<VoiceAllocatorNode>()
|
||||||
|
.ok_or_else(|| "Node is not a VoiceAllocator".to_string())?;
|
||||||
let node_ptr = &mut *graph_node.node as *mut dyn AudioNode;
|
|
||||||
|
|
||||||
// SAFETY: We just checked that this is a VoiceAllocator
|
|
||||||
unsafe {
|
|
||||||
let va_ptr = node_ptr as *mut VoiceAllocatorNode;
|
|
||||||
let va = &mut *va_ptr;
|
|
||||||
|
|
||||||
let node_idx = NodeIndex::new(node_id as usize);
|
let node_idx = NodeIndex::new(node_id as usize);
|
||||||
if let Some(template_node) = va.template_graph_mut().get_graph_node_mut(node_idx) {
|
if let Some(template_node) = va.template_graph_mut().get_graph_node_mut(node_idx) {
|
||||||
|
|
@ -452,7 +413,6 @@ impl AudioGraph {
|
||||||
|
|
||||||
return Ok(());
|
return Ok(());
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
Err("VoiceAllocator node not found".to_string())
|
Err("VoiceAllocator node not found".to_string())
|
||||||
}
|
}
|
||||||
|
|
@ -468,16 +428,8 @@ impl AudioGraph {
|
||||||
use crate::audio::node_graph::nodes::VoiceAllocatorNode;
|
use crate::audio::node_graph::nodes::VoiceAllocatorNode;
|
||||||
|
|
||||||
if let Some(graph_node) = self.graph.node_weight_mut(voice_allocator_idx) {
|
if let Some(graph_node) = self.graph.node_weight_mut(voice_allocator_idx) {
|
||||||
if graph_node.node.node_type() != "VoiceAllocator" {
|
// Downcast to VoiceAllocatorNode using safe Any trait
|
||||||
return;
|
if let Some(va) = graph_node.node.as_any_mut().downcast_mut::<VoiceAllocatorNode>() {
|
||||||
}
|
|
||||||
|
|
||||||
let node_ptr = &mut *graph_node.node as *mut dyn AudioNode;
|
|
||||||
|
|
||||||
// SAFETY: We just checked that this is a VoiceAllocator
|
|
||||||
unsafe {
|
|
||||||
let va_ptr = node_ptr as *mut VoiceAllocatorNode;
|
|
||||||
let va = &mut *va_ptr;
|
|
||||||
let node_idx = NodeIndex::new(node_id as usize);
|
let node_idx = NodeIndex::new(node_id as usize);
|
||||||
va.template_graph_mut().set_node_position(node_idx, x, y);
|
va.template_graph_mut().set_node_position(node_idx, x, y);
|
||||||
}
|
}
|
||||||
|
|
@ -655,30 +607,21 @@ impl AudioGraph {
|
||||||
let num_midi_outputs = outputs.iter().filter(|p| p.signal_type == SignalType::Midi).count();
|
let num_midi_outputs = outputs.iter().filter(|p| p.signal_type == SignalType::Midi).count();
|
||||||
|
|
||||||
// Create mutable slices for audio/CV outputs
|
// Create mutable slices for audio/CV outputs
|
||||||
let mut output_slices: Vec<&mut [f32]> = Vec::with_capacity(num_audio_cv_outputs);
|
// Each buffer is independent, so this is safe
|
||||||
for i in 0..num_audio_cv_outputs {
|
let mut output_slices: Vec<&mut [f32]> = node.output_buffers
|
||||||
if i < node.output_buffers.len() {
|
.iter_mut()
|
||||||
// Safety: We need to work around borrowing rules here
|
.take(num_audio_cv_outputs)
|
||||||
// This is safe because each output buffer is independent
|
.map(|buf| {
|
||||||
let buffer = &mut node.output_buffers[i] as *mut Vec<f32>;
|
let len = buf.len();
|
||||||
unsafe {
|
&mut buf[..process_size.min(len)]
|
||||||
let slice = &mut (&mut *buffer)[..process_size.min((*buffer).len())];
|
})
|
||||||
output_slices.push(slice);
|
.collect();
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Create mutable references for MIDI outputs
|
// Create mutable references for MIDI outputs
|
||||||
let mut midi_output_refs: Vec<&mut Vec<MidiEvent>> = Vec::with_capacity(num_midi_outputs);
|
let mut midi_output_refs: Vec<&mut Vec<MidiEvent>> = node.midi_output_buffers
|
||||||
for i in 0..num_midi_outputs {
|
.iter_mut()
|
||||||
if i < node.midi_output_buffers.len() {
|
.take(num_midi_outputs)
|
||||||
// Safety: Similar to above
|
.collect();
|
||||||
let buffer = &mut node.midi_output_buffers[i] as *mut Vec<MidiEvent>;
|
|
||||||
unsafe {
|
|
||||||
midi_output_refs.push(&mut *buffer);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Process the node with both audio/CV and MIDI
|
// Process the node with both audio/CV and MIDI
|
||||||
node.node.process(&input_slices, &mut output_slices, &midi_input_slices, &mut midi_output_refs, self.sample_rate);
|
node.node.process(&input_slices, &mut output_slices, &midi_input_slices, &mut midi_output_refs, self.sample_rate);
|
||||||
|
|
@ -811,14 +754,9 @@ impl AudioGraph {
|
||||||
}
|
}
|
||||||
|
|
||||||
// For VoiceAllocator nodes, serialize the template graph
|
// For VoiceAllocator nodes, serialize the template graph
|
||||||
// We need to downcast to access template_graph()
|
|
||||||
// This is safe because we know the node type
|
|
||||||
if node.node_type() == "VoiceAllocator" {
|
if node.node_type() == "VoiceAllocator" {
|
||||||
// Use Any to downcast
|
// Downcast using safe Any trait
|
||||||
let node_ptr = &**node as *const dyn crate::audio::node_graph::AudioNode;
|
if let Some(va_node) = node.as_any().downcast_ref::<VoiceAllocatorNode>() {
|
||||||
let node_ptr = node_ptr as *const VoiceAllocatorNode;
|
|
||||||
unsafe {
|
|
||||||
let va_node = &*node_ptr;
|
|
||||||
let template_preset = va_node.template_graph().to_preset("template");
|
let template_preset = va_node.template_graph().to_preset("template");
|
||||||
serialized.template_graph = Some(Box::new(template_preset));
|
serialized.template_graph = Some(Box::new(template_preset));
|
||||||
}
|
}
|
||||||
|
|
@ -830,10 +768,8 @@ impl AudioGraph {
|
||||||
use crate::audio::node_graph::preset::{EmbeddedSampleData, SampleData};
|
use crate::audio::node_graph::preset::{EmbeddedSampleData, SampleData};
|
||||||
use base64::{Engine as _, engine::general_purpose};
|
use base64::{Engine as _, engine::general_purpose};
|
||||||
|
|
||||||
let node_ptr = &**node as *const dyn crate::audio::node_graph::AudioNode;
|
// Downcast using safe Any trait
|
||||||
let node_ptr = node_ptr as *const SimpleSamplerNode;
|
if let Some(sampler_node) = node.as_any().downcast_ref::<SimpleSamplerNode>() {
|
||||||
unsafe {
|
|
||||||
let sampler_node = &*node_ptr;
|
|
||||||
if let Some(sample_path) = sampler_node.get_sample_path() {
|
if let Some(sample_path) = sampler_node.get_sample_path() {
|
||||||
// Check file size
|
// Check file size
|
||||||
let should_embed = std::fs::metadata(sample_path)
|
let should_embed = std::fs::metadata(sample_path)
|
||||||
|
|
@ -877,10 +813,8 @@ impl AudioGraph {
|
||||||
use crate::audio::node_graph::preset::{EmbeddedSampleData, LayerData, SampleData};
|
use crate::audio::node_graph::preset::{EmbeddedSampleData, LayerData, SampleData};
|
||||||
use base64::{Engine as _, engine::general_purpose};
|
use base64::{Engine as _, engine::general_purpose};
|
||||||
|
|
||||||
let node_ptr = &**node as *const dyn crate::audio::node_graph::AudioNode;
|
// Downcast using safe Any trait
|
||||||
let node_ptr = node_ptr as *const MultiSamplerNode;
|
if let Some(multi_sampler_node) = node.as_any().downcast_ref::<MultiSamplerNode>() {
|
||||||
unsafe {
|
|
||||||
let multi_sampler_node = &*node_ptr;
|
|
||||||
let layers_info = multi_sampler_node.get_layers_info();
|
let layers_info = multi_sampler_node.get_layers_info();
|
||||||
if !layers_info.is_empty() {
|
if !layers_info.is_empty() {
|
||||||
let layers: Vec<LayerData> = layers_info
|
let layers: Vec<LayerData> = layers_info
|
||||||
|
|
@ -1070,10 +1004,8 @@ impl AudioGraph {
|
||||||
crate::audio::node_graph::preset::SampleData::SimpleSampler { file_path, embedded_data } => {
|
crate::audio::node_graph::preset::SampleData::SimpleSampler { file_path, embedded_data } => {
|
||||||
// Load sample into SimpleSampler
|
// Load sample into SimpleSampler
|
||||||
if let Some(graph_node) = graph.graph.node_weight_mut(node_idx) {
|
if let Some(graph_node) = graph.graph.node_weight_mut(node_idx) {
|
||||||
let node_ptr = &mut *graph_node.node as *mut dyn crate::audio::node_graph::AudioNode;
|
// Downcast using safe Any trait
|
||||||
let node_ptr = node_ptr as *mut SimpleSamplerNode;
|
if let Some(sampler_node) = graph_node.node.as_any_mut().downcast_mut::<SimpleSamplerNode>() {
|
||||||
unsafe {
|
|
||||||
let sampler_node = &mut *node_ptr;
|
|
||||||
|
|
||||||
// Try embedded data first, then fall back to file path
|
// Try embedded data first, then fall back to file path
|
||||||
if let Some(ref embedded) = embedded_data {
|
if let Some(ref embedded) = embedded_data {
|
||||||
|
|
@ -1104,10 +1036,8 @@ impl AudioGraph {
|
||||||
crate::audio::node_graph::preset::SampleData::MultiSampler { layers } => {
|
crate::audio::node_graph::preset::SampleData::MultiSampler { layers } => {
|
||||||
// Load layers into MultiSampler
|
// Load layers into MultiSampler
|
||||||
if let Some(graph_node) = graph.graph.node_weight_mut(node_idx) {
|
if let Some(graph_node) = graph.graph.node_weight_mut(node_idx) {
|
||||||
let node_ptr = &mut *graph_node.node as *mut dyn crate::audio::node_graph::AudioNode;
|
// Downcast using safe Any trait
|
||||||
let node_ptr = node_ptr as *mut MultiSamplerNode;
|
if let Some(multi_sampler_node) = graph_node.node.as_any_mut().downcast_mut::<MultiSamplerNode>() {
|
||||||
unsafe {
|
|
||||||
let multi_sampler_node = &mut *node_ptr;
|
|
||||||
for layer in layers {
|
for layer in layers {
|
||||||
// Try embedded data first, then fall back to file path
|
// Try embedded data first, then fall back to file path
|
||||||
if let Some(ref embedded) = layer.embedded_data {
|
if let Some(ref embedded) = layer.embedded_data {
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue