From 986db20331cf444aa6fae38437168a0e990e32d0 Mon Sep 17 00:00:00 2001 From: "Lu, Han" Date: Wed, 23 Mar 2016 15:52:46 +0800 Subject: alsabat: move alsa process to a single block Move all alsa callings to a single block (alsa.c), so other blocks such as the main structure, the signal process and the data analysis modules will be independent to alsa, and new modules such as a tinyalsa interface can be easily embedded into alsabat. Signed-off-by: Lu, Han Signed-off-by: Takashi Iwai --- bat/alsa.c | 41 +++++++++++++++++++++++++++++++++++++---- bat/bat.c | 46 ++++++++++++++++++---------------------------- bat/common.c | 1 + bat/common.h | 13 ++++++++++--- bat/signal.c | 13 +++++++------ 5 files changed, 73 insertions(+), 41 deletions(-) diff --git a/bat/alsa.c b/bat/alsa.c index 94f47f4..75158cb 100644 --- a/bat/alsa.c +++ b/bat/alsa.c @@ -40,15 +40,49 @@ struct pcm_container { char *buffer; }; +struct format_map_table { + enum _bat_pcm_format format_bat; + snd_pcm_format_t format_alsa; +}; + +static struct format_map_table map_tables[] = { + { BAT_PCM_FORMAT_UNKNOWN, SND_PCM_FORMAT_UNKNOWN }, + { BAT_PCM_FORMAT_U8, SND_PCM_FORMAT_U8 }, + { BAT_PCM_FORMAT_S16_LE, SND_PCM_FORMAT_S16_LE }, + { BAT_PCM_FORMAT_S24_3LE, SND_PCM_FORMAT_S24_3LE }, + { BAT_PCM_FORMAT_S32_LE, SND_PCM_FORMAT_S32_LE }, + { BAT_PCM_FORMAT_MAX, }, +}; + +static int format_convert(struct bat *bat, snd_pcm_format_t *fmt) +{ + struct format_map_table *t = map_tables; + + for (; t->format_bat != BAT_PCM_FORMAT_MAX; t++) { + if (t->format_bat == bat->format) { + *fmt = t->format_alsa; + return 0; + } + } + fprintf(bat->err, _("Invalid format!\n")); + return -EINVAL; +} + static int set_snd_pcm_params(struct bat *bat, struct pcm_container *sndpcm) { snd_pcm_hw_params_t *params; + snd_pcm_format_t format; unsigned int buffer_time = 0; unsigned int period_time = 0; unsigned int rate; int err; const char *device_name = snd_pcm_name(sndpcm->handle); + /* Convert common format to ALSA format */ + err = format_convert(bat, &format); + if (err != 0) + return err; + /* Allocate a hardware parameters object. */ snd_pcm_hw_params_alloca(¶ms); @@ -72,11 +106,10 @@ static int set_snd_pcm_params(struct bat *bat, struct pcm_container *sndpcm) } /* Set format */ - err = snd_pcm_hw_params_set_format(sndpcm->handle, params, bat->format); + err = snd_pcm_hw_params_set_format(sndpcm->handle, params, format); if (err < 0) { fprintf(bat->err, _("Set parameter to device error: ")); - fprintf(bat->err, _("PCM format: %d %s: %s(%d)\n"), - bat->format, + fprintf(bat->err, _("PCM format: %d %s: %s(%d)\n"), format, device_name, snd_strerror(err), err); return err; } @@ -181,7 +214,7 @@ static int set_snd_pcm_params(struct bat *bat, struct pcm_container *sndpcm) return -EINVAL; } - err = snd_pcm_format_physical_width(bat->format); + err = snd_pcm_format_physical_width(format); if (err < 0) { fprintf(bat->err, _("Invalid parameters: ")); fprintf(bat->err, _("snd_pcm_format_physical_width: %d\n"), diff --git a/bat/bat.c b/bat/bat.c index 85a7282..f10c647 100644 --- a/bat/bat.c +++ b/bat/bat.c @@ -92,37 +92,30 @@ static void get_sine_frequencies(struct bat *bat, char *freq) static void get_format(struct bat *bat, char *optarg) { if (strcasecmp(optarg, "cd") == 0) { - bat->format = SND_PCM_FORMAT_S16_LE; + bat->format = BAT_PCM_FORMAT_S16_LE; bat->rate = 44100; bat->channels = 2; + bat->sample_size = 2; } else if (strcasecmp(optarg, "dat") == 0) { - bat->format = SND_PCM_FORMAT_S16_LE; + bat->format = BAT_PCM_FORMAT_S16_LE; bat->rate = 48000; bat->channels = 2; - } else { - bat->format = snd_pcm_format_value(optarg); - if (bat->format == SND_PCM_FORMAT_UNKNOWN) { - fprintf(bat->err, _("wrong extended format '%s'\n"), - optarg); - exit(EXIT_FAILURE); - } - } - - switch (bat->format) { - case SND_PCM_FORMAT_U8: + bat->sample_size = 2; + } else if (strcasecmp(optarg, "U8") == 0) { + bat->format = BAT_PCM_FORMAT_U8; bat->sample_size = 1; - break; - case SND_PCM_FORMAT_S16_LE: + } else if (strcasecmp(optarg, "S16_LE") == 0) { + bat->format = BAT_PCM_FORMAT_S16_LE; bat->sample_size = 2; - break; - case SND_PCM_FORMAT_S24_3LE: + } else if (strcasecmp(optarg, "S24_3LE") == 0) { + bat->format = BAT_PCM_FORMAT_S24_3LE; bat->sample_size = 3; - break; - case SND_PCM_FORMAT_S32_LE: + } else if (strcasecmp(optarg, "S32_LE") == 0) { + bat->format = BAT_PCM_FORMAT_S32_LE; bat->sample_size = 4; - break; - default: - fprintf(bat->err, _("unsupported format: %d\n"), bat->format); + } else { + bat->format = BAT_PCM_FORMAT_UNKNOWN; + fprintf(bat->err, _("wrong extended format '%s'\n"), optarg); exit(EXIT_FAILURE); } } @@ -295,11 +288,8 @@ _("Usage: alsabat [-options]...\n" " --local internal loop, set to bypass pcm hardware devices\n" " --standalone standalone mode, to bypass analysis\n" )); - fprintf(bat->log, _("Recognized sample formats are: %s %s %s %s\n"), - snd_pcm_format_name(SND_PCM_FORMAT_U8), - snd_pcm_format_name(SND_PCM_FORMAT_S16_LE), - snd_pcm_format_name(SND_PCM_FORMAT_S24_3LE), - snd_pcm_format_name(SND_PCM_FORMAT_S32_LE)); + fprintf(bat->log, _("Recognized sample formats are: ")); + fprintf(bat->log, _("U8 S16_LE S24_3LE S32_LE\n")); fprintf(bat->log, _("The available format shotcuts are:\n")); fprintf(bat->log, _("-f cd (16 bit little endian, 44100, stereo)\n")); fprintf(bat->log, _("-f dat (16 bit little endian, 48000, stereo)\n")); @@ -314,7 +304,7 @@ static void set_defaults(struct bat *bat) bat->channels = 1; bat->frame_size = 2; bat->sample_size = 2; - bat->format = SND_PCM_FORMAT_S16_LE; + bat->format = BAT_PCM_FORMAT_S16_LE; bat->convert_float_to_sample = convert_float_to_int16; bat->convert_sample_to_double = convert_int16_to_double; bat->frames = bat->rate * 2; diff --git a/bat/common.c b/bat/common.c index 11a7e4e..d3d1f28 100644 --- a/bat/common.c +++ b/bat/common.c @@ -17,6 +17,7 @@ #include #include #include +#include #include "aconfig.h" #include "gettext.h" diff --git a/bat/common.h b/bat/common.h index 37d1e4b..ed33d51 100644 --- a/bat/common.h +++ b/bat/common.h @@ -13,8 +13,6 @@ * */ -#include - #define TEMP_RECORD_FILE_NAME "/tmp/bat.wav.XXXXXX" #define DEFAULT_DEV_NAME "default" @@ -110,6 +108,15 @@ struct wav_container { struct bat; +enum _bat_pcm_format { + BAT_PCM_FORMAT_UNKNOWN = -1, + BAT_PCM_FORMAT_S16_LE = 0, + BAT_PCM_FORMAT_S32_LE, + BAT_PCM_FORMAT_U8, + BAT_PCM_FORMAT_S24_3LE, + BAT_PCM_FORMAT_MAX +}; + enum _bat_op_mode { MODE_UNKNOWN = -1, MODE_SINGLE = 0, @@ -142,7 +149,7 @@ struct bat { int frames; /* nb of frames */ int frame_size; /* size of frame */ int sample_size; /* size of sample */ - snd_pcm_format_t format; /* PCM format */ + enum _bat_pcm_format format; /* PCM format */ float sigma_k; /* threshold for peak detection */ float target_freq[MAX_CHANNELS]; diff --git a/bat/signal.c b/bat/signal.c index 8026a35..a47ba97 100644 --- a/bat/signal.c +++ b/bat/signal.c @@ -23,9 +23,11 @@ #include #include #include +#include #include #include #include +#include #include "gettext.h" #include "common.h" @@ -113,22 +115,21 @@ static int adjust_waveform(struct bat *bat, float *val, int frames) float factor, offset = 0.0; switch (bat->format) { - case SND_PCM_FORMAT_U8: + case BAT_PCM_FORMAT_U8: max = INT8_MAX; offset = max; /* shift for unsigned format */ break; - case SND_PCM_FORMAT_S16_LE: + case BAT_PCM_FORMAT_S16_LE: max = INT16_MAX; break; - case SND_PCM_FORMAT_S24_3LE: + case BAT_PCM_FORMAT_S24_3LE: max = (1 << 23) - 1; break; - case SND_PCM_FORMAT_S32_LE: + case BAT_PCM_FORMAT_S32_LE: max = INT32_MAX; break; default: - fprintf(bat->err, _("Invalid PCM format: %s\n"), - snd_pcm_format_name(bat->format)); + fprintf(bat->err, _("Invalid PCM format: %d\n"), bat->format); return -EINVAL; } -- cgit v1.2.1