output_plugin: replaced output_plugin.get_mixer() with mixer_plugin
The mixer core library is now responsible for creating and managing the mixer object. This removes duplicated code from the output plugins.
This commit is contained in:
parent
209c8a540c
commit
66a2c5669e
@ -42,7 +42,7 @@ output_mixer_get_volume(unsigned i)
|
|||||||
if (!output->enabled)
|
if (!output->enabled)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
mixer = ao_plugin_get_mixer(output->plugin, output->data);
|
mixer = output->mixer;
|
||||||
if (mixer == NULL)
|
if (mixer == NULL)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
@ -81,7 +81,7 @@ output_mixer_set_volume(unsigned i, int volume, bool relative)
|
|||||||
if (!output->enabled)
|
if (!output->enabled)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
mixer = ao_plugin_get_mixer(output->plugin, output->data);
|
mixer = output->mixer;
|
||||||
if (mixer == NULL)
|
if (mixer == NULL)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
|
@ -19,7 +19,6 @@
|
|||||||
|
|
||||||
#include "../output_api.h"
|
#include "../output_api.h"
|
||||||
#include "mixer_list.h"
|
#include "mixer_list.h"
|
||||||
#include "mixer_control.h"
|
|
||||||
|
|
||||||
#include <glib.h>
|
#include <glib.h>
|
||||||
#include <alsa/asoundlib.h>
|
#include <alsa/asoundlib.h>
|
||||||
@ -70,9 +69,6 @@ struct alsa_data {
|
|||||||
|
|
||||||
/** the size of one audio frame */
|
/** the size of one audio frame */
|
||||||
size_t frame_size;
|
size_t frame_size;
|
||||||
|
|
||||||
/** the mixer object associated with this output */
|
|
||||||
struct mixer *mixer;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -105,7 +101,6 @@ static void
|
|||||||
alsa_data_free(struct alsa_data *ad)
|
alsa_data_free(struct alsa_data *ad)
|
||||||
{
|
{
|
||||||
g_free(ad->device);
|
g_free(ad->device);
|
||||||
mixer_free(ad->mixer);
|
|
||||||
g_free(ad);
|
g_free(ad);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -151,7 +146,6 @@ alsa_init(G_GNUC_UNUSED const struct audio_format *audio_format,
|
|||||||
}
|
}
|
||||||
|
|
||||||
alsa_configure(ad, param);
|
alsa_configure(ad, param);
|
||||||
ad->mixer = mixer_new(&alsa_mixer, param);
|
|
||||||
|
|
||||||
return ad;
|
return ad;
|
||||||
}
|
}
|
||||||
@ -164,14 +158,6 @@ alsa_finish(void *data)
|
|||||||
alsa_data_free(ad);
|
alsa_data_free(ad);
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct mixer *
|
|
||||||
alsa_get_mixer(void *data)
|
|
||||||
{
|
|
||||||
struct alsa_data *ad = data;
|
|
||||||
|
|
||||||
return ad->mixer;
|
|
||||||
}
|
|
||||||
|
|
||||||
static bool
|
static bool
|
||||||
alsa_test_default_device(void)
|
alsa_test_default_device(void)
|
||||||
{
|
{
|
||||||
@ -400,8 +386,6 @@ alsa_open(void *data, struct audio_format *audio_format, GError **error)
|
|||||||
int err;
|
int err;
|
||||||
bool success;
|
bool success;
|
||||||
|
|
||||||
mixer_open(ad->mixer);
|
|
||||||
|
|
||||||
bitformat = get_bitformat(audio_format);
|
bitformat = get_bitformat(audio_format);
|
||||||
if (bitformat == SND_PCM_FORMAT_UNKNOWN) {
|
if (bitformat == SND_PCM_FORMAT_UNKNOWN) {
|
||||||
/* sample format is not supported by this plugin -
|
/* sample format is not supported by this plugin -
|
||||||
@ -484,8 +468,6 @@ alsa_close(void *data)
|
|||||||
snd_pcm_drain(ad->pcm);
|
snd_pcm_drain(ad->pcm);
|
||||||
|
|
||||||
snd_pcm_close(ad->pcm);
|
snd_pcm_close(ad->pcm);
|
||||||
|
|
||||||
mixer_close(ad->mixer);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static size_t
|
static size_t
|
||||||
@ -514,9 +496,9 @@ const struct audio_output_plugin alsaPlugin = {
|
|||||||
.test_default_device = alsa_test_default_device,
|
.test_default_device = alsa_test_default_device,
|
||||||
.init = alsa_init,
|
.init = alsa_init,
|
||||||
.finish = alsa_finish,
|
.finish = alsa_finish,
|
||||||
.get_mixer = alsa_get_mixer,
|
|
||||||
.open = alsa_open,
|
.open = alsa_open,
|
||||||
.play = alsa_play,
|
.play = alsa_play,
|
||||||
.cancel = alsa_cancel,
|
.cancel = alsa_cancel,
|
||||||
.close = alsa_close,
|
.close = alsa_close,
|
||||||
|
.mixer_plugin = &alsa_mixer,
|
||||||
};
|
};
|
||||||
|
@ -19,7 +19,6 @@
|
|||||||
|
|
||||||
#include "../output_api.h"
|
#include "../output_api.h"
|
||||||
#include "mixer_list.h"
|
#include "mixer_list.h"
|
||||||
#include "mixer_control.h"
|
|
||||||
|
|
||||||
#include <glib.h>
|
#include <glib.h>
|
||||||
|
|
||||||
@ -54,9 +53,6 @@ struct oss_data {
|
|||||||
unsigned num_supported[3];
|
unsigned num_supported[3];
|
||||||
int *unsupported[3];
|
int *unsupported[3];
|
||||||
unsigned num_unsupported[3];
|
unsigned num_unsupported[3];
|
||||||
|
|
||||||
/** the mixer object associated with this output */
|
|
||||||
struct mixer *mixer;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
enum oss_support {
|
enum oss_support {
|
||||||
@ -302,8 +298,6 @@ oss_data_free(struct oss_data *od)
|
|||||||
g_free(od->unsupported[OSS_CHANNELS]);
|
g_free(od->unsupported[OSS_CHANNELS]);
|
||||||
g_free(od->unsupported[OSS_BITS]);
|
g_free(od->unsupported[OSS_BITS]);
|
||||||
|
|
||||||
mixer_free(od->mixer);
|
|
||||||
|
|
||||||
g_free(od);
|
g_free(od);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -372,7 +366,6 @@ oss_open_default(GError **error)
|
|||||||
if (ret[i] == OSS_STAT_NO_ERROR) {
|
if (ret[i] == OSS_STAT_NO_ERROR) {
|
||||||
struct oss_data *od = oss_data_new();
|
struct oss_data *od = oss_data_new();
|
||||||
od->device = default_devices[i];
|
od->device = default_devices[i];
|
||||||
od->mixer = mixer_new(&oss_mixer, NULL);
|
|
||||||
return od;
|
return od;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -412,7 +405,6 @@ oss_output_init(G_GNUC_UNUSED const struct audio_format *audio_format,
|
|||||||
if (device != NULL) {
|
if (device != NULL) {
|
||||||
struct oss_data *od = oss_data_new();
|
struct oss_data *od = oss_data_new();
|
||||||
od->device = device;
|
od->device = device;
|
||||||
od->mixer = mixer_new(&oss_mixer, param);
|
|
||||||
return od;
|
return od;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -427,14 +419,6 @@ oss_output_finish(void *data)
|
|||||||
oss_data_free(od);
|
oss_data_free(od);
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct mixer *
|
|
||||||
oss_get_mixer(void *data)
|
|
||||||
{
|
|
||||||
struct oss_data *od = data;
|
|
||||||
|
|
||||||
return od->mixer;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int
|
static int
|
||||||
oss_set_param(struct oss_data *od, unsigned param, int *value)
|
oss_set_param(struct oss_data *od, unsigned param, int *value)
|
||||||
{
|
{
|
||||||
@ -562,8 +546,6 @@ oss_output_open(void *data, struct audio_format *audio_format, GError **error)
|
|||||||
|
|
||||||
*audio_format = od->audio_format;
|
*audio_format = od->audio_format;
|
||||||
|
|
||||||
mixer_open(od->mixer);
|
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -573,7 +555,6 @@ oss_output_close(void *data)
|
|||||||
struct oss_data *od = data;
|
struct oss_data *od = data;
|
||||||
|
|
||||||
oss_close(od);
|
oss_close(od);
|
||||||
mixer_close(od->mixer);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@ -616,9 +597,9 @@ const struct audio_output_plugin oss_output_plugin = {
|
|||||||
.test_default_device = oss_output_test_default_device,
|
.test_default_device = oss_output_test_default_device,
|
||||||
.init = oss_output_init,
|
.init = oss_output_init,
|
||||||
.finish = oss_output_finish,
|
.finish = oss_output_finish,
|
||||||
.get_mixer = oss_get_mixer,
|
|
||||||
.open = oss_output_open,
|
.open = oss_output_open,
|
||||||
.close = oss_output_close,
|
.close = oss_output_close,
|
||||||
.play = oss_output_play,
|
.play = oss_output_play,
|
||||||
.cancel = oss_output_cancel,
|
.cancel = oss_output_cancel,
|
||||||
|
.mixer_plugin = &oss_mixer,
|
||||||
};
|
};
|
||||||
|
@ -19,7 +19,6 @@
|
|||||||
|
|
||||||
#include "../output_api.h"
|
#include "../output_api.h"
|
||||||
#include "mixer_list.h"
|
#include "mixer_list.h"
|
||||||
#include "mixer_control.h"
|
|
||||||
|
|
||||||
#include <glib.h>
|
#include <glib.h>
|
||||||
#include <pulse/simple.h>
|
#include <pulse/simple.h>
|
||||||
@ -29,7 +28,6 @@
|
|||||||
|
|
||||||
struct pulse_data {
|
struct pulse_data {
|
||||||
const char *name;
|
const char *name;
|
||||||
struct mixer *mixer;
|
|
||||||
|
|
||||||
pa_simple *s;
|
pa_simple *s;
|
||||||
char *server;
|
char *server;
|
||||||
@ -62,7 +60,6 @@ static void pulse_free_data(struct pulse_data *pd)
|
|||||||
g_free(pd->server);
|
g_free(pd->server);
|
||||||
g_free(pd->sink);
|
g_free(pd->sink);
|
||||||
g_free(pd);
|
g_free(pd);
|
||||||
mixer_free(pd->mixer);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void *
|
static void *
|
||||||
@ -78,8 +75,6 @@ pulse_init(G_GNUC_UNUSED const struct audio_format *audio_format,
|
|||||||
pd->sink = param != NULL
|
pd->sink = param != NULL
|
||||||
? config_dup_block_string(param, "sink", NULL) : NULL;
|
? config_dup_block_string(param, "sink", NULL) : NULL;
|
||||||
|
|
||||||
pd->mixer=mixer_new(&pulse_mixer, param);
|
|
||||||
|
|
||||||
return pd;
|
return pd;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -90,15 +85,6 @@ static void pulse_finish(void *data)
|
|||||||
pulse_free_data(pd);
|
pulse_free_data(pd);
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct mixer *
|
|
||||||
pulse_get_mixer(void *data)
|
|
||||||
{
|
|
||||||
struct pulse_data *pd = data;
|
|
||||||
|
|
||||||
return pd->mixer;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static bool pulse_test_default_device(void)
|
static bool pulse_test_default_device(void)
|
||||||
{
|
{
|
||||||
pa_simple *s;
|
pa_simple *s;
|
||||||
@ -147,7 +133,6 @@ pulse_open(void *data, struct audio_format *audio_format, GError **error_r)
|
|||||||
pa_strerror(error));
|
pa_strerror(error));
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
mixer_open(pd->mixer);
|
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -190,9 +175,9 @@ const struct audio_output_plugin pulse_plugin = {
|
|||||||
.test_default_device = pulse_test_default_device,
|
.test_default_device = pulse_test_default_device,
|
||||||
.init = pulse_init,
|
.init = pulse_init,
|
||||||
.finish = pulse_finish,
|
.finish = pulse_finish,
|
||||||
.get_mixer = pulse_get_mixer,
|
|
||||||
.open = pulse_open,
|
.open = pulse_open,
|
||||||
.play = pulse_play,
|
.play = pulse_play,
|
||||||
.cancel = pulse_cancel,
|
.cancel = pulse_cancel,
|
||||||
.close = pulse_close,
|
.close = pulse_close,
|
||||||
|
.mixer_plugin = &pulse_mixer,
|
||||||
};
|
};
|
||||||
|
@ -61,7 +61,7 @@ audio_output_disable_index(unsigned idx)
|
|||||||
ao->enabled = false;
|
ao->enabled = false;
|
||||||
idle_add(IDLE_OUTPUT);
|
idle_add(IDLE_OUTPUT);
|
||||||
|
|
||||||
mixer = ao_plugin_get_mixer(ao->plugin, ao->data);
|
mixer = ao->mixer;
|
||||||
if (mixer != NULL) {
|
if (mixer != NULL) {
|
||||||
mixer_close(mixer);
|
mixer_close(mixer);
|
||||||
idle_add(IDLE_MIXER);
|
idle_add(IDLE_MIXER);
|
||||||
|
@ -21,6 +21,7 @@
|
|||||||
#include "output_api.h"
|
#include "output_api.h"
|
||||||
#include "output_internal.h"
|
#include "output_internal.h"
|
||||||
#include "output_thread.h"
|
#include "output_thread.h"
|
||||||
|
#include "mixer_control.h"
|
||||||
|
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
@ -61,6 +62,8 @@ audio_output_open(struct audio_output *ao,
|
|||||||
const struct audio_format *audio_format,
|
const struct audio_format *audio_format,
|
||||||
const struct music_pipe *mp)
|
const struct music_pipe *mp)
|
||||||
{
|
{
|
||||||
|
bool open;
|
||||||
|
|
||||||
assert(mp != NULL);
|
assert(mp != NULL);
|
||||||
|
|
||||||
if (ao->fail_timer != NULL) {
|
if (ao->fail_timer != NULL) {
|
||||||
@ -93,10 +96,16 @@ audio_output_open(struct audio_output *ao,
|
|||||||
if (ao->thread == NULL)
|
if (ao->thread == NULL)
|
||||||
audio_output_thread_start(ao);
|
audio_output_thread_start(ao);
|
||||||
|
|
||||||
if (!ao->open)
|
open = ao->open;
|
||||||
|
if (!open) {
|
||||||
ao_command(ao, AO_COMMAND_OPEN);
|
ao_command(ao, AO_COMMAND_OPEN);
|
||||||
|
open = ao->open;
|
||||||
|
}
|
||||||
|
|
||||||
return ao->open;
|
if (open && ao->mixer != NULL)
|
||||||
|
mixer_open(ao->mixer);
|
||||||
|
|
||||||
|
return open;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
@ -139,6 +148,9 @@ void audio_output_close(struct audio_output *ao)
|
|||||||
{
|
{
|
||||||
assert(!ao->open || ao->fail_timer == NULL);
|
assert(!ao->open || ao->fail_timer == NULL);
|
||||||
|
|
||||||
|
if (ao->mixer != NULL)
|
||||||
|
mixer_close(ao->mixer);
|
||||||
|
|
||||||
if (ao->open)
|
if (ao->open)
|
||||||
ao_command(ao, AO_COMMAND_CLOSE);
|
ao_command(ao, AO_COMMAND_CLOSE);
|
||||||
else if (ao->fail_timer != NULL) {
|
else if (ao->fail_timer != NULL) {
|
||||||
@ -158,6 +170,9 @@ void audio_output_finish(struct audio_output *ao)
|
|||||||
g_thread_join(ao->thread);
|
g_thread_join(ao->thread);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (ao->mixer != NULL)
|
||||||
|
mixer_free(ao->mixer);
|
||||||
|
|
||||||
ao_plugin_finish(ao->plugin, ao->data);
|
ao_plugin_finish(ao->plugin, ao->data);
|
||||||
|
|
||||||
notify_deinit(&ao->notify);
|
notify_deinit(&ao->notify);
|
||||||
|
@ -22,6 +22,7 @@
|
|||||||
#include "output_internal.h"
|
#include "output_internal.h"
|
||||||
#include "output_list.h"
|
#include "output_list.h"
|
||||||
#include "audio_parser.h"
|
#include "audio_parser.h"
|
||||||
|
#include "mixer_control.h"
|
||||||
|
|
||||||
#include <glib.h>
|
#include <glib.h>
|
||||||
|
|
||||||
@ -134,5 +135,10 @@ audio_output_init(struct audio_output *ao, const struct config_param *param,
|
|||||||
if (ao->data == NULL)
|
if (ao->data == NULL)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
|
if (plugin->mixer_plugin != NULL)
|
||||||
|
ao->mixer = mixer_new(plugin->mixer_plugin, param);
|
||||||
|
else
|
||||||
|
ao->mixer = NULL;
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -52,6 +52,13 @@ struct audio_output {
|
|||||||
*/
|
*/
|
||||||
void *data;
|
void *data;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The #mixer object associated with this audio output device.
|
||||||
|
* May be NULL if none is available, or if software volume is
|
||||||
|
* configured.
|
||||||
|
*/
|
||||||
|
struct mixer *mixer;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This flag is true, when the audio_format of this device is
|
* This flag is true, when the audio_format of this device is
|
||||||
* configured in mpd.conf.
|
* configured in mpd.conf.
|
||||||
|
@ -66,15 +66,6 @@ struct audio_output_plugin {
|
|||||||
*/
|
*/
|
||||||
void (*finish)(void *data);
|
void (*finish)(void *data);
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns the mixer device associated with this audio output.
|
|
||||||
* This does not actually open the mixer device yet.
|
|
||||||
*
|
|
||||||
* @return the mixer object, or NULL if there is no mixer
|
|
||||||
* attached to this audio output
|
|
||||||
*/
|
|
||||||
struct mixer *(*get_mixer)(void *data);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Really open the device.
|
* Really open the device.
|
||||||
*
|
*
|
||||||
@ -125,6 +116,14 @@ struct audio_output_plugin {
|
|||||||
* for continue to pause
|
* for continue to pause
|
||||||
*/
|
*/
|
||||||
bool (*pause)(void *data);
|
bool (*pause)(void *data);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The mixer plugin associated with this output plugin. This
|
||||||
|
* may be NULL if no mixer plugin is implemented. When
|
||||||
|
* created, this mixer plugin gets the same #config_param as
|
||||||
|
* this audio output device.
|
||||||
|
*/
|
||||||
|
const struct mixer_plugin *mixer_plugin;
|
||||||
};
|
};
|
||||||
|
|
||||||
static inline bool
|
static inline bool
|
||||||
@ -150,14 +149,6 @@ ao_plugin_finish(const struct audio_output_plugin *plugin, void *data)
|
|||||||
plugin->finish(data);
|
plugin->finish(data);
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline struct mixer *
|
|
||||||
ao_plugin_get_mixer(const struct audio_output_plugin *plugin, void *data)
|
|
||||||
{
|
|
||||||
return plugin->get_mixer != NULL
|
|
||||||
? plugin->get_mixer(data)
|
|
||||||
: NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline bool
|
static inline bool
|
||||||
ao_plugin_open(const struct audio_output_plugin *plugin,
|
ao_plugin_open(const struct audio_output_plugin *plugin,
|
||||||
void *data, struct audio_format *audio_format,
|
void *data, struct audio_format *audio_format,
|
||||||
|
Loading…
Reference in New Issue
Block a user