MCPcopy Create free account
hub / github.com/Xiaobin-Rong/gtcrn / worker_thread

Function worker_thread

ladspa/src/plugin.rs:150–382  ·  view source on GitHub ↗

Worker thread for audio processing. Processes audio in a separate thread to avoid blocking the real-time audio callback. Uses pre-allocated buffers to prevent memory allocations during processing. Model is created based on the initial state value.

(
    mut input_consumer: ringbuf::HeapCons<f32>,
    mut output_producer: ringbuf::HeapProd<f32>,
    state: Arc<SharedState>,
    host_sample_rate: usize,
)

Source from the content-addressed store, hash-verified

148/// audio callback. Uses pre-allocated buffers to prevent memory allocations
149/// during processing. Model is created based on the initial state value.
150fn worker_thread(
151 mut input_consumer: ringbuf::HeapCons<f32>,
152 mut output_producer: ringbuf::HeapProd<f32>,
153 state: Arc<SharedState>,
154 host_sample_rate: usize,
155) {
156 let needs_resample = host_sample_rate != MODEL_SAMPLE_RATE;
157 let resample_ratio = host_sample_rate as f64 / MODEL_SAMPLE_RATE as f64;
158
159 // Calculate chunk sizes for resampling
160 // At 48kHz host and 16kHz model, ratio is 3.0
161 // We process HOP_SIZE (256) samples at model rate per frame
162 let host_chunk_size = (HOP_SIZE as f64 * resample_ratio).ceil() as usize;
163
164 // Initialize high-quality sinc resamplers
165 let mut downsampler: Option<FftFixedIn<f32>> = if needs_resample {
166 Some(
167 FftFixedIn::new(host_sample_rate, MODEL_SAMPLE_RATE, host_chunk_size, 1, 1)
168 .expect("Failed to create downsampler"),
169 )
170 } else {
171 None
172 };
173
174 let mut upsampler: Option<FftFixedOut<f32>> = if needs_resample {
175 Some(
176 FftFixedOut::new(MODEL_SAMPLE_RATE, host_sample_rate, host_chunk_size, 1, 1)
177 .expect("Failed to create upsampler"),
178 )
179 } else {
180 None
181 };
182
183 // Initialize STFT processor
184 let mut stft = StftProcessor::new(NFFT, HOP_SIZE);
185
186 // Wait for first run() call to set port values before creating model
187 while !state.is_initialized() {
188 if state.should_shutdown() {
189 return;
190 }
191 thread::sleep(Duration::from_millis(1));
192 }
193
194 // Create model based on current state value (now set by run() call)
195 let initial_model_type = state.get_model_type();
196 let mut model = GtcrnModel::new(initial_model_type);
197
198 // Pre-allocated fixed-size buffers (no heap allocations during processing)
199 let mut input_buffer = vec![0.0_f32; host_chunk_size + 64];
200 let mut window = vec![0.0_f32; NFFT];
201 let mut model_accum = vec![0.0_f32; HOP_SIZE * 4]; // Accumulator for downsampled samples
202 let mut model_accum_len: usize = 0;
203
204 // Resampler I/O buffers (single channel, fixed size)
205 let mut resample_in = vec![vec![0.0_f32; host_chunk_size + 64]];
206 let mut resample_out = vec![vec![0.0_f32; HOP_SIZE + 64]];
207 let mut upsample_in = vec![vec![0.0_f32; HOP_SIZE + 64]];

Callers 1

newMethod · 0.85

Calls 10

is_initializedMethod · 0.80
should_shutdownMethod · 0.80
get_model_typeMethod · 0.80
is_enabledMethod · 0.80
get_strengthMethod · 0.80
model_typeMethod · 0.80
set_model_typeMethod · 0.80
analyzeMethod · 0.80
process_frameMethod · 0.80
synthesizeMethod · 0.80

Tested by

no test coverage detected