Skip to content
Snippets Groups Projects
Commit f87008f1 authored by zuul's avatar zuul Committed by Gerrit Code Review
Browse files

Merge "app_mp3: Use correct buffer size and the same sample rate as the channel"

parents d3c4b901 48fd4c81
Branches
Tags 16.2.0-rc2
No related merge requests found
...@@ -77,9 +77,10 @@ ASTERISK_REGISTER_FILE() ...@@ -77,9 +77,10 @@ ASTERISK_REGISTER_FILE()
***/ ***/
static char *app = "MP3Player"; static char *app = "MP3Player";
static int mp3play(const char *filename, int fd) static int mp3play(const char *filename, unsigned int sampling_rate, int fd)
{ {
int res; int res;
char sampling_rate_str[8];
res = ast_safe_fork(0); res = ast_safe_fork(0);
if (res < 0) if (res < 0)
...@@ -93,30 +94,44 @@ static int mp3play(const char *filename, int fd) ...@@ -93,30 +94,44 @@ static int mp3play(const char *filename, int fd)
dup2(fd, STDOUT_FILENO); dup2(fd, STDOUT_FILENO);
ast_close_fds_above_n(STDERR_FILENO); ast_close_fds_above_n(STDERR_FILENO);
snprintf(sampling_rate_str, 8, "%u", sampling_rate);
/* Execute mpg123, but buffer if it's a net connection */ /* Execute mpg123, but buffer if it's a net connection */
if (!strncasecmp(filename, "http://", 7)) { if (!strncasecmp(filename, "http://", 7) && strstr(filename, ".m3u")) {
char buffer_size_str[8];
snprintf(buffer_size_str, 8, "%u", (int) 0.5*2*sampling_rate/1000); // 0.5 seconds for a live stream
/* Most commonly installed in /usr/local/bin */
execl(LOCAL_MPG_123, "mpg123", "-q", "-s", "-b", buffer_size_str, "-f", "8192", "--mono", "-r", sampling_rate_str, "-@", filename, (char *)NULL);
/* But many places has it in /usr/bin */
execl(MPG_123, "mpg123", "-q", "-s", "-b", buffer_size_str, "-f", "8192", "--mono", "-r", sampling_rate_str, "-@", filename, (char *)NULL);
/* As a last-ditch effort, try to use PATH */
execlp("mpg123", "mpg123", "-q", "-s", "-b", buffer_size_str, "-f", "8192", "--mono", "-r", sampling_rate_str, "-@", filename, (char *)NULL);
}
else if (!strncasecmp(filename, "http://", 7)) {
char buffer_size_str[8];
snprintf(buffer_size_str, 8, "%u", 6*2*sampling_rate/1000); // 6 seconds for a remote MP3 file
/* Most commonly installed in /usr/local/bin */ /* Most commonly installed in /usr/local/bin */
execl(LOCAL_MPG_123, "mpg123", "-q", "-s", "-b", "1024", "-f", "8192", "--mono", "-r", "8000", filename, (char *)NULL); execl(LOCAL_MPG_123, "mpg123", "-q", "-s", "-b", buffer_size_str, "-f", "8192", "--mono", "-r", sampling_rate_str, filename, (char *)NULL);
/* But many places has it in /usr/bin */ /* But many places has it in /usr/bin */
execl(MPG_123, "mpg123", "-q", "-s", "-b", "1024","-f", "8192", "--mono", "-r", "8000", filename, (char *)NULL); execl(MPG_123, "mpg123", "-q", "-s", "-b", buffer_size_str, "-f", "8192", "--mono", "-r", sampling_rate_str, filename, (char *)NULL);
/* As a last-ditch effort, try to use PATH */ /* As a last-ditch effort, try to use PATH */
execlp("mpg123", "mpg123", "-q", "-s", "-b", "1024", "-f", "8192", "--mono", "-r", "8000", filename, (char *)NULL); execlp("mpg123", "mpg123", "-q", "-s", "-b", buffer_size_str, "-f", "8192", "--mono", "-r", sampling_rate_str, filename, (char *)NULL);
} }
else if (strstr(filename, ".m3u")) { else if (strstr(filename, ".m3u")) {
/* Most commonly installed in /usr/local/bin */ /* Most commonly installed in /usr/local/bin */
execl(LOCAL_MPG_123, "mpg123", "-q", "-z", "-s", "-b", "1024", "-f", "8192", "--mono", "-r", "8000", "-@", filename, (char *)NULL); execl(LOCAL_MPG_123, "mpg123", "-q", "-z", "-s", "-f", "8192", "--mono", "-r", sampling_rate_str, "-@", filename, (char *)NULL);
/* But many places has it in /usr/bin */ /* But many places has it in /usr/bin */
execl(MPG_123, "mpg123", "-q", "-z", "-s", "-b", "1024","-f", "8192", "--mono", "-r", "8000", "-@", filename, (char *)NULL); execl(MPG_123, "mpg123", "-q", "-z", "-s", "-f", "8192", "--mono", "-r", sampling_rate_str, "-@", filename, (char *)NULL);
/* As a last-ditch effort, try to use PATH */ /* As a last-ditch effort, try to use PATH */
execlp("mpg123", "mpg123", "-q", "-z", "-s", "-b", "1024", "-f", "8192", "--mono", "-r", "8000", "-@", filename, (char *)NULL); execlp("mpg123", "mpg123", "-q", "-z", "-s", "-f", "8192", "--mono", "-r", sampling_rate_str, "-@", filename, (char *)NULL);
} }
else { else {
/* Most commonly installed in /usr/local/bin */ /* Most commonly installed in /usr/local/bin */
execl(MPG_123, "mpg123", "-q", "-s", "-f", "8192", "--mono", "-r", "8000", filename, (char *)NULL); execl(MPG_123, "mpg123", "-q", "-s", "-f", "8192", "--mono", "-r", sampling_rate_str, filename, (char *)NULL);
/* But many places has it in /usr/bin */ /* But many places has it in /usr/bin */
execl(LOCAL_MPG_123, "mpg123", "-q", "-s", "-f", "8192", "--mono", "-r", "8000", filename, (char *)NULL); execl(LOCAL_MPG_123, "mpg123", "-q", "-s", "-f", "8192", "--mono", "-r", sampling_rate_str, filename, (char *)NULL);
/* As a last-ditch effort, try to use PATH */ /* As a last-ditch effort, try to use PATH */
execlp("mpg123", "mpg123", "-q", "-s", "-f", "8192", "--mono", "-r", "8000", filename, (char *)NULL); execlp("mpg123", "mpg123", "-q", "-s", "-f", "8192", "--mono", "-r", sampling_rate_str, filename, (char *)NULL);
} }
/* Can't use ast_log since FD's are closed */ /* Can't use ast_log since FD's are closed */
fprintf(stderr, "Execute of mpg123 failed\n"); fprintf(stderr, "Execute of mpg123 failed\n");
...@@ -155,6 +170,9 @@ static int mp3_exec(struct ast_channel *chan, const char *data) ...@@ -155,6 +170,9 @@ static int mp3_exec(struct ast_channel *chan, const char *data)
} myf = { } myf = {
.f = { 0, }, .f = { 0, },
}; };
struct ast_format * native_format;
unsigned int sampling_rate;
struct ast_format * write_format;
if (ast_strlen_zero(data)) { if (ast_strlen_zero(data)) {
ast_log(LOG_WARNING, "MP3 Playback requires an argument (filename)\n"); ast_log(LOG_WARNING, "MP3 Playback requires an argument (filename)\n");
...@@ -168,15 +186,19 @@ static int mp3_exec(struct ast_channel *chan, const char *data) ...@@ -168,15 +186,19 @@ static int mp3_exec(struct ast_channel *chan, const char *data)
ast_stopstream(chan); ast_stopstream(chan);
native_format = ast_format_cap_get_format(ast_channel_nativeformats(chan), 0);
sampling_rate = ast_format_get_sample_rate(native_format);
write_format = ast_format_cache_get_slin_by_rate(sampling_rate);
owriteformat = ao2_bump(ast_channel_writeformat(chan)); owriteformat = ao2_bump(ast_channel_writeformat(chan));
res = ast_set_write_format(chan, ast_format_slin); res = ast_set_write_format(chan, write_format);
if (res < 0) { if (res < 0) {
ast_log(LOG_WARNING, "Unable to set write format to signed linear\n"); ast_log(LOG_WARNING, "Unable to set write format to signed linear\n");
return -1; return -1;
} }
myf.f.frametype = AST_FRAME_VOICE; myf.f.frametype = AST_FRAME_VOICE;
myf.f.subclass.format = ast_format_slin; myf.f.subclass.format = write_format;
myf.f.mallocd = 0; myf.f.mallocd = 0;
myf.f.offset = AST_FRIENDLY_OFFSET; myf.f.offset = AST_FRIENDLY_OFFSET;
myf.f.src = __PRETTY_FUNCTION__; myf.f.src = __PRETTY_FUNCTION__;
...@@ -184,7 +206,7 @@ static int mp3_exec(struct ast_channel *chan, const char *data) ...@@ -184,7 +206,7 @@ static int mp3_exec(struct ast_channel *chan, const char *data)
myf.f.delivery.tv_usec = 0; myf.f.delivery.tv_usec = 0;
myf.f.data.ptr = myf.frdata; myf.f.data.ptr = myf.frdata;
res = mp3play(data, fds[1]); res = mp3play(data, sampling_rate, fds[1]);
if (!strncasecmp(data, "http://", 7)) { if (!strncasecmp(data, "http://", 7)) {
timeout = 10000; timeout = 10000;
} }
...@@ -211,7 +233,7 @@ static int mp3_exec(struct ast_channel *chan, const char *data) ...@@ -211,7 +233,7 @@ static int mp3_exec(struct ast_channel *chan, const char *data)
res = 0; res = 0;
break; break;
} }
next = ast_tvadd(next, ast_samp2tv(myf.f.samples, 8000)); next = ast_tvadd(next, ast_samp2tv(myf.f.samples, sampling_rate));
} else { } else {
ms = ast_waitfor(chan, ms); ms = ast_waitfor(chan, ms);
if (ms < 0) { if (ms < 0) {
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment