0
1
mirror of https://github.com/radio95-rnt/fm95.git synced 2026-02-27 03:23:54 +01:00

make lpf a IIR

This commit is contained in:
2025-01-02 01:01:14 +01:00
parent d9625757b3
commit 9ddee9239d
7 changed files with 17 additions and 35 deletions

View File

@@ -12,32 +12,15 @@ float apply_pre_emphasis(Emphasis *pe, float sample) {
} }
void init_low_pass_filter(LowPassFilter *lp, float cutoff_frequency, float sample_rate) { void init_low_pass_filter(LowPassFilter *lp, float cutoff_frequency, float sample_rate) {
for (int i = 0; i < FIR_TAPS; i++) { float rc = 1/(M_2PI*cutoff_frequency);
for (int j = 0; j < FIR_PHASES; j++) { lp->alpha = sample_rate/(sample_rate+rc);
int mi = i * FIR_PHASES + j + 1; lp->prev_sample = 0.0f;
float sincpos = mi - (((FIR_TAPS * FIR_PHASES) + 1.0f) / 2.0f);
float firlowpass = (sincpos == 0.0f) ? 1.0f : sinf(M_2PI * cutoff_frequency * sincpos / sample_rate) / (PI * sincpos);
float window = 0.54f - 0.46f * cosf(M_2PI * mi / (FIR_TAPS * FIR_PHASES)); // Hamming window
lp->low_pass_fir[j][i] = firlowpass * window;
}
}
memset(lp->sample_buffer, 0, sizeof(lp->sample_buffer));
lp->buffer_index = 0;
} }
float apply_low_pass_filter(LowPassFilter *lp, float sample) { float apply_low_pass_filter(LowPassFilter *lp, float sample) {
// Update the sample buffer float output = lp->alpha*sample+(1-lp->alpha)*lp->prev_sample;
lp->sample_buffer[lp->buffer_index] = sample; lp->prev_sample = output;
lp->buffer_index = (lp->buffer_index + 1) % FIR_TAPS; return output;
// Apply the filter
float result = 0.0f;
int index = lp->buffer_index;
for (int i = 0; i < FIR_TAPS; i++) {
result += lp->low_pass_fir[0][i] * lp->sample_buffer[index];
index = (index + 1) % FIR_TAPS;
}
return result*6;
} }
void init_delay_line(DelayLine *delay_line, int max_delay) { void init_delay_line(DelayLine *delay_line, int max_delay) {

View File

@@ -15,9 +15,8 @@ void init_emphasis(Emphasis *pe, float tau, float sample_rate);
float apply_pre_emphasis(Emphasis *pe, float sample); float apply_pre_emphasis(Emphasis *pe, float sample);
typedef struct { typedef struct {
float low_pass_fir[FIR_PHASES][FIR_TAPS]; float alpha;
float sample_buffer[FIR_TAPS]; float prev_sample;
int buffer_index;
} LowPassFilter; } LowPassFilter;
void init_low_pass_filter(LowPassFilter *lp, float cutoff_frequency, float sample_rate); void init_low_pass_filter(LowPassFilter *lp, float cutoff_frequency, float sample_rate);

View File

@@ -63,12 +63,12 @@ int main() {
printf("CrosbySTCode : Stereo encoder (using the crosby system) made by radio95 (with help of ChatGPT and Claude, thanks!)\n"); printf("CrosbySTCode : Stereo encoder (using the crosby system) made by radio95 (with help of ChatGPT and Claude, thanks!)\n");
// Define formats and buffer atributes // Define formats and buffer atributes
pa_sample_spec stereo_format = { pa_sample_spec stereo_format = {
.format = PA_SAMPLE_FLOAT32LE, .format = PA_SAMPLE_FLOAT32NE, //Float32 NE, or Float32 Native Endian, the float in c uses the endianess of your pc, or native endian, and float is float32, and double is float64
.channels = 2, .channels = 2,
.rate = SAMPLE_RATE // Same sample rate makes it easy, leave the resampling to pipewire, it should know better .rate = SAMPLE_RATE // Same sample rate makes it easy, leave the resampling to pipewire, it should know better
}; };
pa_sample_spec mono_format = { pa_sample_spec mono_format = {
.format = PA_SAMPLE_FLOAT32LE, .format = PA_SAMPLE_FLOAT32NE,
.channels = 1, .channels = 1,
.rate = SAMPLE_RATE .rate = SAMPLE_RATE
}; };

View File

@@ -62,12 +62,12 @@ int main() {
printf("PSTCode : (Polar) Stereo encoder made by radio95 (with help of ChatGPT and Claude, thanks!). Note that this version is for the OIRT band which is in use in Russia, Belarus and other CIS countries\n"); printf("PSTCode : (Polar) Stereo encoder made by radio95 (with help of ChatGPT and Claude, thanks!). Note that this version is for the OIRT band which is in use in Russia, Belarus and other CIS countries\n");
// Define formats and buffer atributes // Define formats and buffer atributes
pa_sample_spec stereo_format = { pa_sample_spec stereo_format = {
.format = PA_SAMPLE_FLOAT32LE, .format = PA_SAMPLE_FLOAT32NE, //Float32 NE, or Float32 Native Endian, the float in c uses the endianess of your pc, or native endian, and float is float32, and double is float64
.channels = 2, .channels = 2,
.rate = SAMPLE_RATE // Same sample rate makes it easy, leave the resampling to pipewire, it should know better .rate = SAMPLE_RATE // Same sample rate makes it easy, leave the resampling to pipewire, it should know better
}; };
pa_sample_spec mono_format = { pa_sample_spec mono_format = {
.format = PA_SAMPLE_FLOAT32LE, .format = PA_SAMPLE_FLOAT32NE,
.channels = 1, .channels = 1,
.rate = SAMPLE_RATE .rate = SAMPLE_RATE
}; };

View File

@@ -57,7 +57,7 @@ int main() {
// Define formats and buffer atributes // Define formats and buffer atributes
pa_sample_spec audio_format = { pa_sample_spec audio_format = {
.format = PA_SAMPLE_FLOAT32LE, .format = PA_SAMPLE_FLOAT32NE, //Float32 NE, or Float32 Native Endian, the float in c uses the endianess of your pc, or native endian, and float is float32, and double is float64
.channels = 1, .channels = 1,
.rate = SAMPLE_RATE // Same sample rate makes it easy, leave the resampling to pipewire, it should know better .rate = SAMPLE_RATE // Same sample rate makes it easy, leave the resampling to pipewire, it should know better
}; };

View File

@@ -65,12 +65,12 @@ int main() {
printf("SSB-STCode : Stereo encoder made by radio95 (with help of ChatGPT and Claude, thanks!)\n"); printf("SSB-STCode : Stereo encoder made by radio95 (with help of ChatGPT and Claude, thanks!)\n");
// Define formats and buffer atributes // Define formats and buffer atributes
pa_sample_spec stereo_format = { pa_sample_spec stereo_format = {
.format = PA_SAMPLE_FLOAT32LE, .format = PA_SAMPLE_FLOAT32NE, //Float32 NE, or Float32 Native Endian, the float in c uses the endianess of your pc, or native endian, and float is float32, and double is float64
.channels = 2, .channels = 2,
.rate = SAMPLE_RATE // Same sample rate makes it easy, leave the resampling to pipewire, it should know better .rate = SAMPLE_RATE // Same sample rate makes it easy, leave the resampling to pipewire, it should know better
}; };
pa_sample_spec mono_format = { pa_sample_spec mono_format = {
.format = PA_SAMPLE_FLOAT32LE, .format = PA_SAMPLE_FLOAT32NE,
.channels = 1, .channels = 1,
.rate = SAMPLE_RATE .rate = SAMPLE_RATE
}; };

View File

@@ -63,12 +63,12 @@ int main() {
printf("STCode : Stereo encoder made by radio95 (with help of ChatGPT and Claude, thanks!)\n"); printf("STCode : Stereo encoder made by radio95 (with help of ChatGPT and Claude, thanks!)\n");
// Define formats and buffer atributes // Define formats and buffer atributes
pa_sample_spec stereo_format = { pa_sample_spec stereo_format = {
.format = PA_SAMPLE_FLOAT32LE, .format = PA_SAMPLE_FLOAT32NE, //Float32 NE, or Float32 Native Endian, the float in c uses the endianess of your pc, or native endian, and float is float32, and double is float64
.channels = 2, .channels = 2,
.rate = SAMPLE_RATE // Same sample rate makes it easy, leave the resampling to pipewire, it should know better .rate = SAMPLE_RATE // Same sample rate makes it easy, leave the resampling to pipewire, it should know better
}; };
pa_sample_spec mono_format = { pa_sample_spec mono_format = {
.format = PA_SAMPLE_FLOAT32LE, .format = PA_SAMPLE_FLOAT32NE,
.channels = 1, .channels = 1,
.rate = SAMPLE_RATE .rate = SAMPLE_RATE
}; };