[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