OSDN Git Service

alsabat: add buffer size and period size settings
authorvivian,zhang <vivian.zhang@intel.com>
Tue, 31 May 2016 07:31:32 +0000 (15:31 +0800)
committerTakashi Iwai <tiwai@suse.de>
Tue, 31 May 2016 14:05:07 +0000 (16:05 +0200)
Add buffer size and period size settings in alsabat.
With -E and -B options, alsabat performs the test with
specified buffer size and period size

Signed-off-by: Zhang Vivian <vivian.zhang@intel.com>
Acked-by: Liam Girdwood <liam.r.girdwood@linux.intel.com>
Signed-off-by: Takashi Iwai <tiwai@suse.de>
bat/alsa.c
bat/bat.c
bat/common.h
bat/tinyalsa.c

index 75158cb..0a37714 100644 (file)
@@ -74,6 +74,8 @@ static int set_snd_pcm_params(struct bat *bat, struct pcm_container *sndpcm)
        snd_pcm_format_t format;
        unsigned int buffer_time = 0;
        unsigned int period_time = 0;
+       snd_pcm_uframes_t buffer_size = 0;
+       snd_pcm_uframes_t period_size = 0;
        unsigned int rate;
        int err;
        const char *device_name = snd_pcm_name(sndpcm->handle);
@@ -145,39 +147,71 @@ static int set_snd_pcm_params(struct bat *bat, struct pcm_container *sndpcm)
                return -EINVAL;
        }
 
-       if (snd_pcm_hw_params_get_buffer_time_max(params,
-                       &buffer_time, 0) < 0) {
-               fprintf(bat->err, _("Get parameter from device error: "));
-               fprintf(bat->err, _("buffer time: %d %s: %s(%d)\n"),
-                               buffer_time,
-                               device_name, snd_strerror(err), err);
-               return -EINVAL;
-       }
+       if (bat->buffer_size > 0 && bat->period_size == 0)
+               bat->period_size = bat->buffer_size / DIV_BUFFERTIME;
 
-       if (buffer_time > MAX_BUFFERTIME)
-               buffer_time = MAX_BUFFERTIME;
+       if (bat->buffer_size > 0) {
+               buffer_size = bat->buffer_size;
+               period_size = bat->period_size;
 
-       period_time = buffer_time / DIV_BUFFERTIME;
+               fprintf(bat->log, _("Set period size: %d  buffer size: %d\n"),
+                               (int) period_size, (int) buffer_size);
 
-       /* Set buffer time and period time */
-       err = snd_pcm_hw_params_set_buffer_time_near(sndpcm->handle, params,
-                       &buffer_time, 0);
-       if (err < 0) {
-               fprintf(bat->err, _("Set parameter to device error: "));
-               fprintf(bat->err, _("buffer time: %d %s: %s(%d)\n"),
-                               buffer_time,
-                               device_name, snd_strerror(err), err);
-               return err;
-       }
+               err = snd_pcm_hw_params_set_buffer_size_near(sndpcm->handle,
+                               params, &buffer_size);
+               if (err < 0) {
+                       fprintf(bat->err, _("Set parameter to device error: "));
+                       fprintf(bat->err, _("buffer size: %d %s: %s(%d)\n"),
+                                       (int) buffer_size,
+                                       device_name, snd_strerror(err), err);
+                       return err;
+               }
 
-       err = snd_pcm_hw_params_set_period_time_near(sndpcm->handle, params,
-                       &period_time, 0);
-       if (err < 0) {
-               fprintf(bat->err, _("Set parameter to device error: "));
-               fprintf(bat->err, _("period time: %d %s: %s(%d)\n"),
-                               period_time,
-                               device_name, snd_strerror(err), err);
-               return err;
+               err = snd_pcm_hw_params_set_period_size_near(sndpcm->handle,
+                               params, &period_size, 0);
+               if (err < 0) {
+                       fprintf(bat->err, _("Set parameter to device error: "));
+                       fprintf(bat->err, _("period size: %d %s: %s(%d)\n"),
+                                       (int) period_size,
+                                       device_name, snd_strerror(err), err);
+                       return err;
+               }
+       } else {
+               if (snd_pcm_hw_params_get_buffer_time_max(params,
+                               &buffer_time, 0) < 0) {
+                       fprintf(bat->err,
+                                       _("Get parameter from device error: "));
+                       fprintf(bat->err, _("buffer time: %d %s: %s(%d)\n"),
+                                       buffer_time,
+                                       device_name, snd_strerror(err), err);
+                       return -EINVAL;
+               }
+
+               if (buffer_time > MAX_BUFFERTIME)
+                       buffer_time = MAX_BUFFERTIME;
+
+               period_time = buffer_time / DIV_BUFFERTIME;
+
+               /* Set buffer time and period time */
+               err = snd_pcm_hw_params_set_buffer_time_near(sndpcm->handle,
+                               params, &buffer_time, 0);
+               if (err < 0) {
+                       fprintf(bat->err, _("Set parameter to device error: "));
+                       fprintf(bat->err, _("buffer time: %d %s: %s(%d)\n"),
+                                       buffer_time,
+                                       device_name, snd_strerror(err), err);
+                       return err;
+               }
+
+               err = snd_pcm_hw_params_set_period_time_near(sndpcm->handle,
+                               params, &period_time, 0);
+               if (err < 0) {
+                       fprintf(bat->err, _("Set parameter to device error: "));
+                       fprintf(bat->err, _("period time: %d %s: %s(%d)\n"),
+                                       period_time,
+                                       device_name, snd_strerror(err), err);
+                       return err;
+               }
        }
 
        /* Write the parameters to the driver */
@@ -214,6 +248,9 @@ static int set_snd_pcm_params(struct bat *bat, struct pcm_container *sndpcm)
                return -EINVAL;
        }
 
+       fprintf(bat->log, _("Get period size: %d  buffer size: %d\n"),
+                       (int) sndpcm->period_size, (int) sndpcm->buffer_size);
+
        err = snd_pcm_format_physical_width(format);
        if (err < 0) {
                fprintf(bat->err, _("Invalid parameters: "));
index 1afdcb4..cd4ea2d 100644 (file)
--- a/bat/bat.c
+++ b/bat/bat.c
@@ -292,6 +292,8 @@ _("Usage: alsabat [-options]...\n"
 "  -k                     parameter for frequency detecting threshold\n"
 "  -F                     target frequency\n"
 "  -p                     total number of periods to play/capture\n"
+"  -B                     buffer size in frames\n"
+"  -E                     period size in frames\n"
 "      --log=#            file that both stdout and strerr redirecting to\n"
 "      --file=#           file for playback\n"
 "      --saveplay=#       file that storing playback content, for debug\n"
@@ -324,6 +326,8 @@ static void set_defaults(struct bat *bat)
        bat->capture.device = NULL;
        bat->buf = NULL;
        bat->local = false;
+       bat->buffer_size = 0;
+       bat->period_size = 0;
 #ifdef HAVE_LIBTINYALSA
        bat->channels = 2;
        bat->playback.fct = &playback_tinyalsa;
@@ -342,8 +346,8 @@ static void set_defaults(struct bat *bat)
 
 static void parse_arguments(struct bat *bat, int argc, char *argv[])
 {
-       int c, option_index;
-       static const char short_options[] = "D:P:C:f:n:F:c:r:s:k:p:lth";
+       int c, option_index, err;
+       static const char short_options[] = "D:P:C:f:n:F:c:r:s:k:p:B:E:lth";
        static const struct option long_options[] = {
                {"help",     0, 0, 'h'},
                {"log",      1, 0, OPT_LOG},
@@ -414,6 +418,16 @@ static void parse_arguments(struct bat *bat, int argc, char *argv[])
                        bat->periods_total = atoi(optarg);
                        bat->period_is_limited = true;
                        break;
+               case 'B':
+                       err = atoi(optarg);
+                       bat->buffer_size = err >= MIN_BUFFERSIZE
+                                       && err < MAX_BUFFERSIZE ? err : 0;
+                       break;
+               case 'E':
+                       err = atoi(optarg);
+                       bat->period_size = err >= MIN_PERIODSIZE
+                                       && err < MAX_PERIODSIZE ? err : 0;
+                       break;
                case 'h':
                default:
                        usage(bat);
index b789af5..ad02a5a 100644 (file)
 #define DIV_BUFFERTIME                 8
 /* margin to avoid sign inversion when generate sine wav */
 #define RANGE_FACTOR                   0.95
+#define MAX_BUFFERSIZE                 200000
+#define MIN_BUFFERSIZE                 32
+#define MAX_PERIODSIZE                 200000
+#define MIN_PERIODSIZE                 32
+/* default period size for tinyalsa */
+#define TINYALSA_PERIODSIZE                    1024
 
 #define EBATBASE                       1000
 #define ENOPEAK                                (EBATBASE + 1)
@@ -152,6 +158,8 @@ struct bat {
        int frame_size;                 /* size of frame */
        int sample_size;                /* size of sample */
        enum _bat_pcm_format format;    /* PCM format */
+       int buffer_size;                /* buffer size in frames */
+       int period_size;                /* period size in frames */
 
        float sigma_k;                  /* threshold for peak detection */
        float target_freq[MAX_CHANNELS];
index ea5f848..a19dd90 100644 (file)
@@ -57,7 +57,10 @@ static int init_config(struct bat *bat, struct pcm_config *config)
 {
        config->channels = bat->channels;
        config->rate = bat->rate;
-       config->period_size = 1024;
+       if (bat->period_size > 0)
+               config->period_size = bat->period_size;
+       else
+               config->period_size = TINYALSA_PERIODSIZE;
        config->period_count = 4;
        config->start_threshold = 0;
        config->stop_threshold = 0;