diff --git a/src/tools/dsffile.c b/src/tools/dsffile.c index 1d96f470c..7c379df92 100644 --- a/src/tools/dsffile.c +++ b/src/tools/dsffile.c @@ -214,32 +214,39 @@ ssize_t dsf_file_read(struct dsf_file *f, void *data, size_t samples, const struct dsf_layout *layout) { uint8_t *d = data; - const uint8_t *s; - uint32_t i, j, k, total, stride, bytes, step = SPA_ABS(layout->interleave); + int step = SPA_ABS(layout->interleave); bool rev = layout->lsb != f->info.lsb; + size_t total, block, offset, pos; - stride = layout->channels * step; - bytes = samples * stride; - bytes -= bytes % f->info.blocksize; + block = f->offset / f->info.blocksize; + offset = block * f->info.blocksize * f->info.channels; + pos = f->offset % f->info.blocksize; - for (total = 0; total < bytes; total += layout->channels * f->info.blocksize) { - s = f->p + f->offset; + for (total = 0; total < samples && offset + pos < f->info.length; total++) { + const uint8_t *s = f->p + offset + pos; + uint32_t i; - for (i = 0; i < f->info.blocksize; i += step) { - for (j = 0; j < layout->channels; j++) { - const uint8_t *c = &s[f->info.blocksize * j + i]; - if (layout->interleave > 0) { - for (k = 0; k < step; k++) - *d++ = rev ? bitrev[c[k]] : c[k]; - } else { - for (k = step; k > 0; k--) - *d++ = rev ? bitrev[c[k-1]] : c[k-1]; - } + for (i = 0; i < layout->channels; i++) { + const uint8_t *c = &s[f->info.blocksize * i]; + int j; + + if (layout->interleave > 0) { + for (j = 0; j < step; j++) + *d++ = rev ? bitrev[c[j]] : c[j]; + } else { + for (j = step-1; j >= 0; j--) + *d++ = rev ? bitrev[c[j]] : c[j]; } } - f->offset += f->info.channels * f->info.blocksize; + pos += step; + if (pos == f->info.blocksize) { + pos = 0; + offset += f->info.blocksize * f->info.channels; + } } - return total / stride; + f->offset += total * step; + + return total; } int dsf_file_close(struct dsf_file *f) diff --git a/src/tools/pw-cat.c b/src/tools/pw-cat.c index 24edc251f..2a836efff 100644 --- a/src/tools/pw-cat.c +++ b/src/tools/pw-cat.c @@ -915,7 +915,7 @@ 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->stride = data->dsf.info.channels * SPA_ABS(data->dsf.layout.interleave); + data->stride = data->dsf.layout.channels * SPA_ABS(data->dsf.layout.interleave); if (data->verbose) { printf("DSD out: channels:%d bitorder:%s interleave:%d\n", @@ -1268,9 +1268,10 @@ static int setup_dsffile(struct data *data) } if (data->verbose) - printf("opened file \"%s\" channels:%d rate:%d bitorder:%s\n", + printf("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;