mirror of
https://github.com/alsa-project/alsa-utils
synced 2024-11-10 03:35:42 +01:00
aplay/arecord: Added hardware pause support (press SPACE or Enter)
Signed-off-by: Jaroslav Kysela <perex@perex.cz>
This commit is contained in:
parent
b4ff58b685
commit
3bd6533622
1 changed files with 73 additions and 5 deletions
|
@ -41,6 +41,7 @@
|
||||||
#include <locale.h>
|
#include <locale.h>
|
||||||
#include <alsa/asoundlib.h>
|
#include <alsa/asoundlib.h>
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
|
#include <termios.h>
|
||||||
#include <sys/poll.h>
|
#include <sys/poll.h>
|
||||||
#include <sys/uio.h>
|
#include <sys/uio.h>
|
||||||
#include <sys/time.h>
|
#include <sys/time.h>
|
||||||
|
@ -102,6 +103,7 @@ static int avail_min = -1;
|
||||||
static int start_delay = 0;
|
static int start_delay = 0;
|
||||||
static int stop_delay = 0;
|
static int stop_delay = 0;
|
||||||
static int monotonic = 0;
|
static int monotonic = 0;
|
||||||
|
static int can_pause = 0;
|
||||||
static int verbose = 0;
|
static int verbose = 0;
|
||||||
static int vumeter = VUMETER_NONE;
|
static int vumeter = VUMETER_NONE;
|
||||||
static int buffer_pos = 0;
|
static int buffer_pos = 0;
|
||||||
|
@ -1111,6 +1113,7 @@ static void set_params(void)
|
||||||
}
|
}
|
||||||
assert(err >= 0);
|
assert(err >= 0);
|
||||||
monotonic = snd_pcm_hw_params_is_monotonic(params);
|
monotonic = snd_pcm_hw_params_is_monotonic(params);
|
||||||
|
can_pause = snd_pcm_hw_params_can_pause(params);
|
||||||
err = snd_pcm_hw_params(handle, params);
|
err = snd_pcm_hw_params(handle, params);
|
||||||
if (err < 0) {
|
if (err < 0) {
|
||||||
error(_("Unable to install hw params:"));
|
error(_("Unable to install hw params:"));
|
||||||
|
@ -1182,7 +1185,7 @@ static void set_params(void)
|
||||||
int i;
|
int i;
|
||||||
err = snd_pcm_mmap_begin(handle, &areas, &offset, &size);
|
err = snd_pcm_mmap_begin(handle, &areas, &offset, &size);
|
||||||
if (err < 0) {
|
if (err < 0) {
|
||||||
error("snd_pcm_mmap_begin problem: %s", snd_strerror(err));
|
error(_("snd_pcm_mmap_begin problem: %s"), snd_strerror(err));
|
||||||
prg_exit(EXIT_FAILURE);
|
prg_exit(EXIT_FAILURE);
|
||||||
}
|
}
|
||||||
for (i = 0; i < hwparams.channels; i++)
|
for (i = 0; i < hwparams.channels; i++)
|
||||||
|
@ -1194,6 +1197,65 @@ static void set_params(void)
|
||||||
buffer_frames = buffer_size; /* for position test */
|
buffer_frames = buffer_size; /* for position test */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void init_stdin(void)
|
||||||
|
{
|
||||||
|
struct termios term;
|
||||||
|
long flags;
|
||||||
|
|
||||||
|
if (fd == fileno(stdin))
|
||||||
|
return;
|
||||||
|
flags = fcntl(fileno(stdin), F_GETFL);
|
||||||
|
if (flags < 0 || fcntl(fileno(stdin), F_SETFL, flags|O_NONBLOCK) < 0)
|
||||||
|
fprintf(stderr, _("stdin O_NONBLOCK flag setup failed\n"));
|
||||||
|
tcgetattr(fileno(stdin), &term);
|
||||||
|
term.c_lflag &= ~ICANON;
|
||||||
|
tcsetattr(fileno(stdin), TCSANOW, &term);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void do_pause(void)
|
||||||
|
{
|
||||||
|
int err;
|
||||||
|
unsigned char b;
|
||||||
|
|
||||||
|
if (!can_pause) {
|
||||||
|
fprintf(stderr, _("\rPAUSE command ignored (no hw support)\n"));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
err = snd_pcm_pause(handle, 1);
|
||||||
|
if (err < 0) {
|
||||||
|
error(_("pause push error: %s"), snd_strerror(err));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
while (1) {
|
||||||
|
while (read(fileno(stdin), &b, 1) != 1);
|
||||||
|
if (b == ' ' || b == '\r') {
|
||||||
|
while (read(fileno(stdin), &b, 1) == 1);
|
||||||
|
err = snd_pcm_pause(handle, 0);
|
||||||
|
if (err < 0)
|
||||||
|
error(_("pause release error: %s"), snd_strerror(err));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void check_stdin(void)
|
||||||
|
{
|
||||||
|
unsigned char b;
|
||||||
|
|
||||||
|
if (fd != fileno(stdin)) {
|
||||||
|
while (read(fileno(stdin), &b, 1) == 1) {
|
||||||
|
if (b == ' ' || b == '\r') {
|
||||||
|
while (read(fileno(stdin), &b, 1) == 1);
|
||||||
|
fprintf(stderr, _("\r=== PAUSE === "));
|
||||||
|
fflush(stderr);
|
||||||
|
do_pause();
|
||||||
|
fprintf(stderr, " \r");
|
||||||
|
fflush(stderr);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#ifndef timersub
|
#ifndef timersub
|
||||||
#define timersub(a, b, result) \
|
#define timersub(a, b, result) \
|
||||||
do { \
|
do { \
|
||||||
|
@ -1589,12 +1651,13 @@ static ssize_t pcm_write(u_char *data, size_t count)
|
||||||
while (count > 0) {
|
while (count > 0) {
|
||||||
if (test_position)
|
if (test_position)
|
||||||
do_test_position();
|
do_test_position();
|
||||||
|
check_stdin();
|
||||||
r = writei_func(handle, data, count);
|
r = writei_func(handle, data, count);
|
||||||
if (test_position)
|
if (test_position)
|
||||||
do_test_position();
|
do_test_position();
|
||||||
if (r == -EAGAIN || (r >= 0 && (size_t)r < count)) {
|
if (r == -EAGAIN || (r >= 0 && (size_t)r < count)) {
|
||||||
if (!test_nowait)
|
if (!test_nowait)
|
||||||
snd_pcm_wait(handle, 1000);
|
snd_pcm_wait(handle, 100);
|
||||||
} else if (r == -EPIPE) {
|
} else if (r == -EPIPE) {
|
||||||
xrun();
|
xrun();
|
||||||
} else if (r == -ESTRPIPE) {
|
} else if (r == -ESTRPIPE) {
|
||||||
|
@ -1635,12 +1698,13 @@ static ssize_t pcm_writev(u_char **data, unsigned int channels, size_t count)
|
||||||
bufs[channel] = data[channel] + offset * bits_per_sample / 8;
|
bufs[channel] = data[channel] + offset * bits_per_sample / 8;
|
||||||
if (test_position)
|
if (test_position)
|
||||||
do_test_position();
|
do_test_position();
|
||||||
|
check_stdin();
|
||||||
r = writen_func(handle, bufs, count);
|
r = writen_func(handle, bufs, count);
|
||||||
if (test_position)
|
if (test_position)
|
||||||
do_test_position();
|
do_test_position();
|
||||||
if (r == -EAGAIN || (r >= 0 && (size_t)r < count)) {
|
if (r == -EAGAIN || (r >= 0 && (size_t)r < count)) {
|
||||||
if (!test_nowait)
|
if (!test_nowait)
|
||||||
snd_pcm_wait(handle, 1000);
|
snd_pcm_wait(handle, 100);
|
||||||
} else if (r == -EPIPE) {
|
} else if (r == -EPIPE) {
|
||||||
xrun();
|
xrun();
|
||||||
} else if (r == -ESTRPIPE) {
|
} else if (r == -ESTRPIPE) {
|
||||||
|
@ -1678,12 +1742,13 @@ static ssize_t pcm_read(u_char *data, size_t rcount)
|
||||||
while (count > 0) {
|
while (count > 0) {
|
||||||
if (test_position)
|
if (test_position)
|
||||||
do_test_position();
|
do_test_position();
|
||||||
|
check_stdin();
|
||||||
r = readi_func(handle, data, count);
|
r = readi_func(handle, data, count);
|
||||||
if (test_position)
|
if (test_position)
|
||||||
do_test_position();
|
do_test_position();
|
||||||
if (r == -EAGAIN || (r >= 0 && (size_t)r < count)) {
|
if (r == -EAGAIN || (r >= 0 && (size_t)r < count)) {
|
||||||
if (!test_nowait)
|
if (!test_nowait)
|
||||||
snd_pcm_wait(handle, 1000);
|
snd_pcm_wait(handle, 100);
|
||||||
} else if (r == -EPIPE) {
|
} else if (r == -EPIPE) {
|
||||||
xrun();
|
xrun();
|
||||||
} else if (r == -ESTRPIPE) {
|
} else if (r == -ESTRPIPE) {
|
||||||
|
@ -1721,12 +1786,13 @@ static ssize_t pcm_readv(u_char **data, unsigned int channels, size_t rcount)
|
||||||
bufs[channel] = data[channel] + offset * bits_per_sample / 8;
|
bufs[channel] = data[channel] + offset * bits_per_sample / 8;
|
||||||
if (test_position)
|
if (test_position)
|
||||||
do_test_position();
|
do_test_position();
|
||||||
|
check_stdin();
|
||||||
r = readn_func(handle, bufs, count);
|
r = readn_func(handle, bufs, count);
|
||||||
if (test_position)
|
if (test_position)
|
||||||
do_test_position();
|
do_test_position();
|
||||||
if (r == -EAGAIN || (r >= 0 && (size_t)r < count)) {
|
if (r == -EAGAIN || (r >= 0 && (size_t)r < count)) {
|
||||||
if (!test_nowait)
|
if (!test_nowait)
|
||||||
snd_pcm_wait(handle, 1000);
|
snd_pcm_wait(handle, 100);
|
||||||
} else if (r == -EPIPE) {
|
} else if (r == -EPIPE) {
|
||||||
xrun();
|
xrun();
|
||||||
} else if (r == -ESTRPIPE) {
|
} else if (r == -ESTRPIPE) {
|
||||||
|
@ -2361,6 +2427,7 @@ static void playback(char *name)
|
||||||
fd = fileno(stdin);
|
fd = fileno(stdin);
|
||||||
name = "stdin";
|
name = "stdin";
|
||||||
} else {
|
} else {
|
||||||
|
init_stdin();
|
||||||
if ((fd = open64(name, O_RDONLY, 0)) == -1) {
|
if ((fd = open64(name, O_RDONLY, 0)) == -1) {
|
||||||
perror(name);
|
perror(name);
|
||||||
prg_exit(EXIT_FAILURE);
|
prg_exit(EXIT_FAILURE);
|
||||||
|
@ -2616,6 +2683,7 @@ static void capture(char *orig_name)
|
||||||
if (count > fmt_rec_table[file_type].max_filesize)
|
if (count > fmt_rec_table[file_type].max_filesize)
|
||||||
count = fmt_rec_table[file_type].max_filesize;
|
count = fmt_rec_table[file_type].max_filesize;
|
||||||
}
|
}
|
||||||
|
init_stdin();
|
||||||
|
|
||||||
do {
|
do {
|
||||||
/* open a file to write */
|
/* open a file to write */
|
||||||
|
|
Loading…
Reference in a new issue