mirror of
https://gitlab.freedesktop.org/pipewire/pipewire.git
synced 2025-12-20 06:50:03 +01:00
tools: support filenames in raw mode
The raw mode -a only supported reading raw data from stdin/stdout and simply ignored the filename. Make it use the filename to determine where to read from instead. Support stdin/stdout for sysex mode as well and close the file when we are done. Fixes #5012
This commit is contained in:
parent
b68698a086
commit
e30ee9c846
1 changed files with 64 additions and 34 deletions
|
|
@ -113,7 +113,7 @@ struct data {
|
||||||
#define TYPE_SYSEX 4
|
#define TYPE_SYSEX 4
|
||||||
#define TYPE_MIDI2 5
|
#define TYPE_MIDI2 5
|
||||||
int data_type;
|
int data_type;
|
||||||
bool raw;
|
bool rawfile;
|
||||||
const char *remote_name;
|
const char *remote_name;
|
||||||
const char *media_type;
|
const char *media_type;
|
||||||
const char *media_category;
|
const char *media_category;
|
||||||
|
|
@ -125,7 +125,6 @@ struct data {
|
||||||
struct pw_properties *props;
|
struct pw_properties *props;
|
||||||
|
|
||||||
const char *filename;
|
const char *filename;
|
||||||
SNDFILE *file;
|
|
||||||
|
|
||||||
unsigned int bitrate;
|
unsigned int bitrate;
|
||||||
unsigned int rate;
|
unsigned int rate;
|
||||||
|
|
@ -147,6 +146,9 @@ struct data {
|
||||||
bool drained;
|
bool drained;
|
||||||
uint64_t clock_time;
|
uint64_t clock_time;
|
||||||
|
|
||||||
|
struct {
|
||||||
|
SNDFILE *file;
|
||||||
|
} sndfile;
|
||||||
struct {
|
struct {
|
||||||
struct midi_file *file;
|
struct midi_file *file;
|
||||||
struct midi_file_info info;
|
struct midi_file_info info;
|
||||||
|
|
@ -181,7 +183,12 @@ struct data {
|
||||||
#endif
|
#endif
|
||||||
struct {
|
struct {
|
||||||
FILE *file;
|
FILE *file;
|
||||||
|
bool close;
|
||||||
} sysex;
|
} sysex;
|
||||||
|
struct {
|
||||||
|
FILE *file;
|
||||||
|
bool close;
|
||||||
|
} raw;
|
||||||
|
|
||||||
uint64_t sample_limit; /* 0 means unlimited */
|
uint64_t sample_limit; /* 0 means unlimited */
|
||||||
uint64_t samples_processed;
|
uint64_t samples_processed;
|
||||||
|
|
@ -227,7 +234,7 @@ static int sf_playback_fill_x8(struct data *d, void *dest, unsigned int n_frames
|
||||||
{
|
{
|
||||||
sf_count_t rn;
|
sf_count_t rn;
|
||||||
|
|
||||||
rn = sf_read_raw(d->file, dest, n_frames * d->stride);
|
rn = sf_read_raw(d->sndfile.file, dest, n_frames * d->stride);
|
||||||
return (int)rn / d->stride;
|
return (int)rn / d->stride;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -236,7 +243,7 @@ static int sf_playback_fill_s16(struct data *d, void *dest, unsigned int n_frame
|
||||||
sf_count_t rn;
|
sf_count_t rn;
|
||||||
|
|
||||||
assert(sizeof(short) == sizeof(int16_t));
|
assert(sizeof(short) == sizeof(int16_t));
|
||||||
rn = sf_readf_short(d->file, dest, n_frames);
|
rn = sf_readf_short(d->sndfile.file, dest, n_frames);
|
||||||
return (int)rn;
|
return (int)rn;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -245,7 +252,7 @@ static int sf_playback_fill_s32(struct data *d, void *dest, unsigned int n_frame
|
||||||
sf_count_t rn;
|
sf_count_t rn;
|
||||||
|
|
||||||
assert(sizeof(int) == sizeof(int32_t));
|
assert(sizeof(int) == sizeof(int32_t));
|
||||||
rn = sf_readf_int(d->file, dest, n_frames);
|
rn = sf_readf_int(d->sndfile.file, dest, n_frames);
|
||||||
return (int)rn;
|
return (int)rn;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -254,7 +261,7 @@ static int sf_playback_fill_f32(struct data *d, void *dest, unsigned int n_frame
|
||||||
sf_count_t rn;
|
sf_count_t rn;
|
||||||
|
|
||||||
assert(sizeof(float) == 4);
|
assert(sizeof(float) == 4);
|
||||||
rn = sf_readf_float(d->file, dest, n_frames);
|
rn = sf_readf_float(d->sndfile.file, dest, n_frames);
|
||||||
return (int)rn;
|
return (int)rn;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -263,7 +270,7 @@ static int sf_playback_fill_f64(struct data *d, void *dest, unsigned int n_frame
|
||||||
sf_count_t rn;
|
sf_count_t rn;
|
||||||
|
|
||||||
assert(sizeof(double) == 8);
|
assert(sizeof(double) == 8);
|
||||||
rn = sf_readf_double(d->file, dest, n_frames);
|
rn = sf_readf_double(d->sndfile.file, dest, n_frames);
|
||||||
return (int)rn;
|
return (int)rn;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -550,7 +557,7 @@ static int sf_record_fill_x8(struct data *d, void *src, unsigned int n_frames, b
|
||||||
{
|
{
|
||||||
sf_count_t rn;
|
sf_count_t rn;
|
||||||
|
|
||||||
rn = sf_write_raw(d->file, src, n_frames * d->stride);
|
rn = sf_write_raw(d->sndfile.file, src, n_frames * d->stride);
|
||||||
return (int)rn / d->stride;
|
return (int)rn / d->stride;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -559,7 +566,7 @@ static int sf_record_fill_s16(struct data *d, void *src, unsigned int n_frames,
|
||||||
sf_count_t rn;
|
sf_count_t rn;
|
||||||
|
|
||||||
assert(sizeof(short) == sizeof(int16_t));
|
assert(sizeof(short) == sizeof(int16_t));
|
||||||
rn = sf_writef_short(d->file, src, n_frames);
|
rn = sf_writef_short(d->sndfile.file, src, n_frames);
|
||||||
return (int)rn;
|
return (int)rn;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -568,7 +575,7 @@ static int sf_record_fill_s32(struct data *d, void *src, unsigned int n_frames,
|
||||||
sf_count_t rn;
|
sf_count_t rn;
|
||||||
|
|
||||||
assert(sizeof(int) == sizeof(int32_t));
|
assert(sizeof(int) == sizeof(int32_t));
|
||||||
rn = sf_writef_int(d->file, src, n_frames);
|
rn = sf_writef_int(d->sndfile.file, src, n_frames);
|
||||||
return (int)rn;
|
return (int)rn;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -577,7 +584,7 @@ static int sf_record_fill_f32(struct data *d, void *src, unsigned int n_frames,
|
||||||
sf_count_t rn;
|
sf_count_t rn;
|
||||||
|
|
||||||
assert(sizeof(float) == 4);
|
assert(sizeof(float) == 4);
|
||||||
rn = sf_writef_float(d->file, src, n_frames);
|
rn = sf_writef_float(d->sndfile.file, src, n_frames);
|
||||||
return (int)rn;
|
return (int)rn;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -586,7 +593,7 @@ static int sf_record_fill_f64(struct data *d, void *src, unsigned int n_frames,
|
||||||
sf_count_t rn;
|
sf_count_t rn;
|
||||||
|
|
||||||
assert(sizeof(double) == 8);
|
assert(sizeof(double) == 8);
|
||||||
rn = sf_writef_double(d->file, src, n_frames);
|
rn = sf_writef_double(d->sndfile.file, src, n_frames);
|
||||||
return (int)rn;
|
return (int)rn;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1480,10 +1487,16 @@ static int setup_sysex(struct data *data)
|
||||||
if (data->mode == mode_record)
|
if (data->mode == mode_record)
|
||||||
return -ENOTSUP;
|
return -ENOTSUP;
|
||||||
|
|
||||||
data->sysex.file = fopen(data->filename, "r");
|
if (spa_streq(data->filename, "-")) {
|
||||||
if (data->sysex.file == NULL) {
|
data->sysex.file = stdin;
|
||||||
fprintf(stderr, "sysex: can't read file '%s': %m\n", data->filename);
|
data->sysex.close = false;
|
||||||
return -errno;
|
} else {
|
||||||
|
data->sysex.file = fopen(data->filename, "r");
|
||||||
|
if (data->sysex.file == NULL) {
|
||||||
|
fprintf(stderr, "sysex: can't read file '%s': %m\n", data->filename);
|
||||||
|
return -errno;
|
||||||
|
}
|
||||||
|
data->sysex.close = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (data->verbose)
|
if (data->verbose)
|
||||||
|
|
@ -1557,17 +1570,17 @@ static int setup_dsdfile(struct data *data)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int stdout_record(struct data *d, void *src, unsigned int n_frames, bool *null_frame)
|
static int raw_record(struct data *d, void *src, unsigned int n_frames, bool *null_frame)
|
||||||
{
|
{
|
||||||
return fwrite(src, d->stride, n_frames, stdout);
|
return fwrite(src, d->stride, n_frames, d->raw.file);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int stdin_play(struct data *d, void *src, unsigned int n_frames, bool *null_frame)
|
static int raw_play(struct data *d, void *src, unsigned int n_frames, bool *null_frame)
|
||||||
{
|
{
|
||||||
return fread(src, d->stride, n_frames, stdin);
|
return fread(src, d->stride, n_frames, d->raw.file);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int setup_pipe(struct data *data)
|
static int setup_raw(struct data *data)
|
||||||
{
|
{
|
||||||
const struct format_info *info;
|
const struct format_info *info;
|
||||||
|
|
||||||
|
|
@ -1586,10 +1599,23 @@ static int setup_pipe(struct data *data)
|
||||||
|
|
||||||
data->spa_format = info->spa_format;
|
data->spa_format = info->spa_format;
|
||||||
data->stride = info->width * data->channels;
|
data->stride = info->width * data->channels;
|
||||||
data->fill = data->mode == mode_playback ? stdin_play : stdout_record;
|
data->fill = data->mode == mode_playback ? raw_play : raw_record;
|
||||||
|
|
||||||
|
if (spa_streq(data->filename, "-")) {
|
||||||
|
data->raw.file = data->mode == mode_playback ? stdin : stdout;
|
||||||
|
data->raw.close = false;
|
||||||
|
} else {
|
||||||
|
data->raw.file = fopen(data->filename,
|
||||||
|
data->mode == mode_playback ? "r" : "w");
|
||||||
|
if (data->raw.file == NULL) {
|
||||||
|
fprintf(stderr, "raw: can't open file '%s': %m\n", data->filename);
|
||||||
|
return -errno;
|
||||||
|
}
|
||||||
|
data->raw.close = true;
|
||||||
|
}
|
||||||
|
|
||||||
if (data->verbose)
|
if (data->verbose)
|
||||||
fprintf(stderr, "PIPE: rate=%u channels=%u fmt=%s samplesize=%u stride=%u\n",
|
fprintf(stderr, "raw: rate=%u channels=%u fmt=%s samplesize=%u stride=%u\n",
|
||||||
data->rate, data->channels,
|
data->rate, data->channels,
|
||||||
info->name, info->width, data->stride);
|
info->name, info->width, data->stride);
|
||||||
|
|
||||||
|
|
@ -1618,7 +1644,7 @@ static int fill_properties(struct data *data)
|
||||||
if (table[c] == NULL)
|
if (table[c] == NULL)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if ((s = sf_get_string(data->file, c)) == NULL ||
|
if ((s = sf_get_string(data->sndfile.file, c)) == NULL ||
|
||||||
*s == '\0')
|
*s == '\0')
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
|
@ -1627,14 +1653,14 @@ static int fill_properties(struct data *data)
|
||||||
}
|
}
|
||||||
|
|
||||||
spa_zero(sfi);
|
spa_zero(sfi);
|
||||||
if ((res = sf_command(data->file, SFC_GET_CURRENT_SF_INFO, &sfi, sizeof(sfi)))) {
|
if ((res = sf_command(data->sndfile.file, SFC_GET_CURRENT_SF_INFO, &sfi, sizeof(sfi)))) {
|
||||||
pw_log_error("sndfile: %s", sf_error_number(res));
|
pw_log_error("sndfile: %s", sf_error_number(res));
|
||||||
return -EIO;
|
return -EIO;
|
||||||
}
|
}
|
||||||
|
|
||||||
spa_zero(fi);
|
spa_zero(fi);
|
||||||
fi.format = sfi.format;
|
fi.format = sfi.format;
|
||||||
if (sf_command(data->file, SFC_GET_FORMAT_INFO, &fi, sizeof(fi)) == 0 && fi.name)
|
if (sf_command(data->sndfile.file, SFC_GET_FORMAT_INFO, &fi, sizeof(fi)) == 0 && fi.name)
|
||||||
if (pw_properties_get(data->props, PW_KEY_MEDIA_FORMAT) == NULL)
|
if (pw_properties_get(data->props, PW_KEY_MEDIA_FORMAT) == NULL)
|
||||||
pw_properties_set(data->props, PW_KEY_MEDIA_FORMAT, fi.name);
|
pw_properties_set(data->props, PW_KEY_MEDIA_FORMAT, fi.name);
|
||||||
|
|
||||||
|
|
@ -1811,10 +1837,10 @@ static int setup_sndfile(struct data *data)
|
||||||
format_from_filename(&info, data->filename);
|
format_from_filename(&info, data->filename);
|
||||||
}
|
}
|
||||||
|
|
||||||
data->file = sf_open(data->filename,
|
data->sndfile.file = sf_open(data->filename,
|
||||||
data->mode == mode_playback ? SFM_READ : SFM_WRITE,
|
data->mode == mode_playback ? SFM_READ : SFM_WRITE,
|
||||||
&info);
|
&info);
|
||||||
if (!data->file) {
|
if (!data->sndfile.file) {
|
||||||
fprintf(stderr, "sndfile: failed to open audio file \"%s\": %s\n",
|
fprintf(stderr, "sndfile: failed to open audio file \"%s\": %s\n",
|
||||||
data->filename, sf_strerror(NULL));
|
data->filename, sf_strerror(NULL));
|
||||||
if (data->verbose) {
|
if (data->verbose) {
|
||||||
|
|
@ -1853,7 +1879,7 @@ static int setup_sndfile(struct data *data)
|
||||||
if (data->channelmap.n_channels == 0) {
|
if (data->channelmap.n_channels == 0) {
|
||||||
bool def = false;
|
bool def = false;
|
||||||
|
|
||||||
if (sf_command(data->file, SFC_GET_CHANNEL_MAP_INFO,
|
if (sf_command(data->sndfile.file, SFC_GET_CHANNEL_MAP_INFO,
|
||||||
data->channelmap.position,
|
data->channelmap.position,
|
||||||
sizeof(data->channelmap.position[0]) * data->channels)) {
|
sizeof(data->channelmap.position[0]) * data->channels)) {
|
||||||
data->channelmap.n_channels = data->channels;
|
data->channelmap.n_channels = data->channels;
|
||||||
|
|
@ -2097,7 +2123,7 @@ int main(int argc, char *argv[])
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 'a':
|
case 'a':
|
||||||
data.raw = true;
|
data.rawfile = true;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 'M':
|
case 'M':
|
||||||
|
|
@ -2264,8 +2290,8 @@ int main(int argc, char *argv[])
|
||||||
}
|
}
|
||||||
pw_core_add_listener(data.core, &data.core_listener, &core_events, &data);
|
pw_core_add_listener(data.core, &data.core_listener, &core_events, &data);
|
||||||
|
|
||||||
if (data.raw) {
|
if (data.rawfile) {
|
||||||
ret = setup_pipe(&data);
|
ret = setup_raw(&data);
|
||||||
} else {
|
} else {
|
||||||
switch (data.data_type) {
|
switch (data.data_type) {
|
||||||
case TYPE_PCM:
|
case TYPE_PCM:
|
||||||
|
|
@ -2500,8 +2526,8 @@ error_no_context:
|
||||||
error_no_props:
|
error_no_props:
|
||||||
error_no_main_loop:
|
error_no_main_loop:
|
||||||
pw_properties_free(data.props);
|
pw_properties_free(data.props);
|
||||||
if (data.file)
|
if (data.sndfile.file)
|
||||||
sf_close(data.file);
|
sf_close(data.sndfile.file);
|
||||||
if (data.midi.file)
|
if (data.midi.file)
|
||||||
midi_file_close(data.midi.file);
|
midi_file_close(data.midi.file);
|
||||||
if (data.clip.file)
|
if (data.clip.file)
|
||||||
|
|
@ -2510,6 +2536,10 @@ error_no_main_loop:
|
||||||
dsf_file_close(data.dsf.file);
|
dsf_file_close(data.dsf.file);
|
||||||
if (data.dff.file)
|
if (data.dff.file)
|
||||||
dff_file_close(data.dff.file);
|
dff_file_close(data.dff.file);
|
||||||
|
if (data.sysex.file && data.sysex.close)
|
||||||
|
fclose(data.sysex.file);
|
||||||
|
if (data.raw.file && data.raw.close)
|
||||||
|
fclose(data.raw.file);
|
||||||
#ifdef HAVE_PW_CAT_FFMPEG_INTEGRATION
|
#ifdef HAVE_PW_CAT_FFMPEG_INTEGRATION
|
||||||
if (data.encoded.packet)
|
if (data.encoded.packet)
|
||||||
av_packet_free(&data.encoded.packet);
|
av_packet_free(&data.encoded.packet);
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue