diff --git a/backends/gstreamer/rb-player-gst-xfade.c b/backends/gstreamer/rb-player-gst-xfade.c
index 2283201..975a81b 100644
--- a/backends/gstreamer/rb-player-gst-xfade.c
+++ b/backends/gstreamer/rb-player-gst-xfade.c
@@ -1728,6 +1728,7 @@ create_stream (RBPlayerGstXFade *player, const char *uri, gpointer stream_data,
 {
 	RBXFadeStream *stream;
 	GstCaps *caps;
+	gboolean need_retimestamp;
 
 	rb_debug ("creating new stream for %s (stream data %p)", uri, stream_data);
 	stream = g_object_new (RB_TYPE_XFADE_STREAM, NULL, NULL);
@@ -1744,6 +1745,8 @@ create_stream (RBPlayerGstXFade *player, const char *uri, gpointer stream_data,
 	}
 	gst_object_ref (stream->bin);
 
+	need_retimestamp = g_str_has_suffix (uri, ".m4a") || g_str_has_suffix (uri, ".wma");
+
 	stream->source = gst_element_make_from_uri (GST_URI_SRC, stream->uri, NULL);
 	if (stream->source == NULL) {
 		rb_debug ("unable to create source for %s", uri);
@@ -1807,12 +1810,19 @@ create_stream (RBPlayerGstXFade *player, const char *uri, gpointer stream_data,
 	}
 	gst_object_ref (stream->capsfilter);
 
-	caps = gst_caps_new_simple ("audio/x-raw-int",
-				    "channels", G_TYPE_INT, 2,
-				    "rate",	G_TYPE_INT, 44100,
-				    "width",	G_TYPE_INT, 16,
-				    "depth",	G_TYPE_INT, 16,
-				    NULL);
+	if (need_retimestamp) {
+		caps = gst_caps_new_simple ("audio/x-raw-float",
+					    "channels", G_TYPE_INT, 2,
+					    "rate", G_TYPE_INT, 44100,
+					    NULL);
+	} else {
+		caps = gst_caps_new_simple ("audio/x-raw-int",
+					    "channels", G_TYPE_INT, 2,
+					    "rate",	G_TYPE_INT, 44100,
+					    "width",	G_TYPE_INT, 16,
+					    "depth",	G_TYPE_INT, 16,
+					    NULL);
+	}
 	g_object_set (stream->capsfilter, "caps", caps, NULL);
 	gst_caps_unref (caps);
 
@@ -1920,8 +1930,34 @@ create_stream (RBPlayerGstXFade *player, const char *uri, gpointer stream_data,
 
 	/* optionally splice in an identity with
 	 * check-imperfect-timestamp and/or check-imperfect-offset set.
+	 *
+	 * XXX also: some demuxer/decoder combinations result in busted
+	 * streams that don't play properly here.  if we force audioconvert
+	 * to actually do something (float->int conversion in this case),
+	 * it retimestamps and reoffsets the stream, which makes it work.
+	 * not a good solution, obviously.
 	 */
-	if (rb_debug_matches ("check-imperfect", __FILE__)) {
+	if (need_retimestamp) {
+		GstElement *audioconvert;
+		GstElement *capsfilter;
+		GstCaps *caps;
+
+		audioconvert = gst_element_factory_make ("audioconvert", NULL);
+
+		caps = gst_caps_new_simple ("audio/x-raw-int",
+					    "channels", G_TYPE_INT, 2,
+					    "rate",	G_TYPE_INT, 44100,
+					    "width",	G_TYPE_INT, 16,
+					    "depth",	G_TYPE_INT, 16,
+					    NULL);
+		capsfilter = gst_element_factory_make ("capsfilter", NULL);
+		g_object_set (capsfilter, "caps", caps, NULL);
+		gst_caps_unref (caps);
+
+		gst_bin_add_many (GST_BIN (stream->bin), audioconvert, capsfilter, NULL);
+		gst_element_link_many (stream->volume, audioconvert, capsfilter, NULL);
+		stream->src_pad = gst_element_get_pad (capsfilter, "src");
+	} else if (rb_debug_matches ("check-imperfect", __FILE__)) {
 		GstElement *identity;
 
 		identity = gst_element_factory_make ("identity", NULL);
