Files
2024-12-28 11:12:31 -08:00

60 lines
2.2 KiB
Plaintext

#ifndef M_PI
#define M_PI 3.14159265358979323846
#endif
extern "C" __global__
void limiter_kernel(
const double*__restrict__ wav_in, // Input audio signal [L0, R0, L1, R1, ..., LN-1, RN-1]
double* __restrict__ wav_out, // Output audio signal
double* __restrict__ debug_out, // Debug buffer [envelope, gain]
const int n_channels, // Number of channels (e.g., 2 for stereo)
const int n_samples, // Number of samples per channel
double threshold, // Threshold in percents (0-100)
double slope, // Slope angle in percents (0-100)
const double sr, // Sample rate (samples/sec)
double twnd, // Window time for RMS in ms
double tatt, // Attack time in ms
double trel // Release time in ms
) {
// Only one thread handles the entire stereo pair
int ch = blockIdx.x * blockDim.x + threadIdx.x; // Thread processes a single channel
if (ch >= n_channels) return;
double attack_coeff = exp(-1.0 / (sr * (tatt * 1e-3)));
double release_coeff = exp(-1.0 / (sr * (trel * 1e-3)));
double envelope = 0.00;
//threshold = .55;
//slope = 1.0;
for (int i = 0; i < n_samples; ++i) {
double sample = wav_in[i * n_channels + ch];
// Envelope tracking
double abs_sample = fabs(sample);
if (abs_sample > envelope) {
envelope = attack_coeff * (envelope - abs_sample) + abs_sample;
} else {
envelope = release_coeff * (envelope - abs_sample) + abs_sample;
}
// Gain calculation
double gain = 1.0;
if (envelope > threshold) {
gain = pow(10.0, -slope * (log10(envelope) - log10(threshold)));
}
// Upward compression below threshold
double upward_compression_gain = 1.0;
if (envelope < threshold && envelope > 0.0) {
upward_compression_gain = pow(10.0, slope * (log10(threshold) - log10(envelope)));
}
// Apply gain
wav_out[i * n_channels + ch] = sample * gain * upward_compression_gain;
// Debugging output (envelope and gain)
if (debug_out) {
debug_out[i * n_channels + ch] = gain;
}
}
}