[alsa-devel] [PATCH V3 5/6] alsabat: move alsa process to a single block

han.lu at intel.com han.lu at intel.com
Wed Mar 23 08:52:46 CET 2016


From: "Lu, Han" <han.lu at intel.com>

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 at intel.com>

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(&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"),
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 <stddef.h>
 #include <stdlib.h>
 #include <stdbool.h>
+#include <errno.h>
 
 #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 <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];
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 <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;
 	}
 
-- 
2.5.0



More information about the Alsa-devel mailing list