From b1b3582772dae244e6e3569ca6c0cc5780ffb8f3 Mon Sep 17 00:00:00 2001 From: dvdli Date: Mon, 22 Feb 2021 17:24:30 +0800 Subject: support float config and float wave file playback --- include/tinyalsa/pcm.h | 4 ++++ src/pcm.c | 7 +++++++ tests/src/pcm_test.cc | 2 ++ utils/tinyplay.c | 29 ++++++++++++++++++++--------- 4 files changed, 33 insertions(+), 9 deletions(-) diff --git a/include/tinyalsa/pcm.h b/include/tinyalsa/pcm.h index b40550c..5c11e2a 100644 --- a/include/tinyalsa/pcm.h +++ b/include/tinyalsa/pcm.h @@ -178,6 +178,10 @@ enum pcm_format { PCM_FORMAT_S24_3BE, /** Signed, 32-bit, big endian */ PCM_FORMAT_S32_BE, + /** 32-bit float, little endian */ + PCM_FORMAT_FLOAT_LE, + /** 32-bit float, big endian */ + PCM_FORMAT_FLOAT_BE, /** Max of the enumeration list, not an actual format. */ PCM_FORMAT_MAX }; diff --git a/src/pcm.c b/src/pcm.c index 10e477b..3d50ea7 100644 --- a/src/pcm.c +++ b/src/pcm.c @@ -282,6 +282,11 @@ static unsigned int pcm_format_to_alsa(enum pcm_format format) return SNDRV_PCM_FORMAT_S32_LE; case PCM_FORMAT_S32_BE: return SNDRV_PCM_FORMAT_S32_BE; + + case PCM_FORMAT_FLOAT_LE: + return SNDRV_PCM_FORMAT_FLOAT_LE; + case PCM_FORMAT_FLOAT_BE: + return SNDRV_PCM_FORMAT_FLOAT_BE; }; } @@ -556,6 +561,8 @@ unsigned int pcm_format_to_bits(enum pcm_format format) case PCM_FORMAT_S32_BE: case PCM_FORMAT_S24_LE: case PCM_FORMAT_S24_BE: + case PCM_FORMAT_FLOAT_LE: + case PCM_FORMAT_FLOAT_BE: return 32; case PCM_FORMAT_S24_3LE: case PCM_FORMAT_S24_3BE: diff --git a/tests/src/pcm_test.cc b/tests/src/pcm_test.cc index 2668350..da114de 100644 --- a/tests/src/pcm_test.cc +++ b/tests/src/pcm_test.cc @@ -49,6 +49,8 @@ TEST(PcmTest, FormatToBits) { ASSERT_EQ(pcm_format_to_bits(PCM_FORMAT_S24_BE), 32); ASSERT_EQ(pcm_format_to_bits(PCM_FORMAT_S24_3BE), 24); ASSERT_EQ(pcm_format_to_bits(PCM_FORMAT_S32_BE), 32); + ASSERT_EQ(pcm_format_to_bits(PCM_FORMAT_FLOAT_LE), 32); + ASSERT_EQ(pcm_format_to_bits(PCM_FORMAT_FLOAT_BE), 32); } TEST(PcmTest, OpenAndCloseOutPcm) { diff --git a/utils/tinyplay.c b/utils/tinyplay.c index 4c7ccf6..c9e4606 100644 --- a/utils/tinyplay.c +++ b/utils/tinyplay.c @@ -70,6 +70,9 @@ void cmd_init(struct cmd *cmd) #define ID_FMT 0x20746d66 #define ID_DATA 0x61746164 +#define WAVE_FORMAT_PCM 0x0001 +#define WAVE_FORMAT_IEEE_FLOAT 0x0003 + struct riff_wave_header { uint32_t riff_id; uint32_t riff_sz; @@ -164,16 +167,24 @@ int ctx_init(struct ctx* ctx, const struct cmd *cmd) bits = ctx->chunk_fmt.bits_per_sample; } - if (bits == 8) { - config.format = PCM_FORMAT_S8; - } else if (bits == 16) { - config.format = PCM_FORMAT_S16_LE; - } else if (bits == 24) { - config.format = PCM_FORMAT_S24_3LE; - } else if (bits == 32) { - config.format = PCM_FORMAT_S32_LE; + if (ctx->chunk_fmt.audio_format == WAVE_FORMAT_PCM) { + if (bits == 8) { + config.format = PCM_FORMAT_S8; + } else if (bits == 16) { + config.format = PCM_FORMAT_S16_LE; + } else if (bits == 24) { + config.format = PCM_FORMAT_S24_3LE; + } else if (bits == 32) { + config.format = PCM_FORMAT_S32_LE; + } else { + fprintf(stderr, "bit count '%u' not supported\n", bits); + fclose(ctx->file); + return -1; + } + } else if (ctx->chunk_fmt.audio_format == WAVE_FORMAT_IEEE_FLOAT) { + config.format = PCM_FORMAT_FLOAT_LE; } else { - fprintf(stderr, "bit count '%u' not supported\n", bits); + fprintf(stderr, "format '%hu' not supported\n", ctx->chunk_fmt.audio_format); fclose(ctx->file); return -1; } -- cgit v1.2.3