11use crossbeam:: channel:: { Sender , bounded} ;
22use jack:: { AsyncClient , Client , ClientOptions , contrib:: ClosureProcessHandler } ;
3+ use log:: error;
34
45use crate :: io:: processor:: { ProcessHandler , Processor } ;
56use crate :: io:: recorder:: Recorder ;
67use crate :: sim:: chain:: AmplifierChain ;
78
89/// Manages the audio processing chain and JACK client
910pub struct ProcessorManager {
10- client : Option < Client > ,
11- active_client : Option < AsyncClient < Notifications , ClosureProcessHandler < ( ) , ProcessHandler > > > ,
11+ _active_client : AsyncClient < Notifications , ClosureProcessHandler < ( ) , ProcessHandler > > ,
1212 recorder : Option < Recorder > ,
1313 /// GUI → audio thread: push a completely new preset
14- amp_tx : Option < Sender < Box < AmplifierChain > > > ,
14+ amp_tx : Sender < Box < AmplifierChain > > ,
1515 sample_rate : f32 ,
1616}
1717
@@ -25,80 +25,58 @@ impl ProcessorManager {
2525 let ( client, _status) = Client :: new ( "rustortion" , ClientOptions :: NO_START_SERVER )
2626 . map_err ( |e| format ! ( "Failed to create JACK client: {e}" ) ) ?;
2727
28+ let ( tx_amp, rx_amp) = bounded :: < Box < AmplifierChain > > ( 1 ) ; // SPSC, size 1
29+
30+ let processor = Processor :: new_with_channel ( & client, rx_amp, None ) ;
31+ let handler = ClosureProcessHandler :: new ( processor. into_process_handler ( ) ) ;
32+
33+ let sample_rate = client. sample_rate ( ) as f32 ;
34+
35+ let _active_client = client
36+ . activate_async ( Notifications , handler)
37+ . map_err ( |e| format ! ( "activate_async: {e}" ) ) ?;
38+
2839 Ok ( Self {
29- sample_rate : client. sample_rate ( ) as f32 ,
30- client : Some ( client) ,
31- active_client : None ,
40+ sample_rate,
41+ _active_client,
3242 recorder : None ,
33- amp_tx : None ,
43+ amp_tx : tx_amp ,
3444 } )
3545 }
3646
3747 /// Push a new amplifier chain from the GUI side.
3848 /// Never blocks; silently drops if the buffer is full.
3949 pub fn set_amp_chain ( & self , new_chain : AmplifierChain ) {
40- if let Some ( tx) = & self . amp_tx {
41- tx. try_send ( Box :: new ( new_chain) ) . unwrap_or_else ( |e| {
42- log:: error!( "Failed to send new amplifier chain: {e}" ) ;
50+ self . amp_tx
51+ . try_send ( Box :: new ( new_chain) )
52+ . unwrap_or_else ( |e| {
53+ error ! ( "Failed to send new amplifier chain: {e}" ) ;
4354 } ) ;
44- }
4555 }
4656
4757 /// Starts recording if enabled
4858 pub fn enable_recording ( & mut self , record_dir : & str ) -> Result < ( ) , String > {
4959 if self . recorder . is_some ( ) {
50- return Ok ( ( ) ) ; // Already recording
60+ return Ok ( ( ) ) ;
5161 }
5262
5363 let recorder = Recorder :: new ( self . sample_rate as u32 , record_dir)
5464 . map_err ( |e| format ! ( "Failed to start recorder: {e}" ) ) ?;
65+ let _ = recorder. sender ( ) ;
5566
5667 self . recorder = Some ( recorder) ;
5768 Ok ( ( ) )
5869 }
5970
6071 /// Stops recording if active
6172 pub fn disable_recording ( & mut self ) {
62- if let Some ( recorder) = self . recorder . take ( ) {
63- recorder. stop ( ) ;
64- }
65- }
66-
67- /// Starts the audio processing
68- pub fn start ( & mut self ) -> Result < ( ) , String > {
69- if self . active_client . is_some ( ) {
70- return Ok ( ( ) ) ;
73+ if self . recorder . is_none ( ) {
74+ return ;
7175 }
7276
73- let client = self . client . take ( ) . ok_or ( "Client already active" ) ?;
74- let ( tx_amp, rx_amp) = bounded :: < Box < AmplifierChain > > ( 1 ) ; // SPSC, size 1
75-
76- let tx_audio = self . recorder . as_ref ( ) . map ( |r| r. sender ( ) ) ;
77-
78- // Processor owns its mutable chain and a receiver for updates
79- let processor = Processor :: new_with_channel ( & client, rx_amp, tx_audio) ;
80-
81- let callback = processor. into_process_handler ( ) ;
82- let handler = ClosureProcessHandler :: new ( callback) ;
83- let active = client
84- . activate_async ( Notifications , handler)
85- . map_err ( |e| format ! ( "activate_async: {e}" ) ) ?;
86-
87- self . amp_tx = Some ( tx_amp) ;
88- self . active_client = Some ( active) ;
89- Ok ( ( ) )
90- }
91-
92- pub fn stop ( & mut self ) -> Result < ( ) , String > {
93- if let Some ( active) = self . active_client . take ( ) {
94- let ( client, _n, _h) = active
95- . deactivate ( )
96- . map_err ( |e| format ! ( "deactivate: {e:?}" ) ) ?;
97- self . client = Some ( client) ;
77+ if let Some ( recorder) = self . recorder . take ( ) {
78+ recorder. stop ( ) ;
9879 }
99- self . disable_recording ( ) ;
100- self . amp_tx = None ;
101- Ok ( ( ) )
10280 }
10381
10482 /// Returns the sample rate
@@ -109,6 +87,6 @@ impl ProcessorManager {
10987
11088impl Drop for ProcessorManager {
11189 fn drop ( & mut self ) {
112- let _ = self . stop ( ) ;
90+ self . disable_recording ( ) ;
11391 }
11492}
0 commit comments