/* * The frequencies below are from the reference driver. They probably need * further adjustments, because they are not tested at all. You may even need * to play a bit with the registers of the chip to select the proper signal * for the input of the audio rds fifo, and measure it's sampling rate to * calculate the proper baseband frequencies...
*/
/* The spectrum of the signal should be empty between these frequencies. */ #define FREQ_NOISE_START ((s32)(0.100000 * 32768.0)) #define FREQ_NOISE_END ((s32)(1.200000 * 32768.0))
#define dprintk(level, fmt, arg...) do { \ if (dsp_debug >= level) \
printk(KERN_DEBUG pr_fmt("%s: dsp:" fmt), \
__func__, ##arg); \
} while (0)
static s32 int_cos(u32 x)
{
u32 t2, t4, t6, t8;
s32 ret;
u16 period = x / INT_PI;
if (period % 2) return -int_cos(x - INT_PI);
x = x % INT_PI; if (x > INT_PI / 2) return -int_cos(INT_PI / 2 - (x % (INT_PI / 2))); /* * Now x is between 0 and INT_PI/2. * To calculate cos(x) we use it's Taylor polinom.
*/
t2 = x * x / 32768 / 2;
t4 = t2 * x / 32768 * x / 32768 / 3 / 4;
t6 = t4 * x / 32768 * x / 32768 / 5 / 6;
t8 = t6 * x / 32768 * x / 32768 / 7 / 8;
ret = 32768 - t2 + t4 - t6 + t8; return ret;
}
static u32 int_goertzel(s16 x[], u32 N, u32 freq)
{ /* * We use the Goertzel algorithm to determine the power of the * given frequency in the signal
*/
s32 s_prev = 0;
s32 s_prev2 = 0;
s32 coeff = 2 * int_cos(freq);
u32 i;
u64 tmp;
u32 divisor;
for (i = 0; i < N; i++) {
s32 s = x[i] + ((s64)coeff * s_prev / 32768) - s_prev2;
s32 cx88_dsp_detect_stereo_sap(struct cx88_core *core)
{
s16 *samples;
u32 N = 0;
s32 ret = UNSET;
/* If audio RDS fifo is disabled, we can't read the samples */ if (!(cx_read(MO_AUD_DMACNTRL) & 0x04)) return ret; if (!(cx_read(AUD_CTL) & EN_FMRADIO_EN_RDS)) return ret;
/* Wait at least 500 ms after an audio standard change */ if (time_before(jiffies, core->last_change + msecs_to_jiffies(500))) return ret;
samples = read_rds_samples(core, &N);
if (!samples) return ret;
switch (core->tvaudio) { case WW_BG: case WW_DK: case WW_EIAJ: case WW_M:
ret = detect_a2_a2m_eiaj(core, samples, N); break; case WW_BTSC:
ret = detect_btsc(core, samples, N); break; case WW_NONE: case WW_I: case WW_L: case WW_I2SPT: case WW_FM: case WW_I2SADC: break;
}
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.