Revision 7a24c800 audio/alsaaudio.c

b/audio/alsaaudio.c
58 58
    int period_size_out_overridden;
59 59
    int verbose;
60 60
} conf = {
61
#define DEFAULT_BUFFER_SIZE 1024
62
#define DEFAULT_PERIOD_SIZE 256
63
#ifdef HIGH_LATENCY
64
    .size_in_usec_in = 1,
65
    .size_in_usec_out = 1,
66
#endif
67 61
    .pcm_name_out = "default",
68 62
    .pcm_name_in = "default",
69
#ifdef HIGH_LATENCY
70
    .buffer_size_in = 400000,
71
    .period_size_in = 400000 / 4,
72
    .buffer_size_out = 400000,
73
    .period_size_out = 400000 / 4,
74
#else
75
    .buffer_size_in = DEFAULT_BUFFER_SIZE * 4,
76
    .period_size_in = DEFAULT_PERIOD_SIZE * 4,
77
    .buffer_size_out = DEFAULT_BUFFER_SIZE,
78
    .period_size_out = DEFAULT_PERIOD_SIZE,
79
    .buffer_size_in_overridden = 0,
80
    .buffer_size_out_overridden = 0,
81
    .period_size_in_overridden = 0,
82
    .period_size_out_overridden = 0,
83
#endif
84
    .threshold = 0,
85
    .verbose = 0
86 63
};
87 64

  
88 65
struct alsa_params_req {
89 66
    int freq;
90 67
    snd_pcm_format_t fmt;
91 68
    int nchannels;
69
    int size_in_usec;
92 70
    unsigned int buffer_size;
93 71
    unsigned int period_size;
94 72
};
......
286 264
    snd_pcm_t *handle;
287 265
    snd_pcm_hw_params_t *hw_params;
288 266
    int err;
267
    int size_in_usec;
289 268
    unsigned int freq, nchannels;
290 269
    const char *pcm_name = in ? conf.pcm_name_in : conf.pcm_name_out;
291
    unsigned int period_size, buffer_size;
292 270
    snd_pcm_uframes_t obt_buffer_size;
293 271
    const char *typ = in ? "ADC" : "DAC";
294 272
    snd_pcm_format_t obtfmt;
295 273

  
296 274
    freq = req->freq;
297
    period_size = req->period_size;
298
    buffer_size = req->buffer_size;
299 275
    nchannels = req->nchannels;
276
    size_in_usec = req->size_in_usec;
300 277

  
301 278
    snd_pcm_hw_params_alloca (&hw_params);
302 279

  
......
356 333
        goto err;
357 334
    }
358 335

  
359
    if (!((in && conf.size_in_usec_in) || (!in && conf.size_in_usec_out))) {
360
        if (!buffer_size) {
361
            buffer_size = DEFAULT_BUFFER_SIZE;
362
            period_size= DEFAULT_PERIOD_SIZE;
363
        }
364
    }
365

  
366
    if (buffer_size) {
367
        if ((in && conf.size_in_usec_in) || (!in && conf.size_in_usec_out)) {
368
            if (period_size) {
369
                err = snd_pcm_hw_params_set_period_time_near (
370
                    handle,
371
                    hw_params,
372
                    &period_size,
373
                    0
374
                    );
375
                if (err < 0) {
376
                    alsa_logerr2 (err, typ,
377
                                  "Failed to set period time %d\n",
378
                                  req->period_size);
379
                    goto err;
380
                }
381
            }
336
    if (req->buffer_size) {
337
        if (size_in_usec) {
338
            int dir = 0;
339
            unsigned int btime = req->buffer_size;
382 340

  
383 341
            err = snd_pcm_hw_params_set_buffer_time_near (
384 342
                handle,
385 343
                hw_params,
386
                &buffer_size,
387
                0
344
                &btime,
345
                &dir
388 346
                );
389

  
390
            if (err < 0) {
391
                alsa_logerr2 (err, typ,
392
                              "Failed to set buffer time %d\n",
393
                              req->buffer_size);
394
                goto err;
395
            }
396 347
        }
397 348
        else {
398
            int dir;
399
            snd_pcm_uframes_t minval;
400

  
401
            if (period_size) {
402
                minval = period_size;
403
                dir = 0;
404

  
405
                err = snd_pcm_hw_params_get_period_size_min (
406
                    hw_params,
407
                    &minval,
408
                    &dir
409
                    );
410
                if (err < 0) {
411
                    alsa_logerr (
412
                        err,
413
                        "Could not get minmal period size for %s\n",
414
                        typ
415
                        );
416
                }
417
                else {
418
                    if (period_size < minval) {
419
                        if ((in && conf.period_size_in_overridden)
420
                            || (!in && conf.period_size_out_overridden)) {
421
                            dolog ("%s period size(%d) is less "
422
                                   "than minmal period size(%ld)\n",
423
                                   typ,
424
                                   period_size,
425
                                   minval);
426
                        }
427
                        period_size = minval;
428
                    }
429
                }
349
            snd_pcm_uframes_t bsize = req->buffer_size;
430 350

  
431
                err = snd_pcm_hw_params_set_period_size (
432
                    handle,
433
                    hw_params,
434
                    period_size,
435
                    0
436
                    );
437
                if (err < 0) {
438
                    alsa_logerr2 (err, typ, "Failed to set period size %d\n",
439
                                  req->period_size);
440
                    goto err;
441
                }
442
            }
351
            err = snd_pcm_hw_params_set_buffer_size_near (
352
                handle,
353
                hw_params,
354
                &bsize
355
                );
356
        }
357
        if (err < 0) {
358
            alsa_logerr2 (err, typ, "Failed to set buffer %s to %d\n",
359
                          size_in_usec ? "time" : "size", req->buffer_size);
360
            goto err;
361
        }
362
    }
363

  
364
    if (req->period_size) {
365
        if (size_in_usec) {
366
            int dir = 0;
367
            unsigned int ptime = req->period_size;
443 368

  
444
            minval = buffer_size;
445
            err = snd_pcm_hw_params_get_buffer_size_min (
369
            err = snd_pcm_hw_params_set_period_time_near (
370
                handle,
446 371
                hw_params,
447
                &minval
372
                &ptime,
373
                &dir
448 374
                );
449
            if (err < 0) {
450
                alsa_logerr (err, "Could not get minmal buffer size for %s\n",
451
                             typ);
452
            }
453
            else {
454
                if (buffer_size < minval) {
455
                    if ((in && conf.buffer_size_in_overridden)
456
                        || (!in && conf.buffer_size_out_overridden)) {
457
                        dolog (
458
                            "%s buffer size(%d) is less "
459
                            "than minimal buffer size(%ld)\n",
460
                            typ,
461
                            buffer_size,
462
                            minval
463
                            );
464
                    }
465
                    buffer_size = minval;
466
                }
467
            }
375
        }
376
        else {
377
            snd_pcm_uframes_t psize = req->period_size;
468 378

  
469
            err = snd_pcm_hw_params_set_buffer_size (
379
            err = snd_pcm_hw_params_set_buffer_size_near (
470 380
                handle,
471 381
                hw_params,
472
                buffer_size
382
                &psize
473 383
                );
474
            if (err < 0) {
475
                alsa_logerr2 (err, typ, "Failed to set buffer size %d\n",
476
                              req->buffer_size);
477
                goto err;
478
            }
479 384
        }
480
    }
481
    else {
482
        dolog ("warning: Buffer size is not set\n");
385

  
386
        if (err < 0) {
387
            alsa_logerr2 (err, typ, "Failed to set period %s to %d\n",
388
                          size_in_usec ? "time" : "size", req->period_size);
389
            goto err;
390
        }
483 391
    }
484 392

  
485 393
    err = snd_pcm_hw_params (handle, hw_params);
......
697 605
    req.nchannels = as->nchannels;
698 606
    req.period_size = conf.period_size_out;
699 607
    req.buffer_size = conf.buffer_size_out;
608
    req.size_in_usec = conf.size_in_usec_in;
700 609

  
701 610
    if (alsa_open (0, &req, &obt, &handle)) {
702 611
        return -1;
......
774 683
    req.nchannels = as->nchannels;
775 684
    req.period_size = conf.period_size_in;
776 685
    req.buffer_size = conf.buffer_size_in;
686
    req.size_in_usec = conf.size_in_usec_in;
777 687

  
778 688
    if (alsa_open (1, &req, &obt, &handle)) {
779 689
        return -1;
......
953 863
    {"DAC_SIZE_IN_USEC", AUD_OPT_BOOL, &conf.size_in_usec_out,
954 864
     "DAC period/buffer size in microseconds (otherwise in frames)", NULL, 0},
955 865
    {"DAC_PERIOD_SIZE", AUD_OPT_INT, &conf.period_size_out,
956
     "DAC period size", &conf.period_size_out_overridden, 0},
866
     "DAC period size (0 to go with system default)",
867
     &conf.period_size_out_overridden, 0},
957 868
    {"DAC_BUFFER_SIZE", AUD_OPT_INT, &conf.buffer_size_out,
958
     "DAC buffer size", &conf.buffer_size_out_overridden, 0},
869
     "DAC buffer size (0 to go with system default)",
870
     &conf.buffer_size_out_overridden, 0},
959 871

  
960 872
    {"ADC_SIZE_IN_USEC", AUD_OPT_BOOL, &conf.size_in_usec_in,
961 873
     "ADC period/buffer size in microseconds (otherwise in frames)", NULL, 0},
962 874
    {"ADC_PERIOD_SIZE", AUD_OPT_INT, &conf.period_size_in,
963
     "ADC period size", &conf.period_size_in_overridden, 0},
875
     "ADC period size (0 to go with system default)",
876
     &conf.period_size_in_overridden, 0},
964 877
    {"ADC_BUFFER_SIZE", AUD_OPT_INT, &conf.buffer_size_in,
965
     "ADC buffer size", &conf.buffer_size_in_overridden, 0},
878
     "ADC buffer size (0 to go with system default)",
879
     &conf.buffer_size_in_overridden, 0},
966 880

  
967 881
    {"THRESHOLD", AUD_OPT_INT, &conf.threshold,
968 882
     "(undocumented)", NULL, 0},

Also available in: Unified diff