From 26a9ce7b2927f2fc79af46c3152fbc41ee602197 Mon Sep 17 00:00:00 2001
From: Max Kellermann <max@duempel.org>
Date: Tue, 29 Jan 2013 14:32:32 +0100
Subject: [PATCH] output/{alsa,oss}: convert to C++

---
 Makefile.am                                   |   8 +-
 src/OutputList.cxx                            |   4 +-
 ...{oss_mixer_plugin.c => OssMixerPlugin.cxx} |  16 +-
 ...a_output_plugin.c => AlsaOutputPlugin.cxx} | 148 +++++++++---------
 ...a_output_plugin.h => AlsaOutputPlugin.hxx} |   6 +-
 ...ss_output_plugin.c => OssOutputPlugin.cxx} |  62 ++++----
 ...ss_output_plugin.h => OssOutputPlugin.hxx} |   6 +-
 src/pcm_export.h                              |   8 +
 8 files changed, 140 insertions(+), 118 deletions(-)
 rename src/mixer/{oss_mixer_plugin.c => OssMixerPlugin.cxx} (95%)
 rename src/output/{alsa_output_plugin.c => AlsaOutputPlugin.cxx} (88%)
 rename src/output/{alsa_output_plugin.h => AlsaOutputPlugin.hxx} (86%)
 rename src/output/{oss_output_plugin.c => OssOutputPlugin.cxx} (94%)
 rename src/output/{oss_output_plugin.h => OssOutputPlugin.hxx} (86%)

diff --git a/Makefile.am b/Makefile.am
index 4a1dfea7a..959865679 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -809,7 +809,8 @@ libmixer_plugins_a_CPPFLAGS = $(AM_CPPFLAGS) \
 
 if HAVE_ALSA
 liboutput_plugins_a_SOURCES += \
-	src/output/alsa_output_plugin.c src/output/alsa_output_plugin.h
+	src/output/AlsaOutputPlugin.cxx \
+	src/output/AlsaOutputPlugin.hxx
 libmixer_plugins_a_SOURCES += src/mixer/AlsaMixerPlugin.cxx
 endif
 
@@ -851,8 +852,9 @@ endif
 
 if HAVE_OSS
 liboutput_plugins_a_SOURCES += \
-	src/output/oss_output_plugin.c src/output/oss_output_plugin.h
-libmixer_plugins_a_SOURCES += src/mixer/oss_mixer_plugin.c
+	src/output/OssOutputPlugin.cxx \
+	src/output/OssOutputPlugin.hxx
+libmixer_plugins_a_SOURCES += src/mixer/OssMixerPlugin.cxx
 endif
 
 if HAVE_OPENAL
diff --git a/src/OutputList.cxx b/src/OutputList.cxx
index a9a0b3d33..87e441757 100644
--- a/src/OutputList.cxx
+++ b/src/OutputList.cxx
@@ -20,7 +20,7 @@
 #include "config.h"
 #include "OutputList.hxx"
 #include "output_api.h"
-#include "output/alsa_output_plugin.h"
+#include "output/AlsaOutputPlugin.hxx"
 #include "output/ao_output_plugin.h"
 #include "output/ffado_output_plugin.h"
 #include "output/fifo_output_plugin.h"
@@ -29,7 +29,7 @@
 #include "output/mvp_output_plugin.h"
 #include "output/null_output_plugin.h"
 #include "output/openal_output_plugin.h"
-#include "output/oss_output_plugin.h"
+#include "output/OssOutputPlugin.hxx"
 #include "output/osx_output_plugin.h"
 #include "output/pipe_output_plugin.h"
 #include "output/pulse_output_plugin.h"
diff --git a/src/mixer/oss_mixer_plugin.c b/src/mixer/OssMixerPlugin.cxx
similarity index 95%
rename from src/mixer/oss_mixer_plugin.c
rename to src/mixer/OssMixerPlugin.cxx
index 608f1f9b8..490a65414 100644
--- a/src/mixer/oss_mixer_plugin.c
+++ b/src/mixer/OssMixerPlugin.cxx
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2003-2011 The Music Player Daemon Project
+ * Copyright (C) 2003-2013 The Music Player Daemon Project
  * http://www.musicpd.org
  *
  * This program is free software; you can redistribute it and/or modify
@@ -206,11 +206,11 @@ oss_mixer_set_volume(struct mixer *mixer, unsigned volume, GError **error_r)
 }
 
 const struct mixer_plugin oss_mixer_plugin = {
-	.init = oss_mixer_init,
-	.finish = oss_mixer_finish,
-	.open = oss_mixer_open,
-	.close = oss_mixer_close,
-	.get_volume = oss_mixer_get_volume,
-	.set_volume = oss_mixer_set_volume,
-	.global = true,
+	oss_mixer_init,
+	oss_mixer_finish,
+	oss_mixer_open,
+	oss_mixer_close,
+	oss_mixer_get_volume,
+	oss_mixer_set_volume,
+	true,
 };
diff --git a/src/output/alsa_output_plugin.c b/src/output/AlsaOutputPlugin.cxx
similarity index 88%
rename from src/output/alsa_output_plugin.c
rename to src/output/AlsaOutputPlugin.cxx
index d8b184273..4d9f259ad 100644
--- a/src/output/alsa_output_plugin.c
+++ b/src/output/AlsaOutputPlugin.cxx
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2003-2011 The Music Player Daemon Project
+ * Copyright (C) 2003-2013 The Music Player Daemon Project
  * http://www.musicpd.org
  *
  * This program is free software; you can redistribute it and/or modify
@@ -18,7 +18,7 @@
  */
 
 #include "config.h"
-#include "alsa_output_plugin.h"
+#include "AlsaOutputPlugin.hxx"
 #include "output_api.h"
 #include "mixer_list.h"
 #include "pcm_export.h"
@@ -26,6 +26,8 @@
 #include <glib.h>
 #include <alsa/asoundlib.h>
 
+#include <string>
+
 #undef G_LOG_DOMAIN
 #define G_LOG_DOMAIN "alsa"
 
@@ -43,14 +45,16 @@ enum {
 typedef snd_pcm_sframes_t alsa_writei_t(snd_pcm_t * pcm, const void *buffer,
 					snd_pcm_uframes_t size);
 
-struct alsa_data {
+struct AlsaOutput {
 	struct audio_output base;
 
-	struct pcm_export_state export;
+	struct pcm_export_state pcm_export;
 
-	/** the configured name of the ALSA device; NULL for the
-	    default device */
-	char *device;
+	/**
+	 * The configured name of the ALSA device; empty for the
+	 * default device
+	 */
+	std::string device;
 
 	/** use memory mapped I/O? */
 	bool use_mmap;
@@ -101,6 +105,18 @@ struct alsa_data {
 	 * The number of frames written in the current period.
 	 */
 	snd_pcm_uframes_t period_position;
+
+	AlsaOutput():mode(0), writei(snd_pcm_writei) {
+	}
+
+	bool Init(const config_param *param, GError **error_r) {
+		return ao_base_init(&base, &alsa_output_plugin,
+				    param, error_r);
+	}
+
+	void Deinit() {
+		ao_base_finish(&base);
+	}
 };
 
 /**
@@ -113,24 +129,13 @@ alsa_output_quark(void)
 }
 
 static const char *
-alsa_device(const struct alsa_data *ad)
+alsa_device(const AlsaOutput *ad)
 {
-	return ad->device != NULL ? ad->device : default_device;
-}
-
-static struct alsa_data *
-alsa_data_new(void)
-{
-	struct alsa_data *ret = g_new(struct alsa_data, 1);
-
-	ret->mode = 0;
-	ret->writei = snd_pcm_writei;
-
-	return ret;
+	return ad->device.empty() ? default_device : ad->device.c_str();
 }
 
 static void
-alsa_configure(struct alsa_data *ad, const struct config_param *param)
+alsa_configure(AlsaOutput *ad, const struct config_param *param)
 {
 	ad->device = config_dup_block_string(param, "device", NULL);
 
@@ -161,10 +166,10 @@ alsa_configure(struct alsa_data *ad, const struct config_param *param)
 static struct audio_output *
 alsa_init(const struct config_param *param, GError **error_r)
 {
-	struct alsa_data *ad = alsa_data_new();
+	AlsaOutput *ad = new AlsaOutput();
 
-	if (!ao_base_init(&ad->base, &alsa_output_plugin, param, error_r)) {
-		g_free(ad);
+	if (!ad->Init(param, error_r)) {
+		delete ad;
 		return NULL;
 	}
 
@@ -176,12 +181,10 @@ alsa_init(const struct config_param *param, GError **error_r)
 static void
 alsa_finish(struct audio_output *ao)
 {
-	struct alsa_data *ad = (struct alsa_data *)ao;
+	AlsaOutput *ad = (AlsaOutput *)ao;
 
-	ao_base_finish(&ad->base);
-
-	g_free(ad->device);
-	g_free(ad);
+	ad->Deinit();
+	delete ad;
 
 	/* free libasound's config cache */
 	snd_config_update_free_global();
@@ -190,18 +193,18 @@ alsa_finish(struct audio_output *ao)
 static bool
 alsa_output_enable(struct audio_output *ao, G_GNUC_UNUSED GError **error_r)
 {
-	struct alsa_data *ad = (struct alsa_data *)ao;
+	AlsaOutput *ad = (AlsaOutput *)ao;
 
-	pcm_export_init(&ad->export);
+	pcm_export_init(&ad->pcm_export);
 	return true;
 }
 
 static void
 alsa_output_disable(struct audio_output *ao)
 {
-	struct alsa_data *ad = (struct alsa_data *)ao;
+	AlsaOutput *ad = (AlsaOutput *)ao;
 
-	pcm_export_deinit(&ad->export);
+	pcm_export_deinit(&ad->pcm_export);
 }
 
 static bool
@@ -349,7 +352,8 @@ alsa_output_setup_format(snd_pcm_t *pcm, snd_pcm_hw_params_t *hwparams,
 {
 	/* try the input format first */
 
-	int err = alsa_output_try_format(pcm, hwparams, audio_format->format,
+	int err = alsa_output_try_format(pcm, hwparams,
+					 sample_format(audio_format->format),
 					 packed_r, reverse_endian_r);
 
 	/* if unsupported by the hardware, try other formats */
@@ -383,15 +387,11 @@ alsa_output_setup_format(snd_pcm_t *pcm, snd_pcm_hw_params_t *hwparams,
  * the configured settings and the audio format.
  */
 static bool
-alsa_setup(struct alsa_data *ad, struct audio_format *audio_format,
+alsa_setup(AlsaOutput *ad, struct audio_format *audio_format,
 	   bool *packed_r, bool *reverse_endian_r, GError **error)
 {
-	snd_pcm_hw_params_t *hwparams;
-	snd_pcm_sw_params_t *swparams;
 	unsigned int sample_rate = audio_format->sample_rate;
 	unsigned int channels = audio_format->channels;
-	snd_pcm_uframes_t alsa_buffer_size;
-	snd_pcm_uframes_t alsa_period_size;
 	int err;
 	const char *cmd = NULL;
 	int retry = MPD_ALSA_RETRY_NR;
@@ -401,6 +401,7 @@ alsa_setup(struct alsa_data *ad, struct audio_format *audio_format,
 	period_time_ro = period_time = ad->period_time;
 configure_hw:
 	/* configure HW params */
+	snd_pcm_hw_params_t *hwparams;
 	snd_pcm_hw_params_alloca(&hwparams);
 	cmd = "snd_pcm_hw_params_any";
 	err = snd_pcm_hw_params_any(ad->pcm, hwparams);
@@ -434,7 +435,7 @@ configure_hw:
 		g_set_error(error, alsa_output_quark(), err,
 			    "ALSA device \"%s\" does not support format %s: %s",
 			    alsa_device(ad),
-			    sample_format_to_string(audio_format->format),
+			    sample_format_to_string(sample_format(audio_format->format)),
 			    snd_strerror(-err));
 		return false;
 	}
@@ -525,11 +526,13 @@ configure_hw:
 	if (retry != MPD_ALSA_RETRY_NR)
 		g_debug("ALSA period_time set to %d\n", period_time);
 
+	snd_pcm_uframes_t alsa_buffer_size;
 	cmd = "snd_pcm_hw_params_get_buffer_size";
 	err = snd_pcm_hw_params_get_buffer_size(hwparams, &alsa_buffer_size);
 	if (err < 0)
 		goto error;
 
+	snd_pcm_uframes_t alsa_period_size;
 	cmd = "snd_pcm_hw_params_get_period_size";
 	err = snd_pcm_hw_params_get_period_size(hwparams, &alsa_period_size,
 						NULL);
@@ -537,6 +540,7 @@ configure_hw:
 		goto error;
 
 	/* configure SW params */
+	snd_pcm_sw_params_t *swparams;
 	snd_pcm_sw_params_alloca(&swparams);
 
 	cmd = "snd_pcm_sw_params_current";
@@ -586,7 +590,7 @@ error:
 }
 
 static bool
-alsa_setup_dsd(struct alsa_data *ad, struct audio_format *audio_format,
+alsa_setup_dsd(AlsaOutput *ad, struct audio_format *audio_format,
 	       bool *shift8_r, bool *packed_r, bool *reverse_endian_r,
 	       GError **error_r)
 {
@@ -626,7 +630,7 @@ alsa_setup_dsd(struct alsa_data *ad, struct audio_format *audio_format,
 }
 
 static bool
-alsa_setup_or_dsd(struct alsa_data *ad, struct audio_format *audio_format,
+alsa_setup_or_dsd(AlsaOutput *ad, struct audio_format *audio_format,
 		  GError **error_r)
 {
 	bool shift8 = false, packed, reverse_endian;
@@ -642,8 +646,9 @@ alsa_setup_or_dsd(struct alsa_data *ad, struct audio_format *audio_format,
 	if (!success)
 		return false;
 
-	pcm_export_open(&ad->export,
-			audio_format->format, audio_format->channels,
+	pcm_export_open(&ad->pcm_export,
+			sample_format(audio_format->format),
+			audio_format->channels,
 			dsd_usb, shift8, packed, reverse_endian);
 	return true;
 }
@@ -651,12 +656,10 @@ alsa_setup_or_dsd(struct alsa_data *ad, struct audio_format *audio_format,
 static bool
 alsa_open(struct audio_output *ao, struct audio_format *audio_format, GError **error)
 {
-	struct alsa_data *ad = (struct alsa_data *)ao;
-	int err;
-	bool success;
+	AlsaOutput *ad = (AlsaOutput *)ao;
 
-	err = snd_pcm_open(&ad->pcm, alsa_device(ad),
-			   SND_PCM_STREAM_PLAYBACK, ad->mode);
+	int err = snd_pcm_open(&ad->pcm, alsa_device(ad),
+			       SND_PCM_STREAM_PLAYBACK, ad->mode);
 	if (err < 0) {
 		g_set_error(error, alsa_output_quark(), err,
 			    "Failed to open ALSA device \"%s\": %s",
@@ -667,20 +670,20 @@ alsa_open(struct audio_output *ao, struct audio_format *audio_format, GError **e
 	g_debug("opened %s type=%s", snd_pcm_name(ad->pcm),
 		snd_pcm_type_name(snd_pcm_type(ad->pcm)));
 
-	success = alsa_setup_or_dsd(ad, audio_format, error);
-	if (!success) {
+	if (!alsa_setup_or_dsd(ad, audio_format, error)) {
 		snd_pcm_close(ad->pcm);
 		return false;
 	}
 
 	ad->in_frame_size = audio_format_frame_size(audio_format);
-	ad->out_frame_size = pcm_export_frame_size(&ad->export, audio_format);
+	ad->out_frame_size = pcm_export_frame_size(&ad->pcm_export,
+						   audio_format);
 
 	return true;
 }
 
 static int
-alsa_recover(struct alsa_data *ad, int err)
+alsa_recover(AlsaOutput *ad, int err)
 {
 	if (err == -EPIPE) {
 		g_debug("Underrun on ALSA device \"%s\"\n", alsa_device(ad));
@@ -719,7 +722,7 @@ alsa_recover(struct alsa_data *ad, int err)
 static void
 alsa_drain(struct audio_output *ao)
 {
-	struct alsa_data *ad = (struct alsa_data *)ao;
+	AlsaOutput *ad = (AlsaOutput *)ao;
 
 	if (snd_pcm_state(ad->pcm) != SND_PCM_STATE_RUNNING)
 		return;
@@ -753,7 +756,7 @@ alsa_drain(struct audio_output *ao)
 static void
 alsa_cancel(struct audio_output *ao)
 {
-	struct alsa_data *ad = (struct alsa_data *)ao;
+	AlsaOutput *ad = (AlsaOutput *)ao;
 
 	ad->period_position = 0;
 
@@ -763,7 +766,7 @@ alsa_cancel(struct audio_output *ao)
 static void
 alsa_close(struct audio_output *ao)
 {
-	struct alsa_data *ad = (struct alsa_data *)ao;
+	AlsaOutput *ad = (AlsaOutput *)ao;
 
 	snd_pcm_close(ad->pcm);
 }
@@ -772,11 +775,11 @@ static size_t
 alsa_play(struct audio_output *ao, const void *chunk, size_t size,
 	  GError **error)
 {
-	struct alsa_data *ad = (struct alsa_data *)ao;
+	AlsaOutput *ad = (AlsaOutput *)ao;
 
 	assert(size % ad->in_frame_size == 0);
 
-	chunk = pcm_export(&ad->export, chunk, size, &size);
+	chunk = pcm_export(&ad->pcm_export, chunk, size, &size);
 
 	assert(size % ad->out_frame_size == 0);
 
@@ -789,7 +792,7 @@ alsa_play(struct audio_output *ao, const void *chunk, size_t size,
 				% ad->period_frames;
 
 			size_t bytes_written = ret * ad->out_frame_size;
-			return pcm_export_source_size(&ad->export,
+			return pcm_export_source_size(&ad->pcm_export,
 						      bytes_written);
 		}
 
@@ -803,17 +806,20 @@ alsa_play(struct audio_output *ao, const void *chunk, size_t size,
 }
 
 const struct audio_output_plugin alsa_output_plugin = {
-	.name = "alsa",
-	.test_default_device = alsa_test_default_device,
-	.init = alsa_init,
-	.finish = alsa_finish,
-	.enable = alsa_output_enable,
-	.disable = alsa_output_disable,
-	.open = alsa_open,
-	.play = alsa_play,
-	.drain = alsa_drain,
-	.cancel = alsa_cancel,
-	.close = alsa_close,
+	"alsa",
+	alsa_test_default_device,
+	alsa_init,
+	alsa_finish,
+	alsa_output_enable,
+	alsa_output_disable,
+	alsa_open,
+	alsa_close,
+	nullptr,
+	nullptr,
+	alsa_play,
+	alsa_drain,
+	alsa_cancel,
+	nullptr,
 
-	.mixer_plugin = &alsa_mixer_plugin,
+	&alsa_mixer_plugin,
 };
diff --git a/src/output/alsa_output_plugin.h b/src/output/AlsaOutputPlugin.hxx
similarity index 86%
rename from src/output/alsa_output_plugin.h
rename to src/output/AlsaOutputPlugin.hxx
index daa1f3615..dc7e639a8 100644
--- a/src/output/alsa_output_plugin.h
+++ b/src/output/AlsaOutputPlugin.hxx
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2003-2011 The Music Player Daemon Project
+ * Copyright (C) 2003-2013 The Music Player Daemon Project
  * http://www.musicpd.org
  *
  * This program is free software; you can redistribute it and/or modify
@@ -17,8 +17,8 @@
  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
  */
 
-#ifndef MPD_ALSA_OUTPUT_PLUGIN_H
-#define MPD_ALSA_OUTPUT_PLUGIN_H
+#ifndef MPD_ALSA_OUTPUT_PLUGIN_HXX
+#define MPD_ALSA_OUTPUT_PLUGIN_HXX
 
 extern const struct audio_output_plugin alsa_output_plugin;
 
diff --git a/src/output/oss_output_plugin.c b/src/output/OssOutputPlugin.cxx
similarity index 94%
rename from src/output/oss_output_plugin.c
rename to src/output/OssOutputPlugin.cxx
index e366a4537..5810825f1 100644
--- a/src/output/oss_output_plugin.c
+++ b/src/output/OssOutputPlugin.cxx
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2003-2011 The Music Player Daemon Project
+ * Copyright (C) 2003-2013 The Music Player Daemon Project
  * http://www.musicpd.org
  *
  * This program is free software; you can redistribute it and/or modify
@@ -18,7 +18,7 @@
  */
 
 #include "config.h"
-#include "oss_output_plugin.h"
+#include "OssOutputPlugin.hxx"
 #include "output_api.h"
 #include "mixer_list.h"
 #include "fd_util.h"
@@ -60,7 +60,7 @@ struct oss_data {
 	struct audio_output base;
 
 #ifdef AFMT_S24_PACKED
-	struct pcm_export_state export;
+	struct pcm_export_state pcm_export;
 #endif
 
 	int fd;
@@ -163,11 +163,10 @@ oss_output_test_default_device(void)
 static struct audio_output *
 oss_open_default(GError **error)
 {
-	int i;
 	int err[G_N_ELEMENTS(default_devices)];
 	enum oss_stat ret[G_N_ELEMENTS(default_devices)];
 
-	for (i = G_N_ELEMENTS(default_devices); --i >= 0; ) {
+	for (int i = G_N_ELEMENTS(default_devices); --i >= 0; ) {
 		ret[i] = oss_stat_device(default_devices[i], &err[i]);
 		if (ret[i] == OSS_STAT_NO_ERROR) {
 			struct oss_data *od = oss_data_new();
@@ -182,7 +181,7 @@ oss_open_default(GError **error)
 		}
 	}
 
-	for (i = G_N_ELEMENTS(default_devices); --i >= 0; ) {
+	for (int i = G_N_ELEMENTS(default_devices); --i >= 0; ) {
 		const char *dev = default_devices[i];
 		switch(ret[i]) {
 		case OSS_STAT_NO_ERROR:
@@ -243,7 +242,7 @@ oss_output_enable(struct audio_output *ao, G_GNUC_UNUSED GError **error_r)
 {
 	struct oss_data *od = (struct oss_data *)ao;
 
-	pcm_export_init(&od->export);
+	pcm_export_init(&od->pcm_export);
 	return true;
 }
 
@@ -252,7 +251,7 @@ oss_output_disable(struct audio_output *ao)
 {
 	struct oss_data *od = (struct oss_data *)ao;
 
-	pcm_export_deinit(&od->export);
+	pcm_export_deinit(&od->pcm_export);
 }
 
 #endif
@@ -504,7 +503,7 @@ oss_probe_sample_format(int fd, enum sample_format sample_format,
 			enum sample_format *sample_format_r,
 			int *oss_format_r,
 #ifdef AFMT_S24_PACKED
-			struct pcm_export_state *export,
+			struct pcm_export_state *pcm_export,
 #endif
 			GError **error_r)
 {
@@ -539,7 +538,7 @@ oss_probe_sample_format(int fd, enum sample_format sample_format,
 	*oss_format_r = oss_format;
 
 #ifdef AFMT_S24_PACKED
-	pcm_export_open(export, sample_format, 0, false, false,
+	pcm_export_open(pcm_export, sample_format, 0, false, false,
 			oss_format == AFMT_S24_PACKED,
 			oss_format == AFMT_S24_PACKED &&
 			G_BYTE_ORDER != G_LITTLE_ENDIAN);
@@ -556,16 +555,16 @@ static bool
 oss_setup_sample_format(int fd, struct audio_format *audio_format,
 			int *oss_format_r,
 #ifdef AFMT_S24_PACKED
-			struct pcm_export_state *export,
+			struct pcm_export_state *pcm_export,
 #endif
 			GError **error_r)
 {
 	enum sample_format mpd_format;
 	enum oss_setup_result result =
-		oss_probe_sample_format(fd, audio_format->format,
+		oss_probe_sample_format(fd, sample_format(audio_format->format),
 					&mpd_format, oss_format_r,
 #ifdef AFMT_S24_PACKED
-					export,
+					pcm_export,
 #endif
 					error_r);
 	switch (result) {
@@ -603,7 +602,7 @@ oss_setup_sample_format(int fd, struct audio_format *audio_format,
 		result = oss_probe_sample_format(fd, mpd_format,
 						 &mpd_format, oss_format_r,
 #ifdef AFMT_S24_PACKED
-						 export,
+						 pcm_export,
 #endif
 						 error_r);
 		switch (result) {
@@ -635,7 +634,7 @@ oss_setup(struct oss_data *od, struct audio_format *audio_format,
 		oss_setup_sample_rate(od->fd, audio_format, error_r) &&
 		oss_setup_sample_format(od->fd, audio_format, &od->oss_format,
 #ifdef AFMT_S24_PACKED
-					&od->export,
+					&od->pcm_export,
 #endif
 					error_r);
 }
@@ -749,14 +748,14 @@ oss_output_play(struct audio_output *ao, const void *chunk, size_t size,
 		return 0;
 
 #ifdef AFMT_S24_PACKED
-	chunk = pcm_export(&od->export, chunk, size, &size);
+	chunk = pcm_export(&od->pcm_export, chunk, size, &size);
 #endif
 
 	while (true) {
 		ret = write(od->fd, chunk, size);
 		if (ret > 0) {
 #ifdef AFMT_S24_PACKED
-			ret = pcm_export_source_size(&od->export, ret);
+			ret = pcm_export_source_size(&od->pcm_export, ret);
 #endif
 			return ret;
 		}
@@ -771,18 +770,25 @@ oss_output_play(struct audio_output *ao, const void *chunk, size_t size,
 }
 
 const struct audio_output_plugin oss_output_plugin = {
-	.name = "oss",
-	.test_default_device = oss_output_test_default_device,
-	.init = oss_output_init,
-	.finish = oss_output_finish,
+	"oss",
+	oss_output_test_default_device,
+	oss_output_init,
+	oss_output_finish,
 #ifdef AFMT_S24_PACKED
-	.enable = oss_output_enable,
-	.disable = oss_output_disable,
+	oss_output_enable,
+	oss_output_disable,
+#else
+	nullptr,
+	nullptr,
 #endif
-	.open = oss_output_open,
-	.close = oss_output_close,
-	.play = oss_output_play,
-	.cancel = oss_output_cancel,
+	oss_output_open,
+	oss_output_close,
+	nullptr,
+	nullptr,
+	oss_output_play,
+	nullptr,
+	oss_output_cancel,
+	nullptr,
 
-	.mixer_plugin = &oss_mixer_plugin,
+	&oss_mixer_plugin,
 };
diff --git a/src/output/oss_output_plugin.h b/src/output/OssOutputPlugin.hxx
similarity index 86%
rename from src/output/oss_output_plugin.h
rename to src/output/OssOutputPlugin.hxx
index 2aecc2b3a..6c5c9530b 100644
--- a/src/output/oss_output_plugin.h
+++ b/src/output/OssOutputPlugin.hxx
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2003-2011 The Music Player Daemon Project
+ * Copyright (C) 2003-2013 The Music Player Daemon Project
  * http://www.musicpd.org
  *
  * This program is free software; you can redistribute it and/or modify
@@ -17,8 +17,8 @@
  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
  */
 
-#ifndef MPD_OSS_OUTPUT_PLUGIN_H
-#define MPD_OSS_OUTPUT_PLUGIN_H
+#ifndef MPD_OSS_OUTPUT_PLUGIN_HXX
+#define MPD_OSS_OUTPUT_PLUGIN_HXX
 
 extern const struct audio_output_plugin oss_output_plugin;
 
diff --git a/src/pcm_export.h b/src/pcm_export.h
index a7e7c3f68..005db48e0 100644
--- a/src/pcm_export.h
+++ b/src/pcm_export.h
@@ -87,6 +87,10 @@ struct pcm_export_state {
 	uint8_t reverse_endian;
 };
 
+#ifdef __cplusplus
+extern "C" {
+#endif
+
 /**
  * Initialize a #pcm_export_state object.
  */
@@ -144,4 +148,8 @@ G_GNUC_PURE
 size_t
 pcm_export_source_size(const struct pcm_export_state *state, size_t dest_size);
 
+#ifdef __cplusplus
+}
+#endif
+
 #endif