DsfDecoderPlugin.cxx 9.79 KB
Newer Older
1
/*
Max Kellermann's avatar
Max Kellermann committed
2
 * Copyright 2003-2019 The Music Player Daemon Project
3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30
 * http://www.musicpd.org
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License along
 * with this program; if not, write to the Free Software Foundation, Inc.,
 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
 */

/* \file
 *
 * This plugin decodes DSDIFF data (SACD) embedded in DSF files.
 *
 * The DSF code was created using the specification found here:
 * http://dsd-guide.com/sonys-dsf-file-format-spec
 *
 * All functions common to both DSD decoders have been moved to dsdlib
 */

#include "config.h"
31
#include "DsfDecoderPlugin.hxx"
32
#include "../DecoderAPI.hxx"
Max Kellermann's avatar
Max Kellermann committed
33
#include "input/InputStream.hxx"
34
#include "CheckAudioFormat.hxx"
35
#include "util/bit_reverse.h"
36
#include "util/ByteOrder.hxx"
37
#include "DsdLib.hxx"
38
#include "tag/Handler.hxx"
39

40 41
#include <string.h>

42 43
static constexpr unsigned DSF_BLOCK_SIZE = 4096;

44
struct DsfMetaData {
45 46
	unsigned sample_rate, channels;
	bool bitreverse;
47
	offset_type n_blocks;
48
#ifdef ENABLE_ID3TAG
49
	offset_type id3_offset;
50
#endif
51 52
};

53
struct DsfHeader {
54
	/** DSF header id: "DSD " */
55
	DsdId id;
56
	/** DSD chunk size, including id = 28 */
57
	DsdUint64 size;
58
	/** total file size */
59
	DsdUint64 fsize;
60
	/** pointer to id3v2 metadata, should be at the end of the file */
61
	DsdUint64 pmeta;
62
};
63

64
/** DSF file fmt chunk */
65
struct DsfFmtChunk {
66
	/** id: "fmt " */
67
	DsdId id;
68
	/** fmt chunk size, including id, normally 52 */
69
	DsdUint64 size;
70 71 72 73 74 75 76 77 78 79 80 81 82
	/** version of this format = 1 */
	uint32_t version;
	/** 0: DSD raw */
	uint32_t formatid;
	/** channel type, 1 = mono, 2 = stereo, 3 = 3 channels, etc */
	uint32_t channeltype;
	/** Channel number, 1 = mono, 2 = stereo, ... 6 = 6 channels */
	uint32_t channelnum;
	/** sample frequency: 2822400, 5644800 */
	uint32_t sample_freq;
	/** bits per sample 1 or 8 */
	uint32_t bitssample;
	/** Sample count per channel in bytes */
83
	DsdUint64 scnt;
84 85 86 87 88 89
	/** block size per channel = 4096 */
	uint32_t block_size;
	/** reserved, should be all zero */
	uint32_t reserved;
};

90
struct DsfDataChunk {
91
	DsdId id;
92
	/** "data" chunk size, includes header (id+size) */
93
	DsdUint64 size;
94 95 96 97 98 99
};

/**
 * Read and parse all needed metadata chunks for DSF files.
 */
static bool
100
dsf_read_metadata(DecoderClient *client, InputStream &is,
101
		  DsfMetaData *metadata)
102
{
103
	DsfHeader dsf_header;
104
	if (!decoder_read_full(client, is, &dsf_header, sizeof(dsf_header)) ||
105
	    !dsf_header.id.Equals("DSD "))
106 107
		return false;

108
	const offset_type chunk_size = dsf_header.size.Read();
109 110 111
	if (sizeof(dsf_header) != chunk_size)
		return false;

112
#ifdef ENABLE_ID3TAG
113
	const offset_type metadata_offset = dsf_header.pmeta.Read();
114 115
#endif

116
	/* read the 'fmt ' chunk of the DSF file */
117
	DsfFmtChunk dsf_fmt_chunk;
118
	if (!decoder_read_full(client, is,
119
			       &dsf_fmt_chunk, sizeof(dsf_fmt_chunk)) ||
120
	    !dsf_fmt_chunk.id.Equals("fmt "))
121 122
		return false;

123
	const uint64_t fmt_chunk_size = dsf_fmt_chunk.size.Read();
124 125 126
	if (fmt_chunk_size != sizeof(dsf_fmt_chunk))
		return false;

127
	uint32_t samplefreq = FromLE32(dsf_fmt_chunk.sample_freq);
128
	const unsigned channels = FromLE32(dsf_fmt_chunk.channelnum);
129 130

	/* for now, only support version 1 of the standard, DSD raw stereo
131
	   files with a sample freq of 2822400 or 5644800 Hz */
132

133 134
	if (FromLE32(dsf_fmt_chunk.version) != 1 ||
	    FromLE32(dsf_fmt_chunk.formatid) != 0 ||
135
	    !audio_valid_channel_count(channels) ||
136
	    !dsdlib_valid_freq(samplefreq))
137 138
		return false;

139
	uint32_t chblksize = FromLE32(dsf_fmt_chunk.block_size);
140
	/* according to the spec block size should always be 4096 */
141
	if (chblksize != DSF_BLOCK_SIZE)
142 143 144
		return false;

	/* read the 'data' chunk of the DSF file */
145
	DsfDataChunk data_chunk;
146
	if (!decoder_read_full(client, is, &data_chunk, sizeof(data_chunk)) ||
147
	    !data_chunk.id.Equals("data"))
148 149 150 151 152
		return false;

	/* data size of DSF files are padded to multiple of 4096,
	   we use the actual data size as chunk size */

153
	offset_type data_size = data_chunk.size.Read();
154 155 156
	if (data_size < sizeof(data_chunk))
		return false;

157 158
	data_size -= sizeof(data_chunk);

159
	/* data_size cannot be bigger or equal to total file size */
160 161
	if (is.KnownSize() && data_size > is.GetRest())
		return false;
162

163 164 165 166
	/* use the sample count from the DSF header as the upper
	   bound, because some DSF files contain junk at the end of
	   the "data" chunk */
	const uint64_t samplecnt = dsf_fmt_chunk.scnt.Read();
167
	const offset_type playable_size = samplecnt * channels / 8;
168 169 170
	if (data_size > playable_size)
		data_size = playable_size;

171 172
	const size_t block_size = channels * DSF_BLOCK_SIZE;
	metadata->n_blocks = data_size / block_size;
173
	metadata->channels = channels;
174
	metadata->sample_rate = samplefreq;
175
#ifdef ENABLE_ID3TAG
176
	metadata->id3_offset = metadata_offset;
177
#endif
178
	/* check bits per sample format, determine if bitreverse is needed */
179
	metadata->bitreverse = FromLE32(dsf_fmt_chunk.bitssample) == 1;
180 181 182 183 184 185 186 187 188 189
	return true;
}

static void
bit_reverse_buffer(uint8_t *p, uint8_t *end)
{
	for (; p < end; ++p)
		*p = bit_reverse(*p);
}

190 191 192 193 194 195 196
static void
InterleaveDsfBlockMono(uint8_t *gcc_restrict dest,
		       const uint8_t *gcc_restrict src)
{
	memcpy(dest, src, DSF_BLOCK_SIZE);
}

197 198 199 200 201 202 203
/**
 * DSF data is build up of alternating 4096 blocks of DSD samples for left and
 * right. Convert the buffer holding 1 block of 4096 DSD left samples and 1
 * block of 4096 DSD right samples to 8k of samples in normal PCM left/right
 * order.
 */
static void
204 205
InterleaveDsfBlockStereo(uint8_t *gcc_restrict dest,
			 const uint8_t *gcc_restrict src)
206
{
207 208 209
	for (size_t i = 0; i < DSF_BLOCK_SIZE; ++i) {
		dest[2 * i] = src[i];
		dest[2 * i + 1] = src[DSF_BLOCK_SIZE + i];
210 211 212
	}
}

213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242
static void
InterleaveDsfBlockChannel(uint8_t *gcc_restrict dest,
			  const uint8_t *gcc_restrict src,
			  unsigned channels)
{
	for (size_t i = 0; i < DSF_BLOCK_SIZE; ++i, dest += channels, ++src)
		*dest = *src;
}

static void
InterleaveDsfBlockGeneric(uint8_t *gcc_restrict dest,
			  const uint8_t *gcc_restrict src,
			  unsigned channels)
{
	for (unsigned c = 0; c < channels; ++c, ++dest, src += DSF_BLOCK_SIZE)
		InterleaveDsfBlockChannel(dest, src, channels);
}

static void
InterleaveDsfBlock(uint8_t *gcc_restrict dest, const uint8_t *gcc_restrict src,
		   unsigned channels)
{
	if (channels == 1)
		InterleaveDsfBlockMono(dest, src);
	else if (channels == 2)
		InterleaveDsfBlockStereo(dest, src);
	else
		InterleaveDsfBlockGeneric(dest, src, channels);
}

243
static offset_type
244
FrameToBlock(uint64_t frame)
245
{
246
	return frame / DSF_BLOCK_SIZE;
247 248
}

249 250 251 252
/**
 * Decode one complete DSF 'data' chunk i.e. a complete song
 */
static bool
253
dsf_decode_chunk(DecoderClient &client, InputStream &is,
254
		 unsigned channels, unsigned sample_rate,
255
		 offset_type n_blocks,
Max Kellermann's avatar
Max Kellermann committed
256
		 bool bitreverse)
257
{
258
	const size_t block_size = channels * DSF_BLOCK_SIZE;
259
	const offset_type start_offset = is.GetOffset();
260

261
	auto cmd = client.GetCommand();
262
	for (offset_type i = 0; i < n_blocks && cmd != DecoderCommand::STOP;) {
263
		if (cmd == DecoderCommand::SEEK) {
264
			uint64_t frame = client.GetSeekFrame();
265
			offset_type block = FrameToBlock(frame);
266
			if (block >= n_blocks) {
267
				client.CommandFinished();
268 269 270 271 272
				break;
			}

			offset_type offset =
				start_offset + block * block_size;
273
			if (dsdlib_skip_to(&client, is, offset)) {
274
				client.CommandFinished();
275 276
				i = block;
			} else
277
				client.SeekError();
278 279
		}

280 281
		/* worst-case buffer size */
		uint8_t buffer[MAX_CHANNELS * DSF_BLOCK_SIZE];
282
		if (!decoder_read_full(&client, is, buffer, block_size))
283 284 285
			return false;

		if (bitreverse)
286
			bit_reverse_buffer(buffer, buffer + block_size);
287

288 289
		uint8_t interleaved_buffer[MAX_CHANNELS * DSF_BLOCK_SIZE];
		InterleaveDsfBlock(interleaved_buffer, buffer, channels);
290

291 292 293
		cmd = client.SubmitData(is,
					interleaved_buffer, block_size,
					sample_rate / 1000);
294
		++i;
295
	}
296

297
	return true;
298 299 300
}

static void
301
dsf_stream_decode(DecoderClient &client, InputStream &is)
302 303
{
	/* check if it is a proper DSF file */
304
	DsfMetaData metadata;
305
	if (!dsf_read_metadata(&client, is, &metadata))
306 307
		return;

308 309 310 311
	auto audio_format = CheckAudioFormat(metadata.sample_rate / 8,
					     SampleFormat::DSD,
					     metadata.channels);

312
	/* Calculate song time from DSD chunk size and sample frequency */
313
	const auto n_blocks = metadata.n_blocks;
314 315
	auto songtime = SongTime::FromScale<uint64_t>(n_blocks * DSF_BLOCK_SIZE,
						      audio_format.sample_rate);
316 317

	/* success: file was recognized */
318
	client.Ready(audio_format, is.IsSeekable(), songtime);
319

320
	dsf_decode_chunk(client, is, metadata.channels,
321 322 323
			 metadata.sample_rate,
			 n_blocks,
			 metadata.bitreverse);
324 325 326
}

static bool
327
dsf_scan_stream(InputStream &is, TagHandler &handler) noexcept
328 329
{
	/* check DSF metadata */
330
	DsfMetaData metadata;
331
	if (!dsf_read_metadata(nullptr, is, &metadata))
332 333
		return false;

334 335 336
	const auto sample_rate = metadata.sample_rate / 8;
	if (!audio_valid_sample_rate(sample_rate))
		return false;
337

338
	/* calculate song time and add as tag */
339 340
	const auto n_blocks = metadata.n_blocks;
	auto songtime = SongTime::FromScale<uint64_t>(n_blocks * DSF_BLOCK_SIZE,
341
						      sample_rate);
342
	handler.OnDuration(songtime);
343

344
#ifdef ENABLE_ID3TAG
345
	/* Add available tags from the ID3 tag */
346
	dsdlib_tag_id3(is, handler, metadata.id3_offset);
347
#endif
348 349 350 351 352
	return true;
}

static const char *const dsf_suffixes[] = {
	"dsf",
353
	nullptr
354 355 356 357
};

static const char *const dsf_mime_types[] = {
	"application/x-dsf",
358 359
	"audio/x-dsf",
	"audio/x-dsd",
360
	nullptr
361 362
};

363 364 365 366
constexpr DecoderPlugin dsf_decoder_plugin =
	DecoderPlugin("dsf", dsf_stream_decode, dsf_scan_stream)
	.WithSuffixes(dsf_suffixes)
	.WithMimeTypes(dsf_mime_types);