[igt-dev] [PATCH i-g-t] lib/igt_audio: use double instead of int16_t

Simon Ser simon.ser at intel.com
Tue May 14 08:15:48 UTC 2019


In order to be able to generate S32_LE signals, we need a higher precision than
S16_LE. Change the signal generation code to use double instead of int16_t and
introduce a new helper to fill a buffer with S16_LE samples. We already use
arrays of doubles elsewhere (see audio_signal_detect). Similar format-specific
helpers will be added for S32_LE in the future.

Signed-off-by: Simon Ser <simon.ser at intel.com>
---

This patch is necessary for supporting more audio formats, and will be useful
for amplitude checks (no need to convert back-and-forth between normalized
double values and int16_t).

 lib/igt_audio.c       | 41 ++++++++++++++++++++++++++++-------------
 lib/igt_audio.h       |  4 +++-
 tests/kms_chamelium.c |  2 +-
 3 files changed, 32 insertions(+), 15 deletions(-)

diff --git a/lib/igt_audio.c b/lib/igt_audio.c
index fd8cf07c0de3..3d1a38057a92 100644
--- a/lib/igt_audio.c
+++ b/lib/igt_audio.c
@@ -51,7 +51,7 @@ struct audio_signal_freq {
 	int freq;
 	int channel;

-	int16_t *period;
+	double *period;
 	size_t period_len;
 	int offset;
 };
@@ -142,7 +142,7 @@ int audio_signal_add_frequency(struct audio_signal *signal, int frequency,
  */
 void audio_signal_synthesize(struct audio_signal *signal)
 {
-	int16_t *period;
+	double *period;
 	double value;
 	size_t period_len;
 	int freq;
@@ -152,13 +152,13 @@ void audio_signal_synthesize(struct audio_signal *signal)
 		freq = signal->freqs[i].freq;
 		period_len = signal->sampling_rate / freq;

-		period = calloc(1, period_len * sizeof(int16_t));
+		period = calloc(period_len, sizeof(double));

 		for (j = 0; j < period_len; j++) {
 			value = 2.0 * M_PI * freq / signal->sampling_rate * j;
-			value = sin(value) * INT16_MAX / signal->freqs_count;
+			value = sin(value) / signal->freqs_count;

-			period[j] = (int16_t) value;
+			period[j] = value;
 		}

 		signal->freqs[i].period = period;
@@ -202,19 +202,19 @@ void audio_signal_reset(struct audio_signal *signal)
  * @samples: The number of samples to fill
  *
  * Fill the requested number of samples to the target buffer with the audio
- * signal data (in interleaved S16_LE format), at the requested sampling rate
+ * signal data (in interleaved double format), at the requested sampling rate
  * and number of channels.
  */
-void audio_signal_fill(struct audio_signal *signal, int16_t *buffer,
-		       size_t buffer_len)
+void audio_signal_fill(struct audio_signal *signal, double *buffer,
+		       size_t samples)
 {
-	int16_t *destination, *source;
+	double *destination, *source;
 	struct audio_signal_freq *freq;
 	int total;
 	int count;
 	int i, j, k;

-	memset(buffer, 0, sizeof(int16_t) * signal->channels * buffer_len);
+	memset(buffer, 0, sizeof(double) * signal->channels * samples);

 	for (i = 0; i < signal->freqs_count; i++) {
 		freq = &signal->freqs[i];
@@ -222,13 +222,13 @@ void audio_signal_fill(struct audio_signal *signal, int16_t *buffer,

 		igt_assert(freq->period);

-		while (total < buffer_len) {
+		while (total < samples) {
 			source = freq->period + freq->offset;
 			destination = buffer + total * signal->channels;

 			count = freq->period_len - freq->offset;
-			if (count > buffer_len - total)
-				count = buffer_len - total;
+			if (count > samples - total)
+				count = samples - total;

 			freq->offset += count;
 			freq->offset %= freq->period_len;
@@ -247,6 +247,21 @@ void audio_signal_fill(struct audio_signal *signal, int16_t *buffer,
 	}
 }

+void audio_signal_fill_s16_le(struct audio_signal *signal, int16_t *buffer,
+			      size_t samples)
+{
+	double *tmp;
+	size_t i;
+
+	tmp = malloc(sizeof(double) * signal->channels * samples);
+	audio_signal_fill(signal, tmp, samples);
+
+	for (i = 0; i < signal->channels * samples; ++i)
+		buffer[i] = INT16_MAX * tmp[i];
+
+	free(tmp);
+}
+
 /**
  * Checks that frequencies specified in signal, and only those, are included
  * in the input data.
diff --git a/lib/igt_audio.h b/lib/igt_audio.h
index 466e772a75a4..56e080c87848 100644
--- a/lib/igt_audio.h
+++ b/lib/igt_audio.h
@@ -40,8 +40,10 @@ int audio_signal_add_frequency(struct audio_signal *signal, int frequency,
 			       int channel);
 void audio_signal_synthesize(struct audio_signal *signal);
 void audio_signal_reset(struct audio_signal *signal);
-void audio_signal_fill(struct audio_signal *signal, int16_t *buffer,
+void audio_signal_fill(struct audio_signal *signal, double *buffer,
 		       size_t buffer_len);
+void audio_signal_fill_s16_le(struct audio_signal *signal, int16_t *buffer,
+			      size_t buffer_len);
 bool audio_signal_detect(struct audio_signal *signal, int sampling_rate,
 			 int channel, double *data, size_t data_len);
 size_t audio_extract_channel_s32_le(double *dst, size_t dst_cap,
diff --git a/tests/kms_chamelium.c b/tests/kms_chamelium.c
index 502f1efa0727..e1ddc60aca52 100644
--- a/tests/kms_chamelium.c
+++ b/tests/kms_chamelium.c
@@ -790,7 +790,7 @@ audio_output_callback(void *data, short *buffer, int frames)
 {
 	struct audio_state *state = data;

-	audio_signal_fill(state->signal, buffer, frames);
+	audio_signal_fill_s16_le(state->signal, buffer, frames);

 	return state->run ? 0 : -1;
 }
--
2.21.0



More information about the igt-dev mailing list