[alsa-devel] [PATCH BAT V1 4/7] BAT: Add signal generator
han.lu at intel.com
han.lu at intel.com
Tue Sep 15 09:00:20 CEST 2015
From: "Lu, Han" <han.lu at intel.com>
Add function that generates sine waveform through math lib.
The waveform can be used as source for playback or analysis.
Signed-off-by: Lu, Han <han.lu at intel.com>
Signed-off-by: Liam Girdwood <liam.r.girdwood at intel.com>
Signed-off-by: Bernard Gautier <bernard.gautier at intel.com>
diff --git a/bat/signal.c b/bat/signal.c
new file mode 100644
index 0000000..1efb81e
--- /dev/null
+++ b/bat/signal.c
@@ -0,0 +1,88 @@
+/*
+ * Copyright (C) 2013-2015 Intel Corporation
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#include <stdio.h>
+#include <stddef.h>
+#include <stdlib.h>
+#include <math.h>
+#include <stdbool.h>
+
+#include "gettext.h"
+#include "common.h"
+
+void sinf_sign(struct bat *bat,
+ float *out, int length, int max, int *phase, float *val)
+{
+ int i = *phase, k, c, idx;
+ float factor = max * RANGE_FACTOR;
+
+ for (k = 0; k < length; k++) {
+ for (c = 0; c < bat->channels; c++) {
+ idx = k * bat->channels + c;
+ out[idx] = sinf(val[c] * i) * factor;
+ }
+ i++;
+ if (i == bat->rate)
+ i = 0; /* Restart from 0 after one sine wave period */
+ }
+ *phase = i;
+}
+
+void sinf_unsign(struct bat *bat,
+ float *out, int length, int max, int *phase, float *val)
+{
+ int i = *phase, k, c, idx;
+ float factor = max * RANGE_FACTOR / 2.0;
+ float offset = max * (1 - RANGE_FACTOR) / 2.0;
+
+ for (k = 0; k < length; k++) {
+ for (c = 0; c < bat->channels; c++) {
+ idx = k * bat->channels + c;
+ out[idx] = (sinf(val[c] * i) + 1.0) * factor
+ + offset;
+ }
+ i++;
+ if (i == bat->rate)
+ i = 0; /* Restart from 0 after one sine wave period */
+ }
+ *phase = i;
+}
+
+int generate_sine_wave(struct bat *bat, int length, void *buf, int max)
+{
+ static int i;
+ int c, buf_bytes;
+ float sin_val[MAX_CHANNELS];
+ float *sinus_f = NULL;
+
+ buf_bytes = bat->channels * length;
+ sinus_f = (float *) malloc(buf_bytes * sizeof(float));
+ if (sinus_f == NULL) {
+ fprintf(bat->err, _("Not enough memory.\n"));
+ return -ENOMEM;
+ }
+
+ for (c = 0; c < bat->channels; c++)
+ sin_val[c] = 2.0 * M_PI * bat->target_freq[c]
+ / (float) bat->rate;
+
+ bat->sinf_func(bat, sinus_f, length, max, &i, sin_val);
+
+ bat->convert_float_to_sample(sinus_f, buf, length, bat->channels);
+
+ free(sinus_f);
+
+ return 0;
+}
--
1.9.1
More information about the Alsa-devel
mailing list