mirror of
https://github.com/owntone/owntone-server.git
synced 2024-12-26 23:25:56 -05:00
Merge pull request #130 from chme/laudio
[laudio] Make output type for local audio configurable
This commit is contained in:
commit
76a638a277
16
configure.ac
16
configure.ac
@ -73,19 +73,21 @@ AC_ARG_ENABLE(lastfm, AS_HELP_STRING([--enable-lastfm], [enable LastFM support (
|
||||
|
||||
case "$host" in
|
||||
*-*-linux-*)
|
||||
use_alsa=true
|
||||
use_oss4=false
|
||||
;;
|
||||
*-*-kfreebsd*-*|*-*-freebsd*)
|
||||
use_alsa=false
|
||||
use_oss4=true
|
||||
;;
|
||||
esac
|
||||
|
||||
AC_ARG_WITH(oss4, AS_HELP_STRING([--with-oss4], [use OSS4 (default Linux=no, FreeBSD=yes)]),
|
||||
use_oss4=true;
|
||||
AS_IF([test "x$with_oss4" = "xyes"],[use_oss4=true],[use_oss4=false]);
|
||||
)
|
||||
|
||||
AC_ARG_WITH(alsa, AS_HELP_STRING([--with-alsa], [use ALSA (default Linux=yes, FreeBSD=no)]),
|
||||
use_oss4=false;
|
||||
AS_IF([test "x$with_alsa" = "xyes"],[use_alsa=true],[use_alsa=false]);
|
||||
)
|
||||
|
||||
AC_ARG_ENABLE(mpd, AS_HELP_STRING([--enable-mpd], [enable MPD client protocol support (default=no)]),
|
||||
@ -98,7 +100,7 @@ AM_CONDITIONAL(COND_ITUNES, test x$use_itunes = xtrue)
|
||||
AM_CONDITIONAL(COND_SPOTIFY, test x$use_spotify = xtrue)
|
||||
AM_CONDITIONAL(COND_LASTFM, test x$use_lastfm = xtrue)
|
||||
AM_CONDITIONAL(COND_OSS4, test x$use_oss4 = xtrue)
|
||||
AM_CONDITIONAL(COND_ALSA, test x$use_oss4 != xtrue)
|
||||
AM_CONDITIONAL(COND_ALSA, test x$use_alsa = xtrue)
|
||||
AM_CONDITIONAL(COND_MPD, test x$use_mpd = xtrue)
|
||||
|
||||
dnl Checks for libraries.
|
||||
@ -218,11 +220,15 @@ if test x$use_lastfm = xtrue; then
|
||||
AC_DEFINE(HAVE_MXML_GETOPAQUE, 1, [Define to 1 if your mxml has mxmlGetOpaque.]))
|
||||
fi
|
||||
|
||||
if test x$use_oss4 != xtrue; then
|
||||
if test x$use_alsa = xtrue; then
|
||||
PKG_CHECK_MODULES(ALSA, [ alsa ])
|
||||
AC_DEFINE(LAUDIO_USE_ALSA, 1, [define if local audio output uses ALSA])
|
||||
else
|
||||
CPPFLAGS="${CPPFLAGS} -DALSA"
|
||||
fi
|
||||
|
||||
if test x$use_oss4 = xtrue; then
|
||||
AC_CHECK_HEADER(sys/soundcard.h, , AC_MSG_ERROR([sys/soundcard.h not found]))
|
||||
CPPFLAGS="${CPPFLAGS} -DOSS4"
|
||||
fi
|
||||
|
||||
case "$host" in
|
||||
|
@ -139,6 +139,9 @@ library {
|
||||
audio {
|
||||
# Name - used in the speaker list in Remote
|
||||
nickname = "Computer"
|
||||
|
||||
# Type of the output (alsa, oss4, dummy)
|
||||
# type = "alsa"
|
||||
|
||||
# Audio device name for local audio output
|
||||
# card = "default"
|
||||
|
@ -115,7 +115,9 @@ forked_daapd_SOURCES = main.c \
|
||||
daap_query.c daap_query.h \
|
||||
player.c player.h \
|
||||
worker.c worker.h \
|
||||
$(ALSA_SRC) $(OSS4_SRC) laudio.h \
|
||||
$(ALSA_SRC) $(OSS4_SRC) \
|
||||
laudio_dummy.c \
|
||||
laudio.c laudio.h \
|
||||
raop.c raop.h \
|
||||
$(RTSP_SRC) \
|
||||
scan-wma.c \
|
||||
|
@ -92,6 +92,7 @@ static cfg_opt_t sec_library[] =
|
||||
static cfg_opt_t sec_audio[] =
|
||||
{
|
||||
CFG_STR("nickname", "Computer", CFGF_NONE),
|
||||
CFG_STR("type", NULL, CFGF_NONE),
|
||||
#ifdef __linux__
|
||||
CFG_STR("card", "default", CFGF_NONE),
|
||||
#elif defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
|
||||
|
155
src/laudio.c
Normal file
155
src/laudio.c
Normal file
@ -0,0 +1,155 @@
|
||||
/*
|
||||
* Copyright (C) 2015 Christian Meffert <christian.meffert@googlemail.com>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
# include <config.h>
|
||||
#endif
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
#include <stdint.h>
|
||||
#include <inttypes.h>
|
||||
|
||||
#include "conffile.h"
|
||||
#include "logger.h"
|
||||
#include "player.h"
|
||||
#include "laudio.h"
|
||||
|
||||
#ifdef ALSA
|
||||
extern audio_output audio_alsa;
|
||||
#endif
|
||||
#ifdef OSS4
|
||||
extern audio_output audio_oss4;
|
||||
#endif
|
||||
|
||||
extern audio_output audio_dummy;
|
||||
|
||||
static audio_output *outputs[] = {
|
||||
#ifdef ALSA
|
||||
&audio_alsa,
|
||||
#endif
|
||||
#ifdef OSS4
|
||||
&audio_oss4,
|
||||
#endif
|
||||
&audio_dummy,
|
||||
NULL
|
||||
};
|
||||
|
||||
static audio_output *output;
|
||||
|
||||
struct pcm_packet
|
||||
{
|
||||
uint8_t samples[STOB(AIRTUNES_V2_PACKET_SAMPLES)];
|
||||
|
||||
uint64_t rtptime;
|
||||
|
||||
size_t offset;
|
||||
|
||||
struct pcm_packet *next;
|
||||
};
|
||||
|
||||
|
||||
|
||||
void
|
||||
laudio_write(uint8_t *buf, uint64_t rtptime)
|
||||
{
|
||||
output->write(buf, rtptime);
|
||||
}
|
||||
|
||||
uint64_t
|
||||
laudio_get_pos(void)
|
||||
{
|
||||
return output->pos();
|
||||
}
|
||||
|
||||
void
|
||||
laudio_set_volume(int vol)
|
||||
{
|
||||
output->volume(vol);
|
||||
}
|
||||
|
||||
int
|
||||
laudio_start(uint64_t cur_pos, uint64_t next_pkt)
|
||||
{
|
||||
return output->start(cur_pos, next_pkt);
|
||||
}
|
||||
|
||||
void
|
||||
laudio_stop(void)
|
||||
{
|
||||
output->stop();
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
laudio_open(void)
|
||||
{
|
||||
return output->open();
|
||||
}
|
||||
|
||||
void
|
||||
laudio_close(void)
|
||||
{
|
||||
output->close();
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
laudio_init(laudio_status_cb cb)
|
||||
{
|
||||
cfg_t *cfg_audio;
|
||||
char *type;
|
||||
int i;
|
||||
|
||||
cfg_audio = cfg_getsec(cfg, "audio");
|
||||
type = cfg_getstr(cfg_audio, "type");
|
||||
|
||||
output = NULL;
|
||||
if (type)
|
||||
{
|
||||
DPRINTF(E_DBG, L_LAUDIO, "Searching for local audio output: '%s'\n", type);
|
||||
for (i = 0; outputs[i]; i++)
|
||||
{
|
||||
if (0 == strcmp(type, outputs[i]->name))
|
||||
{
|
||||
output = outputs[i];
|
||||
}
|
||||
}
|
||||
|
||||
if (!output)
|
||||
DPRINTF(E_WARN, L_LAUDIO, "No local audio output '%s' available, falling back to default output\n", type);
|
||||
}
|
||||
|
||||
if (!output)
|
||||
{
|
||||
output = outputs[0];
|
||||
}
|
||||
|
||||
DPRINTF(E_INFO, L_LAUDIO, "Local audio output: '%s'\n", output->name);
|
||||
|
||||
return output->init(cb, cfg_audio);
|
||||
}
|
||||
|
||||
void
|
||||
laudio_deinit(void)
|
||||
{
|
||||
output->deinit();
|
||||
}
|
33
src/laudio.h
33
src/laudio.h
@ -17,6 +17,39 @@ enum laudio_state
|
||||
|
||||
typedef void (*laudio_status_cb)(enum laudio_state status);
|
||||
|
||||
typedef struct
|
||||
{
|
||||
// Identifier of th audio output
|
||||
char *name;
|
||||
|
||||
// Initialization function called during startup
|
||||
int (*init)(laudio_status_cb cb, cfg_t *cfg_audio);
|
||||
|
||||
// Deinitialization function called at shutdown
|
||||
void (*deinit)(void);
|
||||
|
||||
// Function to open the output called at playback start or speaker activiation
|
||||
int (*open)(void);
|
||||
|
||||
// Function called after opening the output (during playback start or speaker activiation
|
||||
int (*start)(uint64_t cur_pos, uint64_t next_pkt);
|
||||
|
||||
// block of samples
|
||||
void (*write)(uint8_t *buf, uint64_t rtptime);
|
||||
|
||||
// Stopping audio playback
|
||||
void (*stop)(void);
|
||||
|
||||
// Closes the output
|
||||
void (*close)(void);
|
||||
|
||||
// Returns the rtptime of the packet thats is currently playing
|
||||
uint64_t (*pos)();
|
||||
|
||||
// Sets the volum for the output
|
||||
void (*volume)(int vol);
|
||||
} audio_output;
|
||||
|
||||
void
|
||||
laudio_write(uint8_t *buf, uint64_t rtptime);
|
||||
|
||||
|
@ -76,7 +76,7 @@ update_status(enum laudio_state status)
|
||||
}
|
||||
|
||||
static int
|
||||
laudio_xrun_recover(int err)
|
||||
laudio_alsa_xrun_recover(int err)
|
||||
{
|
||||
int ret;
|
||||
|
||||
@ -127,7 +127,7 @@ laudio_xrun_recover(int err)
|
||||
}
|
||||
|
||||
static int
|
||||
laudio_set_start_threshold(snd_pcm_uframes_t threshold)
|
||||
laudio_alsa_set_start_threshold(snd_pcm_uframes_t threshold)
|
||||
{
|
||||
snd_pcm_sw_params_t *sw_params;
|
||||
int ret;
|
||||
@ -172,12 +172,13 @@ laudio_set_start_threshold(snd_pcm_uframes_t threshold)
|
||||
return -1;
|
||||
}
|
||||
|
||||
void
|
||||
laudio_write(uint8_t *buf, uint64_t rtptime)
|
||||
static void
|
||||
laudio_alsa_write(uint8_t *buf, uint64_t rtptime)
|
||||
{
|
||||
struct pcm_packet *pkt;
|
||||
snd_pcm_sframes_t nsamp;
|
||||
int ret;
|
||||
snd_pcm_sframes_t delay;
|
||||
|
||||
pkt = (struct pcm_packet *)malloc(sizeof(struct pcm_packet));
|
||||
if (!pkt)
|
||||
@ -214,7 +215,7 @@ laudio_write(uint8_t *buf, uint64_t rtptime)
|
||||
else if ((pcm_status != LAUDIO_RUNNING) && (pcm_pos + pcm_buf_threshold >= pcm_start_pos))
|
||||
{
|
||||
/* Kill threshold */
|
||||
ret = laudio_set_start_threshold(0);
|
||||
ret = laudio_alsa_set_start_threshold(0);
|
||||
if (ret < 0)
|
||||
DPRINTF(E_WARN, L_LAUDIO, "Couldn't set PCM start threshold to 0 for output start\n");
|
||||
|
||||
@ -223,11 +224,23 @@ laudio_write(uint8_t *buf, uint64_t rtptime)
|
||||
|
||||
pkt = pcm_pkt_head;
|
||||
|
||||
ret = snd_pcm_delay(hdl, &delay);
|
||||
DPRINTF(E_SPAM, L_LAUDIO, "Current delay %" PRIu64 "\n", delay);
|
||||
snd_pcm_state_t pcmstate = snd_pcm_state(hdl);
|
||||
if (pcmstate == SND_PCM_STATE_RUNNING)
|
||||
{
|
||||
DPRINTF(E_SPAM, L_LAUDIO, "PCM-state == RUNNING\n");
|
||||
}
|
||||
else if (pcmstate == SND_PCM_STATE_PREPARED)
|
||||
{
|
||||
DPRINTF(E_SPAM, L_LAUDIO, "PCM-state == PREPARED\n");
|
||||
}
|
||||
|
||||
while (pkt)
|
||||
{
|
||||
if (pcm_recovery)
|
||||
{
|
||||
ret = laudio_xrun_recover(0);
|
||||
ret = laudio_alsa_xrun_recover(0);
|
||||
if ((ret == 2) && (pcm_recovery < 10))
|
||||
return;
|
||||
else
|
||||
@ -243,7 +256,7 @@ laudio_write(uint8_t *buf, uint64_t rtptime)
|
||||
nsamp = snd_pcm_writei(hdl, pkt->samples + pkt->offset, BTOS(sizeof(pkt->samples) - pkt->offset));
|
||||
if ((nsamp == -EPIPE) || (nsamp == -ESTRPIPE))
|
||||
{
|
||||
ret = laudio_xrun_recover(nsamp);
|
||||
ret = laudio_alsa_xrun_recover(nsamp);
|
||||
if ((ret < 0) || (ret == 1))
|
||||
{
|
||||
if (ret < 0)
|
||||
@ -287,8 +300,8 @@ laudio_write(uint8_t *buf, uint64_t rtptime)
|
||||
}
|
||||
}
|
||||
|
||||
uint64_t
|
||||
laudio_get_pos(void)
|
||||
static uint64_t
|
||||
laudio_alsa_get_pos(void)
|
||||
{
|
||||
snd_pcm_sframes_t delay;
|
||||
int ret;
|
||||
@ -307,8 +320,8 @@ laudio_get_pos(void)
|
||||
return pcm_pos - delay;
|
||||
}
|
||||
|
||||
void
|
||||
laudio_set_volume(int vol)
|
||||
static void
|
||||
laudio_alsa_set_volume(int vol)
|
||||
{
|
||||
int pcm_vol;
|
||||
|
||||
@ -340,8 +353,8 @@ laudio_set_volume(int vol)
|
||||
snd_mixer_selem_set_playback_volume_all(vol_elem, pcm_vol);
|
||||
}
|
||||
|
||||
int
|
||||
laudio_start(uint64_t cur_pos, uint64_t next_pkt)
|
||||
static int
|
||||
laudio_alsa_start(uint64_t cur_pos, uint64_t next_pkt)
|
||||
{
|
||||
int ret;
|
||||
|
||||
@ -353,6 +366,7 @@ laudio_start(uint64_t cur_pos, uint64_t next_pkt)
|
||||
return -1;
|
||||
}
|
||||
|
||||
DPRINTF(E_DBG, L_LAUDIO, "Start local audio curpos %" PRIu64 ", next_pkt %" PRIu64 "\n", cur_pos, next_pkt);
|
||||
DPRINTF(E_DBG, L_LAUDIO, "PCM will start after %d samples (%d packets)\n", pcm_buf_threshold, pcm_buf_threshold / AIRTUNES_V2_PACKET_SAMPLES);
|
||||
|
||||
/* Make pcm_pos the rtptime of the packet containing cur_pos */
|
||||
@ -373,7 +387,7 @@ laudio_start(uint64_t cur_pos, uint64_t next_pkt)
|
||||
pcm_last_error = 0;
|
||||
pcm_recovery = 0;
|
||||
|
||||
ret = laudio_set_start_threshold(pcm_buf_threshold);
|
||||
ret = laudio_alsa_set_start_threshold(pcm_buf_threshold);
|
||||
if (ret < 0)
|
||||
{
|
||||
DPRINTF(E_LOG, L_LAUDIO, "Could not set PCM start threshold for local audio start\n");
|
||||
@ -386,8 +400,8 @@ laudio_start(uint64_t cur_pos, uint64_t next_pkt)
|
||||
return 0;
|
||||
}
|
||||
|
||||
void
|
||||
laudio_stop(void)
|
||||
static void
|
||||
laudio_alsa_stop(void)
|
||||
{
|
||||
struct pcm_packet *pkt;
|
||||
|
||||
@ -509,8 +523,8 @@ mixer_open(void)
|
||||
return -1;
|
||||
}
|
||||
|
||||
int
|
||||
laudio_open(void)
|
||||
static int
|
||||
laudio_alsa_open(void)
|
||||
{
|
||||
snd_pcm_hw_params_t *hw_params;
|
||||
snd_pcm_uframes_t bufsize;
|
||||
@ -633,8 +647,8 @@ laudio_open(void)
|
||||
return -1;
|
||||
}
|
||||
|
||||
void
|
||||
laudio_close(void)
|
||||
static void
|
||||
laudio_alsa_close(void)
|
||||
{
|
||||
struct pcm_packet *pkt;
|
||||
|
||||
@ -664,15 +678,15 @@ laudio_close(void)
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
laudio_init(laudio_status_cb cb)
|
||||
static int
|
||||
laudio_alsa_init(laudio_status_cb cb, cfg_t *cfg_audio)
|
||||
{
|
||||
snd_lib_error_set_handler(logger_alsa);
|
||||
|
||||
status_cb = cb;
|
||||
|
||||
card_name = cfg_getstr(cfg_getsec(cfg, "audio"), "card");
|
||||
mixer_name = cfg_getstr(cfg_getsec(cfg, "audio"), "mixer");
|
||||
card_name = cfg_getstr(cfg_audio, "card");
|
||||
mixer_name = cfg_getstr(cfg_audio, "mixer");
|
||||
|
||||
hdl = NULL;
|
||||
mixer_hdl = NULL;
|
||||
@ -681,8 +695,21 @@ laudio_init(laudio_status_cb cb)
|
||||
return 0;
|
||||
}
|
||||
|
||||
void
|
||||
laudio_deinit(void)
|
||||
static void
|
||||
laudio_alsa_deinit(void)
|
||||
{
|
||||
snd_lib_error_set_handler(NULL);
|
||||
}
|
||||
|
||||
audio_output audio_alsa = {
|
||||
.name = "alsa",
|
||||
.init = &laudio_alsa_init,
|
||||
.deinit = &laudio_alsa_deinit,
|
||||
.start = &laudio_alsa_start,
|
||||
.stop = &laudio_alsa_stop,
|
||||
.open = &laudio_alsa_open,
|
||||
.close = &laudio_alsa_close,
|
||||
.pos = &laudio_alsa_get_pos,
|
||||
.write = &laudio_alsa_write,
|
||||
.volume = &laudio_alsa_set_volume,
|
||||
};
|
||||
|
158
src/laudio_dummy.c
Normal file
158
src/laudio_dummy.c
Normal file
@ -0,0 +1,158 @@
|
||||
/*
|
||||
* Copyright (C) 2015 Christian Meffert <christian.meffert@googlemail.com>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
# include <config.h>
|
||||
#endif
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
#include <stdint.h>
|
||||
#include <inttypes.h>
|
||||
|
||||
#include "conffile.h"
|
||||
#include "logger.h"
|
||||
#include "misc.h"
|
||||
#include "player.h"
|
||||
#include "laudio.h"
|
||||
|
||||
|
||||
static enum laudio_state pcm_status;
|
||||
static laudio_status_cb status_cb;
|
||||
|
||||
static struct timespec timer_res;
|
||||
static struct timespec ts;
|
||||
static uint64_t pcmpos;
|
||||
|
||||
|
||||
|
||||
static uint64_t
|
||||
laudio_dummy_get_pos(void)
|
||||
{
|
||||
struct timespec cur_timer_res;
|
||||
struct timespec cur_ts;
|
||||
uint64_t delta;
|
||||
int ret;
|
||||
|
||||
ret = clock_gettime_with_res(CLOCK_MONOTONIC, &cur_ts, &cur_timer_res);
|
||||
if (ret < 0)
|
||||
{
|
||||
DPRINTF(E_LOG, L_LAUDIO, "Couldn't get clock: %s\n", strerror(errno));
|
||||
return -1;
|
||||
}
|
||||
|
||||
delta = (cur_ts.tv_sec - ts.tv_sec) * 1000000 + (cur_ts.tv_nsec - ts.tv_nsec) / 1000;
|
||||
delta = (delta * 44100) / 1000000;
|
||||
|
||||
DPRINTF(E_DBG, L_LAUDIO, "Start: %" PRIu64 ", Pos: %" PRIu64 "\n", pcmpos, delta);
|
||||
|
||||
return (pcmpos + delta);
|
||||
}
|
||||
|
||||
static void
|
||||
laudio_dummy_write(uint8_t *buf, uint64_t rtptime)
|
||||
{
|
||||
uint64_t pos;
|
||||
|
||||
pos = laudio_dummy_get_pos();
|
||||
|
||||
if (pcm_status != LAUDIO_RUNNING && pos > (pcmpos + 88200))
|
||||
{
|
||||
pcm_status = LAUDIO_RUNNING;
|
||||
status_cb(LAUDIO_RUNNING);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
laudio_dummy_set_volume(int vol)
|
||||
{
|
||||
}
|
||||
|
||||
static int
|
||||
laudio_dummy_start(uint64_t cur_pos, uint64_t next_pkt)
|
||||
{
|
||||
int ret;
|
||||
|
||||
ret = clock_gettime_with_res(CLOCK_MONOTONIC, &ts, &timer_res);
|
||||
|
||||
if (ret < 0)
|
||||
{
|
||||
DPRINTF(E_LOG, L_LAUDIO, "Couldn't get current clock: %s\n", strerror(errno));
|
||||
return -1;
|
||||
}
|
||||
|
||||
pcmpos = cur_pos;
|
||||
|
||||
pcm_status = LAUDIO_STARTED;
|
||||
status_cb(LAUDIO_STARTED);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void
|
||||
laudio_dummy_stop(void)
|
||||
{
|
||||
pcm_status = LAUDIO_STOPPING;
|
||||
status_cb(LAUDIO_STOPPING);
|
||||
pcm_status = LAUDIO_OPEN;
|
||||
status_cb(LAUDIO_OPEN);
|
||||
}
|
||||
|
||||
static int
|
||||
laudio_dummy_open(void)
|
||||
{
|
||||
pcm_status = LAUDIO_OPEN;
|
||||
status_cb(LAUDIO_OPEN);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void
|
||||
laudio_dummy_close(void)
|
||||
{
|
||||
pcm_status = LAUDIO_CLOSED;
|
||||
status_cb(LAUDIO_CLOSED);
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
laudio_dummy_init(laudio_status_cb cb, cfg_t *cfg_audio)
|
||||
{
|
||||
status_cb = cb;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void
|
||||
laudio_dummy_deinit(void)
|
||||
{
|
||||
}
|
||||
|
||||
audio_output audio_dummy = {
|
||||
.name = "dummy",
|
||||
.init = &laudio_dummy_init,
|
||||
.deinit = &laudio_dummy_deinit,
|
||||
.start = &laudio_dummy_start,
|
||||
.stop = &laudio_dummy_stop,
|
||||
.open = &laudio_dummy_open,
|
||||
.close = &laudio_dummy_close,
|
||||
.pos = &laudio_dummy_get_pos,
|
||||
.write = &laudio_dummy_write,
|
||||
.volume = &laudio_dummy_set_volume,
|
||||
};
|
@ -73,8 +73,8 @@ update_status(enum laudio_state status)
|
||||
status_cb(status);
|
||||
}
|
||||
|
||||
void
|
||||
laudio_write(uint8_t *buf, uint64_t rtptime)
|
||||
static void
|
||||
laudio_oss4_write(uint8_t *buf, uint64_t rtptime)
|
||||
{
|
||||
struct pcm_packet *pkt;
|
||||
int scratch;
|
||||
@ -175,8 +175,8 @@ laudio_write(uint8_t *buf, uint64_t rtptime)
|
||||
}
|
||||
}
|
||||
|
||||
uint64_t
|
||||
laudio_get_pos(void)
|
||||
static uint64_t
|
||||
laudio_oss4_get_pos(void)
|
||||
{
|
||||
int delay;
|
||||
int ret;
|
||||
@ -192,8 +192,8 @@ laudio_get_pos(void)
|
||||
return pcm_pos - BTOS(delay);
|
||||
}
|
||||
|
||||
void
|
||||
laudio_set_volume(int vol)
|
||||
static void
|
||||
laudio_oss4_set_volume(int vol)
|
||||
{
|
||||
int oss_vol;
|
||||
int ret;
|
||||
@ -212,8 +212,8 @@ laudio_set_volume(int vol)
|
||||
DPRINTF(E_DBG, L_LAUDIO, "Setting PCM volume to %d (real: %d)\n", vol, (oss_vol & 0xff));
|
||||
}
|
||||
|
||||
int
|
||||
laudio_start(uint64_t cur_pos, uint64_t next_pkt)
|
||||
static int
|
||||
laudio_oss4_start(uint64_t cur_pos, uint64_t next_pkt)
|
||||
{
|
||||
int scratch;
|
||||
int ret;
|
||||
@ -251,8 +251,8 @@ laudio_start(uint64_t cur_pos, uint64_t next_pkt)
|
||||
return 0;
|
||||
}
|
||||
|
||||
void
|
||||
laudio_stop(void)
|
||||
static void
|
||||
laudio_oss4_stop(void)
|
||||
{
|
||||
struct pcm_packet *pkt;
|
||||
int ret;
|
||||
@ -276,8 +276,8 @@ laudio_stop(void)
|
||||
update_status(LAUDIO_OPEN);
|
||||
}
|
||||
|
||||
int
|
||||
laudio_open(void)
|
||||
static int
|
||||
laudio_oss4_open(void)
|
||||
{
|
||||
audio_buf_info bi;
|
||||
oss_sysinfo si;
|
||||
@ -369,8 +369,8 @@ laudio_open(void)
|
||||
return -1;
|
||||
}
|
||||
|
||||
void
|
||||
laudio_close(void)
|
||||
static void
|
||||
laudio_oss4_close(void)
|
||||
{
|
||||
struct pcm_packet *pkt;
|
||||
int ret;
|
||||
@ -396,18 +396,32 @@ laudio_close(void)
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
laudio_init(laudio_status_cb cb)
|
||||
static int
|
||||
laudio_oss4_init(laudio_status_cb cb, cfg_t *cfg_audio)
|
||||
{
|
||||
status_cb = cb;
|
||||
|
||||
card_name = cfg_getstr(cfg_getsec(cfg, "audio"), "card");
|
||||
card_name = cfg_getstr(cfg_audio, "card");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void
|
||||
laudio_deinit(void)
|
||||
static void
|
||||
laudio_oss4_deinit(void)
|
||||
{
|
||||
/* EMPTY */
|
||||
}
|
||||
|
||||
audio_output audio_oss4 = {
|
||||
.name = "oss4",
|
||||
.init = &laudio_oss4_init,
|
||||
.deinit = &laudio_oss4_deinit,
|
||||
.start = &laudio_oss4_start,
|
||||
.stop = &laudio_oss4_stop,
|
||||
.open = &laudio_oss4_open,
|
||||
.close = &laudio_oss4_close,
|
||||
.pos = &laudio_oss4_get_pos,
|
||||
.write = &laudio_oss4_write,
|
||||
.volume = &laudio_oss4_set_volume,
|
||||
};
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user