* [PATCH 1/2] vivid: SDR cap: add control for FM deviation
@ 2015-09-01 23:04 Antti Palosaari
2015-09-01 23:04 ` [PATCH 2/2] vivid: sdr cap: few enhancements Antti Palosaari
0 siblings, 1 reply; 2+ messages in thread
From: Antti Palosaari @ 2015-09-01 23:04 UTC (permalink / raw)
To: linux-media; +Cc: Hans Verkuil, Antti Palosaari
Add user control to adjust generated FM deviation.
Default it to 75kHz like public FM radio broadcast.
Signed-off-by: Antti Palosaari <crope@iki.fi>
---
drivers/media/platform/vivid/vivid-core.h | 1 +
drivers/media/platform/vivid/vivid-ctrls.c | 37 +++++++++++++++++++++++++++-
drivers/media/platform/vivid/vivid-sdr-cap.c | 6 ++++-
3 files changed, 42 insertions(+), 2 deletions(-)
diff --git a/drivers/media/platform/vivid/vivid-core.h b/drivers/media/platform/vivid/vivid-core.h
index c72349c..289640c 100644
--- a/drivers/media/platform/vivid/vivid-core.h
+++ b/drivers/media/platform/vivid/vivid-core.h
@@ -451,6 +451,7 @@ struct vivid_dev {
unsigned sdr_buffersize;
unsigned sdr_adc_freq;
unsigned sdr_fm_freq;
+ unsigned sdr_fm_deviation;
int sdr_fixp_src_phase;
int sdr_fixp_mod_phase;
diff --git a/drivers/media/platform/vivid/vivid-ctrls.c b/drivers/media/platform/vivid/vivid-ctrls.c
index 339c8b7..29834fa 100644
--- a/drivers/media/platform/vivid/vivid-ctrls.c
+++ b/drivers/media/platform/vivid/vivid-ctrls.c
@@ -99,6 +99,7 @@
#define VIVID_CID_RADIO_TX_RDS_BLOCKIO (VIVID_CID_VIVID_BASE + 94)
+#define VIVID_CID_SDR_CAP_FM_DEVIATION (VIVID_CID_VIVID_BASE + 110)
/* General User Controls */
@@ -1257,6 +1258,36 @@ static const struct v4l2_ctrl_config vivid_ctrl_radio_tx_rds_blockio = {
};
+/* SDR Capture Controls */
+
+static int vivid_sdr_cap_s_ctrl(struct v4l2_ctrl *ctrl)
+{
+ struct vivid_dev *dev = container_of(ctrl->handler, struct vivid_dev, ctrl_hdl_sdr_cap);
+
+ switch (ctrl->id) {
+ case VIVID_CID_SDR_CAP_FM_DEVIATION:
+ dev->sdr_fm_deviation = ctrl->val;
+ break;
+ }
+ return 0;
+}
+
+static const struct v4l2_ctrl_ops vivid_sdr_cap_ctrl_ops = {
+ .s_ctrl = vivid_sdr_cap_s_ctrl,
+};
+
+static const struct v4l2_ctrl_config vivid_ctrl_sdr_cap_fm_deviation = {
+ .ops = &vivid_sdr_cap_ctrl_ops,
+ .id = VIVID_CID_SDR_CAP_FM_DEVIATION,
+ .name = "FM Deviation",
+ .type = V4L2_CTRL_TYPE_INTEGER,
+ .min = 100,
+ .max = 200000,
+ .def = 75000,
+ .step = 1,
+};
+
+
static const struct v4l2_ctrl_config vivid_ctrl_class = {
.ops = &vivid_user_gen_ctrl_ops,
.flags = V4L2_CTRL_FLAG_READ_ONLY | V4L2_CTRL_FLAG_WRITE_ONLY,
@@ -1314,7 +1345,7 @@ int vivid_create_controls(struct vivid_dev *dev, bool show_ccs_cap,
v4l2_ctrl_new_custom(hdl_radio_rx, &vivid_ctrl_class, NULL);
v4l2_ctrl_handler_init(hdl_radio_tx, 17);
v4l2_ctrl_new_custom(hdl_radio_tx, &vivid_ctrl_class, NULL);
- v4l2_ctrl_handler_init(hdl_sdr_cap, 18);
+ v4l2_ctrl_handler_init(hdl_sdr_cap, 19);
v4l2_ctrl_new_custom(hdl_sdr_cap, &vivid_ctrl_class, NULL);
/* User Controls */
@@ -1545,6 +1576,10 @@ int vivid_create_controls(struct vivid_dev *dev, bool show_ccs_cap,
&vivid_radio_tx_ctrl_ops,
V4L2_CID_RDS_TX_MUSIC_SPEECH, 0, 1, 1, 1);
}
+ if (dev->has_sdr_cap) {
+ v4l2_ctrl_new_custom(hdl_sdr_cap,
+ &vivid_ctrl_sdr_cap_fm_deviation, NULL);
+ }
if (hdl_user_gen->error)
return hdl_user_gen->error;
if (hdl_user_vid->error)
diff --git a/drivers/media/platform/vivid/vivid-sdr-cap.c b/drivers/media/platform/vivid/vivid-sdr-cap.c
index d2f2188..c36b3f5 100644
--- a/drivers/media/platform/vivid/vivid-sdr-cap.c
+++ b/drivers/media/platform/vivid/vivid-sdr-cap.c
@@ -22,6 +22,7 @@
#include <linux/delay.h>
#include <linux/kthread.h>
#include <linux/freezer.h>
+#include <linux/math64.h>
#include <linux/videodev2.h>
#include <linux/v4l2-dv-timings.h>
#include <media/v4l2-common.h>
@@ -488,12 +489,14 @@ int vidioc_try_fmt_sdr_cap(struct file *file, void *fh, struct v4l2_format *f)
#define FIXP_N (15)
#define FIXP_FRAC (1 << FIXP_N)
#define FIXP_2PI ((int)(2 * 3.141592653589 * FIXP_FRAC))
+#define M_100000PI (3.14159 * 100000)
void vivid_sdr_cap_process(struct vivid_dev *dev, struct vivid_buffer *buf)
{
u8 *vbuf = vb2_plane_vaddr(&buf->vb, 0);
unsigned long i;
unsigned long plane_size = vb2_plane_size(&buf->vb, 0);
+ s64 s64tmp;
s32 src_phase_step;
s32 mod_phase_step;
s32 fixp_i;
@@ -515,7 +518,8 @@ void vivid_sdr_cap_process(struct vivid_dev *dev, struct vivid_buffer *buf)
FIXP_2PI) >> (31 - FIXP_N);
dev->sdr_fixp_src_phase += src_phase_step;
- dev->sdr_fixp_mod_phase += mod_phase_step / 4;
+ s64tmp = (s64) mod_phase_step * dev->sdr_fm_deviation;
+ dev->sdr_fixp_mod_phase += div_s64(s64tmp, M_100000PI);
/*
* Transfer phases to [0 / 2xPI] in order to avoid variable
--
http://palosaari.fi/
^ permalink raw reply related [flat|nested] 2+ messages in thread
* [PATCH 2/2] vivid: sdr cap: few enhancements
2015-09-01 23:04 [PATCH 1/2] vivid: SDR cap: add control for FM deviation Antti Palosaari
@ 2015-09-01 23:04 ` Antti Palosaari
0 siblings, 0 replies; 2+ messages in thread
From: Antti Palosaari @ 2015-09-01 23:04 UTC (permalink / raw)
To: linux-media; +Cc: Hans Verkuil, Antti Palosaari
* Constify struct
* Fix comments
* Fix alignment
* Use modulus to transfer phase angles
* Correct float [-1.0, +1.0] to s8 [-128, 127] conversion
Signed-off-by: Antti Palosaari <crope@iki.fi>
---
drivers/media/platform/vivid/vivid-sdr-cap.c | 31 +++++++++++-----------------
1 file changed, 12 insertions(+), 19 deletions(-)
diff --git a/drivers/media/platform/vivid/vivid-sdr-cap.c b/drivers/media/platform/vivid/vivid-sdr-cap.c
index c36b3f5..fcbf498 100644
--- a/drivers/media/platform/vivid/vivid-sdr-cap.c
+++ b/drivers/media/platform/vivid/vivid-sdr-cap.c
@@ -41,7 +41,7 @@ struct vivid_format {
};
/* format descriptions for capture and preview */
-static struct vivid_format formats[] = {
+static const struct vivid_format formats[] = {
{
.pixelformat = V4L2_SDR_FMT_CU8,
.buffersize = SDR_CAP_SAMPLES_PER_BUF * 2,
@@ -502,16 +502,10 @@ void vivid_sdr_cap_process(struct vivid_dev *dev, struct vivid_buffer *buf)
s32 fixp_i;
s32 fixp_q;
- /*
- * TODO: Generated beep tone goes very crackly when sample rate is
- * increased to ~1Msps or more. That is because of huge rounding error
- * of phase angle caused by used cosine implementation.
- */
-
/* calculate phase step */
#define BEEP_FREQ 1000 /* 1kHz beep */
src_phase_step = DIV_ROUND_CLOSEST(FIXP_2PI * BEEP_FREQ,
- dev->sdr_adc_freq);
+ dev->sdr_adc_freq);
for (i = 0; i < plane_size; i += 2) {
mod_phase_step = fixp_cos32_rad(dev->sdr_fixp_src_phase,
@@ -522,17 +516,15 @@ void vivid_sdr_cap_process(struct vivid_dev *dev, struct vivid_buffer *buf)
dev->sdr_fixp_mod_phase += div_s64(s64tmp, M_100000PI);
/*
- * Transfer phases to [0 / 2xPI] in order to avoid variable
+ * Transfer phase agle to [0, 2xPI] in order to avoid variable
* overflow and make it suitable for cosine implementation
* used, which does not support negative angles.
*/
- while (dev->sdr_fixp_mod_phase < FIXP_2PI)
- dev->sdr_fixp_mod_phase += FIXP_2PI;
- while (dev->sdr_fixp_mod_phase > FIXP_2PI)
- dev->sdr_fixp_mod_phase -= FIXP_2PI;
+ dev->sdr_fixp_src_phase %= FIXP_2PI;
+ dev->sdr_fixp_mod_phase %= FIXP_2PI;
- while (dev->sdr_fixp_src_phase > FIXP_2PI)
- dev->sdr_fixp_src_phase -= FIXP_2PI;
+ if (dev->sdr_fixp_mod_phase < 0)
+ dev->sdr_fixp_mod_phase += FIXP_2PI;
fixp_i = fixp_cos32_rad(dev->sdr_fixp_mod_phase, FIXP_2PI);
fixp_q = fixp_sin32_rad(dev->sdr_fixp_mod_phase, FIXP_2PI);
@@ -544,7 +536,7 @@ void vivid_sdr_cap_process(struct vivid_dev *dev, struct vivid_buffer *buf)
switch (dev->sdr_pixelformat) {
case V4L2_SDR_FMT_CU8:
- /* convert 'fixp float' to u8 */
+ /* convert 'fixp float' to u8 [0, +255] */
/* u8 = X * 127.5 + 127.5; X is float [-1.0, +1.0] */
fixp_i = fixp_i * 1275 + FIXP_FRAC * 1275;
fixp_q = fixp_q * 1275 + FIXP_FRAC * 1275;
@@ -552,9 +544,10 @@ void vivid_sdr_cap_process(struct vivid_dev *dev, struct vivid_buffer *buf)
*vbuf++ = DIV_ROUND_CLOSEST(fixp_q, FIXP_FRAC * 10);
break;
case V4L2_SDR_FMT_CS8:
- /* convert 'fixp float' to s8 */
- fixp_i = fixp_i * 1275;
- fixp_q = fixp_q * 1275;
+ /* convert 'fixp float' to s8 [-128, +127] */
+ /* s8 = X * 127.5 - 0.5; X is float [-1.0, +1.0] */
+ fixp_i = fixp_i * 1275 - FIXP_FRAC * 5;
+ fixp_q = fixp_q * 1275 - FIXP_FRAC * 5;
*vbuf++ = DIV_ROUND_CLOSEST(fixp_i, FIXP_FRAC * 10);
*vbuf++ = DIV_ROUND_CLOSEST(fixp_q, FIXP_FRAC * 10);
break;
--
http://palosaari.fi/
^ permalink raw reply related [flat|nested] 2+ messages in thread
end of thread, other threads:[~2015-09-01 23:05 UTC | newest]
Thread overview: 2+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2015-09-01 23:04 [PATCH 1/2] vivid: SDR cap: add control for FM deviation Antti Palosaari
2015-09-01 23:04 ` [PATCH 2/2] vivid: sdr cap: few enhancements Antti Palosaari
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).