summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlfred E. Heggestad <aeh@db.org>2016-09-04 10:49:41 +0200
committerAlfred E. Heggestad <aeh@db.org>2016-09-04 10:49:41 +0200
commit8abcfeb1486a093a07360c63ea65958e3daaa57d (patch)
treee1bdfe78788ce83ff94f08d8ebc537d69bd8c561
parent1939f2d3ec202c27b43cf6c2350d0b1cd2f6933c (diff)
play: make it re-entrant, add struct player
-rw-r--r--include/baresip.h13
-rw-r--r--modules/debug_cmd/debug_cmd.c22
-rw-r--r--modules/menu/menu.c17
-rw-r--r--src/baresip.c12
-rw-r--r--src/main.c14
-rw-r--r--src/play.c64
-rw-r--r--src/ua.c3
7 files changed, 109 insertions, 36 deletions
diff --git a/include/baresip.h b/include/baresip.h
index 43b38c1..0d6271c 100644
--- a/include/baresip.h
+++ b/include/baresip.h
@@ -504,13 +504,15 @@ struct dnsc *net_dnsc(const struct network *net);
*/
struct play;
+struct player;
-int play_file(struct play **playp, const char *filename, int repeat);
-int play_tone(struct play **playp, struct mbuf *tone,
+int play_file(struct play **playp, struct player *player,
+ const char *filename, int repeat);
+int play_tone(struct play **playp, struct player *player,
+ struct mbuf *tone,
uint32_t srate, uint8_t ch, int repeat);
-void play_init(void);
-void play_close(void);
-void play_set_path(const char *path);
+int play_init(struct player **playerp);
+void play_set_path(struct player *player, const char *path);
/*
@@ -1107,6 +1109,7 @@ void baresip_close(void);
struct network *baresip_network(void);
struct contacts *baresip_contacts(void);
struct commands *baresip_commands(void);
+struct player *baresip_player(void);
#ifdef __cplusplus
diff --git a/modules/debug_cmd/debug_cmd.c b/modules/debug_cmd/debug_cmd.c
index ad3e463..4b29bb1 100644
--- a/modules/debug_cmd/debug_cmd.c
+++ b/modules/debug_cmd/debug_cmd.c
@@ -62,6 +62,27 @@ static int cmd_ua_debug(struct re_printf *pf, void *unused)
}
+static int cmd_play_file(struct re_printf *pf, void *arg)
+{
+ struct cmd_arg *carg = arg;
+ const char *filename = carg->prm;
+ int err;
+
+ err = re_hprintf(pf, "playing audio file \"%s\" ..\n", filename);
+ if (err)
+ return err;
+
+ err = play_file(NULL, baresip_player(), filename, 0);
+ if (err) {
+ warning("debug_cmd: play_file(%s) failed (%m)\n",
+ filename, err);
+ return err;
+ }
+
+ return err;
+}
+
+
static const struct cmd debugcmdv[] = {
{"main", 0, 0, "Main loop debug", re_debug },
{"config", 'g', 0, "Print configuration", cmd_config_print },
@@ -72,6 +93,7 @@ static const struct cmd debugcmdv[] = {
{"timers", 0, 0, "Timer debug", tmr_status },
{"uastat", 'u', 0, "UA debug", cmd_ua_debug },
{"memstat", 'y', 0, "Memory status", mem_status },
+{"play", 0, CMD_PRM, "Play audio file", cmd_play_file },
};
diff --git a/modules/menu/menu.c b/modules/menu/menu.c
index 0366471..66d6894 100644
--- a/modules/menu/menu.c
+++ b/modules/menu/menu.c
@@ -827,6 +827,8 @@ static void redial_handler(void *arg)
static void ua_event_handler(struct ua *ua, enum ua_event ev,
struct call *call, const char *prm, void *arg)
{
+ struct player *player = baresip_player();
+
(void)call;
(void)prm;
(void)arg;
@@ -851,12 +853,13 @@ static void ua_event_handler(struct ua *ua, enum ua_event ev,
if (ANSWERMODE_MANUAL == account_answermode(ua_account(ua))) {
if (list_count(ua_calls(ua)) > 1) {
- (void)play_file(&menu.play,
+ (void)play_file(&menu.play, player,
"callwaiting.wav", 3);
}
else {
/* Alert user */
- (void)play_file(&menu.play, "ring.wav", -1);
+ (void)play_file(&menu.play, player,
+ "ring.wav", -1);
}
if (menu.bell)
@@ -868,7 +871,7 @@ static void ua_event_handler(struct ua *ua, enum ua_event ev,
/* stop any ringtones */
menu.play = mem_deref(menu.play);
- (void)play_file(&menu.play, "ringback.wav", -1);
+ (void)play_file(&menu.play, player, "ringback.wav", -1);
break;
case UA_EVENT_CALL_ESTABLISHED:
@@ -889,8 +892,10 @@ static void ua_event_handler(struct ua *ua, enum ua_event ev,
if (call_scode(call)) {
const char *tone;
tone = translate_errorcode(call_scode(call));
- if (tone)
- (void)play_file(&menu.play, tone, 1);
+ if (tone) {
+ (void)play_file(&menu.play, player,
+ tone, 1);
+ }
}
alert_stop();
@@ -950,7 +955,7 @@ static void message_handler(const struct pl *peer, const struct pl *ctype,
(void)re_fprintf(stderr, "\r%r: \"%b\"\n", peer,
mbuf_buf(body), mbuf_get_left(body));
- (void)play_file(NULL, "message.wav", 0);
+ (void)play_file(NULL, baresip_player(), "message.wav", 0);
}
diff --git a/src/baresip.c b/src/baresip.c
index 5605136..6c68944 100644
--- a/src/baresip.c
+++ b/src/baresip.c
@@ -16,6 +16,7 @@ static struct baresip {
struct network *net;
struct contacts contacts;
struct commands commands;
+ struct player *player;
} baresip;
@@ -44,12 +45,17 @@ int baresip_init(struct config *cfg, bool prefer_ipv6)
if (err)
return err;
+ err = play_init(&baresip.player);
+ if (err)
+ return err;
+
return 0;
}
void baresip_close(void)
{
+ baresip.player = mem_deref(baresip.player);
cmd_close(&baresip.commands);
contact_close(&baresip.contacts);
@@ -73,3 +79,9 @@ struct commands *baresip_commands(void)
{
return &baresip.commands;
}
+
+
+struct player *baresip_player(void)
+{
+ return baresip.player;
+}
diff --git a/src/main.c b/src/main.c
index 85e768b..910e862 100644
--- a/src/main.c
+++ b/src/main.c
@@ -158,12 +158,6 @@ int main(int argc, char *argv[])
goto out;
}
- /* Set audio path preferring the one given in -p argument (if any) */
- if (audio_path)
- play_set_path(audio_path);
- else if (str_isset(conf_config()->audio.audio_path))
- play_set_path(conf_config()->audio.audio_path);
-
/*
* Initialise the top-level baresip struct, must be
* done AFTER configuration is complete.
@@ -174,6 +168,14 @@ int main(int argc, char *argv[])
goto out;
}
+ /* Set audio path preferring the one given in -p argument (if any) */
+ if (audio_path)
+ play_set_path(baresip_player(), audio_path);
+ else if (str_isset(conf_config()->audio.audio_path)) {
+ play_set_path(baresip_player(),
+ conf_config()->audio.audio_path);
+ }
+
/* NOTE: must be done after all arguments are processed */
if (modc) {
size_t i;
diff --git a/src/play.c b/src/play.c
index 43833f4..4c1c454 100644
--- a/src/play.c
+++ b/src/play.c
@@ -29,8 +29,13 @@ struct play {
#ifndef PREFIX
#define PREFIX "/usr"
#endif
-static char play_path[256] = PREFIX "/share/baresip";
-static struct list playl;
+static const char default_play_path[256] = PREFIX "/share/baresip";
+
+
+struct player {
+ struct list playl;
+ char play_path[256];
+};
static void tmr_polling(void *arg);
@@ -39,6 +44,7 @@ static void tmr_polling(void *arg);
static void tmr_stop(void *arg)
{
struct play *play = arg;
+ debug("play: player complete.\n");
mem_deref(play);
}
@@ -203,6 +209,7 @@ static int aufile_load(struct mbuf *mb, const char *filename,
* Play a tone from a PCM buffer
*
* @param playp Pointer to allocated player object
+ * @param player Audio-file player
* @param tone PCM buffer to play
* @param srate Sampling rate
* @param ch Number of channels
@@ -210,7 +217,8 @@ static int aufile_load(struct mbuf *mb, const char *filename,
*
* @return 0 if success, otherwise errorcode
*/
-int play_tone(struct play **playp, struct mbuf *tone, uint32_t srate,
+int play_tone(struct play **playp, struct player *player,
+ struct mbuf *tone, uint32_t srate,
uint8_t ch, int repeat)
{
struct auplay_prm wprm;
@@ -218,6 +226,8 @@ int play_tone(struct play **playp, struct mbuf *tone, uint32_t srate,
struct config *cfg;
int err;
+ if (!player)
+ return EINVAL;
if (playp && *playp)
return EALREADY;
@@ -246,7 +256,7 @@ int play_tone(struct play **playp, struct mbuf *tone, uint32_t srate,
if (err)
goto out;
- list_append(&playl, &play->le, play);
+ list_append(&player->playl, &play->le, play);
tmr_start(&play->tmr, 1000, tmr_polling, play);
out:
@@ -266,12 +276,14 @@ int play_tone(struct play **playp, struct mbuf *tone, uint32_t srate,
* Play an audio file in WAV format
*
* @param playp Pointer to allocated player object
+ * @param player Audio-file player
* @param filename Name of WAV file to play
* @param repeat Number of times to repeat
*
* @return 0 if success, otherwise errorcode
*/
-int play_file(struct play **playp, const char *filename, int repeat)
+int play_file(struct play **playp, struct player *player,
+ const char *filename, int repeat)
{
struct mbuf *mb;
char path[512];
@@ -279,11 +291,13 @@ int play_file(struct play **playp, const char *filename, int repeat)
uint8_t ch = 0;
int err;
+ if (!player)
+ return EINVAL;
if (playp && *playp)
return EALREADY;
if (re_snprintf(path, sizeof(path), "%s/%s",
- play_path, filename) < 0)
+ player->play_path, filename) < 0)
return ENOMEM;
mb = mbuf_alloc(1024);
@@ -296,7 +310,7 @@ int play_file(struct play **playp, const char *filename, int repeat)
goto out;
}
- err = play_tone(playp, mb, srate, ch, repeat);
+ err = play_tone(playp, player, mb, srate, ch, repeat);
out:
mem_deref(mb);
@@ -305,22 +319,40 @@ int play_file(struct play **playp, const char *filename, int repeat)
}
-void play_init(void)
+static void player_destructor(void *data)
{
- list_init(&playl);
+ struct player *player = data;
+
+ list_flush(&player->playl);
}
-/**
- * Close all active audio players
- */
-void play_close(void)
+int play_init(struct player **playerp)
{
- list_flush(&playl);
+ struct player *player;
+
+ if (!playerp)
+ return EINVAL;
+
+ player = mem_zalloc(sizeof(*player), player_destructor);
+ if (!player)
+ return ENOMEM;
+
+ list_init(&player->playl);
+
+ str_ncpy(player->play_path, default_play_path,
+ sizeof(player->play_path));
+
+ *playerp = player;
+
+ return 0;
}
-void play_set_path(const char *path)
+void play_set_path(struct player *player, const char *path)
{
- str_ncpy(play_path, path, sizeof(play_path));
+ if (!player)
+ return;
+
+ str_ncpy(player->play_path, path, sizeof(player->play_path));
}
diff --git a/src/ua.c b/src/ua.c
index 9df14d8..e6287fd 100644
--- a/src/ua.c
+++ b/src/ua.c
@@ -1341,8 +1341,6 @@ int ua_init(const char *software, bool udp, bool tcp, bool tls,
uag.cfg = &cfg->sip;
bsize = cfg->sip.trans_bsize;
- play_init();
-
uag.use_udp = udp;
uag.use_tcp = tcp;
uag.use_tls = tls;
@@ -1396,7 +1394,6 @@ int ua_init(const char *software, bool udp, bool tcp, bool tls,
void ua_close(void)
{
cmd_unregister(baresip_commands(), cmdv);
- play_close();
ui_reset();
uag.evsock = mem_deref(uag.evsock);