@ -56,15 +56,6 @@ ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
# include "asterisk/abstract_jb.h"
# include "asterisk/musiconhold.h"
# include "busy.h"
# include "ringtone.h"
# include "ring10.h"
# include "answer.h"
# ifdef ALSA_MONITOR
# include "alsa-monitor.h"
# endif
/*! Global jitterbuffer configuration - by default, jb is disabled */
static struct ast_jb_conf default_jbconf = {
. flags = 0 ,
@ -102,10 +93,6 @@ static snd_pcm_format_t format = SND_PCM_FORMAT_S16_BE;
static char indevname [ 50 ] = ALSA_INDEV ;
static char outdevname [ 50 ] = ALSA_OUTDEV ;
#if 0
static struct timeval lasttime ;
# endif
static int silencesuppression = 0 ;
static int silencethreshold = 1000 ;
@ -121,37 +108,12 @@ static char mohinterpret[MAX_MUSICCLASS];
static int hookstate = 0 ;
static short silence [ FRAME_SIZE ] = { 0 , } ;
struct sound {
int ind ;
short * data ;
int datalen ;
int samplen ;
int silencelen ;
int repeat ;
} ;
static struct sound sounds [ ] = {
{ AST_CONTROL_RINGING , ringtone , sizeof ( ringtone ) / 2 , 16000 , 32000 , 1 } ,
{ AST_CONTROL_BUSY , busy , sizeof ( busy ) / 2 , 4000 , 4000 , 1 } ,
{ AST_CONTROL_CONGESTION , busy , sizeof ( busy ) / 2 , 2000 , 2000 , 1 } ,
{ AST_CONTROL_RING , ring10 , sizeof ( ring10 ) / 2 , 16000 , 32000 , 1 } ,
{ AST_CONTROL_ANSWER , answer , sizeof ( answer ) / 2 , 2200 , 0 , 0 } ,
} ;
/* Sound command pipe */
static int sndcmd [ 2 ] ;
static struct chan_alsa_pvt {
/* We only have one ALSA structure -- near sighted perhaps, but it
keeps this driver as simple as possible - - as it should be . */
struct ast_channel * owner ;
char exten [ AST_MAX_EXTENSION ] ;
char context [ AST_MAX_CONTEXT ] ;
#if 0
snd_pcm_t * card ;
# endif
snd_pcm_t * icard , * ocard ;
} alsa ;
@ -160,8 +122,6 @@ static struct chan_alsa_pvt {
with 160 sample frames , and a buffer size of 3 , we have a 60 ms buffer ,
usually plenty . */
pthread_t sthread ;
# define MAX_BUFFER_SIZE 100
/* File descriptors for sound device */
@ -170,13 +130,6 @@ static int writedev = -1;
static int autoanswer = 1 ;
static int cursound = - 1 ;
static int sampsent = 0 ;
static int silencelen = 0 ;
static int offset = 0 ;
static int nosound = 0 ;
/* ZZ */
static struct ast_channel * alsa_request ( const char * type , int format , void * data , int * cause ) ;
static int alsa_digit ( struct ast_channel * c , char digit , unsigned int duration ) ;
static int alsa_text ( struct ast_channel * c , const char * text ) ;
@ -204,136 +157,6 @@ static const struct ast_channel_tech alsa_tech = {
. fixup = alsa_fixup ,
} ;
static int send_sound ( void )
{
short myframe [ FRAME_SIZE ] ;
int total = FRAME_SIZE ;
short * frame = NULL ;
int amt = 0 , res , myoff ;
snd_pcm_state_t state ;
if ( cursound = = - 1 )
return 0 ;
res = total ;
if ( sampsent < sounds [ cursound ] . samplen ) {
myoff = 0 ;
while ( total ) {
amt = total ;
if ( amt > ( sounds [ cursound ] . datalen - offset ) )
amt = sounds [ cursound ] . datalen - offset ;
memcpy ( myframe + myoff , sounds [ cursound ] . data + offset , amt * 2 ) ;
total - = amt ;
offset + = amt ;
sampsent + = amt ;
myoff + = amt ;
if ( offset > = sounds [ cursound ] . datalen )
offset = 0 ;
}
/* Set it up for silence */
if ( sampsent > = sounds [ cursound ] . samplen )
silencelen = sounds [ cursound ] . silencelen ;
frame = myframe ;
} else {
if ( silencelen > 0 ) {
frame = silence ;
silencelen - = res ;
} else {
if ( sounds [ cursound ] . repeat ) {
/* Start over */
sampsent = 0 ;
offset = 0 ;
} else {
cursound = - 1 ;
nosound = 0 ;
}
return 0 ;
}
}
if ( res = = 0 | | ! frame )
return 0 ;
# ifdef ALSA_MONITOR
alsa_monitor_write ( ( char * ) frame , res * 2 ) ;
# endif
state = snd_pcm_state ( alsa . ocard ) ;
if ( state = = SND_PCM_STATE_XRUN )
snd_pcm_prepare ( alsa . ocard ) ;
res = snd_pcm_writei ( alsa . ocard , frame , res ) ;
if ( res > 0 )
return 0 ;
return 0 ;
}
static void * sound_thread ( void * unused )
{
fd_set rfds ;
fd_set wfds ;
int max , res ;
for ( ; ; ) {
FD_ZERO ( & rfds ) ;
FD_ZERO ( & wfds ) ;
max = sndcmd [ 0 ] ;
FD_SET ( sndcmd [ 0 ] , & rfds ) ;
if ( cursound > - 1 ) {
FD_SET ( writedev , & wfds ) ;
if ( writedev > max )
max = writedev ;
}
# ifdef ALSA_MONITOR
if ( ! alsa . owner ) {
FD_SET ( readdev , & rfds ) ;
if ( readdev > max )
max = readdev ;
}
# endif
res = ast_select ( max + 1 , & rfds , & wfds , NULL , NULL ) ;
if ( res < 1 ) {
ast_log ( LOG_WARNING , " select failed: %s \n " , strerror ( errno ) ) ;
continue ;
}
# ifdef ALSA_MONITOR
if ( FD_ISSET ( readdev , & rfds ) ) {
/* Keep the pipe going with read audio */
snd_pcm_state_t state ;
short buf [ FRAME_SIZE ] ;
int r ;
state = snd_pcm_state ( alsa . ocard ) ;
if ( state = = SND_PCM_STATE_XRUN ) {
snd_pcm_prepare ( alsa . ocard ) ;
}
r = snd_pcm_readi ( alsa . icard , buf , FRAME_SIZE ) ;
if ( r = = - EPIPE ) {
# if DEBUG
ast_log ( LOG_ERROR , " XRUN read \n " ) ;
# endif
snd_pcm_prepare ( alsa . icard ) ;
} else if ( r = = - ESTRPIPE ) {
ast_log ( LOG_ERROR , " -ESTRPIPE \n " ) ;
snd_pcm_prepare ( alsa . icard ) ;
} else if ( r < 0 ) {
ast_log ( LOG_ERROR , " Read error: %s \n " , snd_strerror ( r ) ) ;
} else
alsa_monitor_read ( ( char * ) buf , r * 2 ) ;
}
# endif
if ( FD_ISSET ( sndcmd [ 0 ] , & rfds ) ) {
read ( sndcmd [ 0 ] , & cursound , sizeof ( cursound ) ) ;
silencelen = 0 ;
offset = 0 ;
sampsent = 0 ;
}
if ( FD_ISSET ( writedev , & wfds ) )
if ( send_sound ( ) )
ast_log ( LOG_WARNING , " Failed to write sound \n " ) ;
}
/* Never reached */
return NULL ;
}
static snd_pcm_t * alsa_card_init ( char * dev , snd_pcm_stream_t stream )
{
int err ;
@ -343,14 +166,8 @@ static snd_pcm_t *alsa_card_init(char *dev, snd_pcm_stream_t stream)
snd_pcm_sw_params_t * swparams = NULL ;
struct pollfd pfd ;
snd_pcm_uframes_t period_size = PERIOD_FRAMES * 4 ;
/* int period_bytes = 0; */
snd_pcm_uframes_t buffer_size = 0 ;
unsigned int rate = DESIRED_RATE ;
#if 0
unsigned int per_min = 1 ;
# endif
/* unsigned int per_max = 8; */
snd_pcm_uframes_t start_threshold , stop_threshold ;
err = snd_pcm_open ( & handle , dev , stream , O_NONBLOCK ) ;
@ -398,17 +215,6 @@ static snd_pcm_t *alsa_card_init(char *dev, snd_pcm_stream_t stream)
ast_debug ( 1 , " Buffer size is set to %d frames \n " , err ) ;
}
#if 0
direction = 0 ;
err = snd_pcm_hw_params_set_periods_min ( handle , hwparams , & per_min , & direction ) ;
if ( err < 0 )
ast_log ( LOG_ERROR , " periods_min: %s \n " , snd_strerror ( err ) ) ;
err = snd_pcm_hw_params_set_periods_max ( handle , hwparams , & per_max , 0 ) ;
if ( err < 0 )
ast_log ( LOG_ERROR , " periods_max: %s \n " , snd_strerror ( err ) ) ;
# endif
err = snd_pcm_hw_params ( handle , hwparams ) ;
if ( err < 0 )
ast_log ( LOG_ERROR , " Couldn't set the new hw params: %s \n " , snd_strerror ( err ) ) ;
@ -417,7 +223,6 @@ static snd_pcm_t *alsa_card_init(char *dev, snd_pcm_stream_t stream)
memset ( swparams , 0 , snd_pcm_sw_params_sizeof ( ) ) ;
snd_pcm_sw_params_current ( handle , swparams ) ;
# if 1
if ( stream = = SND_PCM_STREAM_PLAYBACK )
start_threshold = period_size ;
else
@ -426,9 +231,7 @@ static snd_pcm_t *alsa_card_init(char *dev, snd_pcm_stream_t stream)
err = snd_pcm_sw_params_set_start_threshold ( handle , swparams , start_threshold ) ;
if ( err < 0 )
ast_log ( LOG_ERROR , " start threshold: %s \n " , snd_strerror ( err ) ) ;
# endif
# if 1
if ( stream = = SND_PCM_STREAM_PLAYBACK )
stop_threshold = buffer_size ;
else
@ -437,18 +240,7 @@ static snd_pcm_t *alsa_card_init(char *dev, snd_pcm_stream_t stream)
err = snd_pcm_sw_params_set_stop_threshold ( handle , swparams , stop_threshold ) ;
if ( err < 0 )
ast_log ( LOG_ERROR , " stop threshold: %s \n " , snd_strerror ( err ) ) ;
# endif
#if 0
err = snd_pcm_sw_params_set_xfer_align ( handle , swparams , PERIOD_FRAMES ) ;
if ( err < 0 )
ast_log ( LOG_ERROR , " Unable to set xfer alignment: %s \n " , snd_strerror ( err ) ) ;
# endif
#if 0
err = snd_pcm_sw_params_set_silence_threshold ( handle , swparams , silencethreshold ) ;
if ( err < 0 )
ast_log ( LOG_ERROR , " Unable to set silence threshold: %s \n " , snd_strerror ( err ) ) ;
# endif
err = snd_pcm_sw_params ( handle , swparams ) ;
if ( err < 0 )
ast_log ( LOG_ERROR , " sw_params: %s \n " , snd_strerror ( err ) ) ;
@ -477,7 +269,7 @@ static int soundcard_init(void)
alsa . ocard = alsa_card_init ( outdevname , SND_PCM_STREAM_PLAYBACK ) ;
if ( ! alsa . icard | | ! alsa . ocard ) {
ast_log ( LOG_ERROR , " Problem opening alsa I/O devices\n " ) ;
ast_log ( LOG_ERROR , " Problem opening ALSA I/O devices\n " ) ;
return - 1 ;
}
@ -490,6 +282,7 @@ static int alsa_digit(struct ast_channel *c, char digit, unsigned int duration)
ast_verbose ( " << Console Received digit %c of duration %u ms >> \n " ,
digit , duration ) ;
ast_mutex_unlock ( & alsalock ) ;
return 0 ;
}
@ -498,6 +291,7 @@ static int alsa_text(struct ast_channel *c, const char *text)
ast_mutex_lock ( & alsalock ) ;
ast_verbose ( " << Console Received text %s >> \n " , text ) ;
ast_mutex_unlock ( & alsalock ) ;
return 0 ;
}
@ -512,8 +306,8 @@ static void grab_owner(void)
static int alsa_call ( struct ast_channel * c , char * dest , int timeout )
{
int res = 3 ;
struct ast_frame f = { AST_FRAME_CONTROL } ;
ast_mutex_lock ( & alsalock ) ;
ast_verbose ( " << Call placed to '%s' on console >> \n " , dest ) ;
if ( autoanswer ) {
@ -531,56 +325,39 @@ static int alsa_call(struct ast_channel *c, char *dest, int timeout)
f . subclass = AST_CONTROL_RINGING ;
ast_queue_frame ( alsa . owner , & f ) ;
ast_channel_unlock ( alsa . owner ) ;
ast_indicate ( alsa . owner , AST_CONTROL_RINGING ) ;
}
write ( sndcmd [ 1 ] , & res , sizeof ( res ) ) ;
}
snd_pcm_prepare ( alsa . icard ) ;
snd_pcm_start ( alsa . icard ) ;
ast_mutex_unlock ( & alsalock ) ;
return 0 ;
}
static void answer_sound ( void )
{
int res ;
nosound = 1 ;
res = 4 ;
write ( sndcmd [ 1 ] , & res , sizeof ( res ) ) ;
return 0 ;
}
static int alsa_answer ( struct ast_channel * c )
{
ast_mutex_lock ( & alsalock ) ;
ast_verbose ( " << Console call has been answered >> \n " ) ;
answer_sound ( ) ;
ast_setstate ( c , AST_STATE_UP ) ;
cursound = - 1 ;
snd_pcm_prepare ( alsa . icard ) ;
snd_pcm_start ( alsa . icard ) ;
ast_mutex_unlock ( & alsalock ) ;
return 0 ;
}
static int alsa_hangup ( struct ast_channel * c )
{
int res ;
ast_mutex_lock ( & alsalock ) ;
cursound = - 1 ;
c - > tech_pvt = NULL ;
alsa . owner = NULL ;
ast_verbose ( " << Hangup on console >> \n " ) ;
ast_module_unref ( ast_module_info - > self ) ;
if ( hookstate ) {
hookstate = 0 ;
if ( ! autoanswer ) {
/* Congestion noise */
res = 2 ;
write ( sndcmd [ 1 ] , & res , sizeof ( res ) ) ;
}
}
hookstate = 0 ;
snd_pcm_drop ( alsa . icard ) ;
ast_mutex_unlock ( & alsalock ) ;
return 0 ;
}
@ -594,18 +371,7 @@ static int alsa_write(struct ast_channel *chan, struct ast_frame *f)
/* size_t frames = 0; */
snd_pcm_state_t state ;
/* Immediately return if no sound is enabled */
if ( nosound )
return 0 ;
ast_mutex_lock ( & alsalock ) ;
/* Stop any currently playing sound */
if ( cursound ! = - 1 ) {
snd_pcm_drop ( alsa . ocard ) ;
snd_pcm_prepare ( alsa . ocard ) ;
cursound = - 1 ;
}
/* We have to digest the frame in 160-byte portions */
if ( f - > datalen > sizeof ( sizbuf ) - sizpos ) {
@ -615,9 +381,6 @@ static int alsa_write(struct ast_channel *chan, struct ast_frame *f)
memcpy ( sizbuf + sizpos , f - > data , f - > datalen ) ;
len + = f - > datalen ;
pos = 0 ;
# ifdef ALSA_MONITOR
alsa_monitor_write ( sizbuf , len ) ;
# endif
state = snd_pcm_state ( alsa . ocard ) ;
if ( state = = SND_PCM_STATE_XRUN )
snd_pcm_prepare ( alsa . ocard ) ;
@ -643,9 +406,8 @@ static int alsa_write(struct ast_channel *chan, struct ast_frame *f)
}
}
ast_mutex_unlock ( & alsalock ) ;
if ( res > 0 )
res = 0 ;
return res ;
return res > = 0 ? 0 : res ;
}
@ -661,7 +423,6 @@ static struct ast_frame *alsa_read(struct ast_channel *chan)
int off = 0 ;
ast_mutex_lock ( & alsalock ) ;
/* Acknowledge any pending cmd */
f . frametype = AST_FRAME_NULL ;
f . subclass = 0 ;
f . samples = 0 ;
@ -715,21 +476,21 @@ static struct ast_frame *alsa_read(struct ast_channel *chan)
f . offset = AST_FRIENDLY_OFFSET ;
f . src = " Console " ;
f . mallocd = 0 ;
# ifdef ALSA_MONITOR
alsa_monitor_read ( ( char * ) buf , FRAME_SIZE * 2 ) ;
# endif
}
ast_mutex_unlock ( & alsalock ) ;
return & f ;
}
static int alsa_fixup ( struct ast_channel * oldchan , struct ast_channel * newchan )
{
struct chan_alsa_pvt * p = newchan - > tech_pvt ;
ast_mutex_lock ( & alsalock ) ;
p - > owner = newchan ;
ast_mutex_unlock ( & alsalock ) ;
return 0 ;
}
@ -740,37 +501,29 @@ static int alsa_indicate(struct ast_channel *chan, int cond, const void *data, s
ast_mutex_lock ( & alsalock ) ;
switch ( cond ) {
case AST_CONTROL_BUSY :
res = 1 ;
break ;
case AST_CONTROL_CONGESTION :
res = 2 ;
break ;
case AST_CONTROL_RINGING :
case AST_CONTROL_PROGRESS :
break ;
case - 1 :
res = - 1 ;
break ;
case AST_CONTROL_VIDUPDATE :
res = - 1 ;
break ;
case AST_CONTROL_HOLD :
ast_verbose ( " << Console Has Been Placed on Hold >> \n " ) ;
ast_moh_start ( chan , data , mohinterpret ) ;
break ;
case AST_CONTROL_UNHOLD :
ast_verbose ( " << Console Has Been Retrieved from Hold >> \n " ) ;
ast_moh_stop ( chan ) ;
break ;
default :
ast_log ( LOG_WARNING , " Don't know how to display condition %d on %s \n " , cond , chan - > name ) ;
res = - 1 ;
case AST_CONTROL_BUSY :
case AST_CONTROL_CONGESTION :
case AST_CONTROL_RINGING :
case - 1 :
res = - 1 ; /* Ask for inband indications */
break ;
case AST_CONTROL_PROGRESS :
case AST_CONTROL_PROCEEDING :
case AST_CONTROL_VIDUPDATE :
break ;
case AST_CONTROL_HOLD :
ast_verbose ( " << Console Has Been Placed on Hold >> \n " ) ;
ast_moh_start ( chan , data , mohinterpret ) ;
break ;
case AST_CONTROL_UNHOLD :
ast_verbose ( " << Console Has Been Retrieved from Hold >> \n " ) ;
ast_moh_stop ( chan ) ;
break ;
default :
ast_log ( LOG_WARNING , " Don't know how to display condition %d on %s \n " , cond , chan - > name ) ;
res = - 1 ;
}
if ( res > - 1 )
write ( sndcmd [ 1 ] , & res , sizeof ( res ) ) ;
ast_mutex_unlock ( & alsalock ) ;
return res ;
@ -814,8 +567,7 @@ static struct ast_channel *alsa_request(const char *type, int format, void *data
int oldformat = format ;
struct ast_channel * tmp = NULL ;
format & = AST_FORMAT_SLINEAR ;
if ( ! format ) {
if ( ! ( format & = AST_FORMAT_SLINEAR ) ) {
ast_log ( LOG_NOTICE , " Asked to get a channel of format '%d' \n " , oldformat ) ;
return NULL ;
}
@ -825,8 +577,9 @@ static struct ast_channel *alsa_request(const char *type, int format, void *data
if ( alsa . owner ) {
ast_log ( LOG_NOTICE , " Already have a call on the ALSA channel \n " ) ;
* cause = AST_CAUSE_BUSY ;
} else if ( ! ( tmp = alsa_new ( & alsa , AST_STATE_DOWN ) ) )
} else if ( ! ( tmp = alsa_new ( & alsa , AST_STATE_DOWN ) ) ) {
ast_log ( LOG_WARNING , " Unable to create new ALSA channel \n " ) ;
}
ast_mutex_unlock ( & alsalock ) ;
@ -848,6 +601,7 @@ static char *autoanswer_complete(const char *line, const char *word, int pos, in
default :
return NULL ;
}
return NULL ;
}
@ -870,6 +624,7 @@ static char *console_autoanswer(struct ast_cli_entry *e, int cmd, struct ast_cli
if ( ( a - > argc ! = 2 ) & & ( a - > argc ! = 3 ) )
return CLI_SHOWUSAGE ;
ast_mutex_lock ( & alsalock ) ;
if ( a - > argc = = 2 ) {
ast_cli ( a - > fd , " Auto answer is %s. \n " , autoanswer ? " on " : " off " ) ;
@ -882,6 +637,7 @@ static char *console_autoanswer(struct ast_cli_entry *e, int cmd, struct ast_cli
res = CLI_SHOWUSAGE ;
}
ast_mutex_unlock ( & alsalock ) ;
return res ;
}
@ -900,7 +656,6 @@ static char *console_answer(struct ast_cli_entry *e, int cmd, struct ast_cli_arg
case CLI_GENERATE :
return NULL ;
}
if ( a - > argc ! = 2 )
return CLI_SHOWUSAGE ;
@ -912,14 +667,13 @@ static char *console_answer(struct ast_cli_entry *e, int cmd, struct ast_cli_arg
res = CLI_FAILURE ;
} else {
hookstate = 1 ;
cursound = - 1 ;
grab_owner ( ) ;
if ( alsa . owner ) {
struct ast_frame f = { AST_FRAME_CONTROL , AST_CONTROL_ANSWER } ;
ast_queue_frame ( alsa . owner , & f ) ;
ast_channel_unlock ( alsa . owner ) ;
}
answer_sound ( ) ;
}
snd_pcm_prepare ( alsa . icard ) ;
@ -952,16 +706,17 @@ static char *console_sendtext(struct ast_cli_entry *e, int cmd, struct ast_cli_a
ast_mutex_lock ( & alsalock ) ;
if ( ! alsa . owner ) {
ast_cli ( a - > fd , " No one is calling us \n " ) ;
ast_cli ( a - > fd , " No channel active \n " ) ;
res = CLI_FAILURE ;
} else {
struct ast_frame f = { AST_FRAME_TEXT , 0 } ;
char text2send [ 256 ] = " " ;
text2send [ 0 ] = ' \0 ' ;
while ( tmparg < a - > argc ) {
strncat ( text2send , a - > argv [ tmparg + + ] , sizeof ( text2send ) - strlen ( text2send ) - 1 ) ;
strncat ( text2send , " " , sizeof ( text2send ) - strlen ( text2send ) - 1 ) ;
}
text2send [ strlen ( text2send ) - 1 ] = ' \n ' ;
f . data = text2send ;
f . datalen = strlen ( text2send ) + 1 ;
@ -1001,12 +756,10 @@ static char *console_hangup(struct ast_cli_entry *e, int cmd, struct ast_cli_arg
if ( a - > argc ! = 2 )
return CLI_SHOWUSAGE ;
cursound = - 1 ;
ast_mutex_lock ( & alsalock ) ;
if ( ! alsa . owner & & ! hookstate ) {
ast_cli ( a - > fd , " No call to hangup up \n " ) ;
ast_cli ( a - > fd , " No call to hangup \n " ) ;
res = CLI_FAILURE ;
} else {
hookstate = 0 ;
@ -1047,13 +800,11 @@ static char *console_dial(struct ast_cli_entry *e, int cmd, struct ast_cli_args
if ( alsa . owner ) {
if ( a - > argc = = 3 ) {
d = a - > argv [ 2 ] ;
if ( alsa . owner ) {
struct ast_frame f = { AST_FRAME_DTMF } ;
while ( * d ) {
f . subclass = * d ;
for ( d = a - > argv [ 2 ] ; * d ; d + + ) {
struct ast_frame f = { . frametype = AST_FRAME_DTMF , . subclass = * d } ;
ast_queue_frame ( alsa . owner , & f ) ;
d + + ;
}
}
} else {
@ -1065,6 +816,7 @@ static char *console_dial(struct ast_cli_entry *e, int cmd, struct ast_cli_args
myc = context ;
if ( a - > argc = = 3 ) {
char * stringp = NULL ;
ast_copy_string ( tmp , a - > argv [ 2 ] , sizeof ( tmp ) ) ;
stringp = tmp ;
strsep ( & stringp , " @ " ) ;
@ -1137,11 +889,6 @@ static int load_module(void)
}
ast_config_destroy ( cfg ) ;
if ( pipe ( sndcmd ) ) {
ast_log ( LOG_ERROR , " Unable to create pipe \n " ) ;
return AST_MODULE_LOAD_FAILURE ;
}
if ( soundcard_init ( ) < 0 ) {
ast_verb ( 2 , " No sound card detected -- console channel will be unavailable \n " ) ;
ast_verb ( 2 , " Turn off ALSA support by adding 'noload=chan_alsa.so' in /etc/asterisk/modules.conf \n " ) ;
@ -1155,11 +902,6 @@ static int load_module(void)
ast_cli_register_multiple ( cli_alsa , sizeof ( cli_alsa ) / sizeof ( struct ast_cli_entry ) ) ;
ast_pthread_create_background ( & sthread , NULL , sound_thread , NULL ) ;
# ifdef ALSA_MONITOR
if ( alsa_monitor_start ( ) )
ast_log ( LOG_ERROR , " Problem starting Monitoring \n " ) ;
# endif
return AST_MODULE_LOAD_SUCCESS ;
}
@ -1172,14 +914,11 @@ static int unload_module(void)
snd_pcm_close ( alsa . icard ) ;
if ( alsa . ocard )
snd_pcm_close ( alsa . ocard ) ;
if ( sndcmd [ 0 ] > 0 ) {
close ( sndcmd [ 0 ] ) ;
close ( sndcmd [ 1 ] ) ;
}
if ( alsa . owner )
ast_softhangup ( alsa . owner , AST_SOFTHANGUP_APPUNLOAD ) ;
if ( alsa . owner )
return - 1 ;
return 0 ;
}