tools: add -n option to pw-cat

Add sample limit switch -n to pw-cat to stop the recording or playback
after a set number of samples received.

Change-Id: Iaa551db9849acd6acdb6897dbfaa92a21afa1312
This commit is contained in:
Torkel Niklasson 2025-08-27 21:26:00 +02:00 committed by Wim Taymans
parent 6c110a3b18
commit 1ce85ee2ae

View file

@ -170,6 +170,9 @@ struct data {
struct {
FILE *file;
} sysex;
uint64_t sample_limit; /* 0 means unlimited */
uint64_t samples_processed;
};
#define STR_FMTS "(ulaw|alaw|u8|s8|s16|s32|f32|f64)"
@ -905,8 +908,20 @@ static void on_process(void *userdata)
* fill callback actually returns number of bytes, not frames, since
* this is encoded data. However, the calculations below still work
* out because the stride is set to 1 in setup_encodedfile(). */
if (data->sample_limit > 0) {
uint64_t samples_left = data->sample_limit - data->samples_processed;
if (samples_left == 0) {
pw_main_loop_quit(data->loop);
return;
}
n_frames = SPA_MIN(n_frames, (int)samples_left);
}
n_fill_frames = data->fill(data, p, n_frames, &null_frame);
if (data->sample_limit > 0 && n_fill_frames > 0)
data->samples_processed += n_fill_frames;
if (null_frame) {
/* A null frame is not to be confused with the drain scenario.
* In this case, we want to continue streaming, but in this
@ -938,8 +953,20 @@ static void on_process(void *userdata)
n_frames = size / data->stride;
if (data->sample_limit > 0) {
uint64_t samples_left = data->sample_limit - data->samples_processed;
if (samples_left == 0) {
pw_main_loop_quit(data->loop);
return;
}
n_frames = SPA_MIN(n_frames, (int)samples_left);
}
n_fill_frames = data->fill(data, p, n_frames, &null_frame);
if (data->sample_limit > 0 && n_fill_frames > 0)
data->samples_processed += n_fill_frames;
have_data = true;
}
@ -1035,6 +1062,7 @@ static const struct option long_options[] = {
{ "quality", required_argument, NULL, 'q' },
{ "raw", no_argument, NULL, 'a' },
{ "force-midi", required_argument, NULL, 'M' },
{ "sample-count", required_argument, NULL, 'n' },
{ NULL, 0, NULL, 0 }
};
@ -1081,6 +1109,7 @@ static void show_usage(const char *name, bool is_error)
" -q --quality Resampler quality (0 - 15) (default %d)\n"
" -a, --raw RAW mode\n"
" -M, --force-midi Force midi format, one of \"midi\" or \"ump\", (default ump)\n"
" -n, --sample-count COUNT Stop after COUNT samples\n"
"\n"),
DEFAULT_RATE,
DEFAULT_CHANNELS,
@ -1852,9 +1881,9 @@ int main(int argc, char *argv[])
}
#ifdef HAVE_PW_CAT_FFMPEG_INTEGRATION
while ((c = getopt_long(argc, argv, "hvprmdosR:q:P:aM:", long_options, NULL)) != -1) {
while ((c = getopt_long(argc, argv, "hvprmdosR:q:P:aM:n:", long_options, NULL)) != -1) {
#else
while ((c = getopt_long(argc, argv, "hvprmdsR:q:P:aM:", long_options, NULL)) != -1) {
while ((c = getopt_long(argc, argv, "hvprmdsR:q:P:aM:n:", long_options, NULL)) != -1) {
#endif
switch (c) {
@ -1987,6 +2016,9 @@ int main(int argc, char *argv[])
if (!spa_atof(optarg, &data.volume))
data.volume = (float)atof(optarg);
break;
case 'n':
data.sample_limit = strtoull(optarg, NULL, 10);
break;
default:
goto error_usage;
}