OSDN Git Service

alsabat: move alsa process to a single block
authorLu, Han <han.lu@intel.com>
Wed, 23 Mar 2016 07:52:46 +0000 (15:52 +0800)
committerTakashi Iwai <tiwai@suse.de>
Wed, 23 Mar 2016 16:51:22 +0000 (17:51 +0100)
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 <han.lu@intel.com>
Signed-off-by: Takashi Iwai <tiwai@suse.de>
bat/alsa.c
bat/bat.c
bat/common.c
bat/common.h
bat/signal.c

index 94f47f4..75158cb 100644 (file)
@@ -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(&params);
 
@@ -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"),
index 85a7282..f10c647 100644 (file)
--- 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;
index 11a7e4e..d3d1f28 100644 (file)
@@ -17,6 +17,7 @@
 #include <stddef.h>
 #include <stdlib.h>
 #include <stdbool.h>
+#include <errno.h>
 
 #include "aconfig.h"
 #include "gettext.h"
index 37d1e4b..ed33d51 100644 (file)
@@ -13,8 +13,6 @@
  *
  */
 
-#include <alsa/asoundlib.h>
-
 #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];
index 8026a35..a47ba97 100644 (file)
 #include <stdio.h>
 #include <stddef.h>
 #include <stdlib.h>
+#include <string.h>
 #include <math.h>
 #include <stdint.h>
 #include <stdbool.h>
+#include <errno.h>
 
 #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;
        }