mpg123-1.32.0

This commit is contained in:
Ozkan Sezer
2023-09-24 08:51:02 +03:00
parent 89d671ef14
commit 2279cffc0f
241 changed files with 18940 additions and 16360 deletions

View File

@@ -1,13 +1,36 @@
# Module for non-recursive mpg123 build system.
include src/libout123/modules/Makemodule.am
# Component selection:
# If HAVE_MODULES, the library can be built fully independently.
# If not, the library depends on the one builtin module from
# the subdirectory.
# For dynamic modules.
if HAVE_MODULES
if BUILD_LIBOUT123_MODULES
include src/libout123/modules/Makemodule.am
endif
endif
if NEED_MAINLIB
if BUILD_LIBOUT123
# Just for libdefaultmodule.la.
if !HAVE_MODULES
include src/libout123/modules/Makemodule.am
endif
include_HEADERS += src/libout123/out123.h
# Precursor to the proper libout123.
# For now only wrapping the module loader or the legacy module.
noinst_LTLIBRARIES += src/libout123/libmodule.la
lib_LTLIBRARIES += src/libout123/libout123.la
endif
endif
src_libout123_libout123_la_SOURCES = \
src/libout123/out123.h \
src/libout123/libout123.c \
src/libout123/stringlists.h \
src/libout123/stringlists.c \
@@ -63,9 +86,6 @@ endif
# The sfifo code is directly used in some modules.
EXTRA_DIST += \
src/libout123/out123.h.in \
src/libout123/sfifo.c \
src/libout123/sfifo.h
nodist_include_HEADERS += \
src/libout123/out123.h

View File

@@ -18,7 +18,7 @@
*/
/*
Communication to the buffer is normally via xfermem_putcmd() and blocking
Communication to the buffer is normally via INT123_xfermem_putcmd() and blocking
on a response, relying on the buffer process periodically checking for
pending commands.
@@ -78,7 +78,7 @@ static int buffer_loop(out123_handle *ao);
static void catch_child(void)
{
/* Disabled for now. We do not really need that.
Rather get return status in a controlled way in buffer_exit(). */
Rather get return status in a controlled way in INT123_buffer_exit(). */
/* while (waitpid(-1, NULL, WNOHANG) > 0); */
}
@@ -87,19 +87,19 @@ static void catch_child(void)
*/
/* Start a buffer process. */
int buffer_init(out123_handle *ao, size_t bytes)
int INT123_buffer_init(out123_handle *ao, size_t bytes)
{
buffer_exit(ao);
INT123_buffer_exit(ao);
if(bytes < outburst) bytes = 2*outburst;
#ifdef DONT_CATCH_SIGNALS
#error I really need to catch signals here!
#endif
xfermem_init(&ao->buffermem, bytes, 0, 0);
/* Is catch_child() really useful? buffer_exit() does waitpid().
And if buffer_exit() is not called, the main process might be
INT123_xfermem_init(&ao->buffermem, bytes, 0, 0);
/* Is catch_child() really useful? INT123_buffer_exit() does waitpid().
And if INT123_buffer_exit() is not called, the main process might be
killed off and not be able to run a signal handler anyway. */
catchsignal(SIGCHLD, catch_child);
INT123_catchsignal(SIGCHLD, catch_child);
switch((ao->buffer_pid = fork()))
{
case -1: /* error */
@@ -118,10 +118,10 @@ int buffer_init(out123_handle *ao, size_t bytes)
*/
ao->buffer_pid = -1;
/* Not preparing audio output anymore, that comes later. */
xfermem_init_reader(ao->buffermem);
INT123_xfermem_init_reader(ao->buffermem);
ret = buffer_loop(ao); /* Here the work happens. */
xfermem_done_reader(ao->buffermem);
xfermem_done(ao->buffermem);
INT123_xfermem_done(ao->buffermem);
/* Proper cleanup of output handle, including out123_close(). */
out123_del(ao);
exit(ret);
@@ -129,16 +129,16 @@ int buffer_init(out123_handle *ao, size_t bytes)
default: /* parent */
{
int cmd;
xfermem_init_writer(ao->buffermem);
INT123_xfermem_init_writer(ao->buffermem);
debug("waiting for inital pong from buffer process");
if( (cmd=xfermem_getcmd(ao->buffermem->fd[XF_WRITER], TRUE))
if( (cmd=INT123_xfermem_getcmd(ao->buffermem->fd[XF_WRITER], TRUE))
!= XF_CMD_PONG )
{
if(!AOQUIET)
error2("Got %i instead of expected initial response %i. Killing rogue buffer process."
, cmd, XF_CMD_PONG);
kill(ao->buffer_pid, SIGKILL);
buffer_exit(ao);
INT123_buffer_exit(ao);
return -1;
}
}
@@ -148,24 +148,24 @@ int buffer_init(out123_handle *ao, size_t bytes)
buffer_init_bad:
if(ao->buffermem)
{
xfermem_done(ao->buffermem);
INT123_xfermem_done(ao->buffermem);
ao->buffermem = NULL;
}
return -1;
}
/* End a buffer process. */
void buffer_exit(out123_handle *ao)
void INT123_buffer_exit(out123_handle *ao)
{
int status = 0;
if(ao->buffer_pid == -1) return;
debug("ending buffer");
buffer_stop(ao); /* Puts buffer into waiting-for-command mode. */
buffer_end(ao); /* Gives command to end operation. */
INT123_buffer_stop(ao); /* Puts buffer into waiting-for-command mode. */
INT123_buffer_end(ao); /* Gives command to end operation. */
xfermem_done_writer(ao->buffermem);
waitpid(ao->buffer_pid, &status, 0);
xfermem_done(ao->buffermem);
INT123_xfermem_done(ao->buffermem);
ao->buffermem = NULL;
ao->buffer_pid = -1;
if(WIFEXITED(status))
@@ -187,7 +187,7 @@ static int buffer_cmd_finish(out123_handle *ao)
{
/* Only if buffer returns XF_CMD_OK we got lucky. Otherwise, we expect
the buffer to deliver a reason right after XF_CMD_ERROR. */
switch(xfermem_getcmd(ao->buffermem->fd[XF_WRITER], TRUE))
switch(INT123_xfermem_getcmd(ao->buffermem->fd[XF_WRITER], TRUE))
{
case XF_CMD_OK: return 0;
case XF_CMD_ERROR:
@@ -242,10 +242,10 @@ static int read_parameters(out123_handle *ao
#undef GOOD_READVAL_BUF
}
int buffer_sync_param(out123_handle *ao)
int INT123_buffer_sync_param(out123_handle *ao)
{
int writerfd = ao->buffermem->fd[XF_WRITER];
if(xfermem_putcmd(writerfd, BUF_CMD_PARAM) != 1)
if(INT123_xfermem_putcmd(writerfd, BUF_CMD_PARAM) != 1)
{
ao->errcode = OUT123_BUFFER_ERROR;
return -1;
@@ -260,11 +260,11 @@ int buffer_sync_param(out123_handle *ao)
return buffer_cmd_finish(ao);
}
int buffer_open(out123_handle *ao, const char* driver, const char* device)
int INT123_buffer_open(out123_handle *ao, const char* driver, const char* device)
{
int writerfd = ao->buffermem->fd[XF_WRITER];
if(xfermem_putcmd(writerfd, BUF_CMD_OPEN) != 1)
if(INT123_xfermem_putcmd(writerfd, BUF_CMD_OPEN) != 1)
{
ao->errcode = OUT123_BUFFER_ERROR;
return -1;
@@ -287,11 +287,11 @@ int buffer_open(out123_handle *ao, const char* driver, const char* device)
return -1;
}
int buffer_encodings(out123_handle *ao)
int INT123_buffer_encodings(out123_handle *ao)
{
int writerfd = ao->buffermem->fd[XF_WRITER];
if(xfermem_putcmd(writerfd, BUF_CMD_AUDIOCAP) != 1)
if(INT123_xfermem_putcmd(writerfd, BUF_CMD_AUDIOCAP) != 1)
{
ao->errcode = OUT123_BUFFER_ERROR;
return -1;
@@ -320,16 +320,16 @@ int buffer_encodings(out123_handle *ao)
else return -1;
}
int buffer_formats( out123_handle *ao, const long *rates, int ratecount
int INT123_buffer_formats( out123_handle *ao, const long *rates, int ratecount
, int minchannels, int maxchannels
, struct mpg123_fmt **fmtlist )
{
int writerfd = ao->buffermem->fd[XF_WRITER];
size_t ratesize;
debug("buffer_formats");
debug("INT123_buffer_formats");
if(xfermem_putcmd(writerfd, BUF_CMD_AUDIOFMT) != 1)
if(INT123_xfermem_putcmd(writerfd, BUF_CMD_AUDIOFMT) != 1)
{
ao->errcode = OUT123_BUFFER_ERROR;
return -1;
@@ -362,10 +362,10 @@ int buffer_formats( out123_handle *ao, const long *rates, int ratecount
else return -1;
}
int buffer_start(out123_handle *ao)
int INT123_buffer_start(out123_handle *ao)
{
int writerfd = ao->buffermem->fd[XF_WRITER];
if(xfermem_putcmd(writerfd, BUF_CMD_START) != 1)
if(INT123_xfermem_putcmd(writerfd, BUF_CMD_START) != 1)
{
ao->errcode = OUT123_BUFFER_ERROR;
return -1;
@@ -387,40 +387,40 @@ int buffer_start(out123_handle *ao)
#define BUFFER_SIMPLE_CONTROL(name, cmd) \
void name(out123_handle *ao) \
{ \
xfermem_putcmd(ao->buffermem->fd[XF_WRITER], cmd); \
xfermem_getcmd(ao->buffermem->fd[XF_WRITER], TRUE); \
INT123_xfermem_putcmd(ao->buffermem->fd[XF_WRITER], cmd); \
INT123_xfermem_getcmd(ao->buffermem->fd[XF_WRITER], TRUE); \
}
BUFFER_SIMPLE_CONTROL(buffer_stop, BUF_CMD_STOP)
BUFFER_SIMPLE_CONTROL(buffer_continue, XF_CMD_CONTINUE)
BUFFER_SIMPLE_CONTROL(buffer_ignore_lowmem, XF_CMD_IGNLOW)
BUFFER_SIMPLE_CONTROL(buffer_drain, XF_CMD_DRAIN)
BUFFER_SIMPLE_CONTROL(buffer_end, XF_CMD_TERMINATE)
BUFFER_SIMPLE_CONTROL(buffer_close, BUF_CMD_CLOSE)
BUFFER_SIMPLE_CONTROL(INT123_buffer_stop, BUF_CMD_STOP)
BUFFER_SIMPLE_CONTROL(INT123_buffer_continue, XF_CMD_CONTINUE)
BUFFER_SIMPLE_CONTROL(INT123_buffer_ignore_lowmem, XF_CMD_IGNLOW)
BUFFER_SIMPLE_CONTROL(INT123_buffer_drain, XF_CMD_DRAIN)
BUFFER_SIMPLE_CONTROL(INT123_buffer_end, XF_CMD_TERMINATE)
BUFFER_SIMPLE_CONTROL(INT123_buffer_close, BUF_CMD_CLOSE)
#define BUFFER_SIGNAL_CONTROL(name, cmd) \
void name(out123_handle *ao) \
{ \
kill(ao->buffer_pid, SIGINT); \
xfermem_putcmd(ao->buffermem->fd[XF_WRITER], cmd); \
xfermem_getcmd(ao->buffermem->fd[XF_WRITER], TRUE); \
INT123_xfermem_putcmd(ao->buffermem->fd[XF_WRITER], cmd); \
INT123_xfermem_getcmd(ao->buffermem->fd[XF_WRITER], TRUE); \
}
BUFFER_SIGNAL_CONTROL(buffer_pause, XF_CMD_PAUSE)
BUFFER_SIGNAL_CONTROL(buffer_drop, XF_CMD_DROP)
BUFFER_SIGNAL_CONTROL(INT123_buffer_pause, XF_CMD_PAUSE)
BUFFER_SIGNAL_CONTROL(INT123_buffer_drop, XF_CMD_DROP)
size_t buffer_fill(out123_handle *ao)
size_t INT123_buffer_fill(out123_handle *ao)
{
return xfermem_get_usedspace(ao->buffermem);
return INT123_xfermem_get_usedspace(ao->buffermem);
}
void buffer_ndrain(out123_handle *ao, size_t bytes)
void INT123_buffer_ndrain(out123_handle *ao, size_t bytes)
{
size_t oldfill;
int writerfd = ao->buffermem->fd[XF_WRITER];
oldfill = buffer_fill(ao);
if(xfermem_putcmd(writerfd, BUF_CMD_NDRAIN) != 1)
oldfill = INT123_buffer_fill(ao);
if(INT123_xfermem_putcmd(writerfd, BUF_CMD_NDRAIN) != 1)
{
ao->errcode = OUT123_BUFFER_ERROR;
return;
@@ -438,7 +438,7 @@ void buffer_ndrain(out123_handle *ao, size_t bytes)
/* The workhorse: Send data to the buffer with some synchronization and even
error checking. */
size_t buffer_write(out123_handle *ao, void *buffer, size_t bytes)
size_t INT123_buffer_write(out123_handle *ao, void *buffer, size_t bytes)
{
/*
Writing the whole buffer in one piece is no good as that means
@@ -452,7 +452,7 @@ size_t buffer_write(out123_handle *ao, void *buffer, size_t bytes)
size_t count_piece = bytes > max_piece
? max_piece
: bytes;
int ret = xfermem_write(ao->buffermem
int ret = INT123_xfermem_write(ao->buffermem
, (char*)buffer+written, count_piece);
if(ret)
{
@@ -543,7 +543,7 @@ static void skip_bytes(int fd, size_t count)
while(count)
{
char buf[1024];
if(!unintr_read(fd, buf, (count < sizeof(buf) ? count : sizeof(buf))))
if(!INT123_unintr_read(fd, buf, (count < sizeof(buf) ? count : sizeof(buf))))
return;
}
}
@@ -655,10 +655,10 @@ int buffer_loop(out123_handle *ao)
ao->flags &= ~OUT123_KEEP_PLAYING; /* No need for that here. */
/* Be prepared to use SIGINT for communication. */
catchsignal (SIGINT, catch_interrupt);
INT123_catchsignal (SIGINT, catch_interrupt);
/* sigprocmask (SIG_SETMASK, oldsigset, NULL); */
/* Say hello to the writer. */
xfermem_putcmd(my_fd, XF_CMD_PONG);
INT123_xfermem_putcmd(my_fd, XF_CMD_PONG);
debug1("buffer with preload %g", ao->preload);
while(1)
@@ -666,7 +666,7 @@ int buffer_loop(out123_handle *ao)
/* If a device is opened and playing, it is our first duty to keep it playing. */
if(mystate == play_live)
{
size_t bytes = xfermem_get_usedspace(xf);
size_t bytes = INT123_xfermem_get_usedspace(xf);
debug4( "Play or preload? Got %"SIZE_P" B / %"SIZE_P" B (%i,%i)."
, (size_p)bytes, (size_p)preload_size(ao), preloading, draining );
if(preloading)
@@ -704,7 +704,7 @@ int buffer_loop(out123_handle *ao)
int cmdcount;
int i;
cmdcount = xfermem_getcmds( my_fd
cmdcount = INT123_xfermem_getcmds( my_fd
, (preloading || intflag || (mystate != play_live))
, cmd
, sizeof(cmd) );
@@ -740,10 +740,10 @@ int buffer_loop(out123_handle *ao)
/* Expecting ping-pong only while playing! Otherwise, the writer
could get stuck waiting for free space forever. */
if(mystate == play_live)
xfermem_putcmd(my_fd, XF_CMD_PONG);
INT123_xfermem_putcmd(my_fd, XF_CMD_PONG);
else
{
xfermem_putcmd(my_fd, XF_CMD_ERROR);
INT123_xfermem_putcmd(my_fd, XF_CMD_ERROR);
if(ao->errcode == OUT123_OK)
ao->errcode = OUT123_NOT_LIVE;
if(!GOOD_WRITEVAL(my_fd, ao->errcode))
@@ -756,7 +756,7 @@ int buffer_loop(out123_handle *ao)
writer will notice soon enough. */
read_parameters(ao, XF_READER, cmd, &i, cmdcount);
ao->flags &= ~OUT123_KEEP_PLAYING; /* No need for that here. */
xfermem_putcmd(my_fd, XF_CMD_OK);
INT123_xfermem_putcmd(my_fd, XF_CMD_OK);
break;
case BUF_CMD_OPEN:
{
@@ -778,7 +778,7 @@ int buffer_loop(out123_handle *ao)
mystate = ao->state;
if(success)
{
xfermem_putcmd(my_fd, XF_CMD_OK);
INT123_xfermem_putcmd(my_fd, XF_CMD_OK);
if( xfer_write_string(ao, XF_READER, ao->driver)
|| xfer_write_string(ao, XF_READER, ao->device)
|| xfer_write_string(ao, XF_READER, ao->realname )
@@ -787,7 +787,7 @@ int buffer_loop(out123_handle *ao)
}
else
{
xfermem_putcmd(my_fd, XF_CMD_ERROR);
INT123_xfermem_putcmd(my_fd, XF_CMD_ERROR);
/* Again, no sense to bitch around about communication errors,
just quit. */
if(!GOOD_WRITEVAL(my_fd, ao->errcode))
@@ -800,7 +800,7 @@ int buffer_loop(out123_handle *ao)
out123_close(ao);
draining = FALSE;
mystate = ao->state;
xfermem_putcmd(my_fd, XF_CMD_OK);
INT123_xfermem_putcmd(my_fd, XF_CMD_OK);
break;
case BUF_CMD_AUDIOCAP:
{
@@ -816,13 +816,13 @@ int buffer_loop(out123_handle *ao)
mystate = ao->state;
if(encodings >= 0)
{
xfermem_putcmd(my_fd, XF_CMD_OK);
INT123_xfermem_putcmd(my_fd, XF_CMD_OK);
if(!GOOD_WRITEVAL(my_fd, encodings))
return 2;
}
else
{
xfermem_putcmd(my_fd, XF_CMD_ERROR);
INT123_xfermem_putcmd(my_fd, XF_CMD_ERROR);
if(!GOOD_WRITEVAL(my_fd, ao->errcode))
return 2;
}
@@ -846,7 +846,7 @@ int buffer_loop(out123_handle *ao)
read_record( ao, XF_READER, (void**)&rates
, cmd, &i, cmdcount, &blocksize )
){
xfermem_putcmd(my_fd, XF_CMD_ERROR);
INT123_xfermem_putcmd(my_fd, XF_CMD_ERROR);
if(!GOOD_WRITEVAL(my_fd, ao->errcode))
return 2;
}
@@ -862,7 +862,7 @@ int buffer_loop(out123_handle *ao)
blocksize = sizeof(*fmtlist)*fmtcount;
debug2("responding with %i formats (block: %"SIZE_P")"
, fmtcount, (size_p)blocksize);
xfermem_putcmd(my_fd, XF_CMD_OK);
INT123_xfermem_putcmd(my_fd, XF_CMD_OK);
success =
GOOD_WRITEVAL(my_fd, fmtcount)
&& GOOD_WRITEVAL(my_fd, blocksize)
@@ -872,7 +872,7 @@ int buffer_loop(out123_handle *ao)
return 2;
} else
{
xfermem_putcmd(my_fd, XF_CMD_ERROR);
INT123_xfermem_putcmd(my_fd, XF_CMD_ERROR);
if(!GOOD_WRITEVAL(my_fd, ao->errcode))
return 2;
}
@@ -892,12 +892,12 @@ int buffer_loop(out123_handle *ao)
out123_pause(ao); /* Be nice, start only on buffer_play(). */
mystate = play_live;
preloading = TRUE;
xfermem_putcmd(my_fd, XF_CMD_OK);
INT123_xfermem_putcmd(my_fd, XF_CMD_OK);
}
else
{
mystate = ao->state;
xfermem_putcmd(my_fd, XF_CMD_ERROR);
INT123_xfermem_putcmd(my_fd, XF_CMD_ERROR);
if(!GOOD_WRITEVAL(my_fd, ao->errcode))
return 2;
}
@@ -907,13 +907,13 @@ int buffer_loop(out123_handle *ao)
if(mystate == play_live)
{ /* Drain is implied! */
size_t bytes;
while((bytes = xfermem_get_usedspace(xf)))
while((bytes = INT123_xfermem_get_usedspace(xf)))
buffer_play(ao, bytes);
}
out123_stop(ao);
draining = FALSE;
mystate = ao->state;
xfermem_putcmd(my_fd, XF_CMD_OK);
INT123_xfermem_putcmd(my_fd, XF_CMD_OK);
break;
case XF_CMD_CONTINUE:
intflag = FALSE;
@@ -921,12 +921,12 @@ int buffer_loop(out123_handle *ao)
mystate = play_live; /* We'll get errors reported later if that is not right. */
preloading = FALSE; /* It should continue without delay. */
draining = FALSE; /* But outburst should be cared for. */
xfermem_putcmd(my_fd, XF_CMD_OK);
INT123_xfermem_putcmd(my_fd, XF_CMD_OK);
break;
case XF_CMD_IGNLOW:
intflag = FALSE;
preloading = FALSE;
xfermem_putcmd(my_fd, XF_CMD_OK);
INT123_xfermem_putcmd(my_fd, XF_CMD_OK);
break;
case XF_CMD_DRAIN:
debug("buffer drain");
@@ -935,7 +935,7 @@ int buffer_loop(out123_handle *ao)
{
size_t bytes;
while(
(bytes = xfermem_get_usedspace(xf))
(bytes = INT123_xfermem_get_usedspace(xf))
&& bytes > ao->framesize
)
buffer_play(ao, bytes);
@@ -943,7 +943,7 @@ int buffer_loop(out123_handle *ao)
mystate = ao->state;
}
draining = FALSE;
xfermem_putcmd(my_fd, XF_CMD_OK);
INT123_xfermem_putcmd(my_fd, XF_CMD_OK);
break;
case BUF_CMD_NDRAIN:
{
@@ -964,14 +964,14 @@ int buffer_loop(out123_handle *ao)
{
size_t bytes;
while(
(bytes = xfermem_get_usedspace(xf))
(bytes = INT123_xfermem_get_usedspace(xf))
&& bytes > ao->framesize
&& oldfill >= bytes /* paranoia, overflow would handle it anyway */
&& (oldfill-bytes) < limit
)
buffer_play(ao, bytes > limit ? limit : bytes);
/* Only drain hardware if the end was reached. */
if(!xfermem_get_usedspace(xf))
if(!INT123_xfermem_get_usedspace(xf))
{
out123_drain(ao);
mystate = ao->state;
@@ -982,28 +982,28 @@ int buffer_loop(out123_handle *ao)
}
else
debug("drain without playback ... not good");
xfermem_putcmd(my_fd, XF_CMD_OK);
INT123_xfermem_putcmd(my_fd, XF_CMD_OK);
}
break;
case XF_CMD_TERMINATE:
intflag = FALSE;
/* Will that response always reach the writer? Well, at worst,
it's an ignored error on xfermem_getcmd(). */
xfermem_putcmd(my_fd, XF_CMD_OK);
it's an ignored error on INT123_xfermem_getcmd(). */
INT123_xfermem_putcmd(my_fd, XF_CMD_OK);
return 0;
case XF_CMD_PAUSE:
intflag = FALSE;
draining = FALSE;
out123_pause(ao);
mystate = ao->state;
xfermem_putcmd(my_fd, XF_CMD_OK);
INT123_xfermem_putcmd(my_fd, XF_CMD_OK);
break;
case XF_CMD_DROP:
intflag = FALSE;
draining = FALSE;
xf->readindex = xf->freeindex;
out123_drop(ao);
xfermem_putcmd(my_fd, XF_CMD_OK);
INT123_xfermem_putcmd(my_fd, XF_CMD_OK);
break;
default:
if(!AOQUIET)

View File

@@ -19,39 +19,39 @@
#include "out123_int.h"
#include "compat.h"
int buffer_init(out123_handle *ao, size_t bytes);
void buffer_exit(out123_handle *ao);
int INT123_buffer_init(out123_handle *ao, size_t bytes);
void INT123_buffer_exit(out123_handle *ao);
/* Messages with payload. */
int buffer_sync_param(out123_handle *ao);
int buffer_open(out123_handle *ao, const char* driver, const char* device);
int buffer_encodings(out123_handle *ao);
int buffer_formats( out123_handle *ao, const long *rates, int ratecount
int INT123_buffer_sync_param(out123_handle *ao);
int INT123_buffer_open(out123_handle *ao, const char* driver, const char* device);
int INT123_buffer_encodings(out123_handle *ao);
int INT123_buffer_formats( out123_handle *ao, const long *rates, int ratecount
, int minchannels, int maxchannels
, struct mpg123_fmt **fmtlist );
int buffer_start(out123_handle *ao);
void buffer_ndrain(out123_handle *ao, size_t bytes);
int INT123_buffer_start(out123_handle *ao);
void INT123_buffer_ndrain(out123_handle *ao, size_t bytes);
/* Simple messages to be deal with after playback. */
void buffer_stop(out123_handle *ao);
void buffer_close(out123_handle *ao);
void buffer_continue(out123_handle *ao);
void INT123_buffer_stop(out123_handle *ao);
void INT123_buffer_close(out123_handle *ao);
void INT123_buffer_continue(out123_handle *ao);
/* Still undecided if that one is to be used anywhere. */
void buffer_ignore_lowmem(out123_handle *ao);
void buffer_drain(out123_handle *ao);
void buffer_end(out123_handle *ao);
void INT123_buffer_ignore_lowmem(out123_handle *ao);
void INT123_buffer_drain(out123_handle *ao);
void INT123_buffer_end(out123_handle *ao);
/* Simple messages with interruption of playback. */
void buffer_pause(out123_handle *ao);
void buffer_drop(out123_handle *ao);
void INT123_buffer_pause(out123_handle *ao);
void INT123_buffer_drop(out123_handle *ao);
/* The actual work: Hand over audio data. */
size_t buffer_write(out123_handle *ao, void *buffer, size_t bytes);
size_t INT123_buffer_write(out123_handle *ao, void *buffer, size_t bytes);
/* Thin wrapper over xfermem giving the current buffer fill. */
size_t buffer_fill(out123_handle *ao);
size_t INT123_buffer_fill(out123_handle *ao);
#endif

View File

@@ -1,8 +1,8 @@
/*
hextxt: hex or printf text output (ASCII/UTF-8)
copyright 2017 by the mpg123 project
- free software under the terms of the LGPL 2.1
copyright 2017-2023 by the mpg123 project
free software under the terms of the LGPL 2.1
see COPYING and AUTHORS files in distribution or http://mpg123.org
initially written by Thomas Orgis
@@ -52,7 +52,7 @@ static FILE* open_file(const char *path)
if(!path || !strcmp("-",path) || !strcmp("",path))
return stdout;
else
return compat_fopen(path, "w");
return INT123_compat_fopen(path, "w");
}
/* Hex output defaults to what FhG compliance files used. */
@@ -93,10 +93,10 @@ int hextxt_close(out123_handle *ao)
{
FILE *fp = ao->userptr;
ao->userptr = NULL;
if(fp != stdout && compat_fclose(fp))
if(fp != stdout && INT123_compat_fclose(fp))
{
if(!AOQUIET)
error1("problem closing the output: %s\n", strerror(errno));
error1("problem closing the output: %s\n", INT123_strerror(errno));
return -1;
}
}
@@ -262,5 +262,5 @@ void hextxt_drain(out123_handle *ao)
if(!ao || !ao->userptr)
return;
if(fflush(ao->userptr) && !AOQUIET)
error1("flushing failed: %s\n", strerror(errno));
error1("flushing failed: %s\n", INT123_strerror(errno));
}

View File

@@ -16,7 +16,7 @@ extern mpg123_module_t mpg123_output_module_info;
/* Open a module */
mpg123_module_t*
open_module(const char* type, const char* name, int verbose, const char *bindir)
INT123_open_module(const char* type, const char* name, int verbose, const char *bindir)
{
mpg123_module_t *mod = NULL;
@@ -56,18 +56,18 @@ open_module(const char* type, const char* name, int verbose, const char *bindir)
}
void close_module(mpg123_module_t* module, int verbose)
void INT123_close_module(mpg123_module_t* module, int verbose)
{
debug("close_module()");
debug("INT123_close_module()");
/* Module was never really 'loaded', so nothing to do here. */
}
int list_modules(const char *type, char ***names, char ***descr, int verbose
int INT123_list_modules(const char *type, char ***names, char ***descr, int verbose
, const char *bindir)
{
debug("list_modules()" );
debug("INT123_list_modules()" );
*names = NULL;
*descr = NULL;
@@ -75,10 +75,10 @@ int list_modules(const char *type, char ***names, char ***descr, int verbose
if(
(*names=malloc(sizeof(char*)))
&& !((*names)[0]=NULL) /* for safe cleanup */
&& ((*names)[0]=compat_strdup(mpg123_output_module_info.name))
&& ((*names)[0]=INT123_compat_strdup(mpg123_output_module_info.name))
&& (*descr=malloc(sizeof(char*)))
&& !((*descr)[0]=NULL) /* for safe cleanup */
&& ((*descr)[0]=compat_strdup(mpg123_output_module_info.description))
&& ((*descr)[0]=INT123_compat_strdup(mpg123_output_module_info.description))
)
return 1;
else

View File

@@ -1,12 +1,38 @@
/*
audio: audio output interface
copyright ?-2020 by the mpg123 project - free software under the terms of the LGPL 2.1
copyright ?-2023 by the mpg123 project - free software under the terms of the LGPL 2.1
see COPYING and AUTHORS files in distribution or http://mpg123.org
initially written by Michael Hipp
*/
#define _XOPEN_SOURCE 600
#define _POSIX_C_SOURCE 200112L
#include "out123_int.h"
#ifdef HAVE_SYS_TIME_H
#include <sys/time.h>
#endif
#ifdef _WIN32
// for Sleep()
#include <windows.h>
#endif
// unistd.h sets those
#ifdef HAVE_CLOCK_GETTIME
#if _POSIX_TIMERS > 0
#include <time.h>
#ifdef _POSIX_MONSLEEP_CLOCKOTONIC_CLOCK
#define SLEEP_CLOCK CLOCK_MONOTONIC
#else
#define SLEEP_CLOCK CLOCK_REALTIME
#endif
#endif
#endif
#include "version.h"
#include "wav.h"
#include "hextxt.h"
#ifndef NOXFERMEM
@@ -20,6 +46,24 @@ static int have_buffer(out123_handle *ao)
#include "debug.h"
const char * attribute_align_arg out123_distversion(unsigned int *major, unsigned int *minor, unsigned int *patch)
{
if(major)
*major = MPG123_MAJOR;
if(minor)
*minor = MPG123_MINOR;
if(patch)
*patch = MPG123_PATCH;
return MPG123_VERSION;
}
unsigned int attribute_align_arg out123_libversion(unsigned int *patch)
{
if(patch)
*patch = OUT123_PATCHLEVEL;
return OUT123_API_VERSION;
}
/* An output that is live and does not deal with pausing itself.
The device needs to be closed if we stop feeding. */
#define SENSITIVE_OUTPUT(ao) \
@@ -84,7 +128,7 @@ out123_handle* attribute_align_arg out123_new(void)
#endif
out123_clear_module(ao);
ao->name = compat_strdup(default_name);
ao->name = INT123_compat_strdup(default_name);
ao->realname = NULL;
ao->driver = NULL;
ao->device = NULL;
@@ -113,7 +157,7 @@ void attribute_align_arg out123_del(out123_handle *ao)
out123_close(ao); /* TODO: That talks to the buffer if present. */
out123_set_buffer(ao, 0);
#ifndef NOXFERMEM
if(have_buffer(ao)) buffer_exit(ao);
if(have_buffer(ao)) INT123_buffer_exit(ao);
#endif
if(ao->name)
free(ao->name);
@@ -200,9 +244,9 @@ out123_set_buffer(out123_handle *ao, size_t buffer_bytes)
out123_close(ao);
#ifndef NOXFERMEM
if(have_buffer(ao))
buffer_exit(ao);
INT123_buffer_exit(ao);
if(buffer_bytes)
return buffer_init(ao, buffer_bytes);
return INT123_buffer_init(ao, buffer_bytes);
#endif
return 0;
}
@@ -255,12 +299,12 @@ out123_param( out123_handle *ao, enum out123_parms code
case OUT123_NAME:
if(ao->name)
free(ao->name);
ao->name = compat_strdup(svalue ? svalue : default_name);
ao->name = INT123_compat_strdup(svalue ? svalue : default_name);
break;
case OUT123_BINDIR:
if(ao->bindir)
free(ao->bindir);
ao->bindir = compat_strdup(svalue);
ao->bindir = INT123_compat_strdup(svalue);
break;
default:
ao->errcode = OUT123_BAD_PARAM;
@@ -272,7 +316,7 @@ out123_param( out123_handle *ao, enum out123_parms code
if(have_buffer(ao))
/* No error check; if that fails, buffer is dead and we will notice
soon enough. */
buffer_sync_param(ao);
INT123_buffer_sync_param(ao);
#endif
return ret;
}
@@ -353,10 +397,10 @@ out123_param_from(out123_handle *ao, out123_handle* from_ao)
ao->verbose = from_ao->verbose;
if(ao->name)
free(ao->name);
ao->name = compat_strdup(from_ao->name);
ao->name = INT123_compat_strdup(from_ao->name);
if(ao->bindir)
free(ao->bindir);
ao->bindir = compat_strdup(from_ao->bindir);
ao->bindir = INT123_compat_strdup(from_ao->bindir);
return 0;
}
@@ -382,7 +426,7 @@ out123_open(out123_handle *ao, const char* driver, const char* device)
#ifndef NOXFERMEM
if(have_buffer(ao))
{
if(buffer_open(ao, driver, device))
if(INT123_buffer_open(ao, driver, device))
return OUT123_ERR;
}
else
@@ -397,13 +441,13 @@ out123_open(out123_handle *ao, const char* driver, const char* device)
/* It is ridiculous how these error messages are larger than the pieces
of memory they are about! */
if(device && !(ao->device = compat_strdup(device)))
if(device && !(ao->device = INT123_compat_strdup(device)))
{
if(!AOQUIET) error("OOM device name copy");
return out123_seterr(ao, OUT123_DOOM);
}
if(!(modnames = compat_strdup(names)))
if(!(modnames = INT123_compat_strdup(names)))
{
out123_close(ao); /* Frees ao->device, too. */
if(!AOQUIET) error("OOM driver names");
@@ -422,7 +466,7 @@ out123_open(out123_handle *ao, const char* driver, const char* device)
if(AOVERBOSE(2))
fprintf(stderr, "Chosen output module: %s\n", curname);
/* A bit redundant, but useful when it's a fake module. */
if(!(ao->driver = compat_strdup(curname)))
if(!(ao->driver = INT123_compat_strdup(curname)))
{
out123_close(ao);
if(!AOQUIET) error("OOM driver name");
@@ -462,14 +506,14 @@ void attribute_align_arg out123_close(out123_handle *ao)
#ifndef NOXFERMEM
if(have_buffer(ao))
buffer_close(ao);
INT123_buffer_close(ao);
else
#endif
{
if(ao->deinit)
ao->deinit(ao);
if(ao->module)
close_module(ao->module, modverbose(ao, 0));
INT123_close_module(ao->module, modverbose(ao, 0));
/* Null module methods and pointer. */
out123_clear_module(ao);
}
@@ -521,7 +565,7 @@ out123_start(out123_handle *ao, long rate, int channels, int encoding)
#ifndef NOXFERMEM
if(have_buffer(ao))
{
if(!buffer_start(ao))
if(!INT123_buffer_start(ao))
{
ao->state = play_live;
return OUT123_OK;
@@ -546,7 +590,7 @@ void attribute_align_arg out123_pause(out123_handle *ao)
if(ao && ao->state == play_live)
{
#ifndef NOXFERMEM
if(have_buffer(ao)){ debug("pause with buffer"); buffer_pause(ao); }
if(have_buffer(ao)){ debug("pause with buffer"); INT123_buffer_pause(ao); }
else
#endif
{
@@ -567,7 +611,7 @@ void attribute_align_arg out123_continue(out123_handle *ao)
if(ao && ao->state == play_paused)
{
#ifndef NOXFERMEM
if(have_buffer(ao)) buffer_continue(ao);
if(have_buffer(ao)) INT123_buffer_continue(ao);
else
#endif
/* Re-open live devices to avoid underruns. */
@@ -593,7 +637,7 @@ void attribute_align_arg out123_stop(out123_handle *ao)
return;
#ifndef NOXFERMEM
if(have_buffer(ao))
buffer_stop(ao);
INT123_buffer_stop(ao);
else
#endif
if( ao->state == play_live
@@ -658,7 +702,7 @@ out123_play(out123_handle *ao, void *bytes, size_t count)
#ifndef NOXFERMEM
if(have_buffer(ao))
return buffer_write(ao, bytes, count);
return INT123_buffer_write(ao, bytes, count);
else
#endif
{
@@ -674,10 +718,10 @@ out123_play(out123_handle *ao, void *bytes, size_t count)
do /* Playback in a loop to be able to continue after interruptions. */
{
errno = 0;
int block = count > maxcount ? maxcount : count;
int block = count > (size_t)maxcount ? maxcount : (int)count;
written = ao->write(ao, bytes, block);
debug4( "written: %d errno: %i (%s), keep_on=%d"
, written, errno, strerror(errno)
, written, errno, INT123_strerror(errno)
, ao->flags & OUT123_KEEP_PLAYING );
if(written > 0)
{
@@ -698,7 +742,7 @@ out123_play(out123_handle *ao, void *bytes, size_t count)
ao->errcode = OUT123_DEV_PLAY;
if(!AOQUIET)
merror( "Error in writing audio, wrote only %d of %d (%s?)!"
, written, block, strerror(errno) );
, written, block, INT123_strerror(errno) );
/* This is a serious issue ending this playback round. */
break;
}
@@ -718,7 +762,7 @@ void attribute_align_arg out123_drop(out123_handle *ao)
ao->errcode = 0;
#ifndef NOXFERMEM
if(have_buffer(ao))
buffer_drop(ao);
INT123_buffer_drop(ao);
else
#endif
if(ao->state == play_live)
@@ -744,7 +788,7 @@ void attribute_align_arg out123_drain(out123_handle *ao)
}
#ifndef NOXFERMEM
if(have_buffer(ao))
buffer_drain(ao);
INT123_buffer_drain(ao);
else
#endif
{
@@ -770,7 +814,7 @@ void attribute_align_arg out123_ndrain(out123_handle *ao, size_t bytes)
}
#ifndef NOXFERMEM
if(have_buffer(ao))
buffer_ndrain(ao, bytes);
INT123_buffer_ndrain(ao, bytes);
else
#endif
{
@@ -812,6 +856,166 @@ static int test_close(out123_handle *ao)
return 0;
}
#ifdef SLEEP_CLOCK
// Sleep output sleeps for the proper time, but
// in a way that still allows overlap with actual
// computation, keeping this amount of milliseconds
// in a pretend buffer and returning. This has to be less
// than 1000(less than a second).
static long sleep_buf = 500;
// Otherwise, coarse sleep()ing is used.
static const long billion = 1000000000;
// zero-saturating subtraction of time, paranoid about time_t being signed
static void ts_sub_zero(struct timespec *a, const struct timespec *b)
{
long long nsec = a->tv_nsec - b->tv_nsec;
long long sec = a->tv_sec - b->tv_sec;
sec += nsec/billion;
nsec = nsec%billion;
if(nsec < 0)
{
sec -= 1;
nsec = billion+nsec;
}
if(sec < 0)
{
sec = 0;
nsec = 0;
}
a->tv_sec = (time_t)sec;
a->tv_nsec = (long)nsec;
}
static void ts_update(struct timespec *mytime)
{
struct timespec now, passed;
if(clock_gettime(SLEEP_CLOCK, &now))
{
mytime[1].tv_sec = 0;
mytime[1].tv_nsec = 0;
return;
}
passed = now;
ts_sub_zero(&passed, mytime);
mytime[0] = now;
ts_sub_zero(mytime+1, &passed);
}
#else
// Sleep coarslely. Proper operation only with clock.
static void sleep_seconds(unsigned long s)
{
#ifdef _WIN32
Sleep(s*1000);
#else
sleep(s);
#endif
}
#endif
static int sleep_open(out123_handle *ao)
{
if(!ao)
return OUT123_ERR;
if(ao->format < 0)
{
ao->rate = 44100;
ao->channels = 2;
ao->format = MPG123_ENC_SIGNED_16;
return 0;
}
if(ao->rate < 1)
return OUT123_ERR;
#ifdef SLEEP_CLOCK
// Two time counters:
// 0: last time we played something
// 1: remaining time in buffer
struct timespec *mytime = malloc(2*sizeof(struct timespec));
ao->userptr = mytime;
if(mytime)
{
mytime[0].tv_sec = 0;
mytime[0].tv_nsec = 0;
mytime[1].tv_sec = 0;
mytime[1].tv_nsec = 0;
// Check once if clock_gettime() actually works.
if(clock_gettime(SLEEP_CLOCK, mytime))
{
free(mytime);
ao->userptr = NULL;
}
}
#else
unsigned long *buffer_ms = malloc(sizeof(unsigned long));
ao->userptr = buffer_ms;
if(buffer_ms)
*buffer_ms = 0;
#endif
return (ao->userptr ? OUT123_OK : OUT123_ERR);
}
static int sleep_close(out123_handle *ao)
{
if(!ao)
return -1;
if(ao->userptr)
free(ao->userptr);
ao->userptr = NULL;
return 0;
}
static int sleep_write(out123_handle *ao, unsigned char *buf, int len)
{
if(!ao)
return -1;
double duration = (double)len/((double)ao->framesize*ao->rate);
#ifdef SLEEP_CLOCK
struct timespec *mytime = ao->userptr;
mytime[1].tv_sec += (time_t)duration;
mytime[1].tv_nsec += (long)((duration-(time_t)duration)*billion);
ts_update(mytime);
while(mytime[1].tv_sec > 0 || mytime[1].tv_nsec > sleep_buf*1000000)
{
useconds_t sleep_ms;
if(mytime[1].tv_sec > 0)
sleep_ms = 1000 - sleep_buf;
else
sleep_ms = mytime[1].tv_nsec/1000000 - sleep_buf;
usleep(sleep_ms);
ts_update(mytime);
}
#else
// Just sleep off the whole seconds;
unsigned long *ms = ao->userptr;
*ms += (unsigned long)(duration*1000);
sleep_seconds(*ms/1000);
*ms %= 1000;
#endif
return len;
}
static void sleep_drain(out123_handle *ao)
{
if(!ao || !ao->userptr)
return;
#ifdef SLEEP_CLOCK
struct timespec *mytime = ao->userptr;
ts_update(mytime);
while(mytime[1].tv_sec || mytime[1].tv_nsec)
{
usleep(mytime[1].tv_sec ? 1000000 : mytime[1].tv_nsec/1000000);
ts_update(mytime);
}
#else
unsigned long *ms = ao->userptr;
sleep_seconds(*ms/1000);
if(*ms%1000 > 500)
sleep_seconds(1);
*ms = 0;
#endif
}
/* Open one of our builtin driver modules. */
static int open_fake_module(out123_handle *ao, const char *driver)
{
@@ -826,48 +1030,60 @@ static int open_fake_module(out123_handle *ao, const char *driver)
ao->close = test_close;
}
else
if(!strcmp("sleep", driver))
{
ao->propflags |= OUT123_PROP_LIVE|OUT123_PROP_PERSISTENT;
ao->open = sleep_open;
ao->close = sleep_close;
ao->get_formats = test_get_formats;
ao->write = sleep_write;
ao->flush = builtin_nothing;
ao->drain = sleep_drain;
ao->close = sleep_close;
}
else
if(!strcmp("raw", driver))
{
ao->propflags &= ~OUT123_PROP_LIVE;
ao->open = raw_open;
ao->get_formats = raw_formats;
ao->write = wav_write;
ao->open = INT123_raw_open;
ao->get_formats = INT123_raw_formats;
ao->write = INT123_wav_write;
ao->flush = builtin_nothing;
ao->drain = wav_drain;
ao->close = raw_close;
ao->drain = INT123_wav_drain;
ao->close = INT123_raw_close;
}
else
if(!strcmp("wav", driver))
{
ao->propflags &= ~OUT123_PROP_LIVE;
ao->open = wav_open;
ao->get_formats = wav_formats;
ao->write = wav_write;
ao->open = INT123_wav_open;
ao->get_formats = INT123_wav_formats;
ao->write = INT123_wav_write;
ao->flush = builtin_nothing;
ao->drain = wav_drain;
ao->close = wav_close;
ao->drain = INT123_wav_drain;
ao->close = INT123_wav_close;
}
else
if(!strcmp("cdr", driver))
{
ao->propflags &= ~OUT123_PROP_LIVE;
ao->open = cdr_open;
ao->get_formats = cdr_formats;
ao->write = wav_write;
ao->open = INT123_cdr_open;
ao->get_formats = INT123_cdr_formats;
ao->write = INT123_wav_write;
ao->flush = builtin_nothing;
ao->drain = wav_drain;
ao->close = raw_close;
ao->drain = INT123_wav_drain;
ao->close = INT123_raw_close;
}
else
if(!strcmp("au", driver))
{
ao->propflags &= ~OUT123_PROP_LIVE;
ao->open = au_open;
ao->get_formats = au_formats;
ao->write = wav_write;
ao->open = INT123_au_open;
ao->get_formats = INT123_au_formats;
ao->write = INT123_wav_write;
ao->flush = builtin_nothing;
ao->drain = wav_drain;
ao->close = au_close;
ao->drain = INT123_wav_drain;
ao->close = INT123_au_close;
}
else
if(!strcmp("hex", driver))
@@ -913,7 +1129,7 @@ static void check_output_module( out123_handle *ao
return;
/* Open the module, initial check for availability+libraries. */
ao->module = open_module( "output", name, modverbose(ao, final), ao->bindir);
ao->module = INT123_open_module( "output", name, modverbose(ao, final), ao->bindir);
if(!ao->module)
return;
/* Check if module supports output */
@@ -959,7 +1175,7 @@ static void check_output_module( out123_handle *ao
check_output_module_cleanup:
/* Only if module did not check out we get to clean up here. */
close_module(ao->module, modverbose(ao, final));
INT123_close_module(ao->module, modverbose(ao, final));
out123_clear_module(ao);
return;
}
@@ -991,8 +1207,8 @@ out123_drivers(out123_handle *ao, char ***names, char ***descr)
/* Wrap the call to isolate the lower levels from the user not being
interested in both lists. it's a bit wasteful, but the code looks
ugly enough already down there. */
count = list_modules("output", &tmpnames, &tmpdescr, modverbose(ao, 0), ao->bindir);
debug1("list_modules()=%i", count);
count = INT123_list_modules("output", &tmpnames, &tmpdescr, modverbose(ao, 0), ao->bindir);
debug1("INT123_list_modules()=%i", count);
if(count < 0)
{
if(!AOQUIET)
@@ -1001,19 +1217,21 @@ out123_drivers(out123_handle *ao, char ***names, char ***descr)
}
if(
stringlists_add( &tmpnames, &tmpdescr
INT123_stringlists_add( &tmpnames, &tmpdescr
, "raw", "raw headerless stream (builtin)", &count )
|| stringlists_add( &tmpnames, &tmpdescr
|| INT123_stringlists_add( &tmpnames, &tmpdescr
, "cdr", "compact disc digital audio stream (builtin)", &count )
|| stringlists_add( &tmpnames, &tmpdescr
|| INT123_stringlists_add( &tmpnames, &tmpdescr
, "wav", "RIFF WAVE file (builtin)", &count )
|| stringlists_add( &tmpnames, &tmpdescr
|| INT123_stringlists_add( &tmpnames, &tmpdescr
, "au", "Sun AU file (builtin)", &count )
|| stringlists_add( &tmpnames, &tmpdescr
|| INT123_stringlists_add( &tmpnames, &tmpdescr
, "test", "output into the void (builtin)", &count )
|| stringlists_add( &tmpnames, &tmpdescr
|| INT123_stringlists_add( &tmpnames, &tmpdescr
, "sleep", "output into the void that takes its time (builtin)", &count )
|| INT123_stringlists_add( &tmpnames, &tmpdescr
, "hex", "interleaved hex printout (builtin)", &count )
|| stringlists_add( &tmpnames, &tmpdescr
|| INT123_stringlists_add( &tmpnames, &tmpdescr
, "txt", "plain text printout, a column per channel (builtin)", &count )
)
if(!AOQUIET)
@@ -1045,7 +1263,7 @@ static int devlist_add(void *dll, const char *name, const char *descr)
{
struct devlist *dl = (struct devlist*)dll;
return dl
? stringlists_add(&(dl->names), &(dl->descr), name, descr, &(dl->count))
? INT123_stringlists_add(&(dl->names), &(dl->descr), name, descr, &(dl->count))
: -1;
}
@@ -1067,14 +1285,14 @@ int out123_devices( out123_handle *ao, const char *driver, char ***names, char *
// If the driver is a single word, not a list with commas.
// Then don't try to open drivers just to know which we are talking about.
if(driver && strchr(driver, ',') == NULL)
realdrv = compat_strdup(driver);
realdrv = INT123_compat_strdup(driver);
else
{
mdebug("need to find a driver from: %s", driver ? driver : DEFAULT_OUTPUT_MODULE);
if(out123_open(ao, driver, NULL) != OUT123_OK)
return out123_seterr(ao, OUT123_BAD_DRIVER);
mdebug("deduced driver: %s", ao->driver);
realdrv = compat_strdup(ao->driver);
realdrv = INT123_compat_strdup(ao->driver);
}
if(realdrv == NULL)
return out123_seterr(ao, OUT123_DOOM);
@@ -1083,7 +1301,7 @@ int out123_devices( out123_handle *ao, const char *driver, char ***names, char *
if(open_fake_module(ao, realdrv) != OUT123_OK)
{
ao->module = open_module( "output", realdrv
ao->module = INT123_open_module( "output", realdrv
, modverbose(ao, 0), ao->bindir );
/* Open the module, initial check for availability+libraries. */
if( !ao->module || !ao->module->init_output
@@ -1121,7 +1339,7 @@ int out123_devices( out123_handle *ao, const char *driver, char ***names, char *
free(realdrv);
if(ao->module)
close_module(ao->module, modverbose(ao, 0));
INT123_close_module(ao->module, modverbose(ao, 0));
out123_clear_module(ao);
return ret;
}
@@ -1163,7 +1381,7 @@ out123_encodings(out123_handle *ao, long rate, int channels)
ao->rate = rate;
#ifndef NOXFERMEM
if(have_buffer(ao))
return buffer_encodings(ao);
return INT123_buffer_encodings(ao);
else
#endif
{
@@ -1219,7 +1437,7 @@ out123_formats( out123_handle *ao, const long *rates, int ratecount
#ifndef NOXFERMEM
if(have_buffer(ao))
return buffer_formats( ao, rates, ratecount
return INT123_buffer_formats( ao, rates, ratecount
, minchannels, maxchannels, fmtlist );
else
#endif
@@ -1288,7 +1506,7 @@ size_t attribute_align_arg out123_buffered(out123_handle *ao)
#ifndef NOXFERMEM
if(have_buffer(ao))
{
size_t fill = buffer_fill(ao);
size_t fill = INT123_buffer_fill(ao);
debug2("out123_buffered(%p) = %"SIZE_P, (void*)ao, (size_p)fill);
return fill;
}

View File

@@ -1,7 +1,7 @@
/*
module.c: modular code loader
copyright 1995-2015 by the mpg123 project - free software under the terms of the LGPL 2.1
copyright 1995-2023 by the mpg123 project - free software under the terms of the LGPL 2.1
see COPYING and AUTHORS files in distribution or http://mpg123.org
initially written by Nicholas J Humfrey
*/
@@ -10,7 +10,6 @@
#define _DEFAULT_SOURCE
#define _BSD_SOURCE
#include "config.h"
#include "intsym.h"
#include "stringlists.h"
#include "compat.h"
#include <errno.h>
@@ -42,12 +41,12 @@ static char *get_module_dir(int verbose, const char* bindir)
char *moddir = NULL;
char *defaultdir;
/* First the environment override, then relative to bindir, then installation prefix. */
defaultdir = compat_getenv("MPG123_MODDIR");
defaultdir = INT123_compat_getenv("MPG123_MODDIR");
if(defaultdir)
{
if(verbose > 1)
fprintf(stderr, "Trying module directory from environment: %s\n", defaultdir);
if(compat_isdir(defaultdir))
if(INT123_compat_isdir(defaultdir))
moddir = defaultdir;
else
free(defaultdir);
@@ -61,12 +60,12 @@ static char *get_module_dir(int verbose, const char* bindir)
fprintf(stderr, "Module dir search relative to: %s\n", bindir);
for(i=0; i<sizeof(modulesearch)/sizeof(char*); ++i)
{
moddir = compat_catpath(bindir, modulesearch[i]);
moddir = INT123_compat_catpath(bindir, modulesearch[i]);
if(!moddir)
continue;
if(verbose > 1)
fprintf(stderr, "Looking for module dir: %s\n", moddir);
if(compat_isdir(moddir))
if(INT123_compat_isdir(moddir))
break; /* found it! */
else
{
@@ -77,11 +76,11 @@ static char *get_module_dir(int verbose, const char* bindir)
}
if(!moddir) /* Resort to installation prefix. */
{
if(compat_isdir(PKGLIBDIR))
if(INT123_compat_isdir(PKGLIBDIR))
{
if(verbose > 1)
fprintf(stderr, "Using default module dir: %s\n", PKGLIBDIR);
moddir = compat_strdup(PKGLIBDIR);
moddir = INT123_compat_strdup(PKGLIBDIR);
}
}
}
@@ -109,11 +108,11 @@ mpg123_module_t* open_module_here( const char *dir, const char* type
if(!module_file)
{
if(verbose > -1)
error1( "Failed to allocate memory for module name: %s", strerror(errno) );
error1( "Failed to allocate memory for module name: %s", INT123_strerror(errno) );
return NULL;
}
snprintf(module_file, module_file_len, "%s_%s%s", type, name, LT_MODULE_EXT);
module_path = compat_catpath(dir, module_file);
module_path = INT123_compat_catpath(dir, module_file);
free(module_file);
if(!module_path)
{
@@ -125,7 +124,7 @@ mpg123_module_t* open_module_here( const char *dir, const char* type
fprintf(stderr, "Module path: %s\n", module_path );
/* Open the module */
handle = compat_dlopen(module_path);
handle = INT123_compat_dlopen(module_path);
free(module_path);
if (handle==NULL)
{
@@ -141,14 +140,14 @@ mpg123_module_t* open_module_here( const char *dir, const char* type
module_symbol = malloc(module_symbol_len);
if (module_symbol == NULL) {
if(verbose > -1)
error1( "Failed to allocate memory for module symbol: %s", strerror(errno) );
error1( "Failed to allocate memory for module symbol: %s", INT123_strerror(errno) );
return NULL;
}
snprintf( module_symbol, module_symbol_len, "%s%s%s", MODULE_SYMBOL_PREFIX, type, MODULE_SYMBOL_SUFFIX );
debug1( "Module symbol: %s", module_symbol );
/* Get the information structure from the module */
module = (mpg123_module_t*)compat_dlsym(handle, module_symbol);
module = (mpg123_module_t*)INT123_compat_dlsym(handle, module_symbol);
free( module_symbol );
if (module==NULL) {
if(verbose > -1)
@@ -161,7 +160,7 @@ mpg123_module_t* open_module_here( const char *dir, const char* type
{
if(verbose > -1)
error2( "API version of module does not match (got %i, expected %i).", module->api_version, MPG123_MODULE_API_VERSION);
compat_dlclose(handle);
INT123_compat_dlclose(handle);
return NULL;
}
@@ -172,7 +171,7 @@ mpg123_module_t* open_module_here( const char *dir, const char* type
/* Open a module, including directory search. */
mpg123_module_t* open_module( const char* type, const char* name, int verbose
mpg123_module_t* INT123_open_module( const char* type, const char* name, int verbose
, const char* bindir )
{
mpg123_module_t *module = NULL;
@@ -192,12 +191,12 @@ mpg123_module_t* open_module( const char* type, const char* name, int verbose
return module;
}
void close_module( mpg123_module_t* module, int verbose )
void INT123_close_module( mpg123_module_t* module, int verbose )
{
compat_dlclose(module->handle);
INT123_compat_dlclose(module->handle);
}
int list_modules( const char *type, char ***names, char ***descr, int verbose
int INT123_list_modules( const char *type, char ***names, char ***descr, int verbose
, const char* bindir )
{
char *moddir = NULL;
@@ -220,16 +219,16 @@ int list_modules( const char *type, char ***names, char ***descr, int verbose
debug1("module dir: %s", moddir);
/* Open the module directory */
dir = compat_diropen(moddir);
dir = INT123_compat_diropen(moddir);
if (dir==NULL) {
if(verbose > -1)
error2("Failed to open the module directory (%s): %s\n"
, moddir, strerror(errno));
, moddir, INT123_strerror(errno));
free(moddir);
return -1;
}
while((filename=compat_nextfile(dir)))
while((filename=INT123_compat_nextfile(dir)))
{
/* Pointers to the pieces. */
char *module_name = NULL;
@@ -286,17 +285,17 @@ int list_modules( const char *type, char ***names, char ***descr, int verbose
Yes, this re-builds the file name we chopped to pieces just now. */
if((module=open_module_here(moddir, module_type, module_name, verbose)))
{
if( stringlists_add( names, descr
if( INT123_stringlists_add( names, descr
, module->name, module->description, &count) )
if(verbose > -1)
error("OOM");
/* Close the module again */
close_module(module, verbose);
INT123_close_module(module, verbose);
}
list_modules_continue:
free(filename);
}
compat_dirclose(dir);
INT123_compat_dirclose(dir);
return count;
}

View File

@@ -35,10 +35,10 @@ typedef struct mpg123_module_struct {
/* ------ Declarations from "module.c" ------ */
mpg123_module_t* open_module( const char* type, const char* name, int verbose
mpg123_module_t* INT123_open_module( const char* type, const char* name, int verbose
, const char* bindir );
void close_module(mpg123_module_t* module, int verbose);
int list_modules( const char *type, char ***names, char ***descr, int verbose
void INT123_close_module(mpg123_module_t* module, int verbose);
int INT123_list_modules( const char *type, char ***names, char ***descr, int verbose
, const char* bindir );
#endif

View File

@@ -15,7 +15,7 @@
* CC=cc \
* LDFLAGS=-L/opt/audio/lib \
* AUDIO_LIB=-lAlib \
* OBJECTS=decode.o dct64.o \
* OBJECTS=decode.o INT123_dct64.o \
* CFLAGS=-Ae +O3 -DREAL_IS_FLOAT -D_HPUX_SOURCE -DHPUX -I/opt/audio/include \
* mpg123
*/

View File

@@ -305,7 +305,7 @@ static int connect_jack_ports(out123_handle *ao
++wish_channels;
debug1("wish_channels: %i", wish_channels);
wishlist = malloc(sizeof(char*)*(wish_channels+1));
devcopy = compat_strdup(ao->device);
devcopy = INT123_compat_strdup(ao->device);
if(devcopy == NULL || wishlist == NULL)
{
if(devcopy)
@@ -522,7 +522,7 @@ static int open_jack(out123_handle *ao)
}
debug("Jack open successful.\n");
ao->realname = compat_strdup(realname);
ao->realname = INT123_compat_strdup(realname);
return 0;
}

View File

@@ -128,7 +128,7 @@ static int open_win32(out123_handle *ao){
EXIT_ON_ERROR(hr)
if (ao->device) {
devlen = win32_utf8_wide(ao->device, &device, NULL);
devlen = INT123_win32_utf8_wide(ao->device, &device, NULL);
if(device && devlen > 0) {
hr = IMMDeviceEnumerator_GetDevice(state->pEnumerator, device, &state->pDevice);
mdebug("IMMDeviceEnumerator_GetDevice %x", hr);
@@ -545,7 +545,7 @@ static int enumerate_win32( out123_handle *ao, int (*store_device)(void *devlist
if(FAILED(hr) || pProps == NULL) goto Exit;
/* get ID */
win32_wide_utf8(pwszID, &pszID, NULL);
INT123_win32_wide_utf8(pwszID, &pszID, NULL);
if(pszID == NULL) goto Exit;
/* get Property */
@@ -557,7 +557,7 @@ static int enumerate_win32( out123_handle *ao, int (*store_device)(void *devlist
}
/* get Description*/
win32_wide_utf8(varName.pwszVal, &pszDesc, NULL);
INT123_win32_wide_utf8(varName.pwszVal, &pszDesc, NULL);
PropVariantClear(&varName);
if(pszDesc == NULL) goto Exit;

View File

@@ -14,6 +14,14 @@
/** \file out123.h The header file for the libout123 audio output facility. */
/** A macro to check at compile time which set of API functions to expect.
* This must be incremented at least each time a new symbol is added
* to the header.
*/
#define OUT123_API_VERSION 5
/** library patch level at client build time */
#define OUT123_PATCHLEVEL 0
/* We only need size_t definition. */
#include <stddef.h>
@@ -23,15 +31,7 @@
* know sizes of encodings added to fmt123.h later on.
* If you don't care, just use the macro.
*/
#include <fmt123.h>
/** A macro to check at compile time which set of API functions to expect.
* This should be incremented at least each time a new symbol is added
* to the header.
*/
#ifndef OUT123_API_VERSION
#define OUT123_API_VERSION @OUTAPI_VERSION@
#endif
#include "fmt123.h"
#ifndef MPG123_EXPORT
/** Defines needed for MS Visual Studio(tm) DLL builds.
@@ -118,6 +118,23 @@ struct out123_struct;
/** Typedef shortcut as preferrend name for the handle type. */
typedef struct out123_struct out123_handle;
/** Get version of the mpg123 distribution this library build came with.
* (optional means non-NULL)
* \param major optional address to store major version number
* \param minor optional address to store minor version number
* \param patch optional address to store patchlevel version number
* \return full version string (like "1.2.3-beta4 (experimental)")
*/
MPG123_EXPORT
const char *out123_distversion(unsigned int *major, unsigned int *minor, unsigned int *patch);
/** Get API version of library build.
* \param patch optional address to store patchlevel
* \return API version of library
*/
MPG123_EXPORT
unsigned int out123_libversion(unsigned int *patch);
/** Enumeration of codes for the parameters that it is possible to set/get. */
enum out123_parms
{

View File

@@ -1,7 +1,7 @@
/*
out123_int: internal header for libout123
copyright ?-2021 by the mpg123 project - free software under the terms of the LGPL 2.1
copyright ?-2023 by the mpg123 project - free software under the terms of the LGPL 2.1
see COPYING and AUTHORS files in distribution or http://mpg123.org
initially written by Michael Hipp (some traces left)
*/
@@ -12,12 +12,7 @@
#define MPG123_ENUM_API
#include "config.h"
#include "intsym.h"
#include "abi_align.h"
/* export DLL symbols */
#if defined(WIN32) && defined(DYNAMIC_BUILD)
#define BUILD_MPG123_DLL
#endif
#include "compat.h"
#include "out123.h"
#include "module.h"
@@ -106,10 +101,10 @@ struct out123_struct
/* Lazy. */
#define AOQUIET ((ao->auxflags | ao->flags) & OUT123_QUIET)
#define AOVERBOSE(v) (!AOQUIET && ao->verbose >= (v))
#define GOOD_WRITEVAL(fd, val) (unintr_write(fd, &(val), sizeof((val))) == sizeof((val)))
#define GOOD_WRITEBUF(fd, addr, n) (unintr_write(fd, (addr), (n)) == (n))
#define GOOD_READVAL(fd, val) (unintr_read(fd, &(val), sizeof((val))) == sizeof((val)))
#define GOOD_READBUF(fd, addr, n) (unintr_read(fd, (addr), (n)) == (n))
#define GOOD_WRITEVAL(fd, val) (INT123_unintr_write(fd, &(val), sizeof((val))) == sizeof((val)))
#define GOOD_WRITEBUF(fd, addr, n) (INT123_unintr_write(fd, (addr), (n)) == (n))
#define GOOD_READVAL(fd, val) (INT123_unintr_read(fd, &(val), sizeof((val))) == sizeof((val)))
#define GOOD_READBUF(fd, addr, n) (INT123_unintr_read(fd, (addr), (n)) == (n))
struct audio_format_name {
int val;

View File

@@ -15,7 +15,7 @@
static char* always_strdup(const char *in)
{
char *out = in ? compat_strdup(in) : malloc(1);
char *out = in ? INT123_compat_strdup(in) : malloc(1);
if(!in && out)
out[0] = 0;
return out;
@@ -24,7 +24,7 @@ static char* always_strdup(const char *in)
/* Construction helper for paired string lists.
Returns 0 on success. */
// Also converts NULL to empty string for safer use later.
int stringlists_add( char ***alist, char ***blist
int INT123_stringlists_add( char ***alist, char ***blist
, const char *atext, const char *btext, int *count)
{
char *atextcopy = NULL;
@@ -35,9 +35,9 @@ int stringlists_add( char ***alist, char ***blist
/* If one of these succeeded, the old memory is gone, so always overwrite
the old pointer, worst case is wasted but not leaked memory in an
out-of-memory situation. */
if((morealist = safe_realloc(*alist, sizeof(char*)*(*count+1))))
if((morealist = INT123_safe_realloc(*alist, sizeof(char*)*(*count+1))))
*alist = morealist;
if((moreblist = safe_realloc(*blist, sizeof(char*)*(*count+1))))
if((moreblist = INT123_safe_realloc(*blist, sizeof(char*)*(*count+1))))
*blist = moreblist;
if(!morealist || !moreblist)
return -1;

View File

@@ -10,7 +10,7 @@
#ifndef MPG123_H_STRINGLISTS
#define MPG123_H_STRINGLISTS
int stringlists_add( char ***alist, char ***blist
int INT123_stringlists_add( char ***alist, char ***blist
, const char *atext, const char *btext, int *count);
#endif

View File

@@ -1,7 +1,7 @@
/*
wav.c: write wav/au/cdr files (and headerless raw
copyright ?-2015 by the mpg123 project - free software under the terms of the LGPL 2.1
copyright ?-2023 by the mpg123 project - free software under the terms of the LGPL 2.1
see COPYING and AUTHORS files in distribution or http://mpg123.org
initially written by Samuel Audet
@@ -98,7 +98,7 @@ static void wavdata_del(struct wavdata *wdat)
{
if(!wdat) return;
if(wdat->wavfp && wdat->wavfp != stdout)
compat_fclose(wdat->wavfp);
INT123_compat_fclose(wdat->wavfp);
if(wdat->the_header)
free(wdat->the_header);
free(wdat);
@@ -144,11 +144,12 @@ static long from_little(byte *inval, int b)
static int testEndian(void)
{
long i,a=0,b=0,c=0;
long a=0,b=0,c=0;
int ret = 0;
size_t i;
for(i=0;i<sizeof(long);i++) {
((byte *)&a)[i] = i;
((byte *)&a)[i] = (byte)i;
b<<=8;
b |= i;
c |= i << (i*8);
@@ -170,7 +171,7 @@ static int open_file(struct wavdata *wdat, char *filename)
if(!filename || !strcmp("-",filename) || !strcmp("", filename))
{
wdat->wavfp = stdout;
compat_binmode(STDOUT_FILENO, TRUE);
INT123_compat_binmode(STDOUT_FILENO, TRUE);
/* If stdout is redirected to a file, seeks suddenly can work.
Doing one here to ensure that such a file has the same output
it had when opening directly as such. */
@@ -179,7 +180,7 @@ static int open_file(struct wavdata *wdat, char *filename)
}
else
{
wdat->wavfp = compat_fopen(filename, "wb");
wdat->wavfp = INT123_compat_fopen(filename, "wb");
if(!wdat->wavfp)
return -1;
else
@@ -197,10 +198,10 @@ static int close_file(out123_handle *ao)
if(wdat->wavfp != NULL && wdat->wavfp != stdout)
{
if(compat_fclose(wdat->wavfp))
if(INT123_compat_fclose(wdat->wavfp))
{
if(!AOQUIET)
error1("problem closing the audio file, probably because of flushing to disk: %s\n", strerror(errno));
error1("problem closing the audio file, probably because of flushing to disk: %s\n", INT123_strerror(errno));
ret = -1;
}
}
@@ -229,13 +230,13 @@ static int write_header(out123_handle *ao)
)
{
if(!AOQUIET)
error1("cannot write header: %s", strerror(errno));
error1("cannot write header: %s", INT123_strerror(errno));
return -1;
}
else return 0;
}
int au_open(out123_handle *ao)
int INT123_au_open(out123_handle *ao)
{
struct wavdata *wdat = NULL;
struct auhead *auhead = NULL;
@@ -314,7 +315,7 @@ au_open_bad:
return -1;
}
int cdr_open(out123_handle *ao)
int INT123_cdr_open(out123_handle *ao)
{
struct wavdata *wdat = NULL;
@@ -361,7 +362,7 @@ cdr_open_bad:
}
/* RAW files are headerless WAVs where the format does not matter. */
int raw_open(out123_handle *ao)
int INT123_raw_open(out123_handle *ao)
{
struct wavdata *wdat;
@@ -390,7 +391,7 @@ raw_open_bad:
return -1;
}
int wav_open(out123_handle *ao)
int INT123_wav_open(out123_handle *ao)
{
int bps;
struct wavdata *wdat = NULL;
@@ -539,7 +540,7 @@ wav_open_bad:
return -1;
}
int wav_write(out123_handle *ao, unsigned char *buf, int len)
int INT123_wav_write(out123_handle *ao, unsigned char *buf, int len)
{
struct wavdata *wdat = ao->userptr;
int temp;
@@ -595,7 +596,7 @@ int wav_write(out123_handle *ao, unsigned char *buf, int len)
if(fflush(wdat->wavfp))
{
if(!AOQUIET)
error1("flushing failed: %s\n", strerror(errno));
error1("flushing failed: %s\n", INT123_strerror(errno));
return -1;
}
#endif
@@ -604,7 +605,7 @@ if(fflush(wdat->wavfp))
return temp;
}
int wav_close(out123_handle *ao)
int INT123_wav_close(out123_handle *ao)
{
struct wavdata *wdat = ao->userptr;
@@ -618,7 +619,7 @@ int wav_close(out123_handle *ao)
if(fflush(wdat->wavfp))
{
if(!AOQUIET)
error1("cannot flush WAV stream: %s", strerror(errno));
error1("cannot flush WAV stream: %s", INT123_strerror(errno));
return close_file(ao);
}
if(fseek(wdat->wavfp, 0L, SEEK_SET) >= 0)
@@ -658,7 +659,7 @@ int wav_close(out123_handle *ao)
return close_file(ao);
}
int au_close(out123_handle *ao)
int INT123_au_close(out123_handle *ao)
{
struct wavdata *wdat = ao->userptr;
@@ -672,7 +673,7 @@ int au_close(out123_handle *ao)
if(fflush(wdat->wavfp))
{
if(!AOQUIET)
error1("cannot flush WAV stream: %s", strerror(errno));
error1("cannot flush WAV stream: %s", INT123_strerror(errno));
return close_file(ao);
}
if(fseek(wdat->wavfp, 0L, SEEK_SET) >= 0)
@@ -690,7 +691,7 @@ int au_close(out123_handle *ao)
}
/* CDR data also uses that. */
int raw_close(out123_handle *ao)
int INT123_raw_close(out123_handle *ao)
{
struct wavdata *wdat = ao->userptr;
@@ -705,7 +706,7 @@ int raw_close(out123_handle *ao)
/* Some trivial functions to interface with out123's module architecture. */
int cdr_formats(out123_handle *ao)
int INT123_cdr_formats(out123_handle *ao)
{
if(ao->rate == 44100 && ao->channels == 2)
return MPG123_ENC_SIGNED_16;
@@ -713,17 +714,17 @@ int cdr_formats(out123_handle *ao)
return 0;
}
int au_formats(out123_handle *ao)
int INT123_au_formats(out123_handle *ao)
{
return MPG123_ENC_SIGNED_16|MPG123_ENC_UNSIGNED_8|MPG123_ENC_ULAW_8;
}
int raw_formats(out123_handle *ao)
int INT123_raw_formats(out123_handle *ao)
{
return MPG123_ENC_ANY;
}
int wav_formats(out123_handle *ao)
int INT123_wav_formats(out123_handle *ao)
{
return
MPG123_ENC_SIGNED_16
@@ -737,7 +738,7 @@ int wav_formats(out123_handle *ao)
One could call fsync(), too, but to be safe, that would need to
be called on the directory, too. Also, apps randomly calling
fsync() can cause annoying issues in a system. */
void wav_drain(out123_handle *ao)
void INT123_wav_drain(out123_handle *ao)
{
struct wavdata *wdat = ao->userptr;
@@ -745,5 +746,5 @@ void wav_drain(out123_handle *ao)
return;
if(fflush(wdat->wavfp) && !AOQUIET)
error1("flushing failed: %s\n", strerror(errno));
error1("flushing failed: %s\n", INT123_strerror(errno));
}

View File

@@ -15,19 +15,19 @@
/* Interfaces from wav.c, variants of file writing, to be combined into
fake modules by the main library code. */
int au_open(out123_handle *);
int cdr_open(out123_handle *);
int raw_open(out123_handle *);
int wav_open(out123_handle *);
int wav_write(out123_handle *, unsigned char *buf, int len);
int wav_close(out123_handle *);
int au_close(out123_handle *);
int raw_close(out123_handle *);
int cdr_formats(out123_handle *);
int au_formats(out123_handle *);
int raw_formats(out123_handle *);
int wav_formats(out123_handle *);
void wav_drain(out123_handle *);
int INT123_au_open(out123_handle *);
int INT123_cdr_open(out123_handle *);
int INT123_raw_open(out123_handle *);
int INT123_wav_open(out123_handle *);
int INT123_wav_write(out123_handle *, unsigned char *buf, int len);
int INT123_wav_close(out123_handle *);
int INT123_au_close(out123_handle *);
int INT123_raw_close(out123_handle *);
int INT123_cdr_formats(out123_handle *);
int INT123_au_formats(out123_handle *);
int INT123_raw_formats(out123_handle *);
int INT123_wav_formats(out123_handle *);
void INT123_wav_drain(out123_handle *);
#endif

View File

@@ -1,7 +1,7 @@
/*
xfermem: unidirectional fast pipe
copyright ?-2015 by the mpg123 project - free software under the terms of the LGPL 2.1
copyright ?-2023 by the mpg123 project - free software under the terms of the LGPL 2.1
see COPYING and AUTHORS files in distribution or http://mpg123.org
initially written by Oliver Fromme
old timestamp: Sun Apr 6 02:26:26 MET DST 1997
@@ -30,7 +30,7 @@
#define MAP_ANON MAP_ANONYMOUS
#endif
void xfermem_init (txfermem **xf, size_t bufsize, size_t msize, size_t skipbuf)
void INT123_xfermem_init (txfermem **xf, size_t bufsize, size_t msize, size_t skipbuf)
{
size_t regsize = bufsize + msize + skipbuf + sizeof(txfermem);
@@ -68,13 +68,13 @@ void xfermem_init (txfermem **xf, size_t bufsize, size_t msize, size_t skipbuf)
}
if (shmctl(shmemid, IPC_RMID, &shmemds) == -1) {
perror ("shmctl()");
xfermem_done (*xf);
INT123_xfermem_done (*xf);
exit (1);
}
#endif
if (socketpair(AF_UNIX, SOCK_STREAM, 0, (*xf)->fd) < 0) {
perror ("socketpair()");
xfermem_done (*xf);
INT123_xfermem_done (*xf);
exit (1);
}
(*xf)->freeindex = (*xf)->readindex = 0;
@@ -84,7 +84,7 @@ void xfermem_init (txfermem **xf, size_t bufsize, size_t msize, size_t skipbuf)
(*xf)->metasize = msize + skipbuf;
}
void xfermem_done (txfermem *xf)
void INT123_xfermem_done (txfermem *xf)
{
if(!xf)
return;
@@ -101,21 +101,21 @@ void xfermem_done (txfermem *xf)
#endif
}
void xfermem_init_writer (txfermem *xf)
void INT123_xfermem_init_writer (txfermem *xf)
{
if(xf)
close (xf->fd[XF_READER]);
debug1("xfermem writer fd=%i", xf->fd[XF_WRITER]);
}
void xfermem_init_reader (txfermem *xf)
void INT123_xfermem_init_reader (txfermem *xf)
{
if(xf)
close (xf->fd[XF_WRITER]);
debug1("xfermem reader fd=%i", xf->fd[XF_READER]);
}
size_t xfermem_get_freespace (txfermem *xf)
size_t INT123_xfermem_get_freespace (txfermem *xf)
{
size_t freeindex, readindex;
@@ -131,7 +131,7 @@ size_t xfermem_get_freespace (txfermem *xf)
return ((xf->size - (freeindex - readindex)) - 1);
}
size_t xfermem_get_usedspace (txfermem *xf)
size_t INT123_xfermem_get_usedspace (txfermem *xf)
{
size_t freeindex, readindex;
@@ -193,36 +193,36 @@ static int xfermem_getcmd_raw (int fd, int block, byte *cmds, int count)
}
/* Verbose variant for debugging communication. */
int xfermem_getcmd(int fd, int block)
int INT123_xfermem_getcmd(int fd, int block)
{
byte cmd;
int res = xfermem_getcmd_raw(fd, block, &cmd, 1);
debug3("xfermem_getcmd(%i, %i) = %i", fd, block, res == 1 ? cmd : res);
debug3("INT123_xfermem_getcmd(%i, %i) = %i", fd, block, res == 1 ? cmd : res);
return res == 1 ? cmd : res;
}
int xfermem_getcmds(int fd, int block, byte *cmds, int count)
int INT123_xfermem_getcmds(int fd, int block, byte *cmds, int count)
{
int res = xfermem_getcmd_raw(fd, block, cmds, count);
debug5("xfermem_getcmds(%i, %i, %p, %i) = %i"
debug5("INT123_xfermem_getcmds(%i, %i, %p, %i) = %i"
, fd, block, (void*)cmds, count
, res);
return res;
}
int xfermem_putcmd (int fd, byte cmd)
int INT123_xfermem_putcmd (int fd, byte cmd)
{
for (;;) {
switch (write(fd, &cmd, 1)) {
case 1:
debug2("xfermem_putcmd(%i, %i) = 1", fd, cmd);
debug2("INT123_xfermem_putcmd(%i, %i) = 1", fd, cmd);
return (1);
case -1:
if (errno != EINTR)
{
debug3("xfermem_putcmd(%i, %i) = -1 (%s)"
, fd, cmd, strerror(errno));
debug3("INT123_xfermem_putcmd(%i, %i) = -1 (%s)"
, fd, cmd, INT123_strerror(errno));
return (-1);
}
}
@@ -241,9 +241,9 @@ int xfermem_putcmd (int fd, byte cmd)
hanging for a while. The critical side is that of the reader.
Because of that, it is only sensible to provide a voluntary
xfermem_writer_block() here. The reader does not need such a function.
INT123_xfermem_writer_block() here. The reader does not need such a function.
Only if it has nothing else to do, it will simply block on
xfermem_getcmd(), and the writer promises to xfermem_putcmd() when
INT123_xfermem_getcmd(), and the writer promises to INT123_xfermem_putcmd() when
something happens.
The writer always sends a wakeup command to the reader since the latter
@@ -257,13 +257,13 @@ int xfermem_putcmd (int fd, byte cmd)
/* Wait a bit to get a sign of life from the reader.
Returns -1 if even that did not work. */
int xfermem_writer_block(txfermem *xf)
int INT123_xfermem_writer_block(txfermem *xf)
{
int myfd = xf->fd[XF_WRITER];
int result;
xfermem_putcmd(myfd, XF_CMD_PING);
result = xfermem_getcmd(myfd, TRUE);
INT123_xfermem_putcmd(myfd, XF_CMD_PING);
result = INT123_xfermem_getcmd(myfd, TRUE);
/* Only a pong to my ping is the expected good answer.
Everything else is a problem to be communicated. */
return (result == XF_CMD_PONG) ? 0 : result;
@@ -272,14 +272,14 @@ int xfermem_writer_block(txfermem *xf)
/* Return: 0 on success, -1 on communication error, > 0 for
error on buffer side, some special return code from buffer to be
evaluated. */
int xfermem_write(txfermem *xf, void *buffer, size_t bytes)
int INT123_xfermem_write(txfermem *xf, void *buffer, size_t bytes)
{
if(buffer == NULL || bytes < 1) return 0;
/* You weren't so braindead not allocating enough space at all, right? */
while (xfermem_get_freespace(xf) < bytes)
while (INT123_xfermem_get_freespace(xf) < bytes)
{
int cmd = xfermem_writer_block(xf);
int cmd = INT123_xfermem_writer_block(xf);
if(cmd) /* Non-successful wait. */
return cmd;
}
@@ -298,7 +298,7 @@ int xfermem_write(txfermem *xf, void *buffer, size_t bytes)
xf->freeindex = (xf->freeindex + bytes) % xf->size;
/* Always notify the buffer process. */
debug("write waking");
return xfermem_putcmd(xf->fd[XF_WRITER], XF_CMD_DATA) < 0
return INT123_xfermem_putcmd(xf->fd[XF_WRITER], XF_CMD_DATA) < 0
? -1
: 0;
}

View File

@@ -37,12 +37,12 @@ typedef struct {
* All other entries are initialized once.
*/
void xfermem_init (txfermem **xf, size_t bufsize, size_t msize, size_t skipbuf);
void xfermem_init_writer (txfermem *xf);
void xfermem_init_reader (txfermem *xf);
void INT123_xfermem_init (txfermem **xf, size_t bufsize, size_t msize, size_t skipbuf);
void INT123_xfermem_init_writer (txfermem *xf);
void INT123_xfermem_init_reader (txfermem *xf);
size_t xfermem_get_freespace (txfermem *xf);
size_t xfermem_get_usedspace (txfermem *xf);
size_t INT123_xfermem_get_freespace (txfermem *xf);
size_t INT123_xfermem_get_usedspace (txfermem *xf);
/* Unless otherwise noted, each command demands a reponse if issued from the
writer. The reader does not expect responses, only orders. */
@@ -71,16 +71,16 @@ enum xf_cmd_code
#define XF_WRITER 0
#define XF_READER 1
int xfermem_getcmd(int fd, int block);
int xfermem_getcmds(int fd, int block, byte* cmds, int count);
int xfermem_putcmd(int fd, byte cmd);
int xfermem_writer_block(txfermem *xf);
int INT123_xfermem_getcmd(int fd, int block);
int INT123_xfermem_getcmds(int fd, int block, byte* cmds, int count);
int INT123_xfermem_putcmd(int fd, byte cmd);
int INT123_xfermem_writer_block(txfermem *xf);
/* returns TRUE for being interrupted */
int xfermem_write(txfermem *xf, void *buffer, size_t bytes);
int INT123_xfermem_write(txfermem *xf, void *buffer, size_t bytes);
void xfermem_done (txfermem *xf);
#define xfermem_done_writer xfermem_init_reader
#define xfermem_done_reader xfermem_init_writer
void INT123_xfermem_done (txfermem *xf);
#define xfermem_done_writer INT123_xfermem_init_reader
#define xfermem_done_reader INT123_xfermem_init_writer
#endif