pw-cat: add DFF file suppport

This commit is contained in:
Wim Taymans 2023-09-28 16:54:22 +02:00
parent 428f766d11
commit be1a60c5f9
4 changed files with 397 additions and 10 deletions

View file

@ -41,6 +41,7 @@
#endif
#include "midifile.h"
#include "dfffile.h"
#include "dsffile.h"
#define DEFAULT_MEDIA_TYPE "Audio"
@ -143,6 +144,11 @@ struct data {
struct dsf_file_info info;
struct dsf_layout layout;
} dsf;
struct {
struct dff_file *file;
struct dff_file_info info;
struct dff_layout layout;
} dff;
#ifdef HAVE_PW_CAT_FFMPEG_INTEGRATION
struct {
@ -798,6 +804,10 @@ on_param_changed(void *userdata, uint32_t id, const struct spa_pod *param)
data->dsf.layout.channels = info.info.dsd.channels;
data->dsf.layout.lsb = info.info.dsd.bitorder == SPA_PARAM_BITORDER_lsb;
data->dff.layout.interleave = info.info.dsd.interleave,
data->dff.layout.channels = info.info.dsd.channels;
data->dff.layout.lsb = info.info.dsd.bitorder == SPA_PARAM_BITORDER_lsb;
data->stride = data->dsf.layout.channels * SPA_ABS(data->dsf.layout.interleave);
if (data->verbose) {
@ -1164,26 +1174,46 @@ static int dsf_play(struct data *d, void *src, unsigned int n_frames, bool *null
return dsf_file_read(d->dsf.file, src, n_frames, &d->dsf.layout);
}
static int setup_dsffile(struct data *data)
static int dff_play(struct data *d, void *src, unsigned int n_frames, bool *null_frame)
{
return dff_file_read(d->dff.file, src, n_frames, &d->dff.layout);
}
static int setup_dsdfile(struct data *data)
{
if (data->mode == mode_record)
return -ENOTSUP;
data->dsf.file = dsf_file_open(data->filename, "r", &data->dsf.info);
if (data->dsf.file == NULL) {
fprintf(stderr, "dsffile: can't read dsf file '%s': %m\n", data->filename);
return -errno;
data->dff.file = dff_file_open(data->filename, "r", &data->dff.info);
if (data->dff.file == NULL) {
fprintf(stderr, "dsdfile: can't read dsd file '%s': %m\n", data->filename);
return -errno;
}
}
if (data->verbose)
printf("dsffile: opened file \"%s\" channels:%d rate:%d samples:%"PRIu64" bitorder:%s\n",
if (data->dsf.file != NULL) {
if (data->verbose)
printf("dsffile: opened file \"%s\" channels:%d rate:%d "
"samples:%"PRIu64" bitorder:%s\n",
data->filename,
data->dsf.info.channels, data->dsf.info.rate,
data->dsf.info.samples,
data->dsf.info.lsb ? "lsb" : "msb");
data->fill = dsf_play;
data->fill = dsf_play;
} else {
if (data->verbose)
printf("dfffile: opened file \"%s\" channels:%d rate:%d "
"samples:%"PRIu64" bitorder:%s\n",
data->filename,
data->dff.info.channels, data->dff.info.rate,
data->dff.info.samples,
data->dff.info.lsb ? "lsb" : "msb");
data->fill = dff_play;
}
return 0;
}
@ -1839,7 +1869,7 @@ int main(int argc, char *argv[])
ret = setup_midifile(&data);
break;
case TYPE_DSD:
ret = setup_dsffile(&data);
ret = setup_dsdfile(&data);
break;
#ifdef HAVE_PW_CAT_FFMPEG_INTEGRATION
case TYPE_ENCODED:
@ -1918,13 +1948,21 @@ int main(int argc, char *argv[])
case TYPE_DSD:
{
struct spa_audio_info_dsd info;
uint32_t channel_type;
spa_zero(info);
info.channels = data.dsf.info.channels;
info.rate = data.dsf.info.rate / 8;
if (data.dsf.file != NULL) {
info.channels = data.dsf.info.channels;
info.rate = data.dsf.info.rate / 8;
channel_type = data.dsf.info.channel_type;
} else {
info.channels = data.dff.info.channels;
info.rate = data.dff.info.rate / 8;
channel_type = data.dff.info.channel_type;
}
SPA_FOR_EACH_ELEMENT_VAR(dsd_layouts, i) {
if (i->type != data.dsf.info.channel_type)
if (i->type != channel_type)
continue;
info.channels = i->info.n_channels;
memcpy(info.position, i->info.position,
@ -2020,6 +2058,10 @@ error_no_main_loop:
sf_close(data.file);
if (data.midi.file)
midi_file_close(data.midi.file);
if (data.dsf.file)
dsf_file_close(data.dsf.file);
if (data.dff.file)
dff_file_close(data.dff.file);
#ifdef HAVE_PW_CAT_FFMPEG_INTEGRATION
if (data.encoded.packet)
av_packet_free(&data.encoded.packet);