Beispiel #1
0
static int encode(struct aufilt_enc_st *st, int16_t *sampv, size_t *sampc)
{
    struct enc_st *est = (struct enc_st *)st;
    struct speex_st *sp = est->st;

    if (*sampc) {
        speex_echo_capture(sp->state, sampv, sp->out);
        memcpy(sampv, sp->out, *sampc * 2);
    }

    return 0;
}
Beispiel #2
0
static int tdav_speex_denoise_process_record(tmedia_denoise_t* self, void* audio_frame, tsk_bool_t* silence_or_noise)
{
	tdav_speex_denoise_t *denoiser = (tdav_speex_denoise_t *)self;
	int vad;

	if(denoiser->preprocess_state_record){
		if(denoiser->echo_state && denoiser->echo_output_frame){
			speex_echo_capture(denoiser->echo_state, audio_frame, denoiser->echo_output_frame);
			memcpy(audio_frame, denoiser->echo_output_frame, denoiser->frame_size*sizeof(spx_int16_t));
		}
		vad = speex_preprocess_run(denoiser->preprocess_state_record, audio_frame);
		if(!vad && TMEDIA_DENOISE(denoiser)->vad_enabled){
			*silence_or_noise = tsk_true;
		}
	}

	return 0;
}
Beispiel #3
0
/*
 * Perform echo cancellation to captured frame.
 */
PJ_DEF(pj_status_t) speex_aec_capture( void *state,
				       pj_int16_t *rec_frm,
				       unsigned options )
{
    speex_ec *echo = (speex_ec*) state;

    /* Sanity checks */
    PJ_ASSERT_RETURN(echo && rec_frm, PJ_EINVAL);

    PJ_UNUSED_ARG(options);

    /* Cancel echo */
    pjmedia_copy_samples(echo->tmp_frame, rec_frm, echo->samples_per_frame);
    speex_echo_capture(echo->state,
		       (spx_int16_t*)echo->tmp_frame,
		       (spx_int16_t*)rec_frm);

    /* Apply preprocessing */
    speex_preprocess_run(echo->preprocess, (spx_int16_t*)rec_frm);

    return PJ_SUCCESS;
}
Beispiel #4
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;
}
Beispiel #5
0
bool t_audio_rx::get_sound_samples(unsigned short &sound_payload_size, bool &silence) {
	int status;
	struct timespec sleeptimer;
	//struct timeval debug_timer;
	
	silence = false;

	mtx_3way.lock();

	if (is_3way && !is_main_rx_3way) {
		// We are not the main receiver in a 3-way call, so
		// get the sound samples from the local media buffer.
		// This buffer will be filled by the main receiver.
		if (!media_3way_peer_rx->get(input_sample_buf, SAMPLE_BUF_SIZE)) {
			// The mutex is unlocked before going to sleep.
			// First I had the mutex unlock after the sleep.
			// That worked fine with LinuxThreading, but it does
			// not work with NPTL. It causes a deadlock when
			// the main receiver calls post_media_peer_rx_3way
			// as NPTL does not fair scheduling. This thread
			// simly gets the lock again and the main receiver
			// dies from starvation.
			mtx_3way.unlock();

			// There is not enough data yet. Sleep for 1 ms.
			sleeptimer.tv_sec = 0;
			sleeptimer.tv_nsec = 1000000;
			nanosleep(&sleeptimer, NULL);
			return false;
		}
		
		mtx_3way.unlock();
	} else {
		// Don't keep the 3way mutex locked while waiting for the DSP.
		mtx_3way.unlock();
		
		// Get the sound samples from the DSP
		status = input_device->read(input_sample_buf, SAMPLE_BUF_SIZE);

		if (status != SAMPLE_BUF_SIZE) {
			if (!logged_capture_failure) {
				// Log this failure only once
				log_file->write_header("t_audio_rx::get_sound_samples",
					LOG_NORMAL, LOG_WARNING);
				log_file->write_raw("Audio rx line ");
				log_file->write_raw(get_line()->get_line_number()+1);
				log_file->write_raw(": sound capture failed.\n");
				log_file->write_raw("Status: ");
				log_file->write_raw(status);
				log_file->write_endl();
				log_file->write_footer();
				logged_capture_failure = true;
			}

			stop_running = true;
			return false;
		}

		// If line is muted, then fill sample buffer with silence.
		// Note that we keep reading the dsp, to prevent the DSP buffers
		// from filling up.
		if (get_line()->get_is_muted()) {
			memset(input_sample_buf, 0, SAMPLE_BUF_SIZE);
		}
	}

	// Convert buffer to a buffer of shorts as the samples are 16 bits
	short *sb = (short *)input_sample_buf;

	mtx_3way.lock();
	if (is_3way) {
		// Send the sound samples to the other receiver if we
		// are the main receiver.
		// There may be no other receiver when one of the far-ends
		// has put the call on-hold.
		if (is_main_rx_3way && peer_rx_3way) {
			peer_rx_3way->post_media_peer_rx_3way(input_sample_buf, SAMPLE_BUF_SIZE,
				audio_encoder->get_sample_rate());
		}

		// Mix the sound samples with the 3rd party
		if (media_3way_peer_tx->get(mix_buf_3way, SAMPLE_BUF_SIZE)) {
			short *mix_sb = (short *)mix_buf_3way;
			for (int i = 0; i < SAMPLE_BUF_SIZE / 2; i++) {
				sb[i] = mix_linear_pcm(sb[i], mix_sb[i]);
			}
		}
	}

	mtx_3way.unlock();

	/*** PREPROCESSING & ENCODING ***/

	bool preprocessing_silence = false;

#ifdef HAVE_SPEEX
	// speex acoustic echo cancellation
	if (audio_session->get_do_echo_cancellation() && !audio_session->get_echo_captured_last()) {

	    spx_int16_t *input_buf = new spx_int16_t[SAMPLE_BUF_SIZE/2];
	    MEMMAN_NEW_ARRAY(input_buf);

	    for (int i = 0; i < SAMPLE_BUF_SIZE / 2; i++) {
		input_buf[i] = sb[i];
	    }

	    speex_echo_capture(audio_session->get_speex_echo_state(), input_buf, sb);
	    audio_session->set_echo_captured_last(true);

	    MEMMAN_DELETE_ARRAY(input_buf);
	    delete [] input_buf;
	}

	// preprocessing
	preprocessing_silence = !speex_preprocess_run(speex_preprocess_state, sb);
	
	// According to the speex API documentation the return value
	// from speex_preprocess_run() is only defined when VAD is
	// enabled. So to be safe, reset the return value, if VAD is
	// disabled.
	if (!speex_dsp_vad) preprocessing_silence = false;
#endif

	// encoding
	sound_payload_size = audio_encoder->encode(sb, nsamples, payload, payload_size, silence);	

	// recognizing silence (both from preprocessing and encoding)
	silence = silence || preprocessing_silence;

	return true;
}
Beispiel #6
0
void CSpeexEC::DoSpeexEchoCapture(const short* pRecData, short *out)
{
    if (!m_bHasInit)
        return;
    speex_echo_capture(m_pState, pRecData, out);
}
Beispiel #7
0
int KotiAEC_process(const int16_t* farend, const int16_t* nearend, int16_t* out)
{
    int ret = -1, i = 0, frame_size = 0;
    switch(aec_core_used)
    {
#ifdef WEBRTC_AEC_CORE_ENABLED
    case WEBRTC_AEC:
        if(farend)
            WebRtcAec_BufferFarend(webrtc_aec_pty.webrtc_aec, farend, webrtc_aec_pty.frame_size);
        if(!WebRtcAec_Process(webrtc_aec_pty.webrtc_aec, nearend, NULL, out, NULL, webrtc_aec_pty.frame_size,
                                   webrtc_aec_pty.sndcard_delay_ms, 0))
        {
            ret = 0;
        }

        if(webrtc_aec_pty.webrtc_ns)
        {
            WebRtcNsx_Process((NsxHandle*)webrtc_aec_pty.webrtc_ns, out, NULL, out, NULL);
            if(webrtc_aec_pty.frame_size == 160)
                WebRtcNsx_Process((NsxHandle*)webrtc_aec_pty.webrtc_ns, out+80, NULL, out+80, NULL);
        }

        if(webrtc_aec_pty.webrtc_agc)
        {
            int32_t out_c; uint8_t warn_status;
            WebRtcAgc_Process(webrtc_aec_pty.webrtc_agc, out, NULL, webrtc_aec_pty.frame_size, out, NULL, 32,
                              &out_c, 1, &warn_status);
        }

//        if(webrtc_aec_pty.webrtc_ns)
//        {
//            WebRtcNsx_Process((NsxHandle*)webrtc_aec_pty.webrtc_ns, out, NULL, out, NULL);
//            if(webrtc_aec_pty.frame_size == 160)
//                WebRtcNsx_Process((NsxHandle*)webrtc_aec_pty.webrtc_ns, out+80, NULL, out+80, NULL);
//        }

        frame_size = webrtc_aec_pty.frame_size;
        break;
    case WEBRTC_AECM:
/*
        if(farend)
            WebRtcAecm_BufferFarend(webrtc_aecm_pty.webrtc_aec, farend, webrtc_aecm_pty.frame_size);
        if(!WebRtcAecm_Process(webrtc_aecm_pty.webrtc_aec, nearend, NULL, out, webrtc_aecm_pty.frame_size,
                              webrtc_aecm_pty.sndcard_delay_ms))
        {
            ret = 0;
        }
*/

	memcpy(proc_tmp_buf, nearend, webrtc_aecm_pty.frame_size*2);
        if(webrtc_aecm_pty.webrtc_ns)
        {
            WebRtcNsx_Process((NsxHandle*)webrtc_aecm_pty.webrtc_ns, proc_tmp_buf, NULL, proc_tmp_buf, NULL);
            if(webrtc_aecm_pty.frame_size == 160)
                WebRtcNsx_Process((NsxHandle*)webrtc_aecm_pty.webrtc_ns, proc_tmp_buf+80, NULL, proc_tmp_buf+80, NULL);
        }

        if(webrtc_aecm_pty.webrtc_agc)
        {
            int32_t out_c; uint8_t warn_status;
            WebRtcAgc_Process(webrtc_aecm_pty.webrtc_agc, proc_tmp_buf, NULL, webrtc_aecm_pty.frame_size, proc_tmp_buf, NULL, 32,
                              &out_c, 1, &warn_status);
        }

	// AEC
        if(farend)
            WebRtcAecm_BufferFarend(webrtc_aecm_pty.webrtc_aec, farend, webrtc_aecm_pty.frame_size);
        if(!WebRtcAecm_Process(webrtc_aecm_pty.webrtc_aec, proc_tmp_buf, NULL, out, webrtc_aecm_pty.frame_size,
                              webrtc_aecm_pty.sndcard_delay_ms))
        {
            ret = 0;
        }

        frame_size = webrtc_aecm_pty.frame_size;
        break;
#endif
    case SPEEX_AEC:
    default:
#ifdef OLD_SPEEX_AEC
        speex_echo_cancel((SpeexEchoState*)speex_aec_pty.speex_echo_state, nearend, farend, out, speex_aec_pty.nosie);
        if(speex_preprocess((SpeexPreprocessState*)speex_aec_pty.speex_preprocess_state, out, speex_aec_pty.nosie) == 1)
            ret = 0;
#else
        if(farend)
            speex_echo_cancellation((SpeexEchoState*)speex_aec_pty.speex_echo_state, nearend, farend, out);
        else
            speex_echo_capture((SpeexEchoState*)speex_aec_pty.speex_echo_state, nearend, out);
//        speex_preprocess_estimate_update((SpeexPreprocessState*)speex_aec_pty.speex_preprocess_state, out);
        if(speex_preprocess_run((SpeexPreprocessState*)speex_aec_pty.speex_preprocess_state, out) == 1)
            ret = 0;
#endif

        frame_size = speex_aec_pty.frame_size;
        break;
    }

    // if the output sound needed amplify
    if(output_sound_amplification != 1.0f && output_sound_amplification > 0)
    {
        for(; i<frame_size; ++i)
            out[i] = out[i]*output_sound_amplification;
    }

    return ret;
}