mirror of
https://github.com/servalproject/serval-dna.git
synced 2024-12-18 20:57:56 +00:00
Remove bitrot related to voip testing
This commit is contained in:
parent
025726dcab
commit
1228df2b70
31
INSTALL.md
31
INSTALL.md
@ -170,37 +170,6 @@ Configure
|
||||
The [doc/Servald-Configuration](./doc/Servald-Configuration.md) document
|
||||
describes the configuration of Serval DNA in detail.
|
||||
|
||||
Voice call test
|
||||
---------------
|
||||
|
||||
If the following packages are present then `./configure` will set the
|
||||
`HAVE_VOIPTEST` macro and build **servald** with its `phone` command available
|
||||
for performing voice call testing:
|
||||
|
||||
* [Port audio](http://www.portaudio.com)
|
||||
* [Secret Rabbit Code](http://www.mega-nerd.com/SRC/) (a.k.a. Sample Rate
|
||||
Convert) by Erik de Castro Lopo
|
||||
* [SpanDSP](http://www.soft-switch.org/) by Steve Underwood
|
||||
* [Codec2](http://www.rowetel.com/blog/?page_id=452) by Dave Rowe of Rowetel
|
||||
|
||||
The Codec2 source code can be fetched using [Subversion][]:
|
||||
|
||||
$ cd $HOME/src
|
||||
$ svn checkout https://freetel.svn.sourceforge.net/svnroot/freetel/codec2 codec2
|
||||
$
|
||||
|
||||
There are command-line options to control the `HAVE_VOIPTEST` macro:
|
||||
|
||||
* To force `HAVE_VOIPTEST` to be set, and fail if the necessary packages are
|
||||
not present, use:
|
||||
|
||||
$ ./configure --enable-voiptest
|
||||
|
||||
* To force `HAVE_VOIPTEST` to be un-set (and not check for the presence of the
|
||||
above packages), use:
|
||||
|
||||
$ ./configure --disable-voiptest
|
||||
|
||||
About the examples
|
||||
------------------
|
||||
|
||||
|
15
Makefile.in
15
Makefile.in
@ -16,17 +16,6 @@ SERVALD_SRCS = \
|
||||
$(SERVAL_CLIENT_SOURCES) \
|
||||
$(SERVAL_DAEMON_SOURCES)
|
||||
|
||||
HAVE_ALSA= @HAVE_ALSA@
|
||||
ifeq (HAVE_ALSA,1)
|
||||
SERVALD_SRCS+= audio_alsa.c
|
||||
endif
|
||||
|
||||
HAVE_VOIPTEST= @HAVE_VOIPTEST@
|
||||
ifeq ($(HAVE_VOIPTEST), 1)
|
||||
SERVALD_SRCS+= pa_phone.c
|
||||
VOIPTEST_CFLAGS=-DHAVE_VOIPTEST=1
|
||||
endif
|
||||
|
||||
MONITOR_CLIENT_SRCS = \
|
||||
$(SERVAL_CLIENT_SOURCES) \
|
||||
monitor-client.c
|
||||
@ -41,9 +30,9 @@ SERVAL_DAEMON_OBJS= $(SERVAL_DAEMON_SOURCES:.c=.o)
|
||||
MONITOR_CLIENT_OBJS= $(MONITOR_CLIENT_SRCS:.c=.o)
|
||||
MDP_CLIENT_OBJS= $(MDP_CLIENT_SRCS:.c=.o)
|
||||
|
||||
LDFLAGS=@LDFLAGS@ @LIBS@ @PORTAUDIO_LIBS@ @SRC_LIBS@ @SPANDSP_LIBS@ @CODEC2_LIBS@ @PTHREAD_LIBS@
|
||||
LDFLAGS=@LDFLAGS@ @LIBS@ @PTHREAD_LIBS@
|
||||
|
||||
CFLAGS= -Isqlite-amalgamation-3070900 @CPPFLAGS@ @CFLAGS@ @PORTAUDIO_CFLAGS@ @SRC_CFLAGS@ @SPANDSP_CFLAGS@ @PTHREAD_CFLAGS@ $(VOIPTEST_CFLAGS) -Inacl/include
|
||||
CFLAGS= -Isqlite-amalgamation-3070900 @CPPFLAGS@ @CFLAGS@ @PTHREAD_CFLAGS@ -Inacl/include
|
||||
CFLAGS+=-DSYSCONFDIR="\"$(sysconfdir)\"" -DLOCALSTATEDIR="\"$(localstatedir)\""
|
||||
CFLAGS+=-fPIC
|
||||
CFLAGS+=-Wall -Wno-unused-value
|
||||
|
@ -3135,9 +3135,5 @@ struct cli_schema command_line_options[]={
|
||||
"Listen for incoming connections"},
|
||||
{app_msp_connection,{"msp", "connect", "[--once]", "[--forward=<local_port>]", "<sid>", "<port>", NULL}, 0,
|
||||
"Connect to a remote party"},
|
||||
#ifdef HAVE_VOIPTEST
|
||||
{app_pa_phone,{"phone",NULL}, 0,
|
||||
"Run phone test application"},
|
||||
#endif
|
||||
{NULL,{NULL},0,NULL}
|
||||
};
|
||||
|
25
configure.in
25
configure.in
@ -38,26 +38,6 @@ dnl Specify default Rhizome store directory
|
||||
AC_ARG_VAR([RHIZOME_STORE_PATH], [default Rhizome store directory])
|
||||
AS_IF([test "x$RHIZOME_STORE_PATH" != x], [AC_DEFINE_UNQUOTED([RHIZOME_STORE_PATH], ["$RHIZOME_STORE_PATH"], [default Rhizome store directory])])
|
||||
|
||||
dnl VoIP test app
|
||||
AC_ARG_ENABLE(voiptest,
|
||||
AS_HELP_STRING([--enable-voiptest], [Require VoIP test program (default: only build if dependencies are present)])
|
||||
AS_HELP_STRING([--disable-voiptest], [Disable VoIP test program (don't test for dependencies)])dnl'
|
||||
)
|
||||
|
||||
have_voip=0
|
||||
AS_IF([test "x$enable_voiptest" != "xno"], [
|
||||
have_voip=1
|
||||
PKG_CHECK_MODULES([PORTAUDIO], [portaudio-2.0],,[have_voip=0])
|
||||
PKG_CHECK_MODULES([SRC], [samplerate],,[have_voip=0])
|
||||
PKG_CHECK_MODULES([SPANDSP], [spandsp],,[have_voip=0])
|
||||
AC_CHECK_HEADER([codec2.h],, [have_voip=0])
|
||||
AC_CHECK_LIB([codec2], [codec2_create], [AC_SUBST([CODEC2_LIBS], -lcodec2)], [have_voip=0])
|
||||
])
|
||||
AS_IF([test "x$enable_voiptest" = "xyes" -a "x$have_voip" != "x1" ], [
|
||||
AC_MSG_ERROR([Missing VoIP dependencies])
|
||||
])
|
||||
AC_SUBST([HAVE_VOIPTEST], $have_voip)
|
||||
|
||||
dnl Check for programs.
|
||||
AC_PROG_CC
|
||||
|
||||
@ -141,11 +121,6 @@ AC_CHECK_HEADERS(
|
||||
#endif
|
||||
])
|
||||
|
||||
dnl Check for ALSA
|
||||
AC_CHECK_HEADER([alsa/asoundlib.h], [have_alsa=1], [have_alsa=0])
|
||||
AS_IF([test x"$have_alsa" = "x1"], [AC_DEFINE([HAVE_ALSA_ASOUNDLIB_H])])
|
||||
AS_IF([test x"$have_alsa" = "x1"], [AC_SUBST(HAVE_ALSA,1)], [AC_SUBST(HAVE_ALSA,0)])
|
||||
|
||||
dnl Lazy way of checking for Linux
|
||||
AS_IF([test "x$ac_cv_header_linux_if_h" = xyes], [AC_DEFINE([USE_ABSTRACT_NAMESPACE])])
|
||||
|
||||
|
277
pa_phone.c
277
pa_phone.c
@ -1,277 +0,0 @@
|
||||
/*
|
||||
Serval DNA Portaudio phone interface
|
||||
Copyright (C) 2012 Serval Project Inc.
|
||||
|
||||
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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
#include <codec2.h>
|
||||
#include <spandsp.h>
|
||||
#include "fifo.h"
|
||||
#include <portaudio.h>
|
||||
#include <pthread.h>
|
||||
#include <samplerate.h>
|
||||
#include "serval.h"
|
||||
|
||||
/* Defines */
|
||||
#define IN_FRAMES 128
|
||||
#define NUM_BUFS (8)
|
||||
#define ECHO_LEN (128)
|
||||
#define ADAPT_MODE (ECHO_CAN_USE_ADAPTION | ECHO_CAN_USE_NLP | ECHO_CAN_USE_CNG)
|
||||
|
||||
#define CODEC2_BYTES_PER_FRAME ((CODEC2_BITS_PER_FRAME + 7) / 8)
|
||||
|
||||
/* Prototypes */
|
||||
typedef struct {
|
||||
PaStream *stream;
|
||||
|
||||
SRC_STATE *src;
|
||||
|
||||
pthread_mutex_t mtx; /* Mutex for frobbing queues */
|
||||
|
||||
/* Incoming samples after decompression
|
||||
* Written with result of recvfrom + codec2_decode
|
||||
* Read by sample rate converter
|
||||
*/
|
||||
struct fifo *incoming;
|
||||
int incoverflow;
|
||||
|
||||
/* Samples after rate conversion
|
||||
* Written by sample rate converter
|
||||
* Read by PA callback
|
||||
*/
|
||||
struct fifo *incrate;
|
||||
int underrun;
|
||||
|
||||
/* Outgoing samples
|
||||
* Written by PA callback
|
||||
* Read by codec2_encode + sendto
|
||||
*/
|
||||
struct fifo *outgoing;
|
||||
|
||||
int overrun;
|
||||
|
||||
echo_can_state_t *echocan; /* Echo canceller state */
|
||||
void *codec2; /* Codec2 state */
|
||||
|
||||
} PaCtx;
|
||||
|
||||
static void freectx(PaCtx *ctx);
|
||||
static int patestCallback(const void *inputBuffer, void *outputBuffer, unsigned long framesPerBuffer,
|
||||
const PaStreamCallbackTimeInfo* timeInfo, PaStreamCallbackFlags statusFlags,
|
||||
void *userData);
|
||||
static PaCtx *pa_phone_setup(void);
|
||||
|
||||
/* Declarations */
|
||||
|
||||
int app_pa_phone(const struct cli_parsed *parsed, void *context)
|
||||
{
|
||||
PaCtx *ctx;
|
||||
|
||||
if ((ctx = pa_phone_setup()) == NULL)
|
||||
return -1;
|
||||
|
||||
freectx(ctx);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* This routine will be called by the PortAudio engine when audio is needed.
|
||||
** It may called at interrupt level on some machines so don't do anything
|
||||
** that could mess up the system like calling malloc() or free().
|
||||
*/
|
||||
static int
|
||||
patestCallback(const void *inputBuffer, void *outputBuffer,
|
||||
unsigned long framesPerBuffer,
|
||||
const PaStreamCallbackTimeInfo* timeInfo,
|
||||
PaStreamCallbackFlags statusFlags,
|
||||
void *userData) {
|
||||
PaCtx *ctx;
|
||||
int16_t *in, *out;
|
||||
int avail, amt;
|
||||
|
||||
ctx = (PaCtx *)userData;
|
||||
out = (int16_t *)outputBuffer;
|
||||
in = (int16_t *)inputBuffer;
|
||||
|
||||
pthread_mutex_lock(&ctx->mtx);
|
||||
|
||||
amt = framesPerBuffer * sizeof(out[0]);
|
||||
|
||||
/* Copy out samples to be played */
|
||||
if ((avail = fifo_get(ctx->incrate, (uint8_t *)out, amt)) < amt) {
|
||||
/* Zero out samples there are no data for */
|
||||
bzero(out + (avail / sizeof(out[0])), amt - avail);
|
||||
ctx->underrun += (amt - avail) / sizeof(out[0]);
|
||||
}
|
||||
|
||||
/* Copy in samples to be recorded */
|
||||
if ((avail = fifo_put(ctx->outgoing, (uint8_t *)in, amt)) < amt) {
|
||||
/* Zero out samples there are no data for */
|
||||
bzero(in + (avail / sizeof(out[0])), amt - avail);
|
||||
ctx->overrun += (amt - avail) / sizeof(out[0]);
|
||||
}
|
||||
|
||||
#if 1
|
||||
/* Run the echo canceller */
|
||||
for (int ofs = 0; ofs < framesPerBuffer; ofs++)
|
||||
out[ofs] = echo_can_update(ctx->echocan, in[ofs], out[ofs]);
|
||||
#endif
|
||||
pthread_mutex_unlock(&ctx->mtx);
|
||||
|
||||
return paContinue;
|
||||
}
|
||||
|
||||
static PaCtx *
|
||||
pa_phone_setup(void) {
|
||||
PaCtx *ctx;
|
||||
int err, i, srcerr;
|
||||
PaError err2;
|
||||
|
||||
err = paNoError;
|
||||
err2 = 0;
|
||||
|
||||
if ((ctx = calloc(1, sizeof(PaCtx))) == NULL) {
|
||||
WHY("Unable to allocate PA context");
|
||||
err2 = 1;
|
||||
goto error;
|
||||
}
|
||||
|
||||
/* Init mutex */
|
||||
if (pthread_mutex_init(&ctx->mtx, NULL) != 0) {
|
||||
WHYF("Unable to init mutex: %s\n", strerror(errno));
|
||||
err2 = 1;
|
||||
goto error;
|
||||
}
|
||||
|
||||
/* Allocate FIFOs */
|
||||
i = IN_FRAMES * 10 * sizeof(int16_t);
|
||||
printf("Allocating %d byte FIFOs\n", i);
|
||||
|
||||
if ((ctx->incoming = fifo_alloc(i)) == NULL) {
|
||||
WHY("Unable to allocate incoming FIFO\n");
|
||||
err2 = 1;
|
||||
goto error;
|
||||
}
|
||||
|
||||
if ((ctx->incrate = fifo_alloc(i)) == NULL) {
|
||||
WHY("Unable to allocate incoming SRC FIFO\n");
|
||||
err2 = 1;
|
||||
goto error;
|
||||
}
|
||||
|
||||
if ((ctx->outgoing = fifo_alloc(i)) == NULL) {
|
||||
WHY("Unable to allocate outgoing FIFO\n");
|
||||
err2 = 1;
|
||||
goto error;
|
||||
}
|
||||
|
||||
|
||||
/* Init sample rate converter */
|
||||
if ((ctx->src = src_new(SRC_SINC_BEST_QUALITY, 1, &srcerr)) == NULL) {
|
||||
WHYF("Unable to init sample rate converter: %d\n", srcerr);
|
||||
err2 = 1;
|
||||
goto error;
|
||||
}
|
||||
|
||||
/* Init echo canceller */
|
||||
if ((ctx->echocan = echo_can_init(ECHO_LEN, ADAPT_MODE)) == NULL) {
|
||||
WHY("Unable to init echo canceller\n");
|
||||
err2 = 1;
|
||||
goto error;
|
||||
}
|
||||
|
||||
/* Init codec2 */
|
||||
if ((ctx->codec2 = codec2_create()) == NULL) {
|
||||
WHY("Unable to init codec2\n");
|
||||
err2 = 1;
|
||||
goto error;
|
||||
}
|
||||
|
||||
/* Initialize Port Audio library */
|
||||
if ((err = Pa_Initialize()) != paNoError)
|
||||
goto error;
|
||||
|
||||
/* Open an audio I/O stream. */
|
||||
if ((err = Pa_OpenDefaultStream(&ctx->stream,
|
||||
1, /* input channels */
|
||||
1, /* output channels */
|
||||
paInt16,
|
||||
SAMPLE_RATE,
|
||||
IN_FRAMES, /* frames per buffer */
|
||||
patestCallback,
|
||||
&ctx)) != paNoError)
|
||||
goto error;
|
||||
|
||||
/* Start stream */
|
||||
if ((err = Pa_StartStream(ctx->stream)) != paNoError)
|
||||
goto error;
|
||||
|
||||
/* Close down stream, PA, etc */
|
||||
/* XXX: hangs in pthread_join on Ubuntu 10.04 */
|
||||
#ifndef linux
|
||||
if ((err = Pa_StopStream(ctx->stream)) != paNoError)
|
||||
goto error;
|
||||
#endif
|
||||
|
||||
/* Do stuff */
|
||||
|
||||
if ((err = Pa_CloseStream(ctx->stream)) != paNoError)
|
||||
goto error;
|
||||
|
||||
error:
|
||||
Pa_Terminate();
|
||||
|
||||
/* Free things */
|
||||
freectx(ctx);
|
||||
|
||||
if (err != paNoError)
|
||||
WHYF("Port audio error: %s\n", Pa_GetErrorText(err));
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void
|
||||
freectx(PaCtx *ctx) {
|
||||
/* Destroy mutex */
|
||||
pthread_mutex_destroy(&ctx->mtx);
|
||||
|
||||
/* Free SRC resources */
|
||||
if (ctx->src != NULL)
|
||||
src_delete(ctx->src);
|
||||
|
||||
/* Free echo caneller */
|
||||
if (ctx->echocan != NULL)
|
||||
echo_can_free(ctx->echocan);
|
||||
|
||||
/* Free codec2 */
|
||||
if (ctx->codec2 != NULL)
|
||||
codec2_destroy(ctx->codec2);
|
||||
|
||||
/* Free FIFOs */
|
||||
if (ctx->incoming != NULL)
|
||||
fifo_free(ctx->incoming);
|
||||
if (ctx->incrate != NULL)
|
||||
fifo_free(ctx->incrate);
|
||||
if (ctx->outgoing != NULL)
|
||||
fifo_free(ctx->outgoing);
|
||||
}
|
||||
|
||||
/*
|
||||
* Local variables:
|
||||
* c-basic-offset: 2
|
||||
* End:
|
||||
*/
|
||||
|
Loading…
Reference in New Issue
Block a user