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 <han.lu@intel.com>
Signed-off-by: Takashi Iwai <tiwai@suse.de>
This commit is contained in:
Lu, Han 2016-03-23 15:52:46 +08:00 committed by Takashi Iwai
parent c49a6180c8
commit 986db20331
5 changed files with 74 additions and 42 deletions

View file

@ -40,15 +40,49 @@ struct pcm_container {
char *buffer; 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) static int set_snd_pcm_params(struct bat *bat, struct pcm_container *sndpcm)
{ {
snd_pcm_hw_params_t *params; snd_pcm_hw_params_t *params;
snd_pcm_format_t format;
unsigned int buffer_time = 0; unsigned int buffer_time = 0;
unsigned int period_time = 0; unsigned int period_time = 0;
unsigned int rate; unsigned int rate;
int err; int err;
const char *device_name = snd_pcm_name(sndpcm->handle); 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. */ /* Allocate a hardware parameters object. */
snd_pcm_hw_params_alloca(&params); 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 */ /* 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) { if (err < 0) {
fprintf(bat->err, _("Set parameter to device error: ")); fprintf(bat->err, _("Set parameter to device error: "));
fprintf(bat->err, _("PCM format: %d %s: %s(%d)\n"), fprintf(bat->err, _("PCM format: %d %s: %s(%d)\n"), format,
bat->format,
device_name, snd_strerror(err), err); device_name, snd_strerror(err), err);
return err; return err;
} }
@ -181,7 +214,7 @@ static int set_snd_pcm_params(struct bat *bat, struct pcm_container *sndpcm)
return -EINVAL; return -EINVAL;
} }
err = snd_pcm_format_physical_width(bat->format); err = snd_pcm_format_physical_width(format);
if (err < 0) { if (err < 0) {
fprintf(bat->err, _("Invalid parameters: ")); fprintf(bat->err, _("Invalid parameters: "));
fprintf(bat->err, _("snd_pcm_format_physical_width: %d\n"), fprintf(bat->err, _("snd_pcm_format_physical_width: %d\n"),

View file

@ -92,37 +92,30 @@ static void get_sine_frequencies(struct bat *bat, char *freq)
static void get_format(struct bat *bat, char *optarg) static void get_format(struct bat *bat, char *optarg)
{ {
if (strcasecmp(optarg, "cd") == 0) { if (strcasecmp(optarg, "cd") == 0) {
bat->format = SND_PCM_FORMAT_S16_LE; bat->format = BAT_PCM_FORMAT_S16_LE;
bat->rate = 44100; bat->rate = 44100;
bat->channels = 2; bat->channels = 2;
bat->sample_size = 2;
} else if (strcasecmp(optarg, "dat") == 0) { } else if (strcasecmp(optarg, "dat") == 0) {
bat->format = SND_PCM_FORMAT_S16_LE; bat->format = BAT_PCM_FORMAT_S16_LE;
bat->rate = 48000; bat->rate = 48000;
bat->channels = 2; 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 = 1;
break;
case SND_PCM_FORMAT_S16_LE:
bat->sample_size = 2; bat->sample_size = 2;
break; } else if (strcasecmp(optarg, "U8") == 0) {
case SND_PCM_FORMAT_S24_3LE: bat->format = BAT_PCM_FORMAT_U8;
bat->sample_size = 1;
} else if (strcasecmp(optarg, "S16_LE") == 0) {
bat->format = BAT_PCM_FORMAT_S16_LE;
bat->sample_size = 2;
} else if (strcasecmp(optarg, "S24_3LE") == 0) {
bat->format = BAT_PCM_FORMAT_S24_3LE;
bat->sample_size = 3; bat->sample_size = 3;
break; } else if (strcasecmp(optarg, "S32_LE") == 0) {
case SND_PCM_FORMAT_S32_LE: bat->format = BAT_PCM_FORMAT_S32_LE;
bat->sample_size = 4; bat->sample_size = 4;
break; } else {
default: bat->format = BAT_PCM_FORMAT_UNKNOWN;
fprintf(bat->err, _("unsupported format: %d\n"), bat->format); fprintf(bat->err, _("wrong extended format '%s'\n"), optarg);
exit(EXIT_FAILURE); exit(EXIT_FAILURE);
} }
} }
@ -295,11 +288,8 @@ _("Usage: alsabat [-options]...\n"
" --local internal loop, set to bypass pcm hardware devices\n" " --local internal loop, set to bypass pcm hardware devices\n"
" --standalone standalone mode, to bypass analysis\n" " --standalone standalone mode, to bypass analysis\n"
)); ));
fprintf(bat->log, _("Recognized sample formats are: %s %s %s %s\n"), fprintf(bat->log, _("Recognized sample formats are: "));
snd_pcm_format_name(SND_PCM_FORMAT_U8), fprintf(bat->log, _("U8 S16_LE S24_3LE S32_LE\n"));
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, _("The available format shotcuts are:\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 cd (16 bit little endian, 44100, stereo)\n"));
fprintf(bat->log, _("-f dat (16 bit little endian, 48000, 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->channels = 1;
bat->frame_size = 2; bat->frame_size = 2;
bat->sample_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_float_to_sample = convert_float_to_int16;
bat->convert_sample_to_double = convert_int16_to_double; bat->convert_sample_to_double = convert_int16_to_double;
bat->frames = bat->rate * 2; bat->frames = bat->rate * 2;

View file

@ -17,6 +17,7 @@
#include <stddef.h> #include <stddef.h>
#include <stdlib.h> #include <stdlib.h>
#include <stdbool.h> #include <stdbool.h>
#include <errno.h>
#include "aconfig.h" #include "aconfig.h"
#include "gettext.h" #include "gettext.h"

View file

@ -13,8 +13,6 @@
* *
*/ */
#include <alsa/asoundlib.h>
#define TEMP_RECORD_FILE_NAME "/tmp/bat.wav.XXXXXX" #define TEMP_RECORD_FILE_NAME "/tmp/bat.wav.XXXXXX"
#define DEFAULT_DEV_NAME "default" #define DEFAULT_DEV_NAME "default"
@ -110,6 +108,15 @@ struct wav_container {
struct bat; 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 { enum _bat_op_mode {
MODE_UNKNOWN = -1, MODE_UNKNOWN = -1,
MODE_SINGLE = 0, MODE_SINGLE = 0,
@ -142,7 +149,7 @@ struct bat {
int frames; /* nb of frames */ int frames; /* nb of frames */
int frame_size; /* size of frame */ int frame_size; /* size of frame */
int sample_size; /* size of sample */ 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 sigma_k; /* threshold for peak detection */
float target_freq[MAX_CHANNELS]; float target_freq[MAX_CHANNELS];

View file

@ -23,9 +23,11 @@
#include <stdio.h> #include <stdio.h>
#include <stddef.h> #include <stddef.h>
#include <stdlib.h> #include <stdlib.h>
#include <string.h>
#include <math.h> #include <math.h>
#include <stdint.h> #include <stdint.h>
#include <stdbool.h> #include <stdbool.h>
#include <errno.h>
#include "gettext.h" #include "gettext.h"
#include "common.h" #include "common.h"
@ -113,22 +115,21 @@ static int adjust_waveform(struct bat *bat, float *val, int frames)
float factor, offset = 0.0; float factor, offset = 0.0;
switch (bat->format) { switch (bat->format) {
case SND_PCM_FORMAT_U8: case BAT_PCM_FORMAT_U8:
max = INT8_MAX; max = INT8_MAX;
offset = max; /* shift for unsigned format */ offset = max; /* shift for unsigned format */
break; break;
case SND_PCM_FORMAT_S16_LE: case BAT_PCM_FORMAT_S16_LE:
max = INT16_MAX; max = INT16_MAX;
break; break;
case SND_PCM_FORMAT_S24_3LE: case BAT_PCM_FORMAT_S24_3LE:
max = (1 << 23) - 1; max = (1 << 23) - 1;
break; break;
case SND_PCM_FORMAT_S32_LE: case BAT_PCM_FORMAT_S32_LE:
max = INT32_MAX; max = INT32_MAX;
break; break;
default: default:
fprintf(bat->err, _("Invalid PCM format: %s\n"), fprintf(bat->err, _("Invalid PCM format: %d\n"), bat->format);
snd_pcm_format_name(bat->format));
return -EINVAL; return -EINVAL;
} }