kopia lustrzana https://github.com/xdsopl/robot36
moved ddc to ddc.rsh, made filter order less flexible
rodzic
0dac8080d9
commit
e69c476a41
|
@ -0,0 +1,42 @@
|
|||
/*
|
||||
Copyright 2014 Ahmet Inan <xdsopl@googlemail.com>
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef DDC_RSH
|
||||
#define DDC_RSH
|
||||
|
||||
#include "complex.rsh"
|
||||
#include "ema.rsh"
|
||||
#include "phasor.rsh"
|
||||
|
||||
typedef struct {
|
||||
phasor_t phasor;
|
||||
cema_cascade_t lowpass;
|
||||
} ddc_t;
|
||||
|
||||
static ddc_t ddc(float carrier, float bandwidth, float rate)
|
||||
{
|
||||
return (ddc_t){
|
||||
phasor(-carrier, rate),
|
||||
cema_cutoff_cascade(bandwidth, rate)
|
||||
};
|
||||
}
|
||||
|
||||
static complex_t convert(ddc_t *ddc, float amp)
|
||||
{
|
||||
return cfilter(&ddc->lowpass, amp * rotate(&ddc->phasor));
|
||||
}
|
||||
|
||||
#endif
|
|
@ -19,7 +19,7 @@ limitations under the License.
|
|||
|
||||
#include "complex.rsh"
|
||||
#include "ema.rsh"
|
||||
#include "phasor.rsh"
|
||||
#include "ddc.rsh"
|
||||
|
||||
short *audio_buffer;
|
||||
uchar *value_buffer;
|
||||
|
@ -78,20 +78,6 @@ static float scottieDX_estimator(int length)
|
|||
return filter(&variance, deviation * deviation);
|
||||
}
|
||||
|
||||
static phasor_t cnt_phasor;
|
||||
static cema_cascade_t cnt_lowpass;
|
||||
static complex_t cnt_ddc(float amp)
|
||||
{
|
||||
return cfilter(&cnt_lowpass, amp * rotate(&cnt_phasor));
|
||||
}
|
||||
|
||||
static phasor_t dat_phasor;
|
||||
static cema_cascade_t dat_lowpass;
|
||||
static complex_t dat_ddc(float amp)
|
||||
{
|
||||
return cfilter(&dat_lowpass, amp * rotate(&dat_phasor));
|
||||
}
|
||||
|
||||
static float cnt_fmd_scale;
|
||||
static float cnt_fmd(complex_t baseband)
|
||||
{
|
||||
|
@ -111,6 +97,7 @@ static float dat_fmd(complex_t baseband)
|
|||
}
|
||||
|
||||
static ema_t avg_power, leader_lowpass;
|
||||
static ddc_t cnt_ddc, dat_ddc;
|
||||
static int sample_rate, mode, even_hpos;
|
||||
static int maximum_variance, minimum_sync_length;
|
||||
static int scanline_length, minimum_length, maximum_length;
|
||||
|
@ -401,13 +388,8 @@ void initialize(float rate, int length, int width, int height)
|
|||
avg_power = ema_cutoff(10.0f, sample_rate);
|
||||
leader_lowpass = ema_cutoff(100.0f, sample_rate);
|
||||
|
||||
static const int filter_order = 11;
|
||||
static cema_t cnt_ema_cascade[filter_order], dat_ema_cascade[filter_order];
|
||||
cnt_lowpass = cema_cutoff_cascade(cnt_ema_cascade, cnt_bandwidth, sample_rate, filter_order);
|
||||
dat_lowpass = cema_cutoff_cascade(dat_ema_cascade, dat_bandwidth, sample_rate, filter_order);
|
||||
|
||||
cnt_phasor = phasor(-cnt_carrier, sample_rate);
|
||||
dat_phasor = phasor(-dat_carrier, sample_rate);
|
||||
cnt_ddc = ddc(cnt_carrier, cnt_bandwidth, sample_rate);
|
||||
dat_ddc = ddc(dat_carrier, dat_bandwidth, sample_rate);
|
||||
|
||||
cnt_fmd_scale = sample_rate / (M_PI * cnt_bandwidth);
|
||||
dat_fmd_scale = sample_rate / (M_PI * dat_bandwidth);
|
||||
|
@ -683,8 +665,8 @@ void decode(int samples) {
|
|||
if (filter(&avg_power, power) < 0.0000001f)
|
||||
continue;
|
||||
|
||||
complex_t cnt_baseband = cnt_ddc(amp);
|
||||
complex_t dat_baseband = dat_ddc(amp);
|
||||
complex_t cnt_baseband = convert(&cnt_ddc, amp);
|
||||
complex_t dat_baseband = convert(&dat_ddc, amp);
|
||||
|
||||
float cnt_value = cnt_fmd(cnt_baseband);
|
||||
float dat_value = dat_fmd(dat_baseband);
|
||||
|
|
|
@ -28,9 +28,9 @@ typedef struct {
|
|||
float a;
|
||||
} cema_t;
|
||||
|
||||
static const int cema_cascade_order = 11;
|
||||
typedef struct {
|
||||
cema_t *ema;
|
||||
int order;
|
||||
cema_t ema[cema_cascade_order];
|
||||
} cema_cascade_t;
|
||||
|
||||
static float ema_cutoff_a(float cutoff, float rate)
|
||||
|
@ -60,11 +60,12 @@ static cema_t cema_cutoff(float cutoff, float rate)
|
|||
return cema(ema_cutoff_a(cutoff, rate));
|
||||
}
|
||||
|
||||
static cema_cascade_t cema_cutoff_cascade(cema_t *ema, float cutoff, float rate, int order)
|
||||
static cema_cascade_t cema_cutoff_cascade(float cutoff, float rate)
|
||||
{
|
||||
for (int i = 0; i < order; ++i)
|
||||
ema[i] = cema_cutoff(cutoff / sqrt(rootn(2.0f, order) - 1.0f), rate);
|
||||
return (cema_cascade_t){ ema, order };
|
||||
cema_cascade_t cascade;
|
||||
for (int i = 0; i < cema_cascade_order; ++i)
|
||||
cascade.ema[i] = cema_cutoff(cutoff / sqrt(rootn(2.0f, cema_cascade_order) - 1.0f), rate);
|
||||
return cascade;
|
||||
}
|
||||
|
||||
static inline float filter(ema_t *ema, float input)
|
||||
|
@ -79,7 +80,7 @@ static inline complex_t __attribute__((overloadable)) cfilter(cema_t *ema, compl
|
|||
|
||||
static complex_t __attribute__((overloadable)) cfilter(cema_cascade_t *cascade, complex_t input)
|
||||
{
|
||||
for (int i = 0; i < cascade->order; ++i)
|
||||
for (int i = 0; i < cema_cascade_order; ++i)
|
||||
input = cfilter(cascade->ema + i, input);
|
||||
return input;
|
||||
}
|
||||
|
|
Ładowanie…
Reference in New Issue