rewrite unsafe code in midi handling
This commit is contained in:
parent
9db34daf85
commit
ffe7799b6a
|
|
@ -317,15 +317,9 @@ impl Engine {
|
||||||
self.project.reset_read_ahead_targets();
|
self.project.reset_read_ahead_targets();
|
||||||
|
|
||||||
// Render the entire project hierarchy into the mix buffer
|
// Render the entire project hierarchy into the mix buffer
|
||||||
// Note: We need to use a raw pointer to avoid borrow checker issues
|
|
||||||
// The midi_clip_pool is part of project, so we extract a reference before mutable borrow
|
|
||||||
let midi_pool_ptr = &self.project.midi_clip_pool as *const _;
|
|
||||||
// SAFETY: The midi_clip_pool is not mutated during render, only read
|
|
||||||
let midi_pool_ref = unsafe { &*midi_pool_ptr };
|
|
||||||
self.project.render(
|
self.project.render(
|
||||||
&mut self.mix_buffer,
|
&mut self.mix_buffer,
|
||||||
&self.audio_pool,
|
&self.audio_pool,
|
||||||
midi_pool_ref,
|
|
||||||
&mut self.buffer_pool,
|
&mut self.buffer_pool,
|
||||||
playhead_seconds,
|
playhead_seconds,
|
||||||
self.sample_rate,
|
self.sample_rate,
|
||||||
|
|
@ -2149,15 +2143,11 @@ impl Engine {
|
||||||
Query::ExportAudio(settings, output_path) => {
|
Query::ExportAudio(settings, output_path) => {
|
||||||
// Perform export directly - this will block the audio thread but that's okay
|
// Perform export directly - this will block the audio thread but that's okay
|
||||||
// since we're exporting and not playing back anyway
|
// since we're exporting and not playing back anyway
|
||||||
// Use raw pointer to get midi_pool reference before mutable borrow of project
|
|
||||||
let midi_pool_ptr: *const _ = &self.project.midi_clip_pool;
|
|
||||||
let midi_pool_ref = unsafe { &*midi_pool_ptr };
|
|
||||||
|
|
||||||
// Pass event_tx directly - Rust allows borrowing different fields simultaneously
|
// Pass event_tx directly - Rust allows borrowing different fields simultaneously
|
||||||
match crate::audio::export_audio(
|
match crate::audio::export_audio(
|
||||||
&mut self.project,
|
&mut self.project,
|
||||||
&self.audio_pool,
|
&self.audio_pool,
|
||||||
midi_pool_ref,
|
|
||||||
&settings,
|
&settings,
|
||||||
&output_path,
|
&output_path,
|
||||||
Some(&mut self.event_tx),
|
Some(&mut self.event_tx),
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,4 @@
|
||||||
use super::buffer_pool::BufferPool;
|
use super::buffer_pool::BufferPool;
|
||||||
use super::midi_pool::MidiClipPool;
|
|
||||||
use super::pool::AudioPool;
|
use super::pool::AudioPool;
|
||||||
use super::project::Project;
|
use super::project::Project;
|
||||||
use crate::command::AudioEvent;
|
use crate::command::AudioEvent;
|
||||||
|
|
@ -69,7 +68,6 @@ impl Default for ExportSettings {
|
||||||
pub fn export_audio<P: AsRef<Path>>(
|
pub fn export_audio<P: AsRef<Path>>(
|
||||||
project: &mut Project,
|
project: &mut Project,
|
||||||
pool: &AudioPool,
|
pool: &AudioPool,
|
||||||
midi_pool: &MidiClipPool,
|
|
||||||
settings: &ExportSettings,
|
settings: &ExportSettings,
|
||||||
output_path: P,
|
output_path: P,
|
||||||
mut event_tx: Option<&mut rtrb::Producer<AudioEvent>>,
|
mut event_tx: Option<&mut rtrb::Producer<AudioEvent>>,
|
||||||
|
|
@ -87,7 +85,7 @@ pub fn export_audio<P: AsRef<Path>>(
|
||||||
// Ensure export mode is disabled even if an error occurs.
|
// Ensure export mode is disabled even if an error occurs.
|
||||||
let result = match settings.format {
|
let result = match settings.format {
|
||||||
ExportFormat::Wav | ExportFormat::Flac => {
|
ExportFormat::Wav | ExportFormat::Flac => {
|
||||||
let samples = render_to_memory(project, pool, midi_pool, settings, event_tx.as_mut().map(|tx| &mut **tx))?;
|
let samples = render_to_memory(project, pool, settings, event_tx.as_mut().map(|tx| &mut **tx))?;
|
||||||
// Signal that rendering is done and we're now writing the file
|
// Signal that rendering is done and we're now writing the file
|
||||||
if let Some(ref mut tx) = event_tx {
|
if let Some(ref mut tx) = event_tx {
|
||||||
let _ = tx.push(AudioEvent::ExportFinalizing);
|
let _ = tx.push(AudioEvent::ExportFinalizing);
|
||||||
|
|
@ -99,10 +97,10 @@ pub fn export_audio<P: AsRef<Path>>(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ExportFormat::Mp3 => {
|
ExportFormat::Mp3 => {
|
||||||
export_mp3(project, pool, midi_pool, settings, output_path, event_tx)
|
export_mp3(project, pool, settings, output_path, event_tx)
|
||||||
}
|
}
|
||||||
ExportFormat::Aac => {
|
ExportFormat::Aac => {
|
||||||
export_aac(project, pool, midi_pool, settings, output_path, event_tx)
|
export_aac(project, pool, settings, output_path, event_tx)
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -125,7 +123,6 @@ pub fn export_audio<P: AsRef<Path>>(
|
||||||
pub fn render_to_memory(
|
pub fn render_to_memory(
|
||||||
project: &mut Project,
|
project: &mut Project,
|
||||||
pool: &AudioPool,
|
pool: &AudioPool,
|
||||||
midi_pool: &MidiClipPool,
|
|
||||||
settings: &ExportSettings,
|
settings: &ExportSettings,
|
||||||
mut event_tx: Option<&mut rtrb::Producer<AudioEvent>>,
|
mut event_tx: Option<&mut rtrb::Producer<AudioEvent>>,
|
||||||
) -> Result<Vec<f32>, String>
|
) -> Result<Vec<f32>, String>
|
||||||
|
|
@ -162,7 +159,6 @@ pub fn render_to_memory(
|
||||||
project.render(
|
project.render(
|
||||||
&mut render_buffer,
|
&mut render_buffer,
|
||||||
pool,
|
pool,
|
||||||
midi_pool,
|
|
||||||
&mut buffer_pool,
|
&mut buffer_pool,
|
||||||
playhead,
|
playhead,
|
||||||
settings.sample_rate,
|
settings.sample_rate,
|
||||||
|
|
@ -302,7 +298,6 @@ fn write_flac<P: AsRef<Path>>(
|
||||||
fn export_mp3<P: AsRef<Path>>(
|
fn export_mp3<P: AsRef<Path>>(
|
||||||
project: &mut Project,
|
project: &mut Project,
|
||||||
pool: &AudioPool,
|
pool: &AudioPool,
|
||||||
midi_pool: &MidiClipPool,
|
|
||||||
settings: &ExportSettings,
|
settings: &ExportSettings,
|
||||||
output_path: P,
|
output_path: P,
|
||||||
mut event_tx: Option<&mut rtrb::Producer<AudioEvent>>,
|
mut event_tx: Option<&mut rtrb::Producer<AudioEvent>>,
|
||||||
|
|
@ -382,7 +377,6 @@ fn export_mp3<P: AsRef<Path>>(
|
||||||
project.render(
|
project.render(
|
||||||
&mut render_buffer,
|
&mut render_buffer,
|
||||||
pool,
|
pool,
|
||||||
midi_pool,
|
|
||||||
&mut buffer_pool,
|
&mut buffer_pool,
|
||||||
playhead,
|
playhead,
|
||||||
settings.sample_rate,
|
settings.sample_rate,
|
||||||
|
|
@ -472,7 +466,6 @@ fn export_mp3<P: AsRef<Path>>(
|
||||||
fn export_aac<P: AsRef<Path>>(
|
fn export_aac<P: AsRef<Path>>(
|
||||||
project: &mut Project,
|
project: &mut Project,
|
||||||
pool: &AudioPool,
|
pool: &AudioPool,
|
||||||
midi_pool: &MidiClipPool,
|
|
||||||
settings: &ExportSettings,
|
settings: &ExportSettings,
|
||||||
output_path: P,
|
output_path: P,
|
||||||
mut event_tx: Option<&mut rtrb::Producer<AudioEvent>>,
|
mut event_tx: Option<&mut rtrb::Producer<AudioEvent>>,
|
||||||
|
|
@ -552,7 +545,6 @@ fn export_aac<P: AsRef<Path>>(
|
||||||
project.render(
|
project.render(
|
||||||
&mut render_buffer,
|
&mut render_buffer,
|
||||||
pool,
|
pool,
|
||||||
midi_pool,
|
|
||||||
&mut buffer_pool,
|
&mut buffer_pool,
|
||||||
playhead,
|
playhead,
|
||||||
settings.sample_rate,
|
settings.sample_rate,
|
||||||
|
|
|
||||||
|
|
@ -349,7 +349,6 @@ impl Project {
|
||||||
&mut self,
|
&mut self,
|
||||||
output: &mut [f32],
|
output: &mut [f32],
|
||||||
audio_pool: &AudioClipPool,
|
audio_pool: &AudioClipPool,
|
||||||
midi_pool: &MidiClipPool,
|
|
||||||
buffer_pool: &mut BufferPool,
|
buffer_pool: &mut BufferPool,
|
||||||
playhead_seconds: f64,
|
playhead_seconds: f64,
|
||||||
sample_rate: u32,
|
sample_rate: u32,
|
||||||
|
|
@ -374,7 +373,6 @@ impl Project {
|
||||||
track_id,
|
track_id,
|
||||||
output,
|
output,
|
||||||
audio_pool,
|
audio_pool,
|
||||||
midi_pool,
|
|
||||||
buffer_pool,
|
buffer_pool,
|
||||||
ctx,
|
ctx,
|
||||||
any_solo,
|
any_solo,
|
||||||
|
|
@ -389,7 +387,6 @@ impl Project {
|
||||||
track_id: TrackId,
|
track_id: TrackId,
|
||||||
output: &mut [f32],
|
output: &mut [f32],
|
||||||
audio_pool: &AudioClipPool,
|
audio_pool: &AudioClipPool,
|
||||||
midi_pool: &MidiClipPool,
|
|
||||||
buffer_pool: &mut BufferPool,
|
buffer_pool: &mut BufferPool,
|
||||||
ctx: RenderContext,
|
ctx: RenderContext,
|
||||||
any_solo: bool,
|
any_solo: bool,
|
||||||
|
|
@ -437,7 +434,8 @@ impl Project {
|
||||||
}
|
}
|
||||||
Some(TrackNode::Midi(track)) => {
|
Some(TrackNode::Midi(track)) => {
|
||||||
// Render MIDI track directly into output
|
// Render MIDI track directly into output
|
||||||
track.render(output, midi_pool, ctx.playhead_seconds, ctx.sample_rate, ctx.channels);
|
// Access midi_clip_pool from self - safe because we only need immutable access
|
||||||
|
track.render(output, &self.midi_clip_pool, ctx.playhead_seconds, ctx.sample_rate, ctx.channels);
|
||||||
}
|
}
|
||||||
Some(TrackNode::Group(group)) => {
|
Some(TrackNode::Group(group)) => {
|
||||||
// Read group properties and transform context (index-based child iteration to avoid clone)
|
// Read group properties and transform context (index-based child iteration to avoid clone)
|
||||||
|
|
@ -462,7 +460,6 @@ impl Project {
|
||||||
child_id,
|
child_id,
|
||||||
&mut group_buffer,
|
&mut group_buffer,
|
||||||
audio_pool,
|
audio_pool,
|
||||||
midi_pool,
|
|
||||||
buffer_pool,
|
buffer_pool,
|
||||||
child_ctx,
|
child_ctx,
|
||||||
any_solo,
|
any_solo,
|
||||||
|
|
|
||||||
|
|
@ -54,7 +54,7 @@ pub fn export_audio<P: AsRef<Path>>(
|
||||||
fn export_audio_daw_backend<P: AsRef<Path>>(
|
fn export_audio_daw_backend<P: AsRef<Path>>(
|
||||||
project: &mut Project,
|
project: &mut Project,
|
||||||
pool: &AudioPool,
|
pool: &AudioPool,
|
||||||
midi_pool: &MidiClipPool,
|
_midi_pool: &MidiClipPool,
|
||||||
settings: &AudioExportSettings,
|
settings: &AudioExportSettings,
|
||||||
output_path: P,
|
output_path: P,
|
||||||
) -> Result<(), String> {
|
) -> Result<(), String> {
|
||||||
|
|
@ -78,7 +78,6 @@ fn export_audio_daw_backend<P: AsRef<Path>>(
|
||||||
daw_backend::audio::export::export_audio(
|
daw_backend::audio::export::export_audio(
|
||||||
project,
|
project,
|
||||||
pool,
|
pool,
|
||||||
midi_pool,
|
|
||||||
&daw_settings,
|
&daw_settings,
|
||||||
output_path,
|
output_path,
|
||||||
None,
|
None,
|
||||||
|
|
@ -89,7 +88,7 @@ fn export_audio_daw_backend<P: AsRef<Path>>(
|
||||||
fn export_audio_ffmpeg_mp3<P: AsRef<Path>>(
|
fn export_audio_ffmpeg_mp3<P: AsRef<Path>>(
|
||||||
project: &mut Project,
|
project: &mut Project,
|
||||||
pool: &AudioPool,
|
pool: &AudioPool,
|
||||||
midi_pool: &MidiClipPool,
|
_midi_pool: &MidiClipPool,
|
||||||
settings: &AudioExportSettings,
|
settings: &AudioExportSettings,
|
||||||
output_path: P,
|
output_path: P,
|
||||||
cancel_flag: &Arc<AtomicBool>,
|
cancel_flag: &Arc<AtomicBool>,
|
||||||
|
|
@ -114,7 +113,6 @@ fn export_audio_ffmpeg_mp3<P: AsRef<Path>>(
|
||||||
let pcm_samples = render_to_memory(
|
let pcm_samples = render_to_memory(
|
||||||
project,
|
project,
|
||||||
pool,
|
pool,
|
||||||
midi_pool,
|
|
||||||
&daw_settings,
|
&daw_settings,
|
||||||
None, // No progress events for now
|
None, // No progress events for now
|
||||||
)?;
|
)?;
|
||||||
|
|
@ -292,7 +290,7 @@ fn receive_and_write_packets(
|
||||||
fn export_audio_ffmpeg_aac<P: AsRef<Path>>(
|
fn export_audio_ffmpeg_aac<P: AsRef<Path>>(
|
||||||
project: &mut Project,
|
project: &mut Project,
|
||||||
pool: &AudioPool,
|
pool: &AudioPool,
|
||||||
midi_pool: &MidiClipPool,
|
_midi_pool: &MidiClipPool,
|
||||||
settings: &AudioExportSettings,
|
settings: &AudioExportSettings,
|
||||||
output_path: P,
|
output_path: P,
|
||||||
cancel_flag: &Arc<AtomicBool>,
|
cancel_flag: &Arc<AtomicBool>,
|
||||||
|
|
@ -317,7 +315,6 @@ fn export_audio_ffmpeg_aac<P: AsRef<Path>>(
|
||||||
let pcm_samples = render_to_memory(
|
let pcm_samples = render_to_memory(
|
||||||
project,
|
project,
|
||||||
pool,
|
pool,
|
||||||
midi_pool,
|
|
||||||
&daw_settings,
|
&daw_settings,
|
||||||
None, // No progress events for now
|
None, // No progress events for now
|
||||||
)?;
|
)?;
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue