mirror of
https://gitlab.linphone.org/BC/public/linphone-iphone.git
synced 2026-01-23 06:08:07 +00:00
add support for speex agc within MSVolume
enable it in linphonecore.
This commit is contained in:
parent
eb05a04d21
commit
b08807922d
8 changed files with 252 additions and 27 deletions
|
|
@ -411,6 +411,8 @@ void sound_config_read(LinphoneCore *lc)
|
|||
|
||||
linphone_core_enable_echo_limiter(lc,
|
||||
lp_config_get_int(lc->config,"sound","echolimiter",0));
|
||||
linphone_core_enable_agc(lc,
|
||||
lp_config_get_int(lc->config,"sound","agc",0));
|
||||
}
|
||||
|
||||
void sip_config_read(LinphoneCore *lc)
|
||||
|
|
@ -1435,6 +1437,7 @@ void linphone_core_init_media_streams(LinphoneCore *lc){
|
|||
}
|
||||
|
||||
}
|
||||
audio_stream_enable_automatic_gain_control(lc->audiostream,linphone_core_agc_enabled(lc));
|
||||
#ifdef VIDEO_ENABLED
|
||||
if (lc->video_conf.display || lc->video_conf.capture)
|
||||
lc->videostream=video_stream_new(linphone_core_get_video_port(lc),linphone_core_ipv6_enabled(lc));
|
||||
|
|
@ -1951,6 +1954,14 @@ bool_t linphone_core_echo_limiter_enabled(const LinphoneCore *lc){
|
|||
return lc->sound_conf.ea;
|
||||
}
|
||||
|
||||
void linphone_core_enable_agc(LinphoneCore *lc, bool_t val){
|
||||
lc->sound_conf.agc=val;
|
||||
}
|
||||
|
||||
bool_t linphone_core_agc_enabled(const LinphoneCore *lc){
|
||||
return lc->sound_conf.agc;
|
||||
}
|
||||
|
||||
|
||||
void linphone_core_send_dtmf(LinphoneCore *lc,char dtmf)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -107,6 +107,7 @@ typedef struct sound_config
|
|||
char *remote_ring;
|
||||
bool_t ec;
|
||||
bool_t ea;
|
||||
bool_t agc;
|
||||
} sound_config_t;
|
||||
|
||||
typedef struct codecs_config
|
||||
|
|
@ -713,6 +714,9 @@ bool_t linphone_core_echo_cancelation_enabled(LinphoneCore *lc);
|
|||
void linphone_core_enable_echo_limiter(LinphoneCore *lc, bool_t val);
|
||||
bool_t linphone_core_echo_limiter_enabled(const LinphoneCore *lc);
|
||||
|
||||
void linphone_core_enable_agc(LinphoneCore *lc, bool_t val);
|
||||
bool_t linphone_core_agc_enabled(const LinphoneCore *lc);
|
||||
|
||||
void linphone_core_set_presence_info(LinphoneCore *lc,int minutes_away,const char *contact,LinphoneOnlineStatus os);
|
||||
|
||||
LinphoneOnlineStatus linphone_core_get_presence_info(const LinphoneCore *lc);
|
||||
|
|
|
|||
|
|
@ -8,10 +8,24 @@
|
|||
<primarylanguage>C</primarylanguage>
|
||||
<ignoreparts/>
|
||||
<projectname>linphone</projectname>
|
||||
<projectdirectory>.</projectdirectory>
|
||||
<absoluteprojectpath>false</absoluteprojectpath>
|
||||
<description></description>
|
||||
<defaultencoding></defaultencoding>
|
||||
</general>
|
||||
<kdevcustomproject>
|
||||
<run>
|
||||
<directoryradio>executable</directoryradio>
|
||||
<mainprogram>/home/smorlat/sources/git/linphone/linphone</mainprogram>
|
||||
<programargs></programargs>
|
||||
<globaldebugarguments></globaldebugarguments>
|
||||
<globalcwd>/home/smorlat/sources/git/linphone/linphone</globalcwd>
|
||||
<useglobalprogram>false</useglobalprogram>
|
||||
<terminal>false</terminal>
|
||||
<autocompile>false</autocompile>
|
||||
<autoinstall>false</autoinstall>
|
||||
<autokdesu>false</autokdesu>
|
||||
<envvars/>
|
||||
</run>
|
||||
<filetypes>
|
||||
<filetype>*.java</filetype>
|
||||
|
|
@ -374,11 +388,51 @@
|
|||
<path>win32acm/wineacm.h</path>
|
||||
<path>win32acm/wrapper.h</path>
|
||||
</blacklist>
|
||||
<build>
|
||||
<buildtool>make</buildtool>
|
||||
<builddir></builddir>
|
||||
</build>
|
||||
<other>
|
||||
<prio>0</prio>
|
||||
<otherbin></otherbin>
|
||||
<defaulttarget></defaulttarget>
|
||||
<otheroptions></otheroptions>
|
||||
<selectedenvironment>default</selectedenvironment>
|
||||
<environments>
|
||||
<default/>
|
||||
</environments>
|
||||
</other>
|
||||
<make>
|
||||
<abortonerror>true</abortonerror>
|
||||
<numberofjobs>0</numberofjobs>
|
||||
<prio>0</prio>
|
||||
<dontact>false</dontact>
|
||||
<makebin></makebin>
|
||||
<defaulttarget></defaulttarget>
|
||||
<makeoptions></makeoptions>
|
||||
<selectedenvironment>default</selectedenvironment>
|
||||
<environments>
|
||||
<default/>
|
||||
</environments>
|
||||
</make>
|
||||
</kdevcustomproject>
|
||||
<kdevdebugger>
|
||||
<general>
|
||||
<dbgshell/>
|
||||
<dbgshell></dbgshell>
|
||||
<gdbpath></gdbpath>
|
||||
<configGdbScript></configGdbScript>
|
||||
<runShellScript></runShellScript>
|
||||
<runGdbScript></runGdbScript>
|
||||
<breakonloadinglibs>true</breakonloadinglibs>
|
||||
<separatetty>false</separatetty>
|
||||
<floatingtoolbar>false</floatingtoolbar>
|
||||
<raiseGDBOnStart>false</raiseGDBOnStart>
|
||||
</general>
|
||||
<display>
|
||||
<staticmembers>false</staticmembers>
|
||||
<demanglenames>true</demanglenames>
|
||||
<outputradix>10</outputradix>
|
||||
</display>
|
||||
</kdevdebugger>
|
||||
<kdevdoctreeview>
|
||||
<ignoretocs>
|
||||
|
|
@ -470,6 +524,19 @@
|
|||
<alwaysIncludeNamespaces>false</alwaysIncludeNamespaces>
|
||||
<includePaths>.;</includePaths>
|
||||
</codecompletion>
|
||||
<creategettersetter>
|
||||
<prefixGet></prefixGet>
|
||||
<prefixSet>set</prefixSet>
|
||||
<prefixVariable>m_,_</prefixVariable>
|
||||
<parameterName>theValue</parameterName>
|
||||
<inlineGet>true</inlineGet>
|
||||
<inlineSet>true</inlineSet>
|
||||
</creategettersetter>
|
||||
<splitheadersource>
|
||||
<enabled>false</enabled>
|
||||
<synchronize>true</synchronize>
|
||||
<orientation>Vertical</orientation>
|
||||
</splitheadersource>
|
||||
</kdevcppsupport>
|
||||
<kdevfileview>
|
||||
<groups>
|
||||
|
|
@ -481,4 +548,10 @@
|
|||
<hidenonprojectfiles>false</hidenonprojectfiles>
|
||||
</tree>
|
||||
</kdevfileview>
|
||||
<cppsupportpart>
|
||||
<filetemplates>
|
||||
<interfacesuffix>.h</interfacesuffix>
|
||||
<implementationsuffix>.cpp</implementationsuffix>
|
||||
</filetemplates>
|
||||
</cppsupportpart>
|
||||
</kdevelop>
|
||||
|
|
|
|||
|
|
@ -53,6 +53,7 @@ struct _AudioStream
|
|||
EchoLimiterType el_type; /*use echo limiter: two MSVolume, measured input level controlling local output level*/
|
||||
bool_t play_dtmfs;
|
||||
bool_t use_gc;
|
||||
bool_t use_agc;
|
||||
};
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
|
@ -105,6 +106,9 @@ void audio_stream_enable_echo_limiter(AudioStream *stream, EchoLimiterType type)
|
|||
/*enable gain control, to be done before start() */
|
||||
void audio_stream_enable_gain_control(AudioStream *stream, bool_t val);
|
||||
|
||||
/*enable automatic gain control, to be done before start() */
|
||||
void audio_stream_enable_automatic_gain_control(AudioStream *stream, bool_t val);
|
||||
|
||||
void audio_stream_set_mic_gain(AudioStream *stream, float gain);
|
||||
|
||||
/* stop the audio streaming thread and free everything*/
|
||||
|
|
|
|||
|
|
@ -48,6 +48,8 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
|||
|
||||
#define MS_VOLUME_SET_EA_FORCE MS_FILTER_METHOD(MS_VOLUME_ID,7,float)
|
||||
|
||||
#define MS_VOLUME_ENABLE_AGC MS_FILTER_METHOD(MS_VOLUME_ID,8,int)
|
||||
|
||||
extern MSFilterDesc ms_volume_desc;
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -257,6 +257,13 @@ int audio_stream_start_full(AudioStream *stream, RtpProfile *profile, const char
|
|||
}
|
||||
}
|
||||
|
||||
if (stream->use_agc){
|
||||
int tmp=1;
|
||||
if (stream->volsend==NULL)
|
||||
stream->volsend=ms_filter_new(MS_VOLUME_ID);
|
||||
ms_filter_call_method(stream->volsend,MS_VOLUME_ENABLE_AGC,&tmp);
|
||||
}
|
||||
|
||||
/* give the sound filters some properties */
|
||||
ms_filter_call_method(stream->soundread,MS_FILTER_SET_SAMPLE_RATE,&pt->clock_rate);
|
||||
ms_filter_call_method(stream->soundwrite,MS_FILTER_SET_SAMPLE_RATE,&pt->clock_rate);
|
||||
|
|
@ -382,6 +389,7 @@ AudioStream *audio_stream_new(int locport, bool_t ipv6){
|
|||
stream->rtpsend=ms_filter_new(MS_RTP_SEND_ID);
|
||||
stream->play_dtmfs=TRUE;
|
||||
stream->use_gc=FALSE;
|
||||
stream->use_agc=FALSE;
|
||||
return stream;
|
||||
}
|
||||
|
||||
|
|
@ -406,6 +414,10 @@ void audio_stream_enable_gain_control(AudioStream *stream, bool_t val){
|
|||
stream->use_gc=val;
|
||||
}
|
||||
|
||||
void audio_stream_enable_automatic_gain_control(AudioStream *stream, bool_t val){
|
||||
stream->use_agc=val;
|
||||
}
|
||||
|
||||
void audio_stream_set_mic_gain(AudioStream *stream, float gain){
|
||||
if (stream->volsend){
|
||||
ms_filter_call_method(stream->volsend,MS_VOLUME_SET_GAIN,&gain);
|
||||
|
|
|
|||
|
|
@ -17,9 +17,17 @@ along with this program; if not, write to the Free Software
|
|||
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "mediastreamer-config.h"
|
||||
#endif
|
||||
|
||||
#include "mediastreamer2/msvolume.h"
|
||||
#include <math.h>
|
||||
|
||||
#ifdef HAVE_SPEEXDSP
|
||||
#include <speex/speex_preprocess.h>
|
||||
#endif
|
||||
|
||||
static const float max_e=32767*32767;
|
||||
static const float coef=0.1;
|
||||
static const float gain_k=0.02;
|
||||
|
|
@ -36,7 +44,14 @@ typedef struct Volume{
|
|||
float thres;
|
||||
float force;
|
||||
MSFilter *peer;
|
||||
#ifdef HAVE_SPEEXDSP
|
||||
SpeexPreprocessState *speex_pp;
|
||||
#endif
|
||||
int sample_rate;
|
||||
int nsamples;
|
||||
MSBufferizer *buffer;
|
||||
bool_t ea_active;
|
||||
bool_t agc_enabled;
|
||||
}Volume;
|
||||
|
||||
static void volume_init(MSFilter *f){
|
||||
|
|
@ -49,10 +64,19 @@ static void volume_init(MSFilter *f){
|
|||
v->thres=noise_thres;
|
||||
v->force=en_weight;
|
||||
v->peer=NULL;
|
||||
v->agc_enabled=FALSE;
|
||||
v->buffer=ms_bufferizer_new();
|
||||
v->sample_rate=8000;
|
||||
v->nsamples=80;
|
||||
#ifdef HAVE_SPEEXDSP
|
||||
v->speex_pp=NULL;
|
||||
#endif
|
||||
f->data=v;
|
||||
}
|
||||
|
||||
static void volume_uninit(MSFilter *f){
|
||||
Volume *v=(Volume*)f->data;
|
||||
ms_bufferizer_destroy(v->buffer);
|
||||
ms_free(f->data);
|
||||
}
|
||||
|
||||
|
|
@ -63,12 +87,29 @@ static int volume_get(MSFilter *f, void *arg){
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int volume_set_sample_rate(MSFilter *f, void *arg){
|
||||
Volume *v=(Volume*)f->data;
|
||||
v->sample_rate=*(int*)arg;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int volume_get_linear(MSFilter *f, void *arg){
|
||||
float *farg=(float*)arg;
|
||||
Volume *v=(Volume*)f->data;
|
||||
*farg=(v->energy+1)/max_e;
|
||||
return 0;
|
||||
}
|
||||
#ifdef HAVE_SPEEXDSP
|
||||
static void volume_agc_process(Volume *v, mblk_t *om){
|
||||
speex_preprocess_run(v->speex_pp,(int16_t*)om->b_rptr);
|
||||
}
|
||||
#else
|
||||
|
||||
static void volume_agc_process(Volume *v, mblk_t *om){
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
static inline float compute_gain(float static_gain, float energy, float weight){
|
||||
float ret=static_gain*(1 - (energy*weight));
|
||||
|
|
@ -129,6 +170,12 @@ static int volume_set_peer(MSFilter *f, void *arg){
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int volume_set_agc(MSFilter *f, void *arg){
|
||||
Volume *v=(Volume*)f->data;
|
||||
v->agc_enabled=*(int*)arg;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int volume_set_ea_threshold(MSFilter *f, void*arg){
|
||||
Volume *v=(Volume*)f->data;
|
||||
float val=*(float*)arg;
|
||||
|
|
@ -162,30 +209,88 @@ static inline int16_t saturate(float val){
|
|||
return (val>32767) ? 32767 : ( (val<-32767) ? -32767 : val);
|
||||
}
|
||||
|
||||
static void volume_process(MSFilter *f){
|
||||
mblk_t *m;
|
||||
static float update_energy(int16_t *signal, int numsamples, float last_energy_value){
|
||||
int i;
|
||||
float en=last_energy_value;
|
||||
for (i=0;i<numsamples;++i){
|
||||
float s=(float)signal[i];
|
||||
en=(s*s*coef) + (1.0-coef)*en;
|
||||
}
|
||||
return en;
|
||||
}
|
||||
|
||||
static void apply_gain(mblk_t *m, float gain){
|
||||
int16_t *sample;
|
||||
Volume *v=(Volume*)f->data;
|
||||
float en=v->energy;
|
||||
while((m=ms_queue_get(f->inputs[0]))!=NULL){
|
||||
for ( sample=(int16_t*)m->b_rptr;
|
||||
sample<(int16_t*)m->b_wptr;
|
||||
++sample){
|
||||
float s=*sample;
|
||||
en=(s*s*coef) + (1.0-coef)*en;
|
||||
}
|
||||
if (v->peer){
|
||||
volume_echo_avoider_process(v);
|
||||
}
|
||||
if (v->gain!=1){
|
||||
for ( sample=(int16_t*)m->b_rptr;
|
||||
for ( sample=(int16_t*)m->b_rptr;
|
||||
sample<(int16_t*)m->b_wptr;
|
||||
++sample){
|
||||
float s=*sample;
|
||||
*sample=saturate(s*v->gain);
|
||||
float s=*sample;
|
||||
*sample=saturate(s*gain);
|
||||
}
|
||||
}
|
||||
|
||||
static void volume_preprocess(MSFilter *f){
|
||||
Volume *v=(Volume*)f->data;
|
||||
/*process agc by chunks of 10 ms*/
|
||||
v->nsamples=(int)(0.01*(float)v->sample_rate);
|
||||
if (v->agc_enabled){
|
||||
ms_message("AGC is enabled.");
|
||||
#ifdef HAVE_SPEEXDSP
|
||||
if (v->speex_pp==NULL){
|
||||
int tmp=1;
|
||||
v->speex_pp=speex_preprocess_state_init(v->nsamples,v->sample_rate);
|
||||
if (speex_preprocess_ctl(v->speex_pp,SPEEX_PREPROCESS_SET_AGC,&tmp)==-1){
|
||||
ms_warning("Speex AGC is not available.");
|
||||
}
|
||||
tmp=0;
|
||||
speex_preprocess_ctl(v->speex_pp,SPEEX_PREPROCESS_SET_VAD,&tmp);
|
||||
speex_preprocess_ctl(v->speex_pp,SPEEX_PREPROCESS_SET_DENOISE,&tmp);
|
||||
speex_preprocess_ctl(v->speex_pp,SPEEX_PREPROCESS_SET_DEREVERB,&tmp);
|
||||
}
|
||||
#else
|
||||
ms_error("No AGC possible, mediastreamer2 was compiled without libspeexdsp.");
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
static void volume_process(MSFilter *f){
|
||||
mblk_t *m;
|
||||
Volume *v=(Volume*)f->data;
|
||||
float en=v->energy;
|
||||
|
||||
if (v->agc_enabled){
|
||||
mblk_t *om;
|
||||
int nbytes=v->nsamples*2;
|
||||
ms_bufferizer_put_from_queue(v->buffer,f->inputs[0]);
|
||||
while(ms_bufferizer_get_avail(v->buffer)>=nbytes){
|
||||
om=allocb(nbytes,0);
|
||||
ms_bufferizer_read(v->buffer,om->b_wptr,nbytes);
|
||||
om->b_wptr+=nbytes;
|
||||
en=update_energy((int16_t*)om->b_rptr,om->b_wptr-om->b_rptr,en);
|
||||
volume_agc_process(v,om);
|
||||
|
||||
if (v->peer){
|
||||
volume_echo_avoider_process(v);
|
||||
}
|
||||
if (v->gain!=1){
|
||||
apply_gain(om,v->gain);
|
||||
}
|
||||
ms_queue_put(f->outputs[0],om);
|
||||
}
|
||||
}else{
|
||||
/*light processing: no agc. Work in place in the input buffer*/
|
||||
while((m=ms_queue_get(f->inputs[0]))!=NULL){
|
||||
en=update_energy((int16_t*)m->b_rptr,m->b_wptr-m->b_rptr,en);
|
||||
if (v->peer){
|
||||
volume_echo_avoider_process(v);
|
||||
}
|
||||
if (v->gain!=1){
|
||||
apply_gain(m,v->gain);
|
||||
}
|
||||
ms_queue_put(f->outputs[0],m);
|
||||
}
|
||||
ms_queue_put(f->outputs[0],m);
|
||||
}
|
||||
v->energy=en;
|
||||
}
|
||||
|
|
@ -199,19 +304,22 @@ static MSFilterMethod methods[]={
|
|||
{ MS_VOLUME_SET_EA_THRESHOLD , volume_set_ea_threshold },
|
||||
{ MS_VOLUME_SET_EA_SPEED , volume_set_ea_speed },
|
||||
{ MS_VOLUME_SET_EA_FORCE , volume_set_ea_force },
|
||||
{ MS_FILTER_SET_SAMPLE_RATE, volume_set_sample_rate },
|
||||
{ MS_VOLUME_ENABLE_AGC , volume_set_agc },
|
||||
{ 0 , NULL }
|
||||
};
|
||||
|
||||
#ifndef _MSC_VER
|
||||
MSFilterDesc ms_volume_desc={
|
||||
.name="MSVolume",
|
||||
.text=N_("A filter to make level measurements on 16 bits pcm audio stream"),
|
||||
.text=N_("A filter that controls and measure sound volume"),
|
||||
.id=MS_VOLUME_ID,
|
||||
.category=MS_FILTER_OTHER,
|
||||
.ninputs=1,
|
||||
.noutputs=1,
|
||||
.init=volume_init,
|
||||
.uninit=volume_uninit,
|
||||
.preprocess=volume_preprocess,
|
||||
.process=volume_process,
|
||||
.methods=methods
|
||||
};
|
||||
|
|
@ -219,7 +327,7 @@ MSFilterDesc ms_volume_desc={
|
|||
MSFilterDesc ms_volume_desc={
|
||||
MS_VOLUME_ID,
|
||||
"MSVolume",
|
||||
N_("A filter to make level measurements on 16 bits pcm audio stream"),
|
||||
N_("A filter that controls and measure sound volume"),
|
||||
MS_FILTER_OTHER,
|
||||
NULL,
|
||||
1,
|
||||
|
|
|
|||
|
|
@ -122,8 +122,10 @@ const char *usage="mediastream --local <port> --remote <ip:port> --payload <payl
|
|||
"[ --jitter <miliseconds>]\n"
|
||||
"[ --width <pixels>]\n"
|
||||
"[ --height <pixels> ]\n"
|
||||
"[ --bitrate <bits per seconds>]\n";
|
||||
static void run_media_streams(int localport, const char *remote_ip, int remoteport, int payload, const char *fmtp, int jitter, bool_t ec, int bitrate, MSVideoSize vs);
|
||||
"[ --bitrate <bits per seconds>]\n"
|
||||
"[ --ec (enable echo canceller)]\n"
|
||||
"[ --agc (enable automatic gain control)]\n";
|
||||
static void run_media_streams(int localport, const char *remote_ip, int remoteport, int payload, const char *fmtp, int jitter, bool_t ec, int bitrate, MSVideoSize vs, bool_t agc);
|
||||
|
||||
|
||||
int main(int argc, char * argv[])
|
||||
|
|
@ -136,6 +138,7 @@ int main(int argc, char * argv[])
|
|||
int bitrate=0;
|
||||
MSVideoSize vs;
|
||||
bool_t ec=FALSE;
|
||||
bool_t agc=FALSE;
|
||||
/*create the rtp session */
|
||||
ortp_init();
|
||||
ortp_set_log_level_mask(ORTP_MESSAGE|ORTP_WARNING|ORTP_ERROR|ORTP_FATAL);
|
||||
|
|
@ -188,14 +191,16 @@ int main(int argc, char * argv[])
|
|||
vs.height=atoi(argv[i]);
|
||||
}else if (strcmp(argv[i],"--ec")==0){
|
||||
ec=TRUE;
|
||||
}else if (strcmp(argv[i],"--agc")==0){
|
||||
agc=TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
run_media_streams(localport,ip,remoteport,payload,fmtp,jitter,ec,bitrate,vs);
|
||||
run_media_streams(localport,ip,remoteport,payload,fmtp,jitter,ec,bitrate,vs, agc);
|
||||
return 0;
|
||||
}
|
||||
|
||||
void run_media_streams(int localport, const char *remote_ip, int remoteport, int payload, const char *fmtp, int jitter, bool_t ec, int bitrate, MSVideoSize vs)
|
||||
void run_media_streams(int localport, const char *remote_ip, int remoteport, int payload, const char *fmtp, int jitter, bool_t ec, int bitrate, MSVideoSize vs, bool_t agc)
|
||||
{
|
||||
AudioStream *audio=NULL;
|
||||
#ifdef VIDEO_ENABLED
|
||||
|
|
@ -218,7 +223,13 @@ void run_media_streams(int localport, const char *remote_ip, int remoteport, in
|
|||
|
||||
if (pt->type!=PAYLOAD_VIDEO){
|
||||
printf("Starting audio stream.\n");
|
||||
audio=audio_stream_start(profile,localport,remote_ip,remoteport,payload,jitter, ec);
|
||||
MSSndCardManager *manager=ms_snd_card_manager_get();
|
||||
audio=audio_stream_new(localport,ms_is_ipv6(remote_ip));
|
||||
audio_stream_enable_automatic_gain_control(audio,agc);
|
||||
audio_stream_start_now(audio,profile,remote_ip,remoteport,remoteport+1,payload,jitter,
|
||||
ms_snd_card_manager_get_default_playback_card(manager),
|
||||
ms_snd_card_manager_get_default_capture_card(manager),
|
||||
ec);
|
||||
if (audio) session=audio->session;
|
||||
}else{
|
||||
#ifdef VIDEO_ENABLED
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue