@@ -7,10 +7,10 @@ use crate::amp::stages::Stage;
77use crate :: audio:: peak_meter:: PeakMeter ;
88use crate :: audio:: pitch_shifter:: PitchShifter ;
99use crate :: audio:: recorder:: Recorder ;
10+ use crate :: audio:: rt_drop:: RtDropHandle ;
1011use crate :: audio:: samplers:: Samplers ;
1112use crate :: ir:: cabinet:: IrCabinet ;
1213use crate :: ir:: convolver:: Convolver ;
13- use crate :: ir:: load_service:: ConvolverDropHandle ;
1414use crate :: metronome:: Metronome ;
1515use crate :: tuner:: Tuner ;
1616
@@ -22,6 +22,11 @@ pub struct PreparedIr {
2222pub enum EngineMessage {
2323 SetAmpChain ( Box < AmplifierChain > ) ,
2424 SetInputFilters ( Option < Box < dyn Stage > > , Option < Box < dyn Stage > > ) ,
25+ SetParameter ( usize , & ' static str , f32 ) ,
26+ ReplaceStage ( usize , Box < dyn Stage > ) ,
27+ AddStage ( usize , Box < dyn Stage > ) ,
28+ RemoveStage ( usize ) ,
29+ SwapStages ( usize , usize ) ,
2530 StartRecording ( Recorder ) ,
2631 StopRecording ,
2732 SwapIrConvolver ( Box < PreparedIr > ) ,
@@ -39,8 +44,8 @@ pub struct Engine {
3944 ir_cabinet : Option < IrCabinet > ,
4045 /// Channel for updating the amplifier chain.
4146 engine_receiver : Receiver < EngineMessage > ,
42- /// Handle for sending old convolvers off the RT thread for deallocation.
43- convolver_drop : ConvolverDropHandle ,
47+ /// Handle for sending arbitrary objects off the RT thread for deallocation.
48+ rt_drop : RtDropHandle ,
4449 samplers : Samplers ,
4550 tuner : Tuner ,
4651 recorder : Option < Recorder > ,
@@ -63,16 +68,16 @@ impl Engine {
6368 ir_cabinet : Option < IrCabinet > ,
6469 peak_meter : PeakMeter ,
6570 metronome : Metronome ,
66- convolver_drop : ConvolverDropHandle ,
71+ rt_drop : RtDropHandle ,
6772 ) -> Result < ( Self , EngineHandle ) > {
68- let ( engine_sender, engine_receiver) = bounded :: < EngineMessage > ( 10 ) ;
73+ let ( engine_sender, engine_receiver) = bounded :: < EngineMessage > ( 32 ) ;
6974
7075 Ok ( (
7176 Self {
7277 chain : Box :: new ( AmplifierChain :: new ( ) ) ,
7378 ir_cabinet,
7479 engine_receiver,
75- convolver_drop ,
80+ rt_drop ,
7681 samplers,
7782 tuner,
7883 recorder : None ,
@@ -188,10 +193,44 @@ impl Engine {
188193 pub fn handle_messages ( & mut self ) {
189194 while let Ok ( message) = self . engine_receiver . try_recv ( ) {
190195 match message {
191- EngineMessage :: SetAmpChain ( chain) => {
192- self . chain = chain;
196+ EngineMessage :: SetAmpChain ( new_chain) => {
197+ let old = std:: mem:: replace ( & mut self . chain , new_chain) ;
198+ self . rt_drop . retire ( old) ;
193199 debug ! ( "Received new amplifier chain" ) ;
194200 }
201+ EngineMessage :: SetParameter ( idx, name, value) => {
202+ if let Some ( result) = self . chain . set_parameter ( idx, name, value) {
203+ if let Err ( e) = result {
204+ error ! ( "Failed to set parameter '{name}' on stage {idx}: {e}" ) ;
205+ }
206+ } else {
207+ error ! ( "SetParameter: stage index {idx} out of bounds" ) ;
208+ }
209+ }
210+ EngineMessage :: ReplaceStage ( idx, new_stage) => {
211+ if let Some ( old) = self . chain . replace_stage ( idx, new_stage) {
212+ self . rt_drop . retire ( old) ;
213+ debug ! ( "Replaced stage at index {idx}" ) ;
214+ } else {
215+ error ! ( "ReplaceStage: stage index {idx} out of bounds" ) ;
216+ }
217+ }
218+ EngineMessage :: AddStage ( idx, stage) => {
219+ self . chain . insert_stage ( idx, stage) ;
220+ debug ! ( "Added stage at index {idx}" ) ;
221+ }
222+ EngineMessage :: RemoveStage ( idx) => {
223+ if let Some ( old) = self . chain . remove_stage ( idx) {
224+ self . rt_drop . retire ( old) ;
225+ debug ! ( "Removed stage at index {idx}" ) ;
226+ } else {
227+ error ! ( "RemoveStage: stage index {idx} out of bounds" ) ;
228+ }
229+ }
230+ EngineMessage :: SwapStages ( a, b) => {
231+ self . chain . swap_stages ( a, b) ;
232+ debug ! ( "Swapped stages {a} and {b}" ) ;
233+ }
195234 EngineMessage :: SetInputFilters ( hp, lp) => {
196235 self . input_highpass = hp;
197236 self . input_lowpass = lp;
@@ -201,7 +240,7 @@ impl Engine {
201240 if let Some ( ref mut cab) = self . ir_cabinet {
202241 debug ! ( "IR convolver swapped: {}" , prepared. name) ;
203242 let old = cab. swap_convolver ( prepared. convolver ) ;
204- self . convolver_drop . retire ( old) ;
243+ self . rt_drop . retire ( Box :: new ( old) ) ;
205244 }
206245 }
207246 EngineMessage :: ClearIr => {
@@ -320,6 +359,26 @@ impl EngineHandle {
320359 self . send ( update) ;
321360 }
322361
362+ pub fn set_parameter ( & self , stage_idx : usize , name : & ' static str , value : f32 ) {
363+ self . send ( EngineMessage :: SetParameter ( stage_idx, name, value) ) ;
364+ }
365+
366+ pub fn replace_stage ( & self , idx : usize , stage : Box < dyn Stage > ) {
367+ self . send ( EngineMessage :: ReplaceStage ( idx, stage) ) ;
368+ }
369+
370+ pub fn add_stage ( & self , idx : usize , stage : Box < dyn Stage > ) {
371+ self . send ( EngineMessage :: AddStage ( idx, stage) ) ;
372+ }
373+
374+ pub fn remove_stage ( & self , idx : usize ) {
375+ self . send ( EngineMessage :: RemoveStage ( idx) ) ;
376+ }
377+
378+ pub fn swap_stages ( & self , a : usize , b : usize ) {
379+ self . send ( EngineMessage :: SwapStages ( a, b) ) ;
380+ }
381+
323382 pub fn set_amp_chain ( & self , new_chain : AmplifierChain ) {
324383 let update = EngineMessage :: SetAmpChain ( Box :: new ( new_chain) ) ;
325384 self . send ( update) ;
0 commit comments