From c48a4bc166bfb5827ecea1195a8435458a3d8501 Mon Sep 17 00:00:00 2001 From: Wim Taymans Date: Thu, 28 Apr 2022 12:32:08 +0200 Subject: [PATCH] pw-cat: fix DSF playback again Make the DSD buffers a little bigger because we scale down the rate. Read an interleaved number of samples to fill one quantum. --- spa/plugins/alsa/alsa-pcm-sink.c | 4 ++-- spa/plugins/alsa/alsa-pcm.c | 8 +++++++- spa/plugins/alsa/alsa-pcm.h | 1 + src/tools/dsffile.c | 2 ++ src/tools/pw-cat.c | 5 +++-- 5 files changed, 15 insertions(+), 5 deletions(-) diff --git a/spa/plugins/alsa/alsa-pcm-sink.c b/spa/plugins/alsa/alsa-pcm-sink.c index 3685d0d45..8cef611b4 100644 --- a/spa/plugins/alsa/alsa-pcm-sink.c +++ b/spa/plugins/alsa/alsa-pcm-sink.c @@ -531,8 +531,8 @@ impl_node_port_enum_params(void *object, int seq, SPA_PARAM_BUFFERS_buffers, SPA_POD_CHOICE_RANGE_Int(2, 1, MAX_BUFFERS), SPA_PARAM_BUFFERS_blocks, SPA_POD_Int(this->blocks), SPA_PARAM_BUFFERS_size, SPA_POD_CHOICE_RANGE_Int( - this->quantum_limit * this->frame_size, - 16 * this->frame_size, + this->quantum_limit * this->frame_size * this->frame_scale, + 16 * this->frame_size * this->frame_scale, INT32_MAX), SPA_PARAM_BUFFERS_stride, SPA_POD_Int(this->frame_size)); break; diff --git a/spa/plugins/alsa/alsa-pcm.c b/spa/plugins/alsa/alsa-pcm.c index 6979b7986..2a12430e5 100644 --- a/spa/plugins/alsa/alsa-pcm.c +++ b/spa/plugins/alsa/alsa-pcm.c @@ -1235,7 +1235,7 @@ spa_alsa_enum_format(struct state *state, int seq, uint32_t start, uint32_t num, int spa_alsa_set_format(struct state *state, struct spa_audio_info *fmt, uint32_t flags) { - unsigned int rrate, rchannels, val; + unsigned int rrate, rchannels, val, rscale = 1; snd_pcm_uframes_t period_size; int err, dir; snd_pcm_hw_params_t *params; @@ -1322,21 +1322,26 @@ int spa_alsa_set_format(struct state *state, struct spa_audio_info *fmt, uint32_ case 4: rformat = SND_PCM_FORMAT_DSD_U32_BE; rrate /= 4; + rscale = 4; break; case -4: rformat = SND_PCM_FORMAT_DSD_U32_LE; rrate /= 4; + rscale = 4; break; case 2: rformat = SND_PCM_FORMAT_DSD_U16_BE; rrate /= 2; + rscale = 2; break; case -2: rformat = SND_PCM_FORMAT_DSD_U16_LE; rrate /= 2; + rscale = 2; break; case 1: rformat = SND_PCM_FORMAT_DSD_U8; + rscale = 1; break; default: return -ENOTSUP; @@ -1430,6 +1435,7 @@ int spa_alsa_set_format(struct state *state, struct spa_audio_info *fmt, uint32_ state->channels = rchannels; state->rate = rrate; state->frame_size = snd_pcm_format_physical_width(rformat) / 8; + state->frame_scale = rscale; state->planar = planar; state->blocks = 1; if (planar) diff --git a/spa/plugins/alsa/alsa-pcm.h b/spa/plugins/alsa/alsa-pcm.h index 28d18243d..65ed51a82 100644 --- a/spa/plugins/alsa/alsa-pcm.h +++ b/spa/plugins/alsa/alsa-pcm.h @@ -151,6 +151,7 @@ struct state { int rate; int channels; size_t frame_size; + size_t frame_scale; int blocks; uint32_t rate_denom; uint32_t delay; diff --git a/src/tools/dsffile.c b/src/tools/dsffile.c index 7c379df92..a16f38447 100644 --- a/src/tools/dsffile.c +++ b/src/tools/dsffile.c @@ -222,6 +222,8 @@ dsf_file_read(struct dsf_file *f, void *data, size_t samples, const struct dsf_l offset = block * f->info.blocksize * f->info.channels; pos = f->offset % f->info.blocksize; + samples *= step; + for (total = 0; total < samples && offset + pos < f->info.length; total++) { const uint8_t *s = f->p + offset + pos; uint32_t i; diff --git a/src/tools/pw-cat.c b/src/tools/pw-cat.c index a1b022880..9129b86eb 100644 --- a/src/tools/pw-cat.c +++ b/src/tools/pw-cat.c @@ -709,10 +709,11 @@ on_param_changed(void *userdata, uint32_t id, const struct spa_pod *param) data->stride = data->dsf.layout.channels * SPA_ABS(data->dsf.layout.interleave); if (data->verbose) { - printf("DSD: channels:%d bitorder:%s interleave:%d\n", + printf("DSD: channels:%d bitorder:%s interleave:%d stride:%d\n", data->dsf.layout.channels, data->dsf.layout.lsb ? "lsb" : "msb", - data->dsf.layout.interleave); + data->dsf.layout.interleave, + data->stride); } }