Пример #1
0
static void
dsf_stream_decode(struct decoder *decoder, struct input_stream *is)
{
	struct dsf_metadata metadata = {
		.sample_rate = 0,
		.channels = 0,
	};

	/* check if it is a proper DSF file */
	if (!dsf_read_metadata(decoder, is, &metadata))
		return;

	GError *error = NULL;
	struct audio_format audio_format;
	if (!audio_format_init_checked(&audio_format, metadata.sample_rate / 8,
				       SAMPLE_FORMAT_DSD,
				       metadata.channels, &error)) {
		g_warning("%s", error->message);
		g_error_free(error);
		return;
	}

	/* success: file was recognized */
	decoder_initialized(decoder, &audio_format, false, -1);

	if (!dsf_decode_chunk(decoder, is, metadata.channels,
			      metadata.chunk_size,
			      metadata.bitreverse))
		return;
}

static bool
dsf_scan_stream(struct input_stream *is,
		   G_GNUC_UNUSED const struct tag_handler *handler,
		   G_GNUC_UNUSED void *handler_ctx)
{
	struct dsf_metadata metadata = {
		.sample_rate = 0,
		.channels = 0,
	};

	/* check DSF metadata */
	if (!dsf_read_metadata(NULL, is, &metadata))
		return false;

	struct audio_format audio_format;
	if (!audio_format_init_checked(&audio_format, metadata.sample_rate / 8,
				       SAMPLE_FORMAT_DSD,
				       metadata.channels, NULL))
		/* refuse to parse files which we cannot play anyway */
		return false;

	return true;
}

static const char *const dsf_suffixes[] = {
	"dsf",
	NULL
};

static const char *const dsf_mime_types[] = {
	"application/x-dsf",
	NULL
};

const struct decoder_plugin dsf_decoder_plugin = {
	.name = "dsf",
	.stream_decode = dsf_stream_decode,
	.scan_stream = dsf_scan_stream,
	.suffixes = dsf_suffixes,
	.mime_types = dsf_mime_types,
};
Пример #2
0
static void
dsdiff_stream_decode(struct decoder *decoder, struct input_stream *is)
{
	struct dsdiff_metadata metadata = {
		.sample_rate = 0,
		.channels = 0,
	};

	struct dsdiff_chunk_header chunk_header;
	/* First see if it is is a DFF file */
	if (!dsdiff_read_metadata(decoder, is, &metadata, &chunk_header))
	{
		/* It was not a DFF file, now check if it is a DSF file */
		if (!dsf_read_metadata(decoder, is, &metadata))
			return;
	}

	GError *error = NULL;
	struct audio_format audio_format;
	if (!audio_format_init_checked(&audio_format, metadata.sample_rate / 8,
				       SAMPLE_FORMAT_DSD,
				       metadata.channels, &error)) {
		g_warning("%s", error->message);
		g_error_free(error);
		return;
	}

	/* success: file was recognized */
	decoder_initialized(decoder, &audio_format, false, -1);

	if (!metadata.fileisdff) {
		uint64_t chunk_size = metadata.chunk_size;
		if (!dsdiff_decode_chunk(decoder, is,
					 metadata.channels,
					 chunk_size,
					 metadata.fileisdff,
					 metadata.bitreverse))
			return;

	} else {

		/* every iteration of the following loop decodes one "DSD"
		   chunk from a DFF file */

		while (true) {

			uint64_t chunk_size = dsdiff_chunk_size(&chunk_header);

			if (dsdiff_id_equals(&chunk_header.id, "DSD ")) {
				if (!dsdiff_decode_chunk(decoder, is,
							 metadata.channels,
							 chunk_size,
							 metadata.fileisdff,
						/* Set bitreverse to
						   false for DFF files */
							false))
					break;
			} else {
				/* ignore other chunks */

				if (!dsdiff_skip(decoder, is, chunk_size))
					break;
			}

			/* read next chunk header; the first one was read by
			   dsdiff_read_metadata() */

			if (!dsdiff_read_chunk_header(decoder,
						      is, &chunk_header))
				break;
		}
	}
}

static bool
dsdiff_scan_stream(struct input_stream *is,
		   G_GNUC_UNUSED const struct tag_handler *handler,
		   G_GNUC_UNUSED void *handler_ctx)
{
	struct dsdiff_metadata metadata = {
		.sample_rate = 0,
		.channels = 0,
	};

	struct dsdiff_chunk_header chunk_header;
	/* First check for DFF metadata */
	if (!dsdiff_read_metadata(NULL, is, &metadata, &chunk_header))
	{
		/* It was not an DFF file, now check for DSF metadata */
		if (!dsf_read_metadata(NULL, is, &metadata))
			return false;
	}

	struct audio_format audio_format;
	if (!audio_format_init_checked(&audio_format, metadata.sample_rate / 8,
				       SAMPLE_FORMAT_DSD,
				       metadata.channels, NULL))
		/* refuse to parse files which we cannot play anyway */
		return false;

	/* no total time estimate, no tags implemented yet */
	return true;
}

static const char *const dsdiff_suffixes[] = {
	"dff",
	"dsf",
	NULL
};

static const char *const dsdiff_mime_types[] = {
	"application/x-dff",
	"application/x-dsf",
	NULL
};

const struct decoder_plugin dsdiff_decoder_plugin = {
	.name = "dsdiff",
	.init = dsdiff_init,
	.stream_decode = dsdiff_stream_decode,
	.scan_stream = dsdiff_scan_stream,
	.suffixes = dsdiff_suffixes,
	.mime_types = dsdiff_mime_types,
};