예제 #1
0
void CSpeexEC::Init(int frame_size, int filter_length, int sampling_rate)
{
    Reset();
    
    if (frame_size<=0 || filter_length<=0 || sampling_rate<=0)
    {
        m_nFrameSize  =160;
        m_nFilterLen  = 160*8;
        m_nSampleRate = 8000;
    }
    else
    {
        m_nFrameSize  =frame_size;
        m_nFilterLen  = filter_length;
        m_nSampleRate = sampling_rate;
    }
    
    m_pState = speex_echo_state_init(m_nFrameSize, m_nFilterLen);
    m_pPreprocessorState = speex_preprocess_state_init(m_nFrameSize, m_nSampleRate);
    m_pfNoise = new int[m_nFrameSize+1];
    m_bHasInit = true;
    
    speex_echo_ctl(m_pState, SPEEX_ECHO_SET_SAMPLING_RATE, &m_nSampleRate);
    speex_preprocess_ctl(m_pPreprocessorState, SPEEX_PREPROCESS_SET_ECHO_STATE, m_pState);
}
예제 #2
0
static void speex_ec_preprocess(MSFilter *f){
	SpeexECState *s=(SpeexECState*)f->data;
	int delay_samples=0;
	mblk_t *m;

	s->echostarted=FALSE;
	s->filterlength=(s->tail_length_ms*s->samplerate)/1000;
	s->framesize=adjust_framesize(s->framesize_at_8000,s->samplerate);
	delay_samples=s->delay_ms*s->samplerate/1000;
	ms_message("Initializing speex echo canceler with framesize=%i, filterlength=%i, delay_samples=%i",
		s->framesize,s->filterlength,delay_samples);
	
	s->ecstate=speex_echo_state_init(s->framesize,s->filterlength);
	s->den = speex_preprocess_state_init(s->framesize, s->samplerate);
	speex_echo_ctl(s->ecstate, SPEEX_ECHO_SET_SAMPLING_RATE, &s->samplerate);
	speex_preprocess_ctl(s->den, SPEEX_PREPROCESS_SET_ECHO_STATE, s->ecstate);
	/* fill with zeroes for the time of the delay*/
	m=allocb(delay_samples*2,0);
	m->b_wptr+=delay_samples*2;
	ms_bufferizer_put (&s->delayed_ref,m);
	s->min_ref_samples=-1;
	s->nominal_ref_samples=delay_samples;
	audio_flow_controller_init(&s->afc);
	s->flow_control_time = f->ticker->time;
#ifdef SPEEX_ECHO_GET_BLOB
	apply_config(s);
#else
	if (s->state_str) ms_warning("This version of speex doesn't support echo canceller restoration state. Rebuild speex and mediatreamer2 if you want to use this feature.");
#endif
}
예제 #3
0
bool pa_speex_ec_init(pa_core *c, pa_echo_canceller *ec,
                      pa_sample_spec *rec_ss, pa_channel_map *rec_map,
                      pa_sample_spec *play_ss, pa_channel_map *play_map,
                      pa_sample_spec *out_ss, pa_channel_map *out_map,
                      uint32_t *nframes, const char *args) {
    int rate;
    uint32_t frame_size_ms, filter_size_ms;
    pa_modargs *ma;

    if (!(ma = pa_modargs_new(args, valid_modargs))) {
        pa_log("Failed to parse submodule arguments.");
        goto fail;
    }

    filter_size_ms = DEFAULT_FILTER_SIZE_MS;
    if (pa_modargs_get_value_u32(ma, "filter_size_ms", &filter_size_ms) < 0 || filter_size_ms < 1 || filter_size_ms > 2000) {
        pa_log("Invalid filter_size_ms specification");
        goto fail;
    }

    frame_size_ms = DEFAULT_FRAME_SIZE_MS;
    if (pa_modargs_get_value_u32(ma, "frame_size_ms", &frame_size_ms) < 0 || frame_size_ms < 1 || frame_size_ms > 200) {
        pa_log("Invalid frame_size_ms specification");
        goto fail;
    }

    pa_speex_ec_fixate_spec(rec_ss, rec_map, play_ss, play_map, out_ss, out_map);

    rate = out_ss->rate;
    *nframes = pa_echo_canceller_blocksize_power2(rate, frame_size_ms);

    pa_log_debug ("Using nframes %d, channels %d, rate %d", *nframes, out_ss->channels, out_ss->rate);
    ec->params.priv.speex.state = speex_echo_state_init_mc(*nframes, (rate * filter_size_ms) / 1000, out_ss->channels, out_ss->channels);

    if (!ec->params.priv.speex.state)
        goto fail;

    speex_echo_ctl(ec->params.priv.speex.state, SPEEX_ECHO_SET_SAMPLING_RATE, &rate);

    if (!pa_speex_ec_preprocessor_init(ec, out_ss, *nframes, ma))
        goto fail;

    pa_modargs_free(ma);
    return true;

fail:
    if (ma)
        pa_modargs_free(ma);
    if (ec->params.priv.speex.pp_state) {
        speex_preprocess_state_destroy(ec->params.priv.speex.pp_state);
        ec->params.priv.speex.pp_state = NULL;
    }
    if (ec->params.priv.speex.state) {
        speex_echo_state_destroy(ec->params.priv.speex.state);
        ec->params.priv.speex.state = NULL;
    }
    return false;
}
예제 #4
0
/*
 * Create the echo canceller.
 */
pjs_echo_canceller::pjs_echo_canceller(pj_pool_t *pool_, unsigned clock_rate,
		unsigned samples_per_frame_, unsigned tail_ms, unsigned latency_ms,
		unsigned options) {
	int sampling_rate = clock_rate;
	unsigned ptime, lat_cnt;
	unsigned delay_buf_opt = 0;

	lat_ready = PJ_FALSE;
	/* Create new pool and instantiate and init the EC */
	pool = pj_pool_create(pool_->factory, "ec%p", 256, 256, NULL);
	lock = new PPJ_SemaphoreLock(pool, NULL, 1, 1);
	samples_per_frame = samples_per_frame_;
	frm_buf = (pj_int16_t*) pj_pool_alloc(pool, samples_per_frame << 1);

    state = speex_echo_state_init(samples_per_frame,
    					clock_rate * tail_ms / 1000);

    speex_echo_ctl(state, SPEEX_ECHO_SET_SAMPLING_RATE,
		   &sampling_rate);

    preprocess = speex_preprocess_state_init(samples_per_frame,
						   clock_rate);
    tmp_frame = (pj_int16_t*) pj_pool_zalloc(pool, 2*samples_per_frame);

    speex_preprocess_ctl(preprocess, SPEEX_PREPROCESS_SET_ECHO_STATE,
 			state);

	pj_list_init(&lat_buf);
	pj_list_init(&lat_free);

	PJ_LOG(5, (THIS_FILE, "Creating echo canceler"));

	/* Create latency buffers */
	ptime = samples_per_frame * 1000 / clock_rate;
	if (latency_ms < ptime) {
		/* Give at least one frame delay to simplify programming */
		latency_ms = ptime;
	}
	lat_cnt = latency_ms / ptime;
	while (lat_cnt--) {
		struct frame *frm;

		frm = (struct frame*) pj_pool_alloc(pool,
				(samples_per_frame << 1) + sizeof(struct frame));
		pj_list_push_back(&lat_free, frm);
	}

	/* Create delay buffer to compensate drifts */
	if (options & PJMEDIA_ECHO_USE_SIMPLE_FIFO)
		delay_buf_opt |= PJMEDIA_DELAY_BUF_SIMPLE_FIFO;
	pjmedia_delay_buf_create(pool, NULL, clock_rate, samples_per_frame,
			1, (PJMEDIA_SOUND_BUFFER_COUNT + 1) * ptime, delay_buf_opt,
			&delay_buf);
	PJ_LOG(4, (THIS_FILE, "ECHO canceller created, clock_rate=%d, channel=%d, "
	"samples per frame=%d, tail length=%d ms, "
	"latency=%d ms", clock_rate, 1, samples_per_frame, tail_ms, latency_ms));
}
예제 #5
0
  JNIEXPORT void JNICALL Java_com_pullmi_shanghai_TalkActivity_speex_1EchoCanceller_1open
(JNIEnv *env, jobject jobj, jint jSampleRate, jint jBufSize, jint jTotalSize)
{
  //init 
  int sampleRate = jSampleRate;
  st = speex_echo_state_init(jBufSize, jTotalSize);
  den = speex_preprocess_state_init(jBufSize, sampleRate);
  speex_echo_ctl(st, SPEEX_ECHO_SET_SAMPLING_RATE, &sampleRate);
  speex_preprocess_ctl(den, SPEEX_PREPROCESS_SET_ECHO_STATE, st);
}
예제 #6
0
파일: speex.c 프로젝트: KimT/pulseaudio_kt
pa_bool_t pa_speex_ec_init(pa_core *c, pa_echo_canceller *ec,
                           pa_sample_spec *source_ss, pa_channel_map *source_map,
                           pa_sample_spec *sink_ss, pa_channel_map *sink_map,
                           uint32_t *blocksize, const char *args)
{
    int framelen, y, rate;
    uint32_t frame_size_ms, filter_size_ms;
    pa_modargs *ma;

    if (!(ma = pa_modargs_new(args, valid_modargs))) {
        pa_log("Failed to parse submodule arguments.");
        goto fail;
    }

    filter_size_ms = DEFAULT_FILTER_SIZE_MS;
    if (pa_modargs_get_value_u32(ma, "filter_size_ms", &filter_size_ms) < 0 || filter_size_ms < 1 || filter_size_ms > 2000) {
        pa_log("Invalid filter_size_ms specification");
        goto fail;
    }

    frame_size_ms = DEFAULT_FRAME_SIZE_MS;
    if (pa_modargs_get_value_u32(ma, "frame_size_ms", &frame_size_ms) < 0 || frame_size_ms < 1 || frame_size_ms > 200) {
        pa_log("Invalid frame_size_ms specification");
        goto fail;
    }

    pa_speex_ec_fixate_spec(source_ss, source_map, sink_ss, sink_map);

    rate = source_ss->rate;
    framelen = (rate * frame_size_ms) / 1000;
    /* framelen should be a power of 2, round down to nearest power of two */
    y = 1 << ((8 * sizeof (int)) - 2);
    while (y > framelen)
      y >>= 1;
    framelen = y;

    *blocksize = framelen * pa_frame_size (source_ss);

    pa_log_debug ("Using framelen %d, blocksize %u, channels %d, rate %d", framelen, *blocksize, source_ss->channels, source_ss->rate);

    ec->params.priv.speex.state = speex_echo_state_init_mc (framelen, (rate * filter_size_ms) / 1000, source_ss->channels, source_ss->channels);

    if (!ec->params.priv.speex.state)
	goto fail;

    speex_echo_ctl(ec->params.priv.speex.state, SPEEX_ECHO_SET_SAMPLING_RATE, &rate);

    pa_modargs_free(ma);
    return TRUE;

fail:
    if (ma)
	pa_modargs_free(ma);
    return FALSE;
}
예제 #7
0
RTC::ReturnCode_t EchoCanceler::onActivated(RTC::UniqueId ec_id)
{
  RTC_DEBUG(("onActivated start"));
  is_active = true;
  BufferClr();
  if ( mp_sest == NULL ) {
    int sampleRate = 16000;
    mp_sest = speex_echo_state_init(ECHOLEN, sampleRate * 2);
    speex_echo_ctl(mp_sest, SPEEX_ECHO_SET_SAMPLING_RATE, &sampleRate);
  }
  RTC_DEBUG(("onActivated finish"));
  return RTC::RTC_OK;
}
예제 #8
0
static int aec_alloc(struct speex_st **stp, void **ctx, struct aufilt_prm *prm)
{
    struct speex_st *st;
    uint32_t sampc;
    int err, tmp, fl;

    if (!stp || !ctx || !prm)
        return EINVAL;

    if (*ctx) {
        *stp = mem_ref(*ctx);
        return 0;
    }

    st = mem_zalloc(sizeof(*st), speex_aec_destructor);
    if (!st)
        return ENOMEM;

    sampc = prm->srate * prm->ch * prm->ptime / 1000;

    st->out = mem_alloc(2 * sampc, NULL);
    if (!st->out) {
        err = ENOMEM;
        goto out;
    }

    /* Echo canceller with 200 ms tail length */
    fl = 10 * sampc;
    st->state = speex_echo_state_init(sampc, fl);
    if (!st->state) {
        err = ENOMEM;
        goto out;
    }

    tmp = prm->srate;
    err = speex_echo_ctl(st->state, SPEEX_ECHO_SET_SAMPLING_RATE, &tmp);
    if (err < 0) {
        warning("speex_aec: speex_echo_ctl: err=%d\n", err);
    }

    info("speex_aec: Speex AEC loaded: srate = %uHz\n", prm->srate);

out:
    if (err)
        mem_deref(st);
    else
        *ctx = *stp = st;

    return err;
}
예제 #9
0
void AudioInput::resetAudioProcessor() {
	if (!bResetProcessor)
		return;

	int iArg;

	if (sppPreprocess)
		speex_preprocess_state_destroy(sppPreprocess);
	if (sesEcho)
		speex_echo_state_destroy(sesEcho);

	sppPreprocess = speex_preprocess_state_init(iFrameSize, iSampleRate);

	iArg = 1;
	speex_preprocess_ctl(sppPreprocess, SPEEX_PREPROCESS_SET_VAD, &iArg);
	speex_preprocess_ctl(sppPreprocess, SPEEX_PREPROCESS_SET_AGC, &iArg);
	speex_preprocess_ctl(sppPreprocess, SPEEX_PREPROCESS_SET_DENOISE, &iArg);
	speex_preprocess_ctl(sppPreprocess, SPEEX_PREPROCESS_SET_DEREVERB, &iArg);

	iArg = 30000;
	speex_preprocess_ctl(sppPreprocess, SPEEX_PREPROCESS_SET_AGC_TARGET, &iArg);

	float v = 30000.0f / static_cast<float>(g.s.iMinLoudness);
	iArg = iroundf(floorf(20.0f * log10f(v)));
	speex_preprocess_ctl(sppPreprocess, SPEEX_PREPROCESS_SET_AGC_MAX_GAIN, &iArg);

	iArg = -60;
	speex_preprocess_ctl(sppPreprocess, SPEEX_PREPROCESS_SET_AGC_DECREMENT, &iArg);

	iArg = g.s.iNoiseSuppress;
	speex_preprocess_ctl(sppPreprocess, SPEEX_PREPROCESS_SET_NOISE_SUPPRESS, &iArg);

	if (iEchoChannels > 0) {
		sesEcho = speex_echo_state_init_mc(iFrameSize, iFrameSize * 10, 1, bEchoMulti ? iEchoChannels : 1);
		iArg = iSampleRate;
		speex_echo_ctl(sesEcho, SPEEX_ECHO_SET_SAMPLING_RATE, &iArg);
		speex_preprocess_ctl(sppPreprocess, SPEEX_PREPROCESS_SET_ECHO_STATE, sesEcho);

		qWarning("AudioInput: ECHO CANCELLER ACTIVE");
	} else {
		sesEcho = NULL;
	}

	bResetEncoder = true;

	bResetProcessor = false;
}
예제 #10
0
extern "C" JNIEXPORT void Java_com_haitou_xiaoyoupai_imservice_support_audio_Speex_initEcho(
    JNIEnv *env, jobject jobj, jint frame_size, jint filter_length) {
    if (aec_status == AEC_OPENED)
        return;
    aec_status = AEC_OPENED;

    int frm_size;
    int f_length;

    frm_size = frame_size;
    f_length = filter_length;

    echoState = speex_echo_state_init(frame_size, filter_length);
    den = speex_preprocess_state_init(frame_size, sampleRate);
    speex_echo_ctl(echoState, SPEEX_ECHO_SET_SAMPLING_RATE, &sampleRate);
    speex_preprocess_ctl(den, SPEEX_PREPROCESS_SET_ECHO_STATE, echoState);
}
예제 #11
0
static void apply_config(SpeexECState *s){
	if (s->state_str!=NULL){
		size_t buflen=strlen(s->state_str);
		uint8_t *buffer=alloca(buflen);
		SpeexEchoStateBlob *blob;
		if ((buflen=b64_decode(s->state_str,strlen(s->state_str),buffer,buflen))<=0){
			ms_error("Could not decode base64 %s",s->state_str);
			return;
		}
		blob=speex_echo_state_blob_new_from_memory(buffer,buflen);
		if (blob==NULL){
			ms_error("Could not create blob from config string");
			return;
		}
		if (speex_echo_ctl(s->ecstate, SPEEX_ECHO_SET_BLOB, blob)!=0){
			ms_error("Could not apply speex echo blob !");
		}
		speex_echo_state_blob_free(blob);
		ms_message("speex echo state restored.");
	}	
}
예제 #12
0
static void fetch_config(SpeexECState *s){
	SpeexEchoStateBlob *blob=NULL;
	char *txt;
	size_t txt_len;

	if (s->ecstate==NULL) return;
	
	if (speex_echo_ctl(s->ecstate, SPEEX_ECHO_GET_BLOB, &blob)!=0){
		ms_error("Could not retrieve speex echo blob !");
		return;
	}
	txt_len=(speex_echo_state_blob_get_size(blob)*4)+1;
	txt=ms_malloc0(txt_len);
	if (b64_encode(speex_echo_state_blob_get_data(blob),speex_echo_state_blob_get_size(blob),
			txt,txt_len)==0){
		ms_error("Base64 encoding failed.");
		ms_free(txt);
		return;
	}
	speex_echo_state_blob_free(blob);
	if (s->state_str) ms_free(s->state_str);
	s->state_str=txt;
}
예제 #13
0
int main(int argc, char **argv)
{
   FILE *echo_fd, *ref_fd, *e_fd;
   short echo_buf[NN], ref_buf[NN], e_buf[NN];
   SpeexEchoState *st;
   SpeexPreprocessState *den;
   int sampleRate = 8000;

   if (argc != 4)
   {
      fprintf(stderr, "testecho mic_signal.sw speaker_signal.sw output.sw\n");
      exit(1);
   }
   echo_fd = fopen(argv[2], "rb");
   ref_fd  = fopen(argv[1],  "rb");
   e_fd    = fopen(argv[3], "wb");

   st = speex_echo_state_init(NN, TAIL);
   den = speex_preprocess_state_init(NN, sampleRate);
   speex_echo_ctl(st, SPEEX_ECHO_SET_SAMPLING_RATE, &sampleRate);
   speex_preprocess_ctl(den, SPEEX_PREPROCESS_SET_ECHO_STATE, st);

   while (!feof(ref_fd) && !feof(echo_fd))
   {
      fread(ref_buf, sizeof(short), NN, ref_fd);
      fread(echo_buf, sizeof(short), NN, echo_fd);
      speex_echo_cancellation(st, ref_buf, echo_buf, e_buf);
      speex_preprocess_run(den, e_buf);
      fwrite(e_buf, sizeof(short), NN, e_fd);
   }
   speex_echo_state_destroy(st);
   speex_preprocess_state_destroy(den);
   fclose(e_fd);
   fclose(echo_fd);
   fclose(ref_fd);
   return 0;
}
예제 #14
0
int main(int argc, char **argv)
{
   int echo_fd, ref_fd, e_fd;
   spx_int32_t noise[NN+1];
   short echo_buf[NN], ref_buf[NN], e_buf[NN];
   SpeexEchoState *st;
   SpeexPreprocessState *den;

   if (argc != 4)
   {
      fprintf (stderr, "testecho mic_signal.sw speaker_signal.sw output.sw\n");
      exit(1);
   }
   echo_fd = open (argv[2], O_RDONLY);
   ref_fd  = open (argv[1],  O_RDONLY);
   e_fd    = open (argv[3], O_WRONLY | O_CREAT | O_TRUNC, 0644);

   st = speex_echo_state_init(NN, TAIL);
   den = speex_preprocess_state_init(NN, 8000);
   int tmp = 8000;
   speex_echo_ctl(st, SPEEX_ECHO_SET_SAMPLING_RATE, &tmp);

   while (read(ref_fd, ref_buf, NN*2))
   {
      read(echo_fd, echo_buf, NN*2);
      speex_echo_cancel(st, ref_buf, echo_buf, e_buf, noise);
      /*speex_preprocess(den, e_buf, noise);*/
      write(e_fd, e_buf, NN*2);
   }
   speex_echo_state_destroy(st);
   speex_preprocess_state_destroy(den);
   close(e_fd);
   close(echo_fd);
   close(ref_fd);
   return 0;
}
예제 #15
0
파일: KotiAEC.cpp 프로젝트: aichew/KOTI_AEC
void KotiAEC_init(int16_t frame_size, int32_t sample_freq, AEC_CORE aec_core,
                  int speex_filter_length, int16_t agc_mode, int16_t compression_gain_db, uint8_t limiter_enable, float snd_amplification)
{
    int32_t speex_agc = 0; float speex_agc_level = 24000, speex_agc_level_tmp = 3000;
    int32_t speex_noise_suppress = -15;
    aec_core_used = aec_core;
    output_sound_amplification = snd_amplification;

    switch(aec_core)
    {
#ifdef WEBRTC_AEC_CORE_ENABLED
    case WEBRTC_AEC:
        if(webrtc_aec_pty.webrtc_aec == NULL)
        {
            webrtc_aec_pty.frame_size = frame_size;
            webrtc_aec_pty.sample_freq = sample_freq;
            webrtc_aec_pty.sndcard_sample_freq = sample_freq;
            webrtc_aec_pty.sndcard_delay_ms = ((float)speex_filter_length/sample_freq) * 1000;
            if( WebRtcAec_Create(&webrtc_aec_pty.webrtc_aec) == 0)
                WebRtcAec_Init(webrtc_aec_pty.webrtc_aec, webrtc_aec_pty.sample_freq, webrtc_aec_pty.sndcard_sample_freq);
            if( WebRtcNsx_Create((NsxHandle**)&webrtc_aec_pty.webrtc_ns) == 0)
            {
                WebRtcNsx_Init((NsxHandle*)webrtc_aec_pty.webrtc_ns, webrtc_aec_pty.sample_freq);
                WebRtcNsx_set_policy((NsxHandle*)webrtc_aec_pty.webrtc_ns, 1);
            }
            if( WebRtcAgc_Create(&webrtc_aec_pty.webrtc_agc) == 0)
            {
                WebRtcAgc_Init(webrtc_aec_pty.webrtc_agc, 0, 255, agc_mode/*kAgcModeFixedDigital*/, webrtc_aec_pty.sample_freq);
                WebRtcAgc_config_t conf = {0, compression_gain_db, limiter_enable};
                WebRtcAgc_set_config(webrtc_aec_pty.webrtc_agc, conf);
            }
        }
        else
        {
            WebRtcAec_Init(webrtc_aec_pty.webrtc_aec, webrtc_aec_pty.sample_freq, webrtc_aec_pty.sndcard_sample_freq);
        }
        break;
    case WEBRTC_AECM:
        if(webrtc_aecm_pty.webrtc_aec == NULL)
        {
            webrtc_aecm_pty.frame_size = frame_size;
            webrtc_aecm_pty.sample_freq = sample_freq;
            webrtc_aecm_pty.sndcard_sample_freq = sample_freq;
            webrtc_aecm_pty.sndcard_delay_ms = ((float)speex_filter_length/sample_freq) * 1000;
//            webrtc_aecm_pty.sndcard_delay_ms = speex_filter_length/frame_size;
            if( WebRtcAecm_Create(&webrtc_aecm_pty.webrtc_aec) == 0)
                WebRtcAecm_Init(webrtc_aecm_pty.webrtc_aec, webrtc_aecm_pty.sample_freq);
            if( WebRtcNsx_Create((NsxHandle**)&webrtc_aecm_pty.webrtc_ns) == 0)
            {
                WebRtcNsx_Init((NsxHandle*)webrtc_aecm_pty.webrtc_ns, webrtc_aecm_pty.sample_freq);
                WebRtcNsx_set_policy((NsxHandle*)webrtc_aecm_pty.webrtc_ns, 1);
            }
            if( WebRtcAgc_Create(&webrtc_aecm_pty.webrtc_agc) == 0)
            {
                WebRtcAgc_Init(webrtc_aecm_pty.webrtc_agc, 0, 255, agc_mode/*kAgcModeFixedDigital*/, webrtc_aecm_pty.sample_freq);
                WebRtcAgc_config_t conf = {0, compression_gain_db, limiter_enable};
                WebRtcAgc_set_config(webrtc_aecm_pty.webrtc_agc, conf);
            }
        }
        break;
#endif
    case SPEEX_AEC:
    default:
#ifdef OLD_SPEEX_AEC
        if(speex_aec_pty.speex_echo_state == NULL && speex_aec_pty.speex_preprocess_state == NULL)
        {
            speex_aec_pty.frame_size = frame_size;
            speex_aec_pty.sample_freq = sample_freq;
            speex_aec_pty.filter_length = speex_filter_length;
            if(speex_aec_pty.filter_length < frame_size)
                speex_aec_pty.filter_length = frame_size*FILTER_LENGTH_MULTIPLE_OF_FRAME_SIZE;

            speex_aec_pty.speex_echo_state = speex_echo_state_init(frame_size, speex_aec_pty.filter_length);
            speex_aec_pty.speex_preprocess_state = speex_preprocess_state_init(frame_size, sample_freq);
            speex_echo_ctl((SpeexEchoState*)speex_aec_pty.speex_echo_state, SPEEX_ECHO_SET_SAMPLING_RATE, &speex_aec_pty.sample_freq);

            speex_aec_pty.nosie = (int32_t*) malloc( (frame_size+1) * sizeof(int32_t) );
        }
#else
        if(speex_aec_pty.speex_echo_state == NULL && speex_aec_pty.speex_preprocess_state == NULL)
        {
            speex_aec_pty.frame_size = frame_size;
            speex_aec_pty.sample_freq = sample_freq;
            speex_aec_pty.filter_length = speex_filter_length;
            if(speex_aec_pty.filter_length < frame_size)
                speex_aec_pty.filter_length = frame_size*FILTER_LENGTH_MULTIPLE_OF_FRAME_SIZE;

            speex_aec_pty.speex_echo_state = speex_echo_state_init(frame_size, speex_aec_pty.filter_length);
            speex_aec_pty.speex_preprocess_state = speex_preprocess_state_init(frame_size, sample_freq);
            speex_echo_ctl((SpeexEchoState*)speex_aec_pty.speex_echo_state, SPEEX_ECHO_SET_SAMPLING_RATE, &speex_aec_pty.sample_freq);
            speex_preprocess_ctl((SpeexPreprocessState*)speex_aec_pty.speex_preprocess_state, SPEEX_PREPROCESS_SET_ECHO_STATE,
                                 speex_aec_pty.speex_echo_state);

            speex_aec_pty.nosie = (int32_t*) malloc( (frame_size+1) * sizeof(int32_t) );

            speex_preprocess_ctl((SpeexPreprocessState*)speex_aec_pty.speex_preprocess_state, SPEEX_PREPROCESS_SET_AGC, &speex_agc);
            speex_preprocess_ctl((SpeexPreprocessState*)speex_aec_pty.speex_preprocess_state, SPEEX_PREPROCESS_SET_AGC_LEVEL,
                                 &speex_agc_level);
            speex_preprocess_ctl((SpeexPreprocessState*)speex_aec_pty.speex_preprocess_state, SPEEX_PREPROCESS_SET_NOISE_SUPPRESS,
                                 &speex_noise_suppress);

            speex_aec_pty.speex_preprocess_state_tmp = speex_preprocess_state_init(frame_size, sample_freq);
            speex_preprocess_ctl((SpeexPreprocessState*)speex_aec_pty.speex_preprocess_state_tmp, SPEEX_PREPROCESS_SET_AGC, &speex_agc);
            speex_preprocess_ctl((SpeexPreprocessState*)speex_aec_pty.speex_preprocess_state_tmp, SPEEX_PREPROCESS_SET_AGC_LEVEL,
                                 &speex_agc_level_tmp);
            speex_preprocess_ctl((SpeexPreprocessState*)speex_aec_pty.speex_preprocess_state_tmp, SPEEX_PREPROCESS_SET_NOISE_SUPPRESS,
                                 &speex_noise_suppress);

//            int32_t speex_vad = 1;
//            int32_t speex_vad_prob_start = 80;
//            int32_t speex_vad_prob_continue = 65;
//            speex_preprocess_ctl((SpeexPreprocessState*)speex_aec_pty.speex_preprocess_state, SPEEX_PREPROCESS_SET_VAD, &speex_vad);
//            speex_preprocess_ctl((SpeexPreprocessState*)speex_aec_pty.speex_preprocess_state, SPEEX_PREPROCESS_SET_PROB_START,
//                                 &speex_vad_prob_start);
//            speex_preprocess_ctl((SpeexPreprocessState*)speex_aec_pty.speex_preprocess_state, SPEEX_PREPROCESS_SET_PROB_CONTINUE,
//                                 &speex_vad_prob_continue);

//            int32_t tmp = -1; float tmp1 = 0.0f;
//            speex_preprocess_ctl((SpeexPreprocessState*)speex_aec_pty.speex_preprocess_state, SPEEX_PREPROCESS_GET_DENOISE, &tmp);
//            printf("SPEEX_PREPROCESS_GET_DENOISE: %d\n", tmp);
//            speex_preprocess_ctl((SpeexPreprocessState*)speex_aec_pty.speex_preprocess_state, SPEEX_PREPROCESS_GET_NOISE_SUPPRESS, &tmp);
//            printf("SPEEX_PREPROCESS_GET_NOISE_SUPPRESS: %d\n", tmp);

//            speex_preprocess_ctl((SpeexPreprocessState*)speex_aec_pty.speex_preprocess_state, SPEEX_PREPROCESS_GET_AGC, &tmp);
//            printf("SPEEX_PREPROCESS_GET_AGC: %d\n", tmp);
//            speex_preprocess_ctl((SpeexPreprocessState*)speex_aec_pty.speex_preprocess_state, SPEEX_PREPROCESS_GET_VAD, &tmp);
//            printf("SPEEX_PREPROCESS_GET_VAD: %d\n", tmp);
//            speex_preprocess_ctl((SpeexPreprocessState*)speex_aec_pty.speex_preprocess_state, SPEEX_PREPROCESS_GET_PROB_START, &tmp);
//            printf("SPEEX_PREPROCESS_GET_PROB_START: %d\n", tmp);
//            speex_preprocess_ctl((SpeexPreprocessState*)speex_aec_pty.speex_preprocess_state, SPEEX_PREPROCESS_GET_PROB_CONTINUE, &tmp);
//            printf("SPEEX_PREPROCESS_GET_PROB_CONTINUE: %d\n", tmp);

//            speex_preprocess_ctl((SpeexPreprocessState*)speex_aec_pty.speex_preprocess_state, SPEEX_PREPROCESS_GET_AGC_LEVEL, &tmp1);
//            printf("SPEEX_PREPROCESS_GET_AGC_LEVEL: %f\n", tmp1);
//            speex_preprocess_ctl((SpeexPreprocessState*)speex_aec_pty.speex_preprocess_state, SPEEX_PREPROCESS_GET_AGC_DECREMENT, &tmp);
//            printf("SPEEX_PREPROCESS_GET_AGC_DECREMENT: %d\n", tmp);
//            speex_preprocess_ctl((SpeexPreprocessState*)speex_aec_pty.speex_preprocess_state, SPEEX_PREPROCESS_GET_AGC_INCREMENT, &tmp);
//            printf("SPEEX_PREPROCESS_GET_AGC_INCREMENT: %d\n", tmp);
//            speex_preprocess_ctl((SpeexPreprocessState*)speex_aec_pty.speex_preprocess_state, SPEEX_PREPROCESS_GET_AGC_MAX_GAIN, &tmp);
//            printf("SPEEX_PREPROCESS_GET_AGC_MAX_GAIN: %d\n", tmp);
//            speex_preprocess_ctl((SpeexPreprocessState*)speex_aec_pty.speex_preprocess_state, SPEEX_PREPROCESS_GET_AGC_GAIN, &tmp);
//            printf("SPEEX_PREPROCESS_GET_AGC_GAIN: %d\n", tmp);
//            speex_preprocess_ctl((SpeexPreprocessState*)speex_aec_pty.speex_preprocess_state, SPEEX_PREPROCESS_GET_AGC_TARGET, &tmp);
//            printf("SPEEX_PREPROCESS_GET_AGC_TARGET: %d\n", tmp);
//            speex_preprocess_ctl((SpeexPreprocessState*)speex_aec_pty.speex_preprocess_state, SPEEX_PREPROCESS_GET_AGC_LOUDNESS, &tmp);
//            printf("SPEEX_PREPROCESS_GET_AGC_LOUDNESS: %d\n", tmp);

//            speex_preprocess_ctl((SpeexPreprocessState*)speex_aec_pty.speex_preprocess_state, SPEEX_PREPROCESS_GET_ECHO_SUPPRESS, &tmp);
//            printf("SPEEX_PREPROCESS_GET_ECHO_SUPPRESS: %d\n", tmp);
//            speex_preprocess_ctl((SpeexPreprocessState*)speex_aec_pty.speex_preprocess_state, SPEEX_PREPROCESS_GET_ECHO_SUPPRESS_ACTIVE, &tmp);
//            printf("SPEEX_PREPROCESS_GET_ECHO_SUPPRESS_ACTIVE: %d\n", tmp);
        }
#endif

        break;
    }
}
예제 #16
0
/*
 * Create the AEC. 
 */
PJ_DEF(pj_status_t) speex_aec_create(pj_pool_t *pool,
				     unsigned clock_rate,
				     unsigned channel_count,
				     unsigned samples_per_frame,
				     unsigned tail_ms,
				     unsigned options,
				     void **p_echo )
{
    speex_ec *echo;
    int sampling_rate;

    *p_echo = NULL;

    echo = PJ_POOL_ZALLOC_T(pool, speex_ec);
    PJ_ASSERT_RETURN(echo != NULL, PJ_ENOMEM);

    echo->samples_per_frame = samples_per_frame;
    echo->options = options;

#if 0
    echo->state = speex_echo_state_init_mc(echo->samples_per_frame,
					   clock_rate * tail_ms / 1000,
					   channel_count, channel_count);
#else
    if (channel_count != 1) {
	PJ_LOG(2,("echo_speex.c", "Multichannel EC is not supported by this "
				  "echo canceller. It may not work."));
    }
    echo->state = speex_echo_state_init(echo->samples_per_frame,
    					clock_rate * tail_ms / 1000);
#endif
    if (echo->state == NULL) {
	return PJ_ENOMEM;
    }

    /* Set sampling rate */
    sampling_rate = clock_rate;
    speex_echo_ctl(echo->state, SPEEX_ECHO_SET_SAMPLING_RATE, 
		   &sampling_rate);

    echo->preprocess = speex_preprocess_state_init(echo->samples_per_frame,
						   clock_rate);
    if (echo->preprocess == NULL) {
	speex_echo_state_destroy(echo->state);
	return PJ_ENOMEM;
    }

    /* Disable all preprocessing, we only want echo cancellation */
#if 0
    disabled = 0;
    enabled = 1;
    speex_preprocess_ctl(echo->preprocess, SPEEX_PREPROCESS_SET_DENOISE, 
			 &enabled);
    speex_preprocess_ctl(echo->preprocess, SPEEX_PREPROCESS_SET_AGC, 
			 &disabled);
    speex_preprocess_ctl(echo->preprocess, SPEEX_PREPROCESS_SET_VAD, 
			 &disabled);
    speex_preprocess_ctl(echo->preprocess, SPEEX_PREPROCESS_SET_DEREVERB, 
			 &enabled);
#endif

    /* Control echo cancellation in the preprocessor */
   speex_preprocess_ctl(echo->preprocess, SPEEX_PREPROCESS_SET_ECHO_STATE, 
			echo->state);


    /* Create temporary frame for echo cancellation */
    echo->tmp_frame = (pj_int16_t*) pj_pool_zalloc(pool, 2*samples_per_frame);
    PJ_ASSERT_RETURN(echo->tmp_frame != NULL, PJ_ENOMEM);

    /* Done */
    *p_echo = echo;
    return PJ_SUCCESS;

}
예제 #17
0
void AudioEchoWidget::paintGL() {
	AudioInputPtr ai = g.ai;
	if (! ai || ! ai->sesEcho)
		return;

	ai->qmSpeex.lock();

	spx_int32_t sz;
	speex_echo_ctl(ai->sesEcho, SPEEX_ECHO_GET_IMPULSE_RESPONSE_SIZE, &sz);

	STACKVAR(spx_int32_t, w, sz);
	STACKVAR(float, W, sz);

	speex_echo_ctl(ai->sesEcho, SPEEX_ECHO_GET_IMPULSE_RESPONSE, w);

	ai->qmSpeex.unlock();

	int N = 160;
	int n = 2 * N;
	int M = sz / n;

	drft_lookup d;
	mumble_drft_init(&d, n);

	for (int j=0;j<M;j++) {
		for (int i=0;i<n;i++)
			W[j*n+i] = static_cast<float>(w[j*n+i]) / static_cast<float>(n);
		mumble_drft_forward(&d, & W[j*n]);
	}

	mumble_drft_clear(&d);

	float xscale = 1.0f / static_cast<float>(N);
	float yscale = 1.0f / static_cast<float>(M);

	glBegin(GL_QUADS);

	for (int j = 0; j < M; j++) {
		for (int i=1;i < N; i++) {
			float xa = static_cast<float>(i) * xscale;
			float ya = static_cast<float>(j) * yscale;

			float xb = xa + xscale;
			float yb = ya + yscale;

			mapEchoToColor(sqrtf(W[j*n+2*i]*W[j*n+2*i]+W[j*n+2*i-1]*W[j*n+2*i-1]) / 65536.f);
			glVertex2f(xa, ya);
			glVertex2f(xb, ya);
			glVertex2f(xb, yb);
			glVertex2f(xa, yb);
		}
	}

	glEnd();

	glBegin(GL_LINE_STRIP);
	glColor3f(1.0f, 0.0f, 1.0f);
	xscale = 1.0f / (2.0f*static_cast<float>(n));
	yscale = 1.0f / (200.0f * 32767.0f);
	for (int i=0;i<2*n;i++) {
		glVertex2f(static_cast<float>(i)*xscale, 0.5f + static_cast<float>(w[i]) * yscale);
	}
	glEnd();
}
예제 #18
0
파일: AudioInput.cpp 프로젝트: fffonion/V8
void AudioInput::encodeAudioFrame() {
	int iArg;
	//ClientUser *p=ClientUser::get(g.uiSession);
	int i;
	float sum;
	short max;

	short *psSource;

	iFrameCounter++;

	if (! bRunning) {
		return;
	}

	/*sum=1.0f;
	for (i=0;i<iFrameSize;i++)
		sum += static_cast<float>(psMic[i] * psMic[i]);

	iLevel = sqrtf(sum / static_cast<float>(iFrameSize)) * 9/32768.0f;
	dPeakMic=20.0f*log10f(sqrtf(sum / static_cast<float>(iFrameSize)) / 32768.0f);
	if (dPeakMic < -96.0f)
		dPeakMic = -96.0f;

	max = 1;
	for (i=0;i<iFrameSize;i++)
		max = static_cast<short>(abs(psMic[i]) > max ? abs(psMic[i]) : max);
	dMaxMic = max;

	if (psSpeaker && (iEchoChannels > 0)) {
		sum=1.0f;
		for (i=0;i<iFrameSize;i++)
			sum += static_cast<float>(psSpeaker[i] * psSpeaker[i]);
		dPeakSpeaker=20.0f*log10f(sqrtf(sum / static_cast<float>(iFrameSize)) / 32768.0f);
		if (dPeakSpeaker < -96.0f)
			dPeakSpeaker = -96.0f;
	} else {
		dPeakSpeaker = 0.0;
	}*/

	MutexLocker l(&qmSpeex);

	bResetProcessor = false;

	if (bResetProcessor) {
		if (sppPreprocess)
			speex_preprocess_state_destroy(sppPreprocess);
		if (sesEcho)
			speex_echo_state_destroy(sesEcho);

		sppPreprocess = speex_preprocess_state_init(iFrameSize, iSampleRate);

		iArg = 1;
		speex_preprocess_ctl(sppPreprocess, SPEEX_PREPROCESS_SET_VAD, &iArg);
		//speex_preprocess_ctl(sppPreprocess, SPEEX_PREPROCESS_SET_AGC, &iArg);
		speex_preprocess_ctl(sppPreprocess, SPEEX_PREPROCESS_SET_DENOISE, &iArg);
		speex_preprocess_ctl(sppPreprocess, SPEEX_PREPROCESS_SET_DEREVERB, &iArg);

		iArg = 30000;
		speex_preprocess_ctl(sppPreprocess, SPEEX_PREPROCESS_SET_AGC_TARGET, &iArg);

		float v = 30000.0f / static_cast<float>(g_struct.s.iMinLoudness);
		iArg = (floorf(20.0f * log10f(v)));
		speex_preprocess_ctl(sppPreprocess, SPEEX_PREPROCESS_SET_AGC_MAX_GAIN, &iArg);

		iArg = g_struct.s.iNoiseSuppress;
		speex_preprocess_ctl(sppPreprocess, SPEEX_PREPROCESS_SET_NOISE_SUPPRESS, &iArg);

		if (iEchoChannels > 0) {
			sesEcho = speex_echo_state_init_mc(iFrameSize, iFrameSize*10, 1, bEchoMulti ? iEchoChannels : 1);
			iArg = iSampleRate;
			speex_echo_ctl(sesEcho, SPEEX_ECHO_SET_SAMPLING_RATE, &iArg);
			speex_preprocess_ctl(sppPreprocess, SPEEX_PREPROCESS_SET_ECHO_STATE, sesEcho);

			Trace("AudioInput: ECHO CANCELLER ACTIVE");
		} else {
			sesEcho = NULL;
		}

		bResetProcessor = false;
	}

	int iIsSpeech=1;
	psSource = psMic;
/*
	//回音消除和音质处理
	if (bEcho && sesEcho && psSpeaker)
	{
		speex_echo_cancellation(sesEcho, psMic, psSpeaker, psClean);
		iIsSpeech=speex_preprocess_run(sppPreprocess, psClean);
		psSource = psClean;
	} 
	else {
		iIsSpeech=speex_preprocess_run(sppPreprocess, psMic);
		psSource = psMic;
	}*/

	/*sum=1.0f;
	for (i=0;i<iFrameSize;i++)
		sum += static_cast<float>(psSource[i] * psSource[i]);
	float micLevel = sqrtf(sum / static_cast<float>(iFrameSize));
	dPeakSignal=20.0f*log10f(micLevel / 32768.0f);
	if (dPeakSignal < -96.0f)
		dPeakSignal = -96.0f;

	spx_int32_t prob = 0;
	speex_preprocess_ctl(sppPreprocess, SPEEX_PREPROCESS_GET_PROB, &prob);
	fSpeechProb = static_cast<float>(prob) / 100.0f;

	float level = (g_struct.s.vsVAD == Settings::SignalToNoise) ? fSpeechProb : (1.0f + dPeakMic / 96.0f);

	if (level > g_struct.s.fVADmax)
		iIsSpeech = 1;
	else if (level > g_struct.s.fVADmin && bPreviousVoice)
		iIsSpeech = 1;
	else
		iIsSpeech = 0;

	if (! iIsSpeech) {
		iHoldFrames++;
		if (iHoldFrames < g_struct.s.iVoiceHold)
			iIsSpeech=1;
	} else {
		iHoldFrames = 0;
	}*/

	//tIdle.restart();
	/*
	int r = celt_encoder_ctl(ceEncoder, CELT_SET_POST_MDCT_CALLBACK(celtBack, NULL));
	qWarning() << "Set Callback" << r;
	*/

	//编码 speex或者CELT
	unsigned char buffer[512];
	int len;

	if (umtType != MessageHandler::UDPVoiceSpeex) {
		if (cCodec == NULL)
		{
			cCodec = new CELTCodec;
			umtType = MessageHandler::UDPVoiceCELT;
			ceEncoder = cCodec->encoderCreate();
		}
		else if (cCodec && ! bPreviousVoice) {
			cCodec->encoder_ctl(ceEncoder, CELT_RESET_STATE);
		}

		cCodec->encoder_ctl(ceEncoder, CELT_SET_PREDICTION(0));

		cCodec->encoder_ctl(ceEncoder,CELT_SET_BITRATE(iAudioQuality));
		len = cCodec->encode(ceEncoder, psSource, SAMPLE_RATE / 100, buffer, 512);
		iBitrate = len * 100 * 8;
	} 
	else {
		int vbr = 0;
		speex_encoder_ctl(esSpeex, SPEEX_GET_VBR_MAX_BITRATE, &vbr);
		if (vbr != iAudioQuality) {
			vbr = iAudioQuality;
			speex_encoder_ctl(esSpeex, SPEEX_SET_VBR_MAX_BITRATE, &vbr);
		}

		if (! bPreviousVoice)
			speex_encoder_ctl(esSpeex, SPEEX_RESET_STATE, NULL);

		speex_encode_int(esSpeex, psSource, &sbBits);
		len = speex_bits_write(&sbBits, reinterpret_cast<char *>(buffer), 127);
		iBitrate = len * 50 * 8;
		speex_bits_reset(&sbBits);
	}

	QByteArray qba;
	for(int i=0; i<len; i++)
	{
		qba.push_back(buffer[i]);
	}

	flushCheck(qba, false);

	if (! iIsSpeech)
		iBitrate = 0;

	bPreviousVoice = iIsSpeech;
}
예제 #19
0
static int tdav_speex_denoise_open(tmedia_denoise_t* self, uint32_t frame_size, uint32_t sampling_rate)
{
	tdav_speex_denoise_t *denoiser = (tdav_speex_denoise_t *)self;
	float f;
	int i;

	if(!denoiser->echo_state && TMEDIA_DENOISE(denoiser)->echo_supp_enabled){
		TSK_DEBUG_INFO("Init Aec frame_size[%u] filter_length[%u] SampleRate[%u]",
			(uint32_t)(frame_size* sizeof(spx_int16_t)),TMEDIA_DENOISE(denoiser)->echo_tail*frame_size,sampling_rate);
		if((denoiser->echo_state = speex_echo_state_init(frame_size, TMEDIA_DENOISE(denoiser)->echo_tail))){
			speex_echo_ctl(denoiser->echo_state, SPEEX_ECHO_SET_SAMPLING_RATE, &sampling_rate);
		}
	}

	if(!denoiser->preprocess_state_record && !denoiser->preprocess_state_playback){
		denoiser->frame_size = frame_size;

		if((denoiser->preprocess_state_record = speex_preprocess_state_init(frame_size, sampling_rate))
			&& (denoiser->preprocess_state_playback = speex_preprocess_state_init(frame_size, sampling_rate))
			){

				// Echo suppression
				if(denoiser->echo_state){
					int echo_supp , echo_supp_active = 0;

					speex_preprocess_ctl(denoiser->preprocess_state_record, SPEEX_PREPROCESS_SET_ECHO_STATE, denoiser->echo_state);

					TSK_FREE(denoiser->echo_output_frame);
					denoiser->echo_output_frame = tsk_calloc(denoiser->frame_size, sizeof(spx_int16_t));

					speex_preprocess_ctl(denoiser->preprocess_state_record, SPEEX_PREPROCESS_GET_ECHO_SUPPRESS , &echo_supp );
					speex_preprocess_ctl(denoiser->preprocess_state_record, SPEEX_PREPROCESS_GET_ECHO_SUPPRESS_ACTIVE , &echo_supp_active );                             
					TSK_DEBUG_INFO("AEC echo_supp level [%d] echo_supp_active level[%d] ", echo_supp , echo_supp_active);
					echo_supp = -60 ;
					echo_supp_active = -60 ;
					speex_preprocess_ctl(denoiser->preprocess_state_record, SPEEX_PREPROCESS_SET_ECHO_SUPPRESS , &echo_supp );
					speex_preprocess_ctl(denoiser->preprocess_state_record, SPEEX_PREPROCESS_SET_ECHO_SUPPRESS_ACTIVE , &echo_supp_active );                             
					// TRACES
					speex_preprocess_ctl(denoiser->preprocess_state_record, SPEEX_PREPROCESS_GET_ECHO_SUPPRESS , &echo_supp );
					speex_preprocess_ctl(denoiser->preprocess_state_record, SPEEX_PREPROCESS_GET_ECHO_SUPPRESS_ACTIVE , &echo_supp_active );                             
					TSK_DEBUG_INFO("New aec echo_supp level [%d] echo_supp_active level[%d] ", echo_supp , echo_supp_active);
				}

				// Noise suppression
				if(TMEDIA_DENOISE(denoiser)->noise_supp_enabled){
					TSK_DEBUG_INFO("SpeexDSP: Noise supp enabled");
					i = 1;
					speex_preprocess_ctl(denoiser->preprocess_state_record, SPEEX_PREPROCESS_SET_DENOISE, &i);
					speex_preprocess_ctl(denoiser->preprocess_state_playback, SPEEX_PREPROCESS_SET_DENOISE, &i);
					i = TMEDIA_DENOISE(denoiser)->noise_supp_level;
					speex_preprocess_ctl(denoiser->preprocess_state_record, SPEEX_PREPROCESS_SET_NOISE_SUPPRESS, &i);
					speex_preprocess_ctl(denoiser->preprocess_state_playback, SPEEX_PREPROCESS_SET_NOISE_SUPPRESS, &i);
				}
				else{
					i = 0;
					speex_preprocess_ctl(denoiser->preprocess_state_record, SPEEX_PREPROCESS_SET_DENOISE, &i);
					speex_preprocess_ctl(denoiser->preprocess_state_playback, SPEEX_PREPROCESS_SET_DENOISE, &i);
				}

				// Automatic gain control
				if(TMEDIA_DENOISE(denoiser)->agc_enabled){
					float agc_level = TMEDIA_DENOISE(denoiser)->agc_level;
					TSK_DEBUG_INFO("SpeexDSP: AGC enabled");
					
					i = 1;
					speex_preprocess_ctl(denoiser->preprocess_state_record, SPEEX_PREPROCESS_SET_AGC, &i);
					speex_preprocess_ctl(denoiser->preprocess_state_record, SPEEX_PREPROCESS_SET_AGC_LEVEL, &agc_level);
				}
				else{
					i = 0, f = 8000.0f;
					speex_preprocess_ctl(denoiser->preprocess_state_record, SPEEX_PREPROCESS_SET_AGC, &i);
					speex_preprocess_ctl(denoiser->preprocess_state_record, SPEEX_PREPROCESS_SET_AGC_LEVEL, &f);
				}

				// Voice Activity detection
				i = TMEDIA_DENOISE(denoiser)->vad_enabled ? 1 : 0;
				speex_preprocess_ctl(denoiser->preprocess_state_record, SPEEX_PREPROCESS_SET_VAD, &i);

				return 0;
		}
		else{
			TSK_DEBUG_ERROR("Failed to create Speex preprocessor state");
			return -2;
		}
	}

	return 0;
}
예제 #20
0
void AudioEchoWidget::paintEvent(QPaintEvent *) {
	QPainter paint(this);

	paint.scale(width(), height());
	paint.fillRect(rect(), Qt::black);

	AudioInputPtr ai = g.ai;
	if (! ai || ! ai->sesEcho)
		return;

	ai->qmSpeex.lock();

	spx_int32_t sz;
	speex_echo_ctl(ai->sesEcho, SPEEX_ECHO_GET_IMPULSE_RESPONSE_SIZE, &sz);

	STACKVAR(spx_int32_t, w, sz);
	STACKVAR(float, W, sz);

	speex_echo_ctl(ai->sesEcho, SPEEX_ECHO_GET_IMPULSE_RESPONSE, w);

	ai->qmSpeex.unlock();

	int N = 160;
	int n = 2 * N;
	int M = sz / n;

	drft_lookup d;
	mumble_drft_init(&d, n);

	for (int j=0;j<M;j++) {
		for (int i=0;i<n;i++)
			W[j*n+i] = static_cast<float>(w[j*n+i]) / static_cast<float>(n);
		mumble_drft_forward(&d, & W[j*n]);
	}

	mumble_drft_clear(&d);

	float xscale = 1.0f / static_cast<float>(N);
	float yscale = 1.0f / static_cast<float>(M);

	for (int j = 0; j < M; j++) {
		for (int i=1;i < N; i++) {
			float xa = static_cast<float>(i) * xscale;
			float ya = static_cast<float>(j) * yscale;

			float xb = xa + xscale;
			float yb = ya + yscale;

			const QColor &c = mapEchoToColor(sqrtf(W[j*n+2*i]*W[j*n+2*i]+W[j*n+2*i-1]*W[j*n+2*i-1]) / 65536.f);
			paint.fillRect(QRectF(QPointF(xa, ya), QPointF(xb, yb)), c);
		}
	}

	QPolygonF poly;
	xscale = 1.0f / (2.0f * static_cast<float>(n));
	yscale = 1.0f / (200.0f * 32767.0f);
	for (int i = 0; i < 2 * n; i++) {
		poly << QPointF(static_cast<float>(i) * xscale, 0.5f + static_cast<float>(w[i]) * yscale);
	}
	paint.setPen(QColor::fromRgbF(1.0f, 0.0f, 1.0f));
	paint.drawPolyline(poly);
}
예제 #21
0
void AudioInput::encodeAudioFrame() {
	int iArg;
	ClientPlayer *p=ClientPlayer::get(g.uiSession);
	int i;
	float sum;
	short max;

	short *psSource;

	iFrameCounter++;

	if (! bRunning) {
		return;
	}

	sum=1.0f;
	for (i=0;i<iFrameSize;i++)
		sum += static_cast<float>(psMic[i] * psMic[i]);
	dPeakMic=20.0f*log10f(sqrtf(sum / static_cast<float>(iFrameSize)) / 32768.0f);
	if (dPeakMic < -96.0f)
		dPeakMic = -96.0f;

	max = 1;
	for (i=0;i<iFrameSize;i++)
		max = static_cast<short>(abs(psMic[i]) > max ? abs(psMic[i]) : max);
	dMaxMic = max;

	if (g.bEchoTest) {
		STACKVAR(float, fft, iFrameSize);
		STACKVAR(float, power, iFrameSize);
		float scale = 1.f / static_cast<float>(iFrameSize);
		for (i=0;i<iFrameSize;i++)
			fft[i] = static_cast<float>(psMic[i]) * scale;
		mumble_drft_forward(&fftTable, fft);
		float mp = 0.0f;
		int bin = 0;
		power[0]=power[1]=0.0f;
		for (i=2;i < iFrameSize / 2;i++) {
			power[i] = sqrtf(fft[2*i]*fft[2*i]+fft[2*i-1]*fft[2*i-1]);
			if (power[i] > mp) {
				bin = i;
				mp = power[i];
			}
		}
		for (i=2;i< iFrameSize / 2;i++) {
			if (power[i] * 2 > mp) {
				if (i != bin)
					bin = 0;
			}
		}
		iBestBin = bin * 2;
	}

	if (iEchoChannels > 0) {
		sum=1.0f;
		for (i=0;i<iFrameSize;i++)
			sum += static_cast<float>(psSpeaker[i] * psSpeaker[i]);
		dPeakSpeaker=20.0f*log10f(sqrtf(sum / static_cast<float>(iFrameSize)) / 32768.0f);
		if (dPeakSpeaker < -96.0f)
			dPeakSpeaker = -96.0f;
	} else {
		dPeakSpeaker = 0.0;
	}

	QMutexLocker l(&qmSpeex);

	if (bResetProcessor) {
		if (sppPreprocess)
			speex_preprocess_state_destroy(sppPreprocess);
		if (sesEcho)
			speex_echo_state_destroy(sesEcho);

		sppPreprocess = speex_preprocess_state_init(iFrameSize, SAMPLE_RATE);

		iArg = 1;
		speex_preprocess_ctl(sppPreprocess, SPEEX_PREPROCESS_SET_VAD, &iArg);
		speex_preprocess_ctl(sppPreprocess, SPEEX_PREPROCESS_SET_DENOISE, &iArg);
		speex_preprocess_ctl(sppPreprocess, SPEEX_PREPROCESS_SET_AGC, &iArg);
		speex_preprocess_ctl(sppPreprocess, SPEEX_PREPROCESS_SET_DEREVERB, &iArg);

		iArg = 30000;
		speex_preprocess_ctl(sppPreprocess, SPEEX_PREPROCESS_SET_AGC_TARGET, &iArg);

		float v = 30000.0f / static_cast<float>(g.s.iMinLoudness);
		iArg = lroundf(floorf(20.0f * log10f(v)));
		speex_preprocess_ctl(sppPreprocess, SPEEX_PREPROCESS_SET_AGC_MAX_GAIN, &iArg);

		iArg = g.s.iNoiseSuppress;
		speex_preprocess_ctl(sppPreprocess, SPEEX_PREPROCESS_SET_NOISE_SUPPRESS, &iArg);

		if (iEchoChannels > 0) {
			sesEcho = speex_echo_state_init(iFrameSize, iFrameSize*10);
			iArg = SAMPLE_RATE;
			speex_echo_ctl(sesEcho, SPEEX_SET_SAMPLING_RATE, &iArg);
			speex_preprocess_ctl(sppPreprocess, SPEEX_PREPROCESS_SET_ECHO_STATE, sesEcho);

			jitter_buffer_reset(jb);
			qWarning("AudioInput: ECHO CANCELLER ACTIVE");
		} else {
			sesEcho = NULL;
		}

		iFrames = 0;
		speex_bits_reset(&sbBits);

		bResetProcessor = false;
	}

	int iIsSpeech;

	if (sesEcho) {
		speex_echo_cancellation(sesEcho, psMic, psSpeaker, psClean);
		iIsSpeech=speex_preprocess_run(sppPreprocess, psClean);
		psSource = psClean;
	} else {
		iIsSpeech=speex_preprocess_run(sppPreprocess, psMic);
		psSource = psMic;
	}

	sum=1.0f;
	for (i=0;i<iFrameSize;i++)
		sum += static_cast<float>(psSource[i] * psSource[i]);
	float micLevel = sqrtf(sum / static_cast<float>(iFrameSize));
	dPeakSignal=20.0f*log10f(micLevel / 32768.0f);
	if (dPeakSignal < -96.0f)
		dPeakSignal = -96.0f;

	spx_int32_t prob = 0;
	speex_preprocess_ctl(sppPreprocess, SPEEX_PREPROCESS_GET_PROB, &prob);
	fSpeechProb = static_cast<float>(prob) / 100.0f;

	float level = (g.s.vsVAD == Settings::SignalToNoise) ? fSpeechProb : (1.0f + dPeakMic / 96.0f);

	if (level > g.s.fVADmax)
		iIsSpeech = 1;
	else if (level > g.s.fVADmin && bPreviousVoice)
		iIsSpeech = 1;
	else
		iIsSpeech = 0;

	if (! iIsSpeech) {
		iHoldFrames++;
		if (iHoldFrames < g.s.iVoiceHold)
			iIsSpeech=1;
	} else {
		iHoldFrames = 0;
	}

	if (g.s.atTransmit == Settings::Continous)
		iIsSpeech = 1;
	else if (g.s.atTransmit == Settings::PushToTalk)
		iIsSpeech = g.s.uiDoublePush && ((g.uiDoublePush < g.s.uiDoublePush) || (g.tDoublePush.elapsed() < g.s.uiDoublePush));

	iIsSpeech = iIsSpeech || (g.iPushToTalk > 0) || (g.iAltSpeak > 0);

	if (g.s.bMute || ((g.s.lmLoopMode != Settings::Local) && p && p->bMute) || g.bPushToMute) {
		iIsSpeech = 0;
	}

	if (iIsSpeech) {
		iSilentFrames = 0;
	} else {
		iSilentFrames++;
		if (iSilentFrames > 200)
			iFrameCounter = 0;
	}

	if (p)
		p->setTalking(iIsSpeech, (g.iAltSpeak > 0));

	if (g.s.bPushClick && (g.s.atTransmit == Settings::PushToTalk)) {
		AudioOutputPtr ao = g.ao;
		if (iIsSpeech && ! bPreviousVoice && ao)
			ao->playSine(400.0f,1200.0f,5);
		else if (ao && !iIsSpeech && bPreviousVoice && ao)
			ao->playSine(620.0f,-1200.0f,5);
	}
	if (! iIsSpeech && ! bPreviousVoice) {
		iBitrate = 0;
		if (g.s.iIdleTime && ! g.s.bMute && ((tIdle.elapsed() / 1000000ULL) > g.s.iIdleTime)) {
			emit doMute();
			tIdle.restart();
		}
		return;
	}

	bPreviousVoice = iIsSpeech;

	tIdle.restart();

	if (! iIsSpeech) {
		memset(psMic, 0, sizeof(short) * iFrameSize);
	}

	if (g.s.bTransmitPosition && g.p && ! g.bCenterPosition && (iFrames == 0) && g.p->fetch()) {
		QByteArray q;
		QDataStream ds(&q, QIODevice::WriteOnly);
		ds << g.p->fPosition[0];
		ds << g.p->fPosition[1];
		ds << g.p->fPosition[2];

		speex_bits_pack(&sbBits, 13, 5);
		speex_bits_pack(&sbBits, q.size(), 4);

		const unsigned char *d=reinterpret_cast<const unsigned char*>(q.data());
		for (i=0;i<q.size();i++) {
			speex_bits_pack(&sbBits, d[i], 8);
		}
	}

	speex_encode_int(esEncState, psSource, &sbBits);
	iFrames++;

	speex_encoder_ctl(esEncState, SPEEX_GET_BITRATE, &iBitrate);

	flushCheck();
}
예제 #22
0
static void
AudioQualityImprovement_updatePreprocess(AudioQualityImprovement *aqi)
{
    if (aqi->echo)
    {
        int frameSize = 0;

        if ((aqi->echoFilterLengthInMillis > 0)
                && (aqi->sampleRate > 0)
                && speex_echo_ctl(
                    aqi->echo,
                    SPEEX_ECHO_GET_FRAME_SIZE, &frameSize))
            frameSize = 0;
        if (frameSize
                && (aqi->frameSize
                    == (frameSize * (16 /* sampleSizeInBits */ / 8))))
        {
            int echoFilterLength
                = (int)
                    ((aqi->sampleRate * aqi->echoFilterLengthInMillis)
                        / 1000);

            if (aqi->filterLengthOfEcho != echoFilterLength)
                frameSize = 0;
        }
        else
            frameSize = 0;
        if (frameSize < 1)
        {
            if (aqi->preprocess)
            {
                speex_preprocess_ctl(
                    aqi->preprocess,
                    SPEEX_PREPROCESS_SET_ECHO_STATE, NULL);
            }
            speex_echo_state_destroy(aqi->echo);
            aqi->echo = NULL;
        }
    }
    if (aqi->preprocess
            && ((aqi->frameSize != aqi->frameSizeOfPreprocess)
                || (aqi->sampleRate != aqi->sampleRateOfPreprocess)))
    {
        speex_preprocess_state_destroy(aqi->preprocess);
        aqi->preprocess = NULL;
    }
    if ((aqi->frameSize > 0) && (aqi->sampleRate > 0))
    {
        if (aqi->echoFilterLengthInMillis > 0)
        {
            if (!(aqi->echo))
            {
                int echoFrameSize
                    = aqi->frameSize / (16 /* sampleSizeInBits */ / 8);
                int echoFilterLength
                    = (int)
                        ((aqi->sampleRate * aqi->echoFilterLengthInMillis)
                            / 1000);

                aqi->echo
                    = speex_echo_state_init(echoFrameSize, echoFilterLength);
                aqi->filterLengthOfEcho = echoFilterLength;
                /*
                 * Since echo has just been (re)created, make sure that the
                 * delay in play will happen again taking into consideration the
                 * latest frameSize.
                 */
                if (aqi->play)
                    AudioQualityImprovement_updatePlayIsDelaying(aqi);
            }
            if (aqi->echo)
            {
                speex_echo_ctl(
                    aqi->echo,
                    SPEEX_ECHO_SET_SAMPLING_RATE, &(aqi->sampleRate));
            }
        }
        if (aqi->denoise || aqi->echo)
        {
            if (!(aqi->preprocess))
            {
                aqi->preprocess
                    = speex_preprocess_state_init(
                        aqi->frameSize / (16 /* sampleSizeInBits */ / 8),
                        aqi->sampleRate);
                aqi->frameSizeOfPreprocess = aqi->frameSize;
                aqi->sampleRateOfPreprocess = aqi->sampleRate;
                if (aqi->preprocess)
                {
                    int on = 1;

                    speex_preprocess_ctl(
                        aqi->preprocess,
                        SPEEX_PREPROCESS_SET_DEREVERB, &on);
                    speex_preprocess_ctl(
                        aqi->preprocess,
                        SPEEX_PREPROCESS_SET_VAD, &on);
                }
            }
            if (aqi->preprocess)
            {
                int denoise = (aqi->denoise == JNI_TRUE) ? 1 : 0;

                speex_preprocess_ctl(
                    aqi->preprocess,
                    SPEEX_PREPROCESS_SET_DENOISE, &denoise);
                if (aqi->echo)
                {
                    speex_preprocess_ctl(
                        aqi->preprocess,
                        SPEEX_PREPROCESS_SET_ECHO_STATE, aqi->echo);
                }
            }
        }
    }
}
예제 #23
0
파일: AudioInput.cpp 프로젝트: fffonion/V8
void AudioInput::encodeAudioFrame() {
	int iArg;
	//ClientUser *p=ClientUser::get(g.uiSession);
	int i;
	float sum;
	short max;

	short *psSource;

	iFrameCounter++;

	if (! bRunning) {
		return;
	}

	MutexLocker l(&qmSpeex);

	bResetProcessor = false;

	if (bResetProcessor) {
		if (sppPreprocess)
			speex_preprocess_state_destroy(sppPreprocess);
		if (sesEcho)
			speex_echo_state_destroy(sesEcho);

		sppPreprocess = speex_preprocess_state_init(iFrameSize, iSampleRate);

		iArg = 1;
		speex_preprocess_ctl(sppPreprocess, SPEEX_PREPROCESS_SET_VAD, &iArg);
		//speex_preprocess_ctl(sppPreprocess, SPEEX_PREPROCESS_SET_AGC, &iArg);
		speex_preprocess_ctl(sppPreprocess, SPEEX_PREPROCESS_SET_DENOISE, &iArg);
		speex_preprocess_ctl(sppPreprocess, SPEEX_PREPROCESS_SET_DEREVERB, &iArg);

		iArg = 30000;
		speex_preprocess_ctl(sppPreprocess, SPEEX_PREPROCESS_SET_AGC_TARGET, &iArg);

		float v = 30000.0f / static_cast<float>(g_struct.s.iMinLoudness);
		iArg = (floorf(20.0f * log10f(v)));
		speex_preprocess_ctl(sppPreprocess, SPEEX_PREPROCESS_SET_AGC_MAX_GAIN, &iArg);

		iArg = g_struct.s.iNoiseSuppress;
		speex_preprocess_ctl(sppPreprocess, SPEEX_PREPROCESS_SET_NOISE_SUPPRESS, &iArg);

		if (iEchoChannels > 0) {
			sesEcho = speex_echo_state_init_mc(iFrameSize, iFrameSize*10, 1, bEchoMulti ? iEchoChannels : 1);
			iArg = iSampleRate;
			speex_echo_ctl(sesEcho, SPEEX_ECHO_SET_SAMPLING_RATE, &iArg);
			speex_preprocess_ctl(sppPreprocess, SPEEX_PREPROCESS_SET_ECHO_STATE, sesEcho);

			Trace("AudioInput: ECHO CANCELLER ACTIVE");
		} else {
			sesEcho = NULL;
		}

		bResetProcessor = false;
	}

	int iIsSpeech=1;
	psSource = psMic;
/*
	//回音消除和音质处理
	if (bEcho && sesEcho && psSpeaker)
	{
		speex_echo_cancellation(sesEcho, psMic, psSpeaker, psClean);
		iIsSpeech=speex_preprocess_run(sppPreprocess, psClean);
		psSource = psClean;
	} 
	else {
		iIsSpeech=speex_preprocess_run(sppPreprocess, psMic);
		psSource = psMic;
	}*/

	/*sum=1.0f;
	for (i=0;i<iFrameSize;i++)
		sum += static_cast<float>(psSource[i] * psSource[i]);
	float micLevel = sqrtf(sum / static_cast<float>(iFrameSize));
	dPeakSignal=20.0f*log10f(micLevel / 32768.0f);
	if (dPeakSignal < -96.0f)
		dPeakSignal = -96.0f;

	spx_int32_t prob = 0;
	speex_preprocess_ctl(sppPreprocess, SPEEX_PREPROCESS_GET_PROB, &prob);
	fSpeechProb = static_cast<float>(prob) / 100.0f;

	float level = (g_struct.s.vsVAD == Settings::SignalToNoise) ? fSpeechProb : (1.0f + dPeakMic / 96.0f);

	if (level > g_struct.s.fVADmax)
		iIsSpeech = 1;
	else if (level > g_struct.s.fVADmin && bPreviousVoice)
		iIsSpeech = 1;
	else
		iIsSpeech = 0;

	if (! iIsSpeech) {
		iHoldFrames++;
		if (iHoldFrames < g_struct.s.iVoiceHold)
			iIsSpeech=1;
	} else {
		iHoldFrames = 0;
	}*/

	//tIdle.restart();
	/*
	int r = celt_encoder_ctl(ceEncoder, CELT_SET_POST_MDCT_CALLBACK(celtBack, NULL));
	qWarning() << "Set Callback" << r;
	*/

	//编码 speex或者CELT
	unsigned char buffer[512];
	int len;

	if (umtType == MessageHandler::UDPVoiceCELT) {
		if (cCodec == NULL)
		{
			cCodec = CELTCodec::instance();
			ceEncoder = cCodec->encoderCreate();
		}
		else if (cCodec && ! bPreviousVoice) {
			cCodec->encoder_ctl(ceEncoder, CELT_RESET_STATE);
		}

		cCodec->encoder_ctl(ceEncoder, CELT_SET_PREDICTION(0));

		cCodec->encoder_ctl(ceEncoder,CELT_SET_BITRATE(iAudioQuality));
		len = cCodec->encode(ceEncoder, psSource, SAMPLE_RATE / 50, buffer, 512);
		iBitrate = len * 50 * 8;
		
		/*////////////////////////////////////////////////////////////////////////

		if (m_de_cdDecoder == NULL) {
			m_de_cdDecoder = cCodec->decoderCreate();
		}
		
		celt_int16 fout2[2560]={0};

		if (cCodec)
		{
			int len3 = cCodec->decode(m_de_cdDecoder, buffer, len, fout2, SAMPLE_RATE / 50);
			len3++;

			UINT dwDataWrote;
			if( FAILED(g_pWaveFile.Write( SAMPLE_RATE / 50*2*2, (BYTE*)fout2, 
				&dwDataWrote ) ))
			{
				int a=0;
				a++;
			}
			else
			{
				OutputDebugString(L"plushuwav g_pWaveFile.Write 3");				
			}
		}

		///////////////////////////////////////////////////////////////////////*/
	} 
	else {
		assert(0);
	}

	QByteArray qba;
	for(int i=0; i<len; i++)
	{
		qba.push_back(buffer[i]);
	}

	flushCheck(qba, false);

	if (! iIsSpeech)
		iBitrate = 0;

	bPreviousVoice = iIsSpeech;
}
예제 #24
0
파일: voe.c 프로젝트: pharmafirma/reconos
int main(int argc, char **argv)
{
	int sd, rc, n, tmp;
	char msg[MAX_MSG];
	int nfds;
	int send_timestamp = 0;
	int recv_started = 0;
	struct pollfd *pfds;
	struct alsa_dev *dev;
	CELTEncoder *enc_state;
	CELTDecoder *dec_state;
	CELTMode *mode;
	struct sched_param param;
	JitterBuffer *jitter;
	SpeexEchoState *echo_state;
	char mac_own[6], mac_remote[6];

	if (argc != 4)
		panic("Usage %s plughw:0,0 <lmac in xx:xx:xx:xx:xx:xx> <rmac>\n", argv[0]);
 
	register_signal(SIGINT, sighandler);

	hack_mac(mac_own, argv[2], strlen(argv[2]));
	hack_mac(mac_remote, argv[3], strlen(argv[3]));
 
	sd = socket(AF_LANA, SOCK_RAW, 0);
	if (sd < 0)
		panic("%s: cannot open socket \n", argv[0]);

	printf("If ready hit key!\n"); //user must do binding
	getchar();

	dev = alsa_open(argv[1], SAMPLING_RATE, CHANNELS, FRAME_SIZE);

	mode = celt_mode_create(SAMPLING_RATE, FRAME_SIZE, NULL);
	enc_state = celt_encoder_create(mode, CHANNELS, NULL);
	dec_state = celt_decoder_create(mode, CHANNELS, NULL);

	param.sched_priority = sched_get_priority_min(SCHED_FIFO);
	if (sched_setscheduler(0, SCHED_FIFO, &param))
		whine("sched_setscheduler error!\n");
   
	/* Setup all file descriptors for poll()ing */
	nfds = alsa_nfds(dev);
	pfds = xmalloc(sizeof(*pfds) * (nfds + 1));

	alsa_getfds(dev, pfds, nfds);

	pfds[nfds].fd = sd;
	pfds[nfds].events = POLLIN;

	/* Setup jitter buffer using decoder */
	jitter = jitter_buffer_init(FRAME_SIZE);
	tmp = FRAME_SIZE;
	jitter_buffer_ctl(jitter, JITTER_BUFFER_SET_MARGIN, &tmp);

	/* Echo canceller with 200 ms tail length */
	echo_state = speex_echo_state_init(FRAME_SIZE, 10 * FRAME_SIZE);
	tmp = SAMPLING_RATE;
	speex_echo_ctl(echo_state, SPEEX_ECHO_SET_SAMPLING_RATE, &tmp);

	register_signal_f(SIGALRM, timer_elapsed, SA_SIGINFO);

	alsa_start(dev);
	printf("ALSA started!\n");

	itimer.it_interval.tv_sec = 0;
	itimer.it_interval.tv_usec = interval;
	itimer.it_value.tv_sec = 0;
	itimer.it_value.tv_usec = interval;
	setitimer(ITIMER_REAL, &itimer, NULL);

	while (!sigint) {
		poll(pfds, nfds + 1, -1);

		/* Received packets */
		if (pfds[nfds].revents & POLLIN) {
			memset(msg, 0, MAX_MSG);
			n = recv(sd, msg, MAX_MSG, 0);
			if (n <= 0)
				goto do_alsa;
			pkts_in++;
			int recv_timestamp;
			memcpy(&recv_timestamp, msg, sizeof(recv_timestamp));
			JitterBufferPacket packet;
			packet.data = msg+4/*+6+6+2*/;
			packet.len = n-4/*-6-6-2*/;
			packet.timestamp = recv_timestamp;
			packet.span = FRAME_SIZE;
			packet.sequence = 0;

			/* Put content of the packet into the jitter buffer,
			   except for the pseudo-header */
			jitter_buffer_put(jitter, &packet);
			recv_started = 1;
		}
do_alsa:
		/* Ready to play a frame (playback) */
		if (alsa_play_ready(dev, pfds, nfds)) {
			short pcm[FRAME_SIZE * CHANNELS] = {0};
			if (recv_started) {
				JitterBufferPacket packet;
				/* Get audio from the jitter buffer */
				packet.data = msg;
				packet.len  = MAX_MSG;
				jitter_buffer_tick(jitter);
				jitter_buffer_get(jitter, &packet, FRAME_SIZE,
						  NULL);
				if (packet.len == 0)
					packet.data=NULL;
				celt_decode(dec_state, (const unsigned char *)
					    packet.data, packet.len, pcm);
			}
			/* Playback the audio and reset the echo canceller
			   if we got an underrun */

			alsa_write(dev, pcm, FRAME_SIZE);
//			if (alsa_write(dev, pcm, FRAME_SIZE)) 
//				speex_echo_state_reset(echo_state);
			/* Put frame into playback buffer */
//			speex_echo_playback(echo_state, pcm);
		}

		/* Audio available from the soundcard (capture) */
		if (alsa_cap_ready(dev, pfds, nfds)) {
			short pcm[FRAME_SIZE * CHANNELS];
			      //pcm2[FRAME_SIZE * CHANNELS];
			char outpacket[MAX_MSG];

			alsa_read(dev, pcm, FRAME_SIZE);
			/* Perform echo cancellation */
//			speex_echo_capture(echo_state, pcm, pcm2);
//			for (i = 0; i < FRAME_SIZE * CHANNELS; ++i)
//				pcm[i] = pcm2[i];

			celt_encode(enc_state, pcm, NULL, (unsigned char *)
				    (outpacket+4+6+6+2), PACKETSIZE);

			/* Pseudo header: four null bytes and a 32-bit
			   timestamp; XXX hack */
			memcpy(outpacket,mac_remote,6);
			memcpy(outpacket+6,mac_own,6);
			outpacket[6+6] = (uint8_t) 0xac;
			outpacket[6+6+1] = (uint8_t) 0xdc;
			memcpy(outpacket+6+6+2, &send_timestamp, sizeof(send_timestamp));
			send_timestamp += FRAME_SIZE;

			rc = sendto(sd, outpacket, PACKETSIZE+4+6+6+2, 0, NULL, 0);
			if (rc < 0)
				panic("cannot send to socket");
			pkts_out++;
		}
	}

	itimer.it_interval.tv_sec = 0;
	itimer.it_interval.tv_usec = 0;
	itimer.it_value.tv_sec = 0;
	itimer.it_value.tv_usec = 0;
	setitimer(ITIMER_REAL, &itimer, NULL); 

	close(sd);
	return 0;
}
예제 #25
0
파일: speex.c 프로젝트: cktakahasi/pa
pa_bool_t pa_speex_ec_init(pa_core *c, pa_echo_canceller *ec,
                           pa_sample_spec *source_ss, pa_channel_map *source_map,
                           pa_sample_spec *sink_ss, pa_channel_map *sink_map,
                           uint32_t *nframes, const char *args)
{
    int rate;
    uint32_t y, frame_size_ms, filter_size_ms;
    pa_modargs *ma;

    if (!(ma = pa_modargs_new(args, valid_modargs))) {
        pa_log("Failed to parse submodule arguments.");
        goto fail;
    }

    filter_size_ms = DEFAULT_FILTER_SIZE_MS;
    if (pa_modargs_get_value_u32(ma, "filter_size_ms", &filter_size_ms) < 0 || filter_size_ms < 1 || filter_size_ms > 2000) {
        pa_log("Invalid filter_size_ms specification");
        goto fail;
    }

    frame_size_ms = DEFAULT_FRAME_SIZE_MS;
    if (pa_modargs_get_value_u32(ma, "frame_size_ms", &frame_size_ms) < 0 || frame_size_ms < 1 || frame_size_ms > 200) {
        pa_log("Invalid frame_size_ms specification");
        goto fail;
    }

    pa_speex_ec_fixate_spec(source_ss, source_map, sink_ss, sink_map);

    rate = source_ss->rate;
    *nframes = (rate * frame_size_ms) / 1000;
    /* nframes should be a power of 2, round down to nearest power of two */
    y = 1 << ((8 * sizeof (uint32_t)) - 2);
    while (y > *nframes)
      y >>= 1;
    *nframes = y;

    pa_log_debug ("Using nframes %d, channels %d, rate %d", *nframes, source_ss->channels, source_ss->rate);

    ec->params.priv.speex.state = speex_echo_state_init_mc (*nframes, (rate * filter_size_ms) / 1000, source_ss->channels, source_ss->channels);

    if (!ec->params.priv.speex.state)
        goto fail;

    speex_echo_ctl(ec->params.priv.speex.state, SPEEX_ECHO_SET_SAMPLING_RATE, &rate);

    if (!pa_speex_ec_preprocessor_init(ec, source_ss, *nframes, ma))
        goto fail;

    pa_modargs_free(ma);
    return TRUE;

fail:
    if (ma)
        pa_modargs_free(ma);
    if (ec->params.priv.speex.pp_state) {
        speex_preprocess_state_destroy(ec->params.priv.speex.pp_state);
        ec->params.priv.speex.pp_state = NULL;
    }
    if (ec->params.priv.speex.state) {
        speex_echo_state_destroy(ec->params.priv.speex.state);
        ec->params.priv.speex.state = NULL;
    }
    return FALSE;
}
예제 #26
0
int main(int argc, char *argv[])
{

    int sd, rc, n;
    int i;
    struct sockaddr_in cliAddr, remoteAddr;
    char msg[MAX_MSG];
    struct hostent *h;
    int local_port, remote_port;
    int nfds;
    struct pollfd *pfds;
    SpeexPreprocessState *preprocess;
    AlsaDevice *audio_dev;
    int tmp;

    if (argc != 5)
    {
        fprintf(stderr, "wrong options\n");
        exit(1);
    }

    h = gethostbyname(argv[2]);
    if(h==NULL) {
        fprintf(stderr, "%s: unknown host '%s' \n", argv[0], argv[1]);
        exit(1);
    }

    local_port = atoi(argv[3]);
    remote_port = atoi(argv[4]);

    printf("%s: sending data to '%s' (IP : %s) \n", argv[0], h->h_name,
           inet_ntoa(*(struct in_addr *)h->h_addr_list[0]));

    {
        remoteAddr.sin_family = h->h_addrtype;
        memcpy((char *) &remoteAddr.sin_addr.s_addr,
               h->h_addr_list[0], h->h_length);
        remoteAddr.sin_port = htons(remote_port);
    }
    /* socket creation */
    sd=socket(AF_INET, SOCK_DGRAM, 0);
    if(sd<0) {
        printf("%s: cannot open socket \n",argv[0]);
        exit(1);
    }

    /* bind any port */
    cliAddr.sin_family = AF_INET;
    cliAddr.sin_addr.s_addr = htonl(INADDR_ANY);
    cliAddr.sin_port = htons(local_port);

    rc = bind(sd, (struct sockaddr *) &cliAddr, sizeof(cliAddr));
    if(rc<0) {
        printf("%s: cannot bind port\n", argv[0]);
        exit(1);
    }

    /* Setup audio device */
    audio_dev = alsa_device_open(argv[1], SAMPLING_RATE, 1, FRAME_SIZE);

    /* Setup the encoder and decoder in wideband */
    void *enc_state, *dec_state;
    enc_state = speex_encoder_init(&speex_wb_mode);
    tmp = 8;
    speex_encoder_ctl(enc_state, SPEEX_SET_QUALITY, &tmp);
    tmp = 2;
    speex_encoder_ctl(enc_state, SPEEX_SET_COMPLEXITY, &tmp);
    dec_state = speex_decoder_init(&speex_wb_mode);
    tmp = 1;
    speex_decoder_ctl(dec_state, SPEEX_SET_ENH, &tmp);
    SpeexBits enc_bits, dec_bits;
    speex_bits_init(&enc_bits);
    speex_bits_init(&dec_bits);


    struct sched_param param;
    /*param.sched_priority = 40; */
    param.sched_priority = sched_get_priority_min(SCHED_FIFO);
    if (sched_setscheduler(0,SCHED_FIFO,&param))
        perror("sched_setscheduler");

    int send_timestamp = 0;
    int recv_started=0;

    /* Setup all file descriptors for poll()ing */
    nfds = alsa_device_nfds(audio_dev);
    pfds = malloc(sizeof(*pfds)*(nfds+1));
    alsa_device_getfds(audio_dev, pfds, nfds);
    pfds[nfds].fd = sd;
    pfds[nfds].events = POLLIN;

    /* Setup jitter buffer using decoder */
    SpeexJitter jitter;
    speex_jitter_init(&jitter, dec_state, SAMPLING_RATE);

    /* Echo canceller with 200 ms tail length */
    SpeexEchoState *echo_state = speex_echo_state_init(FRAME_SIZE, 10*FRAME_SIZE);
    tmp = SAMPLING_RATE;
    speex_echo_ctl(echo_state, SPEEX_ECHO_SET_SAMPLING_RATE, &tmp);

    /* Setup preprocessor and associate with echo canceller for residual echo suppression */
    preprocess = speex_preprocess_state_init(FRAME_SIZE, SAMPLING_RATE);
    speex_preprocess_ctl(preprocess, SPEEX_PREPROCESS_SET_ECHO_STATE, echo_state);

    alsa_device_start(audio_dev);

    /* Infinite loop on capture, playback and receiving packets */
    while (1)
    {
        /* Wait for either 1) capture 2) playback 3) socket data */
        poll(pfds, nfds+1, -1);
        /* Received packets */
        if (pfds[nfds].revents & POLLIN)
        {
            /*fprintf (stderr, "x");*/
            n = recv(sd, msg, MAX_MSG, 0);
            int recv_timestamp = ((int*)msg)[1];
            int payload = ((int*)msg)[0];

            if ((payload & 0x80000000) == 0)
            {
                /* Put content of the packet into the jitter buffer, except for the pseudo-header */
                speex_jitter_put(&jitter, msg+8, n-8, recv_timestamp);
                recv_started = 1;
            }

        }
        /* Ready to play a frame (playback) */
        if (alsa_device_playback_ready(audio_dev, pfds, nfds))
        {
            short pcm[FRAME_SIZE];
            if (recv_started)
            {
                /* Get audio from the jitter buffer */
                speex_jitter_get(&jitter, pcm, NULL);
            } else {
                for (i=0; i<FRAME_SIZE; i++)
                    pcm[i] = 0;
            }
            /* Playback the audio and reset the echo canceller if we got an underrun */
            if (alsa_device_write(audio_dev, pcm, FRAME_SIZE))
                speex_echo_state_reset(echo_state);
            /* Put frame into playback buffer */
            speex_echo_playback(echo_state, pcm);
        }
        /* Audio available from the soundcard (capture) */
        if (alsa_device_capture_ready(audio_dev, pfds, nfds))
        {
            short pcm[FRAME_SIZE], pcm2[FRAME_SIZE];
            char outpacket[MAX_MSG];
            /* Get audio from the soundcard */
            alsa_device_read(audio_dev, pcm, FRAME_SIZE);

            /* Perform echo cancellation */
            speex_echo_capture(echo_state, pcm, pcm2);
            for (i=0; i<FRAME_SIZE; i++)
                pcm[i] = pcm2[i];

            speex_bits_reset(&enc_bits);

            /* Apply noise/echo suppression */
            speex_preprocess_run(preprocess, pcm);

            /* Encode */
            speex_encode_int(enc_state, pcm, &enc_bits);
            int packetSize = speex_bits_write(&enc_bits, outpacket+8, MAX_MSG);

            /* Pseudo header: four null bytes and a 32-bit timestamp */
            ((int*)outpacket)[0] = htonl(0);
            ((int*)outpacket)[1] = send_timestamp;
            send_timestamp += FRAME_SIZE;
            rc = sendto(sd, outpacket, packetSize+8, 0,
                        (struct sockaddr *) &remoteAddr,
                        sizeof(remoteAddr));

            if(rc<0) {
                printf("cannot send audio data\n");
                close(sd);
                exit(1);
            }
        }


    }


    return 0;
}