60 lines
2.2 KiB
Plaintext
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;
|
|
}
|
|
}
|
|
} |