mirror of
				https://gitlab.freedesktop.org/pipewire/pipewire.git
				synced 2025-11-03 09:01:54 -05:00 
			
		
		
		
	pw-cat: improve DSD file reading
Support reading non-multiples of the blocksize. Stop reading at the end of the file.
This commit is contained in:
		
							parent
							
								
									ce2f1b3737
								
							
						
					
					
						commit
						a6304b47f6
					
				
					 2 changed files with 29 additions and 21 deletions
				
			
		| 
						 | 
					@ -214,32 +214,39 @@ ssize_t
 | 
				
			||||||
dsf_file_read(struct dsf_file *f, void *data, size_t samples, const struct dsf_layout *layout)
 | 
					dsf_file_read(struct dsf_file *f, void *data, size_t samples, const struct dsf_layout *layout)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	uint8_t *d = data;
 | 
						uint8_t *d = data;
 | 
				
			||||||
	const uint8_t *s;
 | 
						int step = SPA_ABS(layout->interleave);
 | 
				
			||||||
	uint32_t i, j, k, total, stride, bytes, step = SPA_ABS(layout->interleave);
 | 
					 | 
				
			||||||
	bool rev = layout->lsb != f->info.lsb;
 | 
						bool rev = layout->lsb != f->info.lsb;
 | 
				
			||||||
 | 
						size_t total, block, offset, pos;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	stride = layout->channels * step;
 | 
						block = f->offset / f->info.blocksize;
 | 
				
			||||||
	bytes = samples * stride;
 | 
						offset = block * f->info.blocksize * f->info.channels;
 | 
				
			||||||
	bytes -= bytes % f->info.blocksize;
 | 
						pos = f->offset % f->info.blocksize;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	for (total = 0; total < bytes; total += layout->channels * f->info.blocksize) {
 | 
						for (total = 0; total < samples && offset + pos < f->info.length; total++) {
 | 
				
			||||||
		s = f->p + f->offset;
 | 
							const uint8_t *s = f->p + offset + pos;
 | 
				
			||||||
 | 
							uint32_t i;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		for (i = 0; i < f->info.blocksize; i += step)  {
 | 
							for (i = 0; i < layout->channels; i++) {
 | 
				
			||||||
			for (j = 0; j < layout->channels; j++) {
 | 
								const uint8_t *c = &s[f->info.blocksize * i];
 | 
				
			||||||
				const uint8_t *c = &s[f->info.blocksize * j + i];
 | 
								int j;
 | 
				
			||||||
				if (layout->interleave > 0) {
 | 
					
 | 
				
			||||||
					for (k = 0; k < step; k++)
 | 
								if (layout->interleave > 0) {
 | 
				
			||||||
						*d++ = rev ? bitrev[c[k]] : c[k];
 | 
									for (j = 0; j < step; j++)
 | 
				
			||||||
				} else {
 | 
										*d++ = rev ? bitrev[c[j]] : c[j];
 | 
				
			||||||
					for (k = step; k > 0; k--)
 | 
								} else {
 | 
				
			||||||
						*d++ = rev ? bitrev[c[k-1]] : c[k-1];
 | 
									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)
 | 
					int dsf_file_close(struct dsf_file *f)
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -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.channels = info.info.dsd.channels;
 | 
				
			||||||
	data->dsf.layout.lsb = info.info.dsd.bitorder == SPA_PARAM_BITORDER_lsb;
 | 
						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) {
 | 
						if (data->verbose) {
 | 
				
			||||||
		printf("DSD out: channels:%d bitorder:%s interleave:%d\n",
 | 
							printf("DSD out: channels:%d bitorder:%s interleave:%d\n",
 | 
				
			||||||
| 
						 | 
					@ -1268,9 +1268,10 @@ static int setup_dsffile(struct data *data)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (data->verbose)
 | 
						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->filename,
 | 
				
			||||||
				data->dsf.info.channels, data->dsf.info.rate,
 | 
									data->dsf.info.channels, data->dsf.info.rate,
 | 
				
			||||||
 | 
									data->dsf.info.samples,
 | 
				
			||||||
				data->dsf.info.lsb ? "lsb" : "msb");
 | 
									data->dsf.info.lsb ? "lsb" : "msb");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	data->fill = dsf_play;
 | 
						data->fill = dsf_play;
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue