From cb42c4dbbc4d4bf245371876352e5c986b248799 Mon Sep 17 00:00:00 2001 From: Simon Ser Date: Thu, 23 May 2019 15:52:19 +0300 Subject: lib/igt_audio: introduce audio_convert_to This function converts normalized doubles into an ALSA PCM format. Instead of having per-format audio_signal_fill_* functions, we can only have audio_signal_fill that outputs normalized doubles. Then in ALSA's playback callback, we can simply use the new audio_convert_to function to fill the buffer. This makes the test code simpler and prevents code duplication when another ALSA playback callback is implemented. This adds a dependency of igt_audio over ALSA for the PCM format enum, but I don't think this is a concern, since I don't see the point of using igt_audio without igt_alsa. If this is an issue, it would always be possible to replace ALSA's enum with our own in the future. Signed-off-by: Simon Ser Reviewed-by: Martin Peres --- lib/igt_audio.c | 87 ++++++++++++++++++++++++++++----------------------------- lib/igt_audio.h | 12 ++++---- 2 files changed, 47 insertions(+), 52 deletions(-) (limited to 'lib') diff --git a/lib/igt_audio.c b/lib/igt_audio.c index ea2d83a5..be665b03 100644 --- a/lib/igt_audio.c +++ b/lib/igt_audio.c @@ -304,51 +304,6 @@ void audio_signal_fill(struct audio_signal *signal, double *buffer, audio_sanity_check(buffer, signal->channels * samples); } -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); -} - -void audio_signal_fill_s24_le(struct audio_signal *signal, int32_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] = 0x7FFFFF * tmp[i]; - - free(tmp); -} - -void audio_signal_fill_s32_le(struct audio_signal *signal, int32_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] = INT32_MAX * tmp[i]; - - free(tmp); -} - /** * Checks that frequencies specified in signal, and only those, are included * in the input data. @@ -508,6 +463,48 @@ size_t audio_extract_channel_s32_le(double *dst, size_t dst_cap, return dst_len; } +static void audio_convert_to_s16_le(int16_t *dst, double *src, size_t len) +{ + size_t i; + + for (i = 0; i < len; ++i) + dst[i] = INT16_MAX * src[i]; +} + +static void audio_convert_to_s24_le(int32_t *dst, double *src, size_t len) +{ + size_t i; + + for (i = 0; i < len; ++i) + dst[i] = 0x7FFFFF * src[i]; +} + +static void audio_convert_to_s32_le(int32_t *dst, double *src, size_t len) +{ + size_t i; + + for (i = 0; i < len; ++i) + dst[i] = INT32_MAX * src[i]; +} + +void audio_convert_to(void *dst, double *src, size_t len, + snd_pcm_format_t format) +{ + switch (format) { + case SND_PCM_FORMAT_S16_LE: + audio_convert_to_s16_le(dst, src, len); + break; + case SND_PCM_FORMAT_S24_LE: + audio_convert_to_s24_le(dst, src, len); + break; + case SND_PCM_FORMAT_S32_LE: + audio_convert_to_s32_le(dst, src, len); + break; + default: + assert(false); /* unreachable */ + } +} + #define RIFF_TAG "RIFF" #define WAVE_TAG "WAVE" #define FMT_TAG "fmt " diff --git a/lib/igt_audio.h b/lib/igt_audio.h index c8de7087..5c910c27 100644 --- a/lib/igt_audio.h +++ b/lib/igt_audio.h @@ -32,6 +32,8 @@ #include #include +#include + struct audio_signal; struct audio_signal *audio_signal_init(int channels, int sampling_rate); @@ -41,18 +43,14 @@ int audio_signal_add_frequency(struct audio_signal *signal, int frequency, void audio_signal_synthesize(struct audio_signal *signal); void audio_signal_reset(struct audio_signal *signal); 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); -void audio_signal_fill_s24_le(struct audio_signal *signal, int32_t *buffer, - size_t buffer_len); -void audio_signal_fill_s32_le(struct audio_signal *signal, int32_t *buffer, - size_t buffer_len); + size_t samples); bool audio_signal_detect(struct audio_signal *signal, int sampling_rate, int channel, const double *samples, size_t samples_len); size_t audio_extract_channel_s32_le(double *dst, size_t dst_cap, int32_t *src, size_t src_len, int n_channels, int channel); +void audio_convert_to(void *dst, double *src, size_t len, + snd_pcm_format_t format); int audio_create_wav_file_s32_le(const char *qualifier, uint32_t sample_rate, uint16_t channels, char **path); -- cgit v1.2.3