Index: audio_check.c
===================================================================
--- audio_check.c	(revision 1)
+++ audio_check.c	(working copy)
@@ -47,6 +47,18 @@
 }
 
 bool
+audio_check_frame_type(enum frame_type frame_type, GError **error_r)
+{
+	if (!audio_valid_frame_type(frame_type)) {
+		g_set_error(error_r, audio_format_quark(), 0,
+			    "Invalid frame type: %u", frame_type);
+		return false;
+	}
+
+	return true;
+}
+
+bool
 audio_check_channel_count(unsigned channels, GError **error_r)
 {
 	if (!audio_valid_channel_count(channels)) {
@@ -60,13 +72,14 @@
 
 bool
 audio_format_init_checked(struct audio_format *af, unsigned long sample_rate,
-			  enum sample_format sample_format, unsigned channels,
-			  GError **error_r)
+			  enum sample_format sample_format, enum frame_type frame_type,
+			  unsigned channels, GError **error_r)
 {
 	if (audio_check_sample_rate(sample_rate, error_r) &&
 	    audio_check_sample_format(sample_format, error_r) &&
+	    audio_check_frame_type(frame_type, error_r) &&
 	    audio_check_channel_count(channels, error_r)) {
-		audio_format_init(af, sample_rate, sample_format, channels);
+		audio_format_init(af, sample_rate, sample_format, frame_type, channels);
 		assert(audio_format_valid(af));
 		return true;
 	} else
Index: audio_check.h
===================================================================
--- audio_check.h	(revision 1)
+++ audio_check.h	(working copy)
@@ -42,6 +42,9 @@
 audio_check_sample_format(enum sample_format, GError **error_r);
 
 bool
+audio_check_frame_type(enum frame_type, GError **error_r);
+
+bool
 audio_check_channel_count(unsigned sample_format, GError **error_r);
 
 /**
@@ -49,7 +52,7 @@
  */
 bool
 audio_format_init_checked(struct audio_format *af, unsigned long sample_rate,
-			  enum sample_format sample_format, unsigned channels,
-			  GError **error_r);
+			  enum sample_format sample_format, enum frame_type frame_type,
+			  unsigned channels, GError **error_r);
 
 #endif
Index: audio_format.c
===================================================================
--- audio_format.c	(revision 1)
+++ audio_format.c	(working copy)
@@ -41,6 +41,9 @@
 	if (mask->format != SAMPLE_FORMAT_UNDEFINED)
 		af->format = mask->format;
 
+	if (mask->frame_type != FRAME_TYPE_UNDEFINED)
+		af->frame_type = mask->frame_type;
+
 	if (mask->channels != 0)
 		af->channels = mask->channels;
 
@@ -54,6 +57,7 @@
 	case SAMPLE_FORMAT_UNDEFINED:
 		return "?";
 
+	case SAMPLE_FORMAT_U8:
 	case SAMPLE_FORMAT_S8:
 		return "8";
 
Index: audio_format.h
===================================================================
--- audio_format.h	(revision 1)
+++ audio_format.h	(working copy)
@@ -28,6 +28,8 @@
 enum sample_format {
 	SAMPLE_FORMAT_UNDEFINED = 0,
 
+	SAMPLE_FORMAT_U8,
+
 	SAMPLE_FORMAT_S8,
 	SAMPLE_FORMAT_S16,
 
@@ -51,10 +53,16 @@
 	SAMPLE_FORMAT_FLOAT,
 };
 
+enum frame_type {  
+	FRAME_TYPE_UNDEFINED = 0,  
+	FRAME_TYPE_PCM,  
+	FRAME_TYPE_DSD,
+};
+
 static const unsigned MAX_CHANNELS = 8;
 
 /**
- * This structure describes the format of a raw PCM stream.
+ * This structure describes the format of raw PCM/DSD stream.
  */
 struct audio_format {
 	/**
@@ -71,6 +79,12 @@
 	uint8_t format;
 
 	/**
+	 * The type the samples are stored in.  See the #frame_type
+	 * enum for valid values.
+	 */
+	uint8_t frame_type;
+
+	/**
 	 * The number of channels.  Only mono (1) and stereo (2) are
 	 * fully supported currently.
 	 */
@@ -99,6 +113,7 @@
 {
 	af->sample_rate = 0;
 	af->format = SAMPLE_FORMAT_UNDEFINED;
+	af->frame_type = FRAME_TYPE_UNDEFINED;
 	af->channels = 0;
 	af->reverse_endian = false;
 }
@@ -108,11 +123,12 @@
  * attributes to valid values.
  */
 static inline void audio_format_init(struct audio_format *af,
-				     uint32_t sample_rate,
-				     enum sample_format format, uint8_t channels)
+				     uint32_t sample_rate, enum sample_format format, 
+				     enum frame_type frame_type, uint8_t channels)
 {
 	af->sample_rate = sample_rate;
 	af->format = (uint8_t)format;
+	af->frame_type = (uint8_t)frame_type;
 	af->channels = channels;
 	af->reverse_endian = false;
 }
@@ -135,7 +151,7 @@
 audio_format_fully_defined(const struct audio_format *af)
 {
 	return af->sample_rate != 0 && af->format != SAMPLE_FORMAT_UNDEFINED &&
-		af->channels != 0;
+		af->frame_type != FRAME_TYPE_UNDEFINED && af->channels != 0;
 }
 
 /**
@@ -146,7 +162,7 @@
 audio_format_mask_defined(const struct audio_format *af)
 {
 	return af->sample_rate != 0 || af->format != SAMPLE_FORMAT_UNDEFINED ||
-		af->channels != 0;
+		af->frame_type != FRAME_TYPE_UNDEFINED || af->channels != 0;
 }
 
 /**
@@ -162,13 +178,12 @@
 
 /**
  * Checks whether the sample format is valid.
- *
- * @param bits the number of significant bits per sample
  */
 static inline bool
 audio_valid_sample_format(enum sample_format format)
 {
 	switch (format) {
+	case SAMPLE_FORMAT_U8:
 	case SAMPLE_FORMAT_S8:
 	case SAMPLE_FORMAT_S16:
 	case SAMPLE_FORMAT_S24:
@@ -185,6 +200,24 @@
 }
 
 /**
+ * Checks whether the frame_type is valid.
+ */
+static inline bool
+audio_valid_frame_type(enum frame_type frame_type)
+{
+	switch (frame_type) {
+	case FRAME_TYPE_PCM:
+	case FRAME_TYPE_DSD:
+		return true;
+
+	case FRAME_TYPE_UNDEFINED:
+		break;
+	}
+
+	return false;
+}
+
+/**
  * Checks whether the number of channels is valid.
  */
 static inline bool
@@ -202,6 +235,7 @@
 {
 	return audio_valid_sample_rate(af->sample_rate) &&
 		audio_valid_sample_format((enum sample_format)af->format) &&
+		audio_valid_frame_type((enum frame_type)af->frame_type) &&
 		audio_valid_channel_count(af->channels);
 }
 
@@ -216,6 +250,8 @@
 		audio_valid_sample_rate(af->sample_rate)) &&
 		(af->format == SAMPLE_FORMAT_UNDEFINED ||
 		 audio_valid_sample_format((enum sample_format)af->format)) &&
+		(af->frame_type == FRAME_TYPE_UNDEFINED ||
+		 audio_valid_frame_type((enum frame_type)af->frame_type)) &&
 		(af->channels == 0 || audio_valid_channel_count(af->channels));
 }
 
@@ -224,6 +260,7 @@
 {
 	return a->sample_rate == b->sample_rate &&
 		a->format == b->format &&
+		a->frame_type == b->frame_type &&
 		a->channels == b->channels &&
 		a->reverse_endian == b->reverse_endian;
 }
@@ -237,6 +274,7 @@
 sample_format_size(enum sample_format format)
 {
 	switch (format) {
+	case SAMPLE_FORMAT_U8:
 	case SAMPLE_FORMAT_S8:
 		return 1;
 
Index: audio_parser.c
===================================================================
--- audio_parser.c	(revision 1)
+++ audio_parser.c	(working copy)
@@ -197,7 +197,7 @@
 		return false;
 	}
 
-	audio_format_init(dest, rate, sample_format, channels);
+	audio_format_init(dest, rate, sample_format, FRAME_TYPE_PCM, channels);
 	assert(mask ? audio_format_mask_valid(dest)
 	       : audio_format_valid(dest));
 
Index: decoder/_flac_common.c
===================================================================
--- decoder/_flac_common.c	(revision 1)
+++ decoder/_flac_common.c	(working copy)
@@ -90,7 +90,7 @@
 	if (!audio_format_init_checked(&data->audio_format,
 				       stream_info->sample_rate,
 				       flac_sample_format(stream_info->bits_per_sample),
-				       stream_info->channels, &error)) {
+				       FRAME_TYPE_PCM, stream_info->channels, &error)) {
 		g_warning("%s", error->message);
 		g_error_free(error);
 		data->unsupported = true;
@@ -178,7 +178,7 @@
 	if (!audio_format_init_checked(&data->audio_format,
 				       header->sample_rate,
 				       flac_sample_format(header->bits_per_sample),
-				       header->channels, &error)) {
+				       FRAME_TYPE_PCM, header->channels, &error)) {
 		g_warning("%s", error->message);
 		g_error_free(error);
 		data->unsupported = true;
Index: decoder/audiofile_decoder_plugin.c
===================================================================
--- decoder/audiofile_decoder_plugin.c	(revision 1)
+++ decoder/audiofile_decoder_plugin.c	(working copy)
@@ -181,6 +181,7 @@
 	if (!audio_format_init_checked(&audio_format,
 				       afGetRate(af_fp, AF_DEFAULT_TRACK),
 				       audiofile_setup_sample_format(af_fp),
+				       FRAME_TYPE_PCM,
 				       afGetVirtualChannels(af_fp, AF_DEFAULT_TRACK),
 				       &error)) {
 		g_warning("%s", error->message);
Index: decoder/faad_decoder_plugin.c
===================================================================
--- decoder/faad_decoder_plugin.c	(revision 1)
+++ decoder/faad_decoder_plugin.c	(working copy)
@@ -283,7 +283,8 @@
 	decoder_buffer_consume(buffer, nbytes);
 
 	return audio_format_init_checked(audio_format, sample_rate,
-					 SAMPLE_FORMAT_S16, channels, error_r);
+					 SAMPLE_FORMAT_S16, FRAME_TYPE_PCM, 
+					 channels, error_r);
 }
 
 /**
Index: decoder/ffmpeg_decoder_plugin.c
===================================================================
--- decoder/ffmpeg_decoder_plugin.c	(revision 1)
+++ decoder/ffmpeg_decoder_plugin.c	(working copy)
@@ -493,6 +493,7 @@
 	if (!audio_format_init_checked(&audio_format,
 				       codec_context->sample_rate,
 				       ffmpeg_sample_format(codec_context),
+				       FRAME_TYPE_PCM,
 				       codec_context->channels, &error)) {
 		g_warning("%s", error->message);
 		g_error_free(error);
Index: decoder/flac_pcm.c
===================================================================
--- decoder/flac_pcm.c	(revision 1)
+++ decoder/flac_pcm.c	(working copy)
@@ -103,6 +103,7 @@
 
 	case SAMPLE_FORMAT_S24:
 	case SAMPLE_FORMAT_FLOAT:
+	case SAMPLE_FORMAT_U8:
 	case SAMPLE_FORMAT_UNDEFINED:
 		/* unreachable */
 		assert(false);
Index: decoder/gme_decoder_plugin.c
===================================================================
--- decoder/gme_decoder_plugin.c	(revision 1)
+++ decoder/gme_decoder_plugin.c	(working copy)
@@ -139,7 +139,7 @@
 
 	GError *error = NULL;
 	if (!audio_format_init_checked(&audio_format, GME_SAMPLE_RATE,
-				       SAMPLE_FORMAT_S16, GME_CHANNELS,
+				       SAMPLE_FORMAT_S16, FRAME_TYPE_PCM, GME_CHANNELS,
 				       &error)) {
 		g_warning("%s", error->message);
 		g_error_free(error);
Index: decoder/mad_decoder_plugin.c
===================================================================
--- decoder/mad_decoder_plugin.c	(revision 1)
+++ decoder/mad_decoder_plugin.c	(working copy)
@@ -1152,6 +1152,7 @@
 	if (!audio_format_init_checked(&audio_format,
 				       data.frame.header.samplerate,
 				       SAMPLE_FORMAT_S24_P32,
+				       FRAME_TYPE_PCM,
 				       MAD_NCHANNELS(&data.frame.header),
 				       &error)) {
 		g_warning("%s", error->message);
Index: decoder/mikmod_decoder_plugin.c
===================================================================
--- decoder/mikmod_decoder_plugin.c	(revision 1)
+++ decoder/mikmod_decoder_plugin.c	(working copy)
@@ -162,7 +162,8 @@
 	/* Prevent module from looping forever */
 	handle->loop = 0;
 
-	audio_format_init(&audio_format, mikmod_sample_rate, SAMPLE_FORMAT_S16, 2);
+	audio_format_init(&audio_format, mikmod_sample_rate, 
+				SAMPLE_FORMAT_S16, FRAME_TYPE_PCM, 2);
 	assert(audio_format_valid(&audio_format));
 
 	decoder_initialized(decoder, &audio_format, false, 0);
Index: decoder/modplug_decoder_plugin.c
===================================================================
--- decoder/modplug_decoder_plugin.c	(revision 1)
+++ decoder/modplug_decoder_plugin.c	(working copy)
@@ -121,7 +121,8 @@
 		return;
 	}
 
-	audio_format_init(&audio_format, 44100, SAMPLE_FORMAT_S16, 2);
+	audio_format_init(&audio_format, 44100, SAMPLE_FORMAT_S16,
+				FRAME_TYPE_PCM, 2);
 	assert(audio_format_valid(&audio_format));
 
 	decoder_initialized(decoder, &audio_format,
Index: decoder/mp4ff_decoder_plugin.c
===================================================================
--- decoder/mp4ff_decoder_plugin.c	(revision 1)
+++ decoder/mp4ff_decoder_plugin.c	(working copy)
@@ -161,7 +161,7 @@
 	}
 
 	if (!audio_format_init_checked(audio_format, sample_rate,
-				       SAMPLE_FORMAT_S16, channels,
+				       SAMPLE_FORMAT_S16, FRAME_TYPE_PCM, channels,
 				       &error)) {
 		g_warning("%s", error->message);
 		g_error_free(error);
Index: decoder/mpcdec_decoder_plugin.c
===================================================================
--- decoder/mpcdec_decoder_plugin.c	(revision 1)
+++ decoder/mpcdec_decoder_plugin.c	(working copy)
@@ -195,6 +195,7 @@
 
 	if (!audio_format_init_checked(&audio_format, info.sample_freq,
 				       SAMPLE_FORMAT_S24_P32,
+				       FRAME_TYPE_PCM,
 				       info.channels, &error)) {
 		g_warning("%s", error->message);
 		g_error_free(error);
Index: decoder/mpg123_decoder_plugin.c
===================================================================
--- decoder/mpg123_decoder_plugin.c	(revision 1)
+++ decoder/mpg123_decoder_plugin.c	(working copy)
@@ -88,7 +88,8 @@
 		return false;
 	}
 
-	if (!audio_format_init_checked(audio_format, rate, SAMPLE_FORMAT_S16,
+	if (!audio_format_init_checked(audio_format, rate, SAMPLE_FORMAT_S16, 
+					   FRAME_TYPE_PCM,
 				       channels, &gerror)) {
 		g_warning("%s", gerror->message);
 		g_error_free(gerror);
Index: decoder/sidplay_decoder_plugin.cxx
===================================================================
--- decoder/sidplay_decoder_plugin.cxx	(revision 1)
+++ decoder/sidplay_decoder_plugin.cxx	(working copy)
@@ -285,7 +285,8 @@
 	/* initialize the MPD decoder */
 
 	struct audio_format audio_format;
-	audio_format_init(&audio_format, 48000, SAMPLE_FORMAT_S16, channels);
+	audio_format_init(&audio_format, 48000, SAMPLE_FORMAT_S16, 
+				   FRAME_TYPE_PCM, channels);
 	assert(audio_format_valid(&audio_format));
 
 	decoder_initialized(decoder, &audio_format, true, (float)song_len);
Index: decoder/sndfile_decoder_plugin.c
===================================================================
--- decoder/sndfile_decoder_plugin.c	(revision 1)
+++ decoder/sndfile_decoder_plugin.c	(working copy)
@@ -136,6 +136,7 @@
 	   sf_readf_short() on low-quality source files. */
 	if (!audio_format_init_checked(&audio_format, info.samplerate,
 				       SAMPLE_FORMAT_S32,
+				       FRAME_TYPE_PCM,
 				       info.channels, &error)) {
 		g_warning("%s", error->message);
 		g_error_free(error);
Index: decoder/vorbis_decoder_plugin.c
===================================================================
--- decoder/vorbis_decoder_plugin.c	(revision 1)
+++ decoder/vorbis_decoder_plugin.c	(working copy)
@@ -303,6 +303,7 @@
 
 	if (!audio_format_init_checked(&audio_format, vi->rate,
 				       SAMPLE_FORMAT_S16,
+				       FRAME_TYPE_PCM,
 				       vi->channels, &error)) {
 		g_warning("%s", error->message);
 		g_error_free(error);
Index: decoder/wavpack_decoder_plugin.c
===================================================================
--- decoder/wavpack_decoder_plugin.c	(revision 1)
+++ decoder/wavpack_decoder_plugin.c	(working copy)
@@ -169,6 +169,7 @@
 	if (!audio_format_init_checked(&audio_format,
 				       WavpackGetSampleRate(wpc),
 				       sample_format,
+				       FRAME_TYPE_PCM,
 				       WavpackGetNumChannels(wpc), &error)) {
 		g_warning("%s", error->message);
 		g_error_free(error);
Index: filter/normalize_filter_plugin.c
===================================================================
--- filter/normalize_filter_plugin.c	(revision 1)
+++ filter/normalize_filter_plugin.c	(working copy)
@@ -33,6 +33,8 @@
 
 	struct Compressor *compressor;
 
+	struct audio_format audio_format;
+	
 	struct pcm_buffer buffer;
 };
 
@@ -66,9 +68,13 @@
 {
 	struct normalize_filter *filter = (struct normalize_filter *)_filter;
 
-	audio_format->format = SAMPLE_FORMAT_S16;
-	audio_format->reverse_endian = false;
+	if (audio_format->frame_type == FRAME_TYPE_PCM) {
+		audio_format->format = SAMPLE_FORMAT_S16;
+		audio_format->reverse_endian = false;
+	}
 
+	filter->audio_format = *audio_format;
+	
 	filter->compressor = Compressor_new(0);
 
 	pcm_buffer_init(&filter->buffer);
@@ -93,6 +99,10 @@
 	struct normalize_filter *filter = (struct normalize_filter *)_filter;
 	void *dest;
 
+	if (filter->audio_format.frame_type != FRAME_TYPE_PCM)
+		/* optimized special case: no PCM sample = no-op */
+		return src;
+	
 	dest = pcm_buffer_get(&filter->buffer, src_size);
 
 	memcpy(dest, src, src_size);
Index: filter/replay_gain_filter_plugin.c
===================================================================
--- filter/replay_gain_filter_plugin.c	(revision 1)
+++ filter/replay_gain_filter_plugin.c	(working copy)
@@ -140,7 +140,8 @@
 	struct replay_gain_filter *filter =
 		(struct replay_gain_filter *)_filter;
 
-	audio_format->reverse_endian = false;
+	if (audio_format->frame_type == FRAME_TYPE_PCM)
+		audio_format->reverse_endian = false;
 
 	filter->audio_format = *audio_format;
 	pcm_buffer_init(&filter->buffer);
@@ -179,8 +180,9 @@
 
 	*dest_size_r = src_size;
 
-	if (filter->volume == PCM_VOLUME_1)
-		/* optimized special case: 100% volume = no-op */
+	if (filter->volume >= PCM_VOLUME_1 || 
+		filter->audio_format.frame_type != FRAME_TYPE_PCM)
+		/* optimized special case: 100% volume or no PCM sample = no-op */
 		return src;
 
 	dest = pcm_buffer_get(&filter->buffer, src_size);
@@ -196,10 +198,10 @@
 	memcpy(dest, src, src_size);
 
 	success = pcm_volume(dest, src_size, filter->audio_format.format,
-			     filter->volume);
+				filter->volume);
 	if (!success) {
 		g_set_error(error_r, replay_gain_quark(), 0,
-			    "pcm_volume() has failed");
+				"pcm_volume() has failed");
 		return NULL;
 	}
 
Index: filter/volume_filter_plugin.c
===================================================================
--- filter/volume_filter_plugin.c	(revision 1)
+++ filter/volume_filter_plugin.c	(working copy)
@@ -74,7 +74,9 @@
 {
 	struct volume_filter *filter = (struct volume_filter *)_filter;
 
-	audio_format->reverse_endian = false;
+	if (audio_format->frame_type == FRAME_TYPE_PCM) {
+		audio_format->reverse_endian = false;
+	}
 
 	filter->audio_format = *audio_format;
 	pcm_buffer_init(&filter->buffer);
@@ -100,8 +102,9 @@
 
 	*dest_size_r = src_size;
 
-	if (filter->volume >= PCM_VOLUME_1)
-		/* optimized special case: 100% volume = no-op */
+	if (filter->volume >= PCM_VOLUME_1 || 
+		filter->audio_format.frame_type != FRAME_TYPE_PCM)
+		/* optimized special case: 100% volume or no PCM sample = no-op */
 		return src;
 
 	dest = pcm_buffer_get(&filter->buffer, src_size);
Index: output/alsa_output_plugin.c
===================================================================
--- output/alsa_output_plugin.c	(revision 1)
+++ output/alsa_output_plugin.c	(working copy)
@@ -255,8 +255,10 @@
 		return -EINVAL;
 
 	int err = snd_pcm_hw_params_set_format(pcm, hwparams, alsa_format);
-	if (err == 0)
+	if (err == 0) {
 		audio_format->format = sample_format;
+		audio_format->frame_type = FRAME_TYPE_PCM;
+	}
 
 	return err;
 }
@@ -279,6 +281,7 @@
 	if (err == 0) {
 		audio_format->format = sample_format;
 		audio_format->reverse_endian = true;
+		audio_format->frame_type = FRAME_TYPE_PCM;
 	}
 
 	return err;
Index: output/ao_output_plugin.c
===================================================================
--- output/ao_output_plugin.c	(revision 1)
+++ output/ao_output_plugin.c	(working copy)
@@ -188,6 +188,8 @@
 	ao_sample_format format = OUR_AO_FORMAT_INITIALIZER;
 	struct ao_data *ad = (struct ao_data *)ao;
 
+	audio_format->frame_type = FRAME_TYPE_PCM;
+	
 	switch (audio_format->format) {
 	case SAMPLE_FORMAT_S8:
 		format.bits = 8;
Index: output/ffado_output_plugin.c
===================================================================
--- output/ffado_output_plugin.c	(revision 1)
+++ output/ffado_output_plugin.c	(working copy)
@@ -242,6 +242,8 @@
 {
 	struct mpd_ffado_device *fd = (struct mpd_ffado_device *)ao;
 
+	audio_format->frame_type = FRAME_TYPE_PCM;
+	
 	/* will be converted to floating point, choose best input
 	   format */
 	audio_format->format = SAMPLE_FORMAT_S24_P32;
Index: output/jack_output_plugin.c
===================================================================
--- output/jack_output_plugin.c	(revision 1)
+++ output/jack_output_plugin.c	(working copy)
@@ -177,6 +177,8 @@
 static void
 set_audioformat(struct jack_data *jd, struct audio_format *audio_format)
 {
+	audio_format->frame_type = FRAME_TYPE_PCM;
+
 	audio_format->sample_rate = jack_get_sample_rate(jd->client);
 
 	if (jd->num_source_ports == 1)
Index: output/mvp_output_plugin.c
===================================================================
--- output/mvp_output_plugin.c	(revision 1)
+++ output/mvp_output_plugin.c	(working copy)
@@ -162,6 +162,8 @@
 {
 	unsigned mix[5];
 
+	audio_format->frame_type = FRAME_TYPE_PCM;
+	
 	switch (audio_format->channels) {
 	case 1:
 		mix[0] = 1;
Index: output/openal_output_plugin.c
===================================================================
--- output/openal_output_plugin.c	(revision 1)
+++ output/openal_output_plugin.c	(working copy)
@@ -59,10 +59,12 @@
 static ALenum
 openal_audio_format(struct audio_format *audio_format)
 {
+	audio_format->frame_type = FRAME_TYPE_PCM;
+	
 	/* note: cannot map SAMPLE_FORMAT_S8 to AL_FORMAT_STEREO8 or
 	   AL_FORMAT_MONO8 since OpenAL expects unsigned 8 bit
 	   samples, while MPD uses signed samples */
-
+	
 	switch (audio_format->format) {
 	case SAMPLE_FORMAT_S16:
 		if (audio_format->channels == 2)
Index: output/oss_output_plugin.c
===================================================================
--- output/oss_output_plugin.c	(revision 1)
+++ output/oss_output_plugin.c	(working copy)
@@ -395,6 +395,7 @@
 {
 	switch (format) {
 	case SAMPLE_FORMAT_UNDEFINED:
+	case SAMPLE_FORMAT_U8:
 	case SAMPLE_FORMAT_FLOAT:
 		return AFMT_QUERY;
 
@@ -478,6 +479,9 @@
 				  &oss_format, msg, error_r)
 		: UNSUPPORTED;
 	enum sample_format mpd_format;
+
+	audio_format->frame_type = FRAME_TYPE_PCM;
+	
 	switch (result) {
 	case SUCCESS:
 		mpd_format = sample_format_from_oss(oss_format);
Index: output/osx_output_plugin.c
===================================================================
--- output/osx_output_plugin.c	(revision 1)
+++ output/osx_output_plugin.c	(working copy)
@@ -337,6 +337,8 @@
 	stream_description.mFormatID = kAudioFormatLinearPCM;
 	stream_description.mFormatFlags = kLinearPCMFormatFlagIsSignedInteger;
 
+	audio_format->frame_type = FRAME_TYPE_PCM;
+
 	switch (audio_format->format) {
 	case SAMPLE_FORMAT_S8:
 		stream_description.mBitsPerChannel = 8;
Index: output/pulse_output_plugin.c
===================================================================
--- output/pulse_output_plugin.c	(revision 1)
+++ output/pulse_output_plugin.c	(working copy)
@@ -618,6 +618,8 @@
 	   we just force MPD to send us everything as 16 bit */
 	audio_format->format = SAMPLE_FORMAT_S16;
 
+	audio_format->frame_type = FRAME_TYPE_PCM;
+	
 	ss.format = PA_SAMPLE_S16NE;
 	ss.rate = audio_format->sample_rate;
 	ss.channels = audio_format->channels;
Index: output/raop_output_plugin.c
===================================================================
--- output/raop_output_plugin.c	(revision 1)
+++ output/raop_output_plugin.c	(working copy)
@@ -925,6 +925,7 @@
 	}
 	g_mutex_unlock(raop_session->list_mutex);
 
+	audio_format->frame_type = FRAME_TYPE_PCM;
 	audio_format->format = SAMPLE_FORMAT_S16;
 	if (!raopcl_connect(rd, error_r)) {
 		raop_output_remove(rd);
Index: output/roar_output_plugin.c
===================================================================
--- output/roar_output_plugin.c	(revision 1)
+++ output/roar_output_plugin.c	(working copy)
@@ -153,6 +153,8 @@
 	info->channels = audio_format->channels;
 	info->codec = ROAR_CODEC_PCM_S;
 
+	audio_format->frame_type = FRAME_TYPE_PCM;
+	
 	switch (audio_format->format) {
 	case SAMPLE_FORMAT_UNDEFINED:
 		info->bits = 16;
Index: output/solaris_output_plugin.c
===================================================================
--- output/solaris_output_plugin.c	(revision 1)
+++ output/solaris_output_plugin.c	(working copy)
@@ -112,6 +112,8 @@
 	struct audio_info info;
 	int ret, flags;
 
+	audio_format->frame_type = FRAME_TYPE_PCM;
+	
 	/* support only 16 bit mono/stereo for now; nothing else has
 	   been tested */
 	audio_format->format = SAMPLE_FORMAT_S16;
Index: output/winmm_output_plugin.c
===================================================================
--- output/winmm_output_plugin.c	(revision 1)
+++ output/winmm_output_plugin.c	(working copy)
@@ -156,6 +156,8 @@
 		return false;
 	}
 
+	audio_format->frame_type = FRAME_TYPE_PCM;
+	
 	switch (audio_format->format) {
 	case SAMPLE_FORMAT_S8:
 	case SAMPLE_FORMAT_S16:
Index: pcm_byteswap.c
===================================================================
--- pcm_byteswap.c	(revision 1)
+++ pcm_byteswap.c	(working copy)
@@ -68,6 +68,7 @@
 {
 	switch (format) {
 	case SAMPLE_FORMAT_UNDEFINED:
+	case SAMPLE_FORMAT_U8:
 	case SAMPLE_FORMAT_S24:
 	case SAMPLE_FORMAT_FLOAT:
 		/* not implemented */
Index: pcm_convert.c
===================================================================
--- pcm_convert.c	(revision 1)
+++ pcm_convert.c	(working copy)
@@ -45,6 +45,11 @@
 	pcm_buffer_init(&state->pack_buffer);
 	pcm_buffer_init(&state->channels_buffer);
 	pcm_buffer_init(&state->byteswap_buffer);
+
+	for (unsigned i = 0; i < MAX_CHANNELS; ++i)
+		state->dsd2pcm[i] = dsd2pcm_init();
+
+	pcm_buffer_init(&state->dsd_buffer);
 }
 
 void pcm_convert_deinit(struct pcm_convert_state *state)
@@ -55,6 +60,11 @@
 	pcm_buffer_deinit(&state->pack_buffer);
 	pcm_buffer_deinit(&state->channels_buffer);
 	pcm_buffer_deinit(&state->byteswap_buffer);
+	
+	for (unsigned i = 0; i < MAX_CHANNELS; ++i)
+		dsd2pcm_destroy(state->dsd2pcm[i]);
+
+	pcm_buffer_deinit(&state->dsd_buffer);
 }
 
 static const void *
@@ -68,6 +78,7 @@
 
 	switch (format) {
 	case SAMPLE_FORMAT_UNDEFINED:
+	case SAMPLE_FORMAT_U8:
 	case SAMPLE_FORMAT_S8:
 	case SAMPLE_FORMAT_S24:
 	case SAMPLE_FORMAT_FLOAT:
@@ -234,7 +245,9 @@
 
 	struct audio_format audio_format;
 	audio_format_init(&audio_format, dest_format->sample_rate,
-			  SAMPLE_FORMAT_S24_P32, dest_format->channels);
+			  SAMPLE_FORMAT_S24_P32, 
+			  FRAME_TYPE_PCM, 
+			  dest_format->channels);
 
 	const int32_t *buffer;
 	size_t buffer_size;
@@ -381,6 +394,21 @@
 	    size_t *dest_size_r,
 	    GError **error_r)
 {
+	if (src_format->frame_type == FRAME_TYPE_DSD) {
+
+/** TODO
+		audio_format_init(dest_format, 352800, 
+				SAMPLE_FORMAT_FLOAT, FRAME_TYPE_PCM, src_format->channels);
+	
+		src = pcm_buffer_get(state->dsd_buffer, audio_format_sample_size(dest_format) * src_size);
+		
+		for (unsigned c = 0; c < src_format->channels; ++c)
+			dsd2pcm_translate(state->dsd2pcm[c], now_frames,
+					  src + c, src_format->channels,
+					  lsbitfirst, src + c, src_format->channels);
+*/
+	}
+	
 	if (src_format->reverse_endian) {
 		/* convert to host byte order, because all of our
 		   conversion libraries assume host byte order */
Index: pcm_convert.h
===================================================================
--- pcm_convert.h	(revision 1)
+++ pcm_convert.h	(working copy)
@@ -23,6 +23,7 @@
 #include "pcm_resample.h"
 #include "pcm_dither.h"
 #include "pcm_buffer.h"
+#include "dsd2pcm/dsd2pcm.h"
 
 struct audio_format;
 
@@ -47,6 +48,12 @@
 
 	/** the buffer for swapping the byte order */
 	struct pcm_buffer byteswap_buffer;
+
+	/**  */
+	dsd2pcm_ctx *dsd2pcm[MAX_CHANNELS];
+
+	/** the buffer for the dsd data */
+	struct pcm_buffer dsd_buffer;
 };
 
 static inline GQuark
Index: pcm_format.c
===================================================================
--- pcm_format.c	(revision 1)
+++ pcm_format.c	(working copy)
@@ -147,6 +147,7 @@
 
 	switch (src_format) {
 	case SAMPLE_FORMAT_UNDEFINED:
+	case SAMPLE_FORMAT_U8:
 		break;
 
 	case SAMPLE_FORMAT_S8:
@@ -265,6 +266,7 @@
 
 	switch (src_format) {
 	case SAMPLE_FORMAT_UNDEFINED:
+	case SAMPLE_FORMAT_U8:
 		break;
 
 	case SAMPLE_FORMAT_S8:
@@ -389,6 +391,7 @@
 
 	switch (src_format) {
 	case SAMPLE_FORMAT_UNDEFINED:
+	case SAMPLE_FORMAT_U8:
 		break;
 
 	case SAMPLE_FORMAT_S8:
@@ -524,6 +527,7 @@
 {
 	switch (src_format) {
 	case SAMPLE_FORMAT_UNDEFINED:
+	case SAMPLE_FORMAT_U8:
 		break;
 
 	case SAMPLE_FORMAT_S8:
Index: pcm_mix.c
===================================================================
--- pcm_mix.c	(revision 1)
+++ pcm_mix.c	(working copy)
@@ -119,6 +119,7 @@
 {
 	switch (format) {
 	case SAMPLE_FORMAT_UNDEFINED:
+	case SAMPLE_FORMAT_U8:
 	case SAMPLE_FORMAT_S24:
 		/* not implemented */
 		return false;
@@ -228,6 +229,7 @@
 {
 	switch (format) {
 	case SAMPLE_FORMAT_UNDEFINED:
+	case SAMPLE_FORMAT_U8:
 	case SAMPLE_FORMAT_S24:
 		/* not implemented */
 		return false;
Index: pcm_volume.c
===================================================================
--- pcm_volume.c	(revision 1)
+++ pcm_volume.c	(working copy)
@@ -158,6 +158,7 @@
 	const void *end = pcm_end_pointer(buffer, length);
 	switch (format) {
 	case SAMPLE_FORMAT_UNDEFINED:
+	case SAMPLE_FORMAT_U8:
 	case SAMPLE_FORMAT_S24:
 		/* not implemented */
 		return false;
