output: pass audio_format to plugin.init() and plugin.open()
Pass the globally configured audio_format as a const pointer to plugin.init(). plugin.open() gets a writable pointer which contains the audio_format requested by the plugin. Its initial value is either the configured audio_format or the input file's audio_format.
This commit is contained in:
parent
d32f49a90b
commit
3cae6856b8
@ -73,6 +73,7 @@ static void freeAlsaData(AlsaData * ad)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static int alsa_initDriver(struct audio_output *audioOutput,
|
static int alsa_initDriver(struct audio_output *audioOutput,
|
||||||
|
mpd_unused const struct audio_format *audio_format,
|
||||||
ConfigParam * param)
|
ConfigParam * param)
|
||||||
{
|
{
|
||||||
/* no need for pthread_once thread-safety when reading config */
|
/* no need for pthread_once thread-safety when reading config */
|
||||||
@ -136,10 +137,10 @@ static snd_pcm_format_t get_bitformat(const struct audio_format *af)
|
|||||||
return SND_PCM_FORMAT_UNKNOWN;
|
return SND_PCM_FORMAT_UNKNOWN;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int alsa_openDevice(struct audio_output *audioOutput)
|
static int alsa_openDevice(struct audio_output *audioOutput,
|
||||||
|
struct audio_format *audioFormat)
|
||||||
{
|
{
|
||||||
AlsaData *ad = audioOutput->data;
|
AlsaData *ad = audioOutput->data;
|
||||||
struct audio_format *audioFormat = &audioOutput->outAudioFormat;
|
|
||||||
snd_pcm_format_t bitformat;
|
snd_pcm_format_t bitformat;
|
||||||
snd_pcm_hw_params_t *hwparams;
|
snd_pcm_hw_params_t *hwparams;
|
||||||
snd_pcm_sw_params_t *swparams;
|
snd_pcm_sw_params_t *swparams;
|
||||||
|
@ -55,6 +55,7 @@ static void audioOutputAo_error(void)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static int audioOutputAo_initDriver(struct audio_output *audioOutput,
|
static int audioOutputAo_initDriver(struct audio_output *audioOutput,
|
||||||
|
mpd_unused const struct audio_format *audio_format,
|
||||||
ConfigParam * param)
|
ConfigParam * param)
|
||||||
{
|
{
|
||||||
ao_info *ai;
|
ao_info *ai;
|
||||||
@ -174,7 +175,8 @@ static void audioOutputAo_closeDevice(struct audio_output *audioOutput)
|
|||||||
audioOutput->open = 0;
|
audioOutput->open = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int audioOutputAo_openDevice(struct audio_output *audioOutput)
|
static int audioOutputAo_openDevice(struct audio_output *audioOutput,
|
||||||
|
struct audio_format *audio_format)
|
||||||
{
|
{
|
||||||
ao_sample_format format;
|
ao_sample_format format;
|
||||||
AoData *ad = (AoData *) audioOutput->data;
|
AoData *ad = (AoData *) audioOutput->data;
|
||||||
@ -183,10 +185,10 @@ static int audioOutputAo_openDevice(struct audio_output *audioOutput)
|
|||||||
audioOutputAo_closeDevice(audioOutput);
|
audioOutputAo_closeDevice(audioOutput);
|
||||||
}
|
}
|
||||||
|
|
||||||
format.bits = audioOutput->outAudioFormat.bits;
|
format.bits = audio_format->bits;
|
||||||
format.rate = audioOutput->outAudioFormat.sampleRate;
|
format.rate = audio_format->sampleRate;
|
||||||
format.byte_format = AO_FMT_NATIVE;
|
format.byte_format = AO_FMT_NATIVE;
|
||||||
format.channels = audioOutput->outAudioFormat.channels;
|
format.channels = audio_format->channels;
|
||||||
|
|
||||||
ad->device = ao_open_live(ad->driverId, &format, ad->options);
|
ad->device = ao_open_live(ad->driverId, &format, ad->options);
|
||||||
|
|
||||||
|
@ -152,6 +152,7 @@ static int openFifo(FifoData *fd)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static int fifo_initDriver(struct audio_output *audioOutput,
|
static int fifo_initDriver(struct audio_output *audioOutput,
|
||||||
|
mpd_unused const struct audio_format *audio_format,
|
||||||
ConfigParam *param)
|
ConfigParam *param)
|
||||||
{
|
{
|
||||||
FifoData *fd;
|
FifoData *fd;
|
||||||
@ -190,14 +191,15 @@ static void fifo_finishDriver(struct audio_output *audioOutput)
|
|||||||
freeFifoData(fd);
|
freeFifoData(fd);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int fifo_openDevice(struct audio_output *audioOutput)
|
static int fifo_openDevice(struct audio_output *audioOutput,
|
||||||
|
struct audio_format *audio_format)
|
||||||
{
|
{
|
||||||
FifoData *fd = (FifoData *)audioOutput->data;
|
FifoData *fd = (FifoData *)audioOutput->data;
|
||||||
|
|
||||||
if (fd->timer)
|
if (fd->timer)
|
||||||
timer_free(fd->timer);
|
timer_free(fd->timer);
|
||||||
|
|
||||||
fd->timer = timer_new(&audioOutput->outAudioFormat);
|
fd->timer = timer_new(audio_format);
|
||||||
|
|
||||||
audioOutput->open = 1;
|
audioOutput->open = 1;
|
||||||
|
|
||||||
|
@ -34,6 +34,9 @@ typedef struct _JackData {
|
|||||||
const char *output_ports[2];
|
const char *output_ports[2];
|
||||||
int ringbuf_sz;
|
int ringbuf_sz;
|
||||||
|
|
||||||
|
/* for srate() only */
|
||||||
|
struct audio_format *audio_format;
|
||||||
|
|
||||||
/* locks */
|
/* locks */
|
||||||
pthread_mutex_t play_audio_lock;
|
pthread_mutex_t play_audio_lock;
|
||||||
pthread_cond_t play_audio;
|
pthread_cond_t play_audio;
|
||||||
@ -117,7 +120,7 @@ static void jack_finishDriver(struct audio_output *audioOutput)
|
|||||||
static int srate(mpd_unused jack_nframes_t rate, void *data)
|
static int srate(mpd_unused jack_nframes_t rate, void *data)
|
||||||
{
|
{
|
||||||
JackData *jd = (JackData *) ((struct audio_output *) data)->data;
|
JackData *jd = (JackData *) ((struct audio_output *) data)->data;
|
||||||
struct audio_format *audioFormat = &(((struct audio_output *) data)->outAudioFormat);
|
struct audio_format *audioFormat = jd->audio_format;
|
||||||
|
|
||||||
audioFormat->sampleRate = (int)jack_get_sample_rate(jd->client);
|
audioFormat->sampleRate = (int)jack_get_sample_rate(jd->client);
|
||||||
|
|
||||||
@ -179,10 +182,10 @@ static void shutdown_callback(void *arg)
|
|||||||
jd->shutdown = 1;
|
jd->shutdown = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void set_audioformat(struct audio_output *audioOutput)
|
static void set_audioformat(struct audio_output *audioOutput,
|
||||||
|
struct audio_format *audioFormat)
|
||||||
{
|
{
|
||||||
JackData *jd = audioOutput->data;
|
JackData *jd = audioOutput->data;
|
||||||
struct audio_format *audioFormat = &audioOutput->outAudioFormat;
|
|
||||||
|
|
||||||
audioFormat->sampleRate = (int) jack_get_sample_rate(jd->client);
|
audioFormat->sampleRate = (int) jack_get_sample_rate(jd->client);
|
||||||
DEBUG("samplerate = %d\n", audioFormat->sampleRate);
|
DEBUG("samplerate = %d\n", audioFormat->sampleRate);
|
||||||
@ -198,7 +201,9 @@ static void error_callback(const char *msg)
|
|||||||
ERROR("jack: %s\n", msg);
|
ERROR("jack: %s\n", msg);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int jack_initDriver(struct audio_output *audioOutput, ConfigParam *param)
|
static int jack_initDriver(struct audio_output *audioOutput,
|
||||||
|
mpd_unused const struct audio_format *audio_format,
|
||||||
|
ConfigParam *param)
|
||||||
{
|
{
|
||||||
JackData *jd;
|
JackData *jd;
|
||||||
BlockParam *bp;
|
BlockParam *bp;
|
||||||
@ -264,12 +269,15 @@ static int jack_testDefault(void)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int connect_jack(struct audio_output *audioOutput)
|
static int connect_jack(struct audio_output *audioOutput,
|
||||||
|
struct audio_format *audio_format)
|
||||||
{
|
{
|
||||||
JackData *jd = audioOutput->data;
|
JackData *jd = audioOutput->data;
|
||||||
const char **jports;
|
const char **jports;
|
||||||
char *port_name;
|
char *port_name;
|
||||||
|
|
||||||
|
jd->audio_format = audio_format;
|
||||||
|
|
||||||
if ( (jd->client = jack_client_new(jd->name)) == NULL ) {
|
if ( (jd->client = jack_client_new(jd->name)) == NULL ) {
|
||||||
ERROR("jack server not running?\n");
|
ERROR("jack server not running?\n");
|
||||||
return -1;
|
return -1;
|
||||||
@ -345,19 +353,21 @@ static int connect_jack(struct audio_output *audioOutput)
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int jack_openDevice(struct audio_output *audioOutput)
|
static int jack_openDevice(struct audio_output *audioOutput,
|
||||||
|
struct audio_format *audio_format)
|
||||||
{
|
{
|
||||||
JackData *jd = audioOutput->data;
|
JackData *jd = audioOutput->data;
|
||||||
|
|
||||||
assert(jd != NULL);
|
assert(jd != NULL);
|
||||||
|
|
||||||
if (jd->client == NULL && connect_jack(audioOutput) < 0) {
|
if (jd->client == NULL && connect_jack(audioOutput,
|
||||||
|
audio_format) < 0) {
|
||||||
freeJackClient(jd);
|
freeJackClient(jd);
|
||||||
audioOutput->open = 0;
|
audioOutput->open = 0;
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
set_audioformat(audioOutput);
|
set_audioformat(audioOutput, audio_format);
|
||||||
audioOutput->open = 1;
|
audioOutput->open = 1;
|
||||||
|
|
||||||
DEBUG("jack_openDevice (pid=%d)!\n", getpid ());
|
DEBUG("jack_openDevice (pid=%d)!\n", getpid ());
|
||||||
|
@ -94,6 +94,7 @@ static int mvp_testDefault(void)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static int mvp_initDriver(struct audio_output *audioOutput,
|
static int mvp_initDriver(struct audio_output *audioOutput,
|
||||||
|
mpd_unused const struct audio_format *audio_format,
|
||||||
ConfigParam * param)
|
ConfigParam * param)
|
||||||
{
|
{
|
||||||
MvpData *md = xmalloc(sizeof(MvpData));
|
MvpData *md = xmalloc(sizeof(MvpData));
|
||||||
@ -172,11 +173,11 @@ static int mvp_setPcmParams(MvpData * md, unsigned long rate, int channels,
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int mvp_openDevice(struct audio_output *audioOutput)
|
static int mvp_openDevice(struct audio_output *audioOutput,
|
||||||
|
struct audio_format *audioFormat)
|
||||||
{
|
{
|
||||||
long long int stc = 0;
|
long long int stc = 0;
|
||||||
MvpData *md = audioOutput->data;
|
MvpData *md = audioOutput->data;
|
||||||
AudioFormat *audioFormat = &audioOutput->outAudioFormat;
|
|
||||||
int mix[5] = { 0, 2, 7, 1, 0 };
|
int mix[5] = { 0, 2, 7, 1, 0 };
|
||||||
|
|
||||||
if ((md->fd = open("/dev/adec_pcm", O_RDWR | O_NONBLOCK)) < 0) {
|
if ((md->fd = open("/dev/adec_pcm", O_RDWR | O_NONBLOCK)) < 0) {
|
||||||
|
@ -20,15 +20,17 @@
|
|||||||
#include "../timer.h"
|
#include "../timer.h"
|
||||||
|
|
||||||
static int null_initDriver(struct audio_output *audioOutput,
|
static int null_initDriver(struct audio_output *audioOutput,
|
||||||
|
mpd_unused const struct audio_format *audio_format,
|
||||||
mpd_unused ConfigParam *param)
|
mpd_unused ConfigParam *param)
|
||||||
{
|
{
|
||||||
audioOutput->data = NULL;
|
audioOutput->data = NULL;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int null_openDevice(struct audio_output *audioOutput)
|
static int null_openDevice(struct audio_output *audioOutput,
|
||||||
|
struct audio_format *audio_format)
|
||||||
{
|
{
|
||||||
audioOutput->data = timer_new(&audioOutput->outAudioFormat);
|
audioOutput->data = timer_new(audio_format);
|
||||||
audioOutput->open = 1;
|
audioOutput->open = 1;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -375,6 +375,7 @@ static int oss_open_default(mpd_unused struct audio_output *ao,
|
|||||||
}
|
}
|
||||||
|
|
||||||
static int oss_initDriver(struct audio_output *audioOutput,
|
static int oss_initDriver(struct audio_output *audioOutput,
|
||||||
|
mpd_unused const struct audio_format *audio_format,
|
||||||
ConfigParam * param)
|
ConfigParam * param)
|
||||||
{
|
{
|
||||||
OssData *od = newOssData();
|
OssData *od = newOssData();
|
||||||
@ -480,11 +481,11 @@ fail:
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int oss_openDevice(struct audio_output *audioOutput)
|
static int oss_openDevice(struct audio_output *audioOutput,
|
||||||
|
struct audio_format *audioFormat)
|
||||||
{
|
{
|
||||||
int ret;
|
int ret;
|
||||||
OssData *od = audioOutput->data;
|
OssData *od = audioOutput->data;
|
||||||
struct audio_format *audioFormat = &audioOutput->outAudioFormat;
|
|
||||||
|
|
||||||
od->channels = (mpd_sint8)audioFormat->channels;
|
od->channels = (mpd_sint8)audioFormat->channels;
|
||||||
od->sampleRate = audioFormat->sampleRate;
|
od->sampleRate = audioFormat->sampleRate;
|
||||||
|
@ -81,6 +81,7 @@ static int osx_testDefault()
|
|||||||
}
|
}
|
||||||
|
|
||||||
static int osx_initDriver(struct audio_output *audioOutput,
|
static int osx_initDriver(struct audio_output *audioOutput,
|
||||||
|
mpd_unused const struct audio_format *audio_format,
|
||||||
ConfigParam * param)
|
ConfigParam * param)
|
||||||
{
|
{
|
||||||
OsxData *od = newOsxData();
|
OsxData *od = newOsxData();
|
||||||
@ -216,13 +217,13 @@ static OSStatus osx_render(void *vdata,
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int osx_openDevice(struct audio_output *audioOutput)
|
static int osx_openDevice(struct audio_output *audioOutput,
|
||||||
|
struct audio_format *audioFormat)
|
||||||
{
|
{
|
||||||
OsxData *od = (OsxData *) audioOutput->data;
|
OsxData *od = (OsxData *) audioOutput->data;
|
||||||
ComponentDescription desc;
|
ComponentDescription desc;
|
||||||
Component comp;
|
Component comp;
|
||||||
AURenderCallbackStruct callback;
|
AURenderCallbackStruct callback;
|
||||||
AudioFormat *audioFormat = &audioOutput->outAudioFormat;
|
|
||||||
AudioStreamBasicDescription streamDesc;
|
AudioStreamBasicDescription streamDesc;
|
||||||
|
|
||||||
desc.componentType = kAudioUnitType_Output;
|
desc.componentType = kAudioUnitType_Output;
|
||||||
|
@ -62,6 +62,7 @@ static void freePulseData(PulseData * pd)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static int pulse_initDriver(struct audio_output *audioOutput,
|
static int pulse_initDriver(struct audio_output *audioOutput,
|
||||||
|
mpd_unused const struct audio_format *audio_format,
|
||||||
ConfigParam * param)
|
ConfigParam * param)
|
||||||
{
|
{
|
||||||
BlockParam *server = NULL;
|
BlockParam *server = NULL;
|
||||||
@ -109,17 +110,16 @@ static int pulse_testDefault(void)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int pulse_openDevice(struct audio_output *audioOutput)
|
static int pulse_openDevice(struct audio_output *audioOutput,
|
||||||
|
struct audio_format *audioFormat)
|
||||||
{
|
{
|
||||||
PulseData *pd;
|
PulseData *pd;
|
||||||
struct audio_format *audioFormat;
|
|
||||||
pa_sample_spec ss;
|
pa_sample_spec ss;
|
||||||
time_t t;
|
time_t t;
|
||||||
int error;
|
int error;
|
||||||
|
|
||||||
t = time(NULL);
|
t = time(NULL);
|
||||||
pd = audioOutput->data;
|
pd = audioOutput->data;
|
||||||
audioFormat = &audioOutput->outAudioFormat;
|
|
||||||
|
|
||||||
if (pd->connAttempts != 0 &&
|
if (pd->connAttempts != 0 &&
|
||||||
(t - pd->lastAttempt) < CONN_ATTEMPT_INTERVAL)
|
(t - pd->lastAttempt) < CONN_ATTEMPT_INTERVAL)
|
||||||
|
@ -88,6 +88,7 @@ static void free_shout_data(struct shout_data *sd)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static int my_shout_init_driver(struct audio_output *audio_output,
|
static int my_shout_init_driver(struct audio_output *audio_output,
|
||||||
|
const struct audio_format *audio_format,
|
||||||
ConfigParam * param)
|
ConfigParam * param)
|
||||||
{
|
{
|
||||||
struct shout_data *sd;
|
struct shout_data *sd;
|
||||||
@ -177,7 +178,9 @@ static int my_shout_init_driver(struct audio_output *audio_output,
|
|||||||
}
|
}
|
||||||
|
|
||||||
check_block_param("format");
|
check_block_param("format");
|
||||||
sd->audio_format = audio_output->reqAudioFormat;
|
|
||||||
|
assert(audio_format != NULL);
|
||||||
|
sd->audio_format = *audio_format;
|
||||||
|
|
||||||
block_param = getBlockParam(param, "encoding");
|
block_param = getBlockParam(param, "encoding");
|
||||||
if (block_param) {
|
if (block_param) {
|
||||||
@ -439,7 +442,8 @@ static int open_shout_conn(struct audio_output *audio_output)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int my_shout_open_device(struct audio_output *audio_output)
|
static int my_shout_open_device(struct audio_output *audio_output,
|
||||||
|
struct audio_format *audio_format)
|
||||||
{
|
{
|
||||||
struct shout_data *sd = (struct shout_data *) audio_output->data;
|
struct shout_data *sd = (struct shout_data *) audio_output->data;
|
||||||
|
|
||||||
@ -449,7 +453,7 @@ static int my_shout_open_device(struct audio_output *audio_output)
|
|||||||
if (sd->timer)
|
if (sd->timer)
|
||||||
timer_free(sd->timer);
|
timer_free(sd->timer);
|
||||||
|
|
||||||
sd->timer = timer_new(&audio_output->outAudioFormat);
|
sd->timer = timer_new(audio_format);
|
||||||
|
|
||||||
audio_output->open = 1;
|
audio_output->open = 1;
|
||||||
|
|
||||||
|
@ -38,11 +38,14 @@ struct audio_output_plugin {
|
|||||||
|
|
||||||
int (*test_default_device)(void);
|
int (*test_default_device)(void);
|
||||||
|
|
||||||
int (*init)(struct audio_output *ao, ConfigParam *param);
|
int (*init)(struct audio_output *ao,
|
||||||
|
const struct audio_format *audio_format,
|
||||||
|
ConfigParam *param);
|
||||||
|
|
||||||
void (*finish)(struct audio_output *ao);
|
void (*finish)(struct audio_output *ao);
|
||||||
|
|
||||||
int (*open)(struct audio_output *ao);
|
int (*open)(struct audio_output *ao,
|
||||||
|
struct audio_format *audio_format);
|
||||||
|
|
||||||
int (*play)(struct audio_output *ao,
|
int (*play)(struct audio_output *ao,
|
||||||
const char *playChunk, size_t size);
|
const char *playChunk, size_t size);
|
||||||
|
@ -102,7 +102,7 @@ int audio_output_init(struct audio_output *ao, ConfigParam * param)
|
|||||||
notify_init(&ao->notify);
|
notify_init(&ao->notify);
|
||||||
ao->command = AO_COMMAND_NONE;
|
ao->command = AO_COMMAND_NONE;
|
||||||
|
|
||||||
if (plugin->init(ao, param) != 0)
|
if (plugin->init(ao, format ? &ao->reqAudioFormat : NULL, param) != 0)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
|
@ -75,7 +75,7 @@ static void *audio_output_task(void *arg)
|
|||||||
|
|
||||||
case AO_COMMAND_OPEN:
|
case AO_COMMAND_OPEN:
|
||||||
assert(!ao->open);
|
assert(!ao->open);
|
||||||
ao->plugin->open(ao);
|
ao->plugin->open(ao, &ao->outAudioFormat);
|
||||||
ao_command_finished(ao);
|
ao_command_finished(ao);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user