示例#1
0
	/***
	Encodes 8 kHz-sampled narrowband speech at a bit rate of or 16 kbit/s,
	uses 5 ms frames.
	The encoder receives 10 ms speech => 160 bytes.
	***/
static void enc_process (MSFilter *f){
	EncState *s=(EncState*)f->data;
	struct	BV16_Bit_Stream bs;
	short *buf= NULL;
	mblk_t *inputMessage = NULL, *outputMessage = NULL;
	int frame_per_packet=s->ptime/5;
	int in_rcvd_bytes = 0;

	in_rcvd_bytes = SIGNAL_FRAME_SIZE * frame_per_packet;
	buf=(short*)alloca(in_rcvd_bytes);
	memset((void*)buf,0, in_rcvd_bytes );

	while((inputMessage=ms_queue_get(f->inputs[0]))!=NULL){
		ms_bufferizer_put(s->bufferizer,inputMessage);

	}

	/* process ptimes ms of data : (ptime in ms)/1000->ptime is seconds * 8000(sample rate) * 2(byte per sample) */
	while(ms_bufferizer_get_avail(s->bufferizer)>= in_rcvd_bytes){
		int bufferIndex;
		outputMessage = allocb(BITSTREAM_FRAME_SIZE*frame_per_packet,0); /* output bitStream is 80 bits long * number of samples */
		/* process buffer in 5 ms frames but read everything first*/
		ms_bufferizer_read(s->bufferizer,(uint8_t*)buf,in_rcvd_bytes);
		for (bufferIndex=0; bufferIndex<frame_per_packet; bufferIndex++) {
			BV16_Encode(&bs, &s->state, (short*)&buf[bufferIndex*FRSZ]);
			BV16_BitPack( (UWord8*)outputMessage->b_wptr, &bs );
			outputMessage->b_wptr+=BITSTREAM_FRAME_SIZE;
		}
		mblk_set_timestamp_info(outputMessage,s->ts);
		ms_bufferizer_fill_current_metas(s->bufferizer, outputMessage);
		ms_queue_put(f->outputs[0],outputMessage);
		s->ts +=  FRSZ * frame_per_packet;
	}

}
static void detector_process(MSFilter *f) {
    DetectorState *s=(DetectorState *)f->data;
    mblk_t *m;

    while ((m=ms_queue_get(f->inputs[0]))!=NULL) {
        ms_queue_put(f->outputs[0],m);
        if (s->tone_def->frequency!=0) {
            ms_bufferizer_put(s->buf,dupmsg(m));
        }
    }
    if (s->tone_def->frequency!=0) {
        uint8_t *buf=_alloca(s->framesize);

        while(ms_bufferizer_read(s->buf,buf,s->framesize)!=0) {
            float en=compute_energy((int16_t*)buf,s->framesize/2);
            if (en>energy_min) {
                float freq_en=goertzel_state_run(&s->tone_gs,(int16_t*)buf,s->framesize/2,en);
                if (freq_en>=s->tone_def->min_amplitude) {
                    if (s->dur==0) s->starttime=f->ticker->time;
                    s->dur+=s->frame_ms;
                    if (s->dur>s->tone_def->min_duration && !s->event_sent) {
                        MSToneDetectorEvent event;

                        strncpy(event.tone_name,s->tone_def->tone_name,sizeof(event.tone_name));
                        event.tone_start_time=s->starttime;
                        ms_filter_notify(f,MS_TONE_DETECTOR_EVENT,&event);
                        s->event_sent=TRUE;
                    }
                } else end_tone(s);
            } else end_tone(s);
        }
    }
}
示例#3
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
}
示例#4
0
static void enc_process(MSFilter *f){
	EncState *s=(EncState*)f->data;
	mblk_t *im;
	unsigned int unitary_buff_size = sizeof(int16_t)*160;
	unsigned int buff_size = unitary_buff_size*s->ptime/20;
	int16_t* buff;
	int offset;

	while((im=ms_queue_get(f->inputs[0]))!=NULL){
		ms_bufferizer_put(s->bufferizer,im);
	}
	while(ms_bufferizer_get_avail(s->bufferizer) >= buff_size) {
		mblk_t *om=allocb(33*s->ptime/20,0);
		buff = (int16_t *)alloca(buff_size);
		ms_bufferizer_read(s->bufferizer,(uint8_t*)buff,buff_size);

		for (offset=0;offset<buff_size;offset+=unitary_buff_size) {
			gsm_encode(s->state,(gsm_signal*)&buff[offset/sizeof(int16_t)],(gsm_byte*)om->b_wptr);
			om->b_wptr+=33;
		}
		mblk_set_timestamp_info(om,s->ts);
		ms_queue_put(f->outputs[0],om);
		s->ts+=buff_size/sizeof(int16_t)/*sizeof(buf)/2*/;
	}
}
static void enc_process(MSFilter *f){
	static const int nsamples=160;
	EncState *s=(EncState*)f->data;
	mblk_t *im,*om;
	int16_t samples[nsamples];
	
	while((im=ms_queue_get(f->inputs[0]))!=NULL){
		ms_bufferizer_put (s->mb,im);
	}
	while((ms_bufferizer_read(s->mb,(uint8_t*)samples,nsamples*2))>=nsamples*2){
		int ret;
		om=allocb(33,0);
		*om->b_wptr=0xf0;
		om->b_wptr++;
		ret=Encoder_Interface_Encode(s->enc,MR122,samples,om->b_wptr,0);
		if (ret<=0){
			ms_warning("Encoder returned %i",ret);
			freemsg(om);
			continue;
		}
		om->b_wptr+=ret;
		mblk_set_timestamp_info(om,s->ts);
		s->ts+=nsamples;
		ms_queue_put(f->outputs[0],om);
	}
}
示例#6
0
static void filter_process ( MSFilter *f ) {
    isac_encoder_struct_t* obj = (isac_encoder_struct_t*)f->data;

    mblk_t *im;
    mblk_t *om=NULL;
    u_int8_t* input_buf = NULL;
    WebRtc_Word16 ret;
    static int out_count = 0;

    // get the input data and put it into our buffered input
    while( (im = ms_queue_get( f->inputs[0] ) ) != NULL ) {
        ms_bufferizer_put( obj->bufferizer, im );
    }

    // feed the encoder with 160 16bit samples, until it has reached enough data
    // to produce a packet
    while( ms_bufferizer_get_avail(obj->bufferizer) > ISAC_SAMPLES_PER_ENCODE*2 ){

        om = allocb( WebRtcIsacfix_GetNewFrameLen(obj->isac), 0 );
        if(!input_buf) input_buf = ms_malloc( ISAC_SAMPLES_PER_ENCODE*2 );
        ms_bufferizer_read(obj->bufferizer, input_buf, ISAC_SAMPLES_PER_ENCODE*2);

        ret = WebRtcIsacfix_Encode(obj->isac,
                                   (const WebRtc_Word16*)input_buf,
                                   (WebRtc_Word16*)om->b_wptr);

        if( ret < 0) {

            ms_error( "WebRtcIsacfix_Encode error: %d", WebRtcIsacfix_GetErrorCode(obj->isac) );
            freeb(om);

        } else if( ret == 0 ) {
            // Encode() buffered the input, not yet able to produce a packet, continue feeding it
            // 160 samples per-call
            obj->ts += ISAC_SAMPLES_PER_ENCODE;
            freeb(om);

        } else {

            // a new packet has been encoded, send it
            obj->ts += ISAC_SAMPLES_PER_ENCODE;
            om->b_wptr += ret;
            out_count++;
//            ms_message("packet %d out, samples %d", out_count, obj->ts);

            mblk_set_timestamp_info( om, obj->ts );
            ms_queue_put(f->outputs[0], om);

            om = NULL;
        }

    }

    if( input_buf ){
        ms_free(input_buf);
    }
}
示例#7
0
static void au_write_process(MSFilter *f){
	ms_debug("au_write_process");
	mblk_t *m;
	AUData *d=(AUData*)((MSSndCard*)f->data)->data;
	
	while((m=ms_queue_get(f->inputs[0]))!=NULL){
		ms_mutex_lock(&d->mutex);
		ms_bufferizer_put(d->bufferizer,m);
		ms_mutex_unlock(&d->mutex);
	}
}
示例#8
0
static void aq_put(MSFilter * f, mblk_t * m)
{
	AQData *d = (AQData *) f->data;
	ms_mutex_lock(&d->mutex);
	ms_bufferizer_put(d->bufferizer, m);
	ms_mutex_unlock(&d->mutex);

	int len =
		(d->writeBufferByteSize * d->writeAudioFormat.mSampleRate / 1) /
		d->devicewriteFormat.mSampleRate /
		d->devicewriteFormat.mChannelsPerFrame;
	if (d->write_started == FALSE && d->bufferizer->size >= len) {
		AudioQueueBufferRef curbuf = d->writeBuffers[d->curWriteBuffer];
#if 0
		OSStatus err;
		UInt32 bsize = d->writeBufferByteSize;
		uint8_t *pData = ms_malloc(len);

		ms_bufferizer_read(d->bufferizer, pData, len);
		err = AudioConverterConvertBuffer(d->writeAudioConverter,
										  len,
										  pData,
										  &bsize, curbuf->mAudioData);
		if (err != noErr) {
			ms_error("writeCallback: AudioConverterConvertBuffer %d", err);
		}
		ms_free(pData);

		if (bsize != d->writeBufferByteSize)
			ms_warning("d->writeBufferByteSize = %i len = %i bsize = %i",
					   d->writeBufferByteSize, len, bsize);
#else
		ms_bufferizer_read(d->bufferizer, curbuf->mAudioData, len);
#endif
		curbuf->mAudioDataByteSize = d->writeBufferByteSize;
		putWriteAQ(d, d->curWriteBuffer);
		++d->curWriteBuffer;
	}
	if (d->write_started == FALSE
		&& d->curWriteBuffer == kNumberAudioOutDataBuffers - 1) {
		OSStatus err;
		err = AudioQueueStart(d->writeQueue, NULL	// start time. NULL means ASAP.
			);
		if (err != noErr) {
			ms_error("AudioQueueStart -write- %d", err);
		}
		d->write_started = TRUE;

	}
}
static void* msandroid_read_cb(msandroid_sound_read_data* d) {
    mblk_t *m;
    int nread;
    jmethodID read_id=0;
    jmethodID record_id=0;

    set_high_prio();

    //JNIEnv *jni_env = ms_get_jni_env();
    JNIEnv *jni_env = NULL;
    JavaVM *jvm = ms_get_jvm();
    if (jvm->AttachCurrentThread(&jni_env, NULL)!=0) {
        ms_fatal("AttachCurrentThread() failed !");
        goto end;
    }
    record_id = jni_env->GetMethodID(d->audio_record_class,"startRecording", "()V");
    if(record_id==0) {
        ms_error("cannot find AudioRecord.startRecording() method");
        goto end;
    }
    //start recording
    ms_message("Start recording");
    jni_env->CallVoidMethod(d->audio_record,record_id);

    // int read (byte[] audioData, int offsetInBytes, int sizeInBytes)
    read_id = jni_env->GetMethodID(d->audio_record_class,"read", "([BII)I");
    if(read_id==0) {
        ms_error("cannot find AudioRecord.read() method");
        goto end;
    }

    while (d->started && (nread=jni_env->CallIntMethod(d->audio_record,read_id,d->read_buff,0, d->read_chunk_size))>0) {
        m = allocb(nread,0);
        jni_env->GetByteArrayRegion(d->read_buff, 0,nread, (jbyte*)m->b_wptr);
        //ms_error("%i octets read",nread);
        m->b_wptr += nread;
        d->read_samples+=nread/(2*d->nchannels);
        compute_timespec(d);
        ms_mutex_lock(&d->mutex);
        ms_bufferizer_put (&d->rb,m);
        ms_mutex_unlock(&d->mutex);
    };

    goto end;
end: {
        jvm->DetachCurrentThread();
        ms_thread_exit(NULL);
        return 0;
    }
}
示例#10
0
static void enc_process(MSFilter *f){
	SpeexEncState *s=(SpeexEncState*)f->data;
	mblk_t *im;
	int nbytes;
	uint8_t *buf;
	int frame_per_packet=1;

	if (s->frame_size<=0)
		return;

	ms_filter_lock(f);

	if (s->ptime>=20)
	{
		frame_per_packet = s->ptime/20;
	}

	if (frame_per_packet<=0)
		frame_per_packet=1;
	if (frame_per_packet>7) /* 7*20 == 140 ms max */
		frame_per_packet=7;

	nbytes=s->frame_size*2;
	buf=(uint8_t*)alloca(nbytes*frame_per_packet);

	while((im=ms_queue_get(f->inputs[0]))!=NULL){
		ms_bufferizer_put(s->bufferizer,im);
	}
	while(ms_bufferizer_read(s->bufferizer,buf,nbytes*frame_per_packet)==nbytes*frame_per_packet){
		mblk_t *om=allocb(nbytes*frame_per_packet,0);//too large...
		int k;
		SpeexBits bits;
		speex_bits_init(&bits);
		for (k=0;k<frame_per_packet;k++)
		{
			speex_encode_int(s->state,(int16_t*)(buf + (k*s->frame_size*2)),&bits);
			s->ts+=s->frame_size;
		}
		speex_bits_insert_terminator(&bits);
		k=speex_bits_write(&bits, (char*)om->b_wptr, nbytes*frame_per_packet);
		om->b_wptr+=k;

		mblk_set_timestamp_info(om,s->ts-s->frame_size);
		ms_bufferizer_fill_current_metas(s->bufferizer, om);
		ms_queue_put(f->outputs[0],om);
		speex_bits_destroy(&bits);
	}
	ms_filter_unlock(f);
}
示例#11
0
static void enc_process(MSFilter *f){
	EncState *s=(EncState*)f->data;
	mblk_t *im;
	int16_t buf[160];
	
	while((im=ms_queue_get(f->inputs[0]))!=NULL){
		ms_bufferizer_put(s->bufferizer,im);
	}
	while(ms_bufferizer_read(s->bufferizer,(uint8_t*)buf,sizeof(buf))==sizeof(buf)) {
		mblk_t *om=allocb(33,0);
		gsm_encode(s->state,(gsm_signal*)buf,(gsm_byte*)om->b_wptr);
		om->b_wptr+=33;
		mblk_set_timestamp_info(om,s->ts);
		ms_queue_put(f->outputs[0],om);
		s->ts+=sizeof(buf)/2;
	}
}
示例#12
0
static void* msandroid_read_cb(msandroid_sound_read_data* d) {
	mblk_t *m;
	int nread;
	JNIEnv *jni_env = 0;
	jmethodID read_id=0;
	jmethodID record_id=0;


	jint result = d->jvm->AttachCurrentThread(&jni_env,NULL);
	if (result != 0) {
		ms_error("cannot attach VM\n");
		goto end;
	}
	record_id = jni_env->GetMethodID(d->audio_record_class,"startRecording", "()V");
	if(record_id==0) {
		ms_error("cannot find AudioRecord.startRecording() method");
		goto end;
	}
	//start recording
	jni_env->CallVoidMethod(d->audio_record,record_id);

	// int read (byte[] audioData, int offsetInBytes, int sizeInBytes)
	read_id = jni_env->GetMethodID(d->audio_record_class,"read", "([BII)I");
	if(read_id==0) {
		ms_error("cannot find AudioRecord.read() method");
		goto end;
	}

	while (d->started && (nread=jni_env->CallIntMethod(d->audio_record,read_id,d->read_buff,0, d->read_chunk_size))>0) {
		m = allocb(nread,0);
		jni_env->GetByteArrayRegion(d->read_buff, 0,nread, (jbyte*)m->b_wptr);
		//ms_error("%i octets read",nread);
		m->b_wptr += nread;
		ms_mutex_lock(&d->mutex);
		ms_bufferizer_put (&d->rb,m);
		ms_mutex_unlock(&d->mutex);
	};
	goto end;
	end: {
		d->jvm->DetachCurrentThread();
		return 0;
	}
}
示例#13
0
static void detector_process(MSFilter *f){
	DetectorState *s=(DetectorState *)f->data;
	mblk_t *m;
	
	while ((m=ms_queue_get(f->inputs[0]))!=NULL){
		ms_queue_put(f->outputs[0],m);
		if (s->nscans>0){
			ms_bufferizer_put(s->buf,dupmsg(m));
		}
	}
	if (s->nscans>0){
		uint8_t *buf=alloca(s->framesize);

		while(ms_bufferizer_read(s->buf,buf,s->framesize)!=0){
			float en=compute_energy((int16_t*)buf,s->framesize/2);
			if (en>energy_min_threshold*(32767.0*32767.0*0.7)){
				int i;
				for(i=0;i<s->nscans;++i){
					GoertzelState *gs=&s->tone_gs[i];
					MSToneDetectorDef *tone_def=&s->tone_def[i];
					float freq_en=goertzel_state_run(gs,(int16_t*)buf,s->framesize/2,en);
					if (freq_en>=tone_def->min_amplitude){
						if (gs->dur==0) gs->starttime=f->ticker->time;
						gs->dur+=s->frame_ms;
						if (gs->dur>=tone_def->min_duration && !gs->event_sent){
							MSToneDetectorEvent event;
						
							strncpy(event.tone_name,tone_def->tone_name,sizeof(event.tone_name));
							event.tone_start_time=gs->starttime;
							ms_filter_notify(f,MS_TONE_DETECTOR_EVENT,&event);
							gs->event_sent=TRUE;
						}
					}else{
						gs->event_sent=FALSE;
						gs->dur=0;
						gs->starttime=0;
					}
				}
			}else end_all_tones(s);
		}
	}
}
示例#14
0
static void webrtc_aec_preprocess(MSFilter *f)
{
	WebRTCAECState *s = (WebRTCAECState *) f->data;
	AecmConfig config;
	int delay_samples = 0;
	mblk_t *m;
	int error_code;

	s->echostarted = FALSE;
	delay_samples = s->delay_ms * s->samplerate / 1000;
	s->framesize=(framesize*s->samplerate)/8000;
	ms_message("Initializing WebRTC echo canceler with framesize=%i, delay_ms=%i, delay_samples=%i", s->framesize, s->delay_ms, delay_samples);

	if ((s->aecmInst = WebRtcAecm_Create()) == NULL) {
		s->bypass_mode = TRUE;
		ms_error("WebRtcAecm_Create(): error, entering bypass mode");
		return;
	}
	if ((error_code = WebRtcAecm_Init(s->aecmInst, s->samplerate)) < 0) {
		if (error_code == AECM_BAD_PARAMETER_ERROR) {
			ms_error("WebRtcAecm_Init(): WebRTC echo canceller does not support %d samplerate", s->samplerate);
		}
		s->bypass_mode = TRUE;
		ms_error("Entering bypass mode");
		return;
	}
	config.cngMode = TRUE;
	config.echoMode = 3;
	if (WebRtcAecm_set_config(s->aecmInst, config)!=0){
		ms_error("WebRtcAecm_set_config(): failed.");
	}

	/* 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;
	ms_audio_flow_controller_init(&s->afc);
	s->flow_control_time = f->ticker->time;
}
示例#15
0
static void enc_process(MSFilter *f) {
    EncState *s = (EncState*) f->data;
    unsigned int unitary_buff_size = sizeof (int16_t)*160;
    unsigned int buff_size = unitary_buff_size * s->ptime / 20;
    mblk_t *im;
    uint8_t tmp[OUT_MAX_SIZE];
    int16_t samples[buff_size];

    while ((im = ms_queue_get(f->inputs[0])) != NULL) {
        ms_bufferizer_put(s->mb, im);
    }
    while (ms_bufferizer_get_avail(s->mb) >= buff_size) {
        mblk_t *om = allocb(OUT_MAX_SIZE * buff_size / unitary_buff_size + 1, 0);
        ms_bufferizer_read(s->mb, (uint8_t*) samples, buff_size);

        *om->b_wptr = 0xf0;
        uint8_t *tocs = om->b_wptr++;

        om->b_wptr += buff_size / unitary_buff_size;
        int offset;
        for (offset = 0; offset < buff_size; offset += unitary_buff_size) {
            int ret = Encoder_Interface_Encode(s->enc, s->mode, &samples[offset / sizeof (int16_t)], tmp, s->dtx);
            if (ret <= 0 || ret > 32) {
                ms_warning("Encoder returned %i", ret);
                freemsg(om);
                continue;
            }
            memcpy(om->b_wptr, &tmp[1], ret - 1);
            om->b_wptr += ret - 1;
            *(++tocs) = tmp[0] | 0x80; // Not last payload
        }
        *tocs &= 0x7F; // last payload

        mblk_set_timestamp_info(om, s->ts);
        ms_queue_put(f->outputs[0], om);

        s->ts += buff_size / sizeof (int16_t)/*sizeof(buf)/2*/;
    }
}
示例#16
0
文件: ilbc.c 项目: Distrotech/msilbc
static void enc_process(MSFilter *f){
	EncState *s=(EncState*)f->data;
	mblk_t *im,*om;
	int size=s->nsamples*2;
	int16_t samples[1610]; /* BLOCKL_MAX * 7 is the largest size for ptime == 140 */
	float samples2[BLOCKL_MAX];
	int i;
	int frame_per_packet=1;

	if (s->ptime>=20 && s->ms_per_frame>0 && s->ptime%s->ms_per_frame==0)
	{
		frame_per_packet = s->ptime/s->ms_per_frame;
	}

	if (frame_per_packet<=0)
		frame_per_packet=1;
	if (frame_per_packet>7) /* 7*20 == 140 ms max */
		frame_per_packet=7;

	while((im=ms_queue_get(f->inputs[0]))!=NULL){
		ms_bufferizer_put(s->bufferizer,im);
	}
	while(ms_bufferizer_read(s->bufferizer,(uint8_t*)samples,size*frame_per_packet)==(size*frame_per_packet)){
		int k;
		om=allocb(s->nbytes*frame_per_packet,0);
		for (k=0;k<frame_per_packet;k++)
		{
			for (i=0;i<s->nsamples;i++){
				samples2[i]=samples[i+(s->nsamples*k)];
			}
			iLBC_encode((uint8_t*)om->b_wptr,samples2,&s->ilbc_enc);
			om->b_wptr+=s->nbytes;			
		}
		s->ts+=s->nsamples*frame_per_packet;
		mblk_set_timestamp_info(om,s->ts);
		ms_bufferizer_fill_current_metas(s->bufferizer,om);
		ms_queue_put(f->outputs[0],om);
	}
}
示例#17
0
static void enc_process(MSFilter *f){
	EncState *s=(EncState*)f->data;
	mblk_t *im;
	int size = BV16_CODE_SIZE *2;
	int i,frames;
	uint8_t buf[BV16_FRAME_SIZE * 2 * 4];
	
	while((im=ms_queue_get(f->inputs[0]))!=NULL){
		ms_bufferizer_put(s->bufferizer,im);
	}

	while(ms_bufferizer_read(s->bufferizer,(uint8_t*)buf,sizeof(buf))==sizeof(buf)) {
		mblk_t *om=allocb(BV16_CODE_SIZE*8,0);
		uint8_t *in_buf = (uint8_t *)buf;

		frames = sizeof(buf)/(BV16_FRAME_SIZE  * 2);
		
		
		for(i=0;i<frames;i++)
		{
			//BV16_Encode(&s->ebs, &s->cs,(short *)in_buf);
			//BV16_BitPack((unsigned short *)om->b_wptr, &s->ebs);

			bv16_encode(s->enc,
				(uint8_t *)om->b_wptr,
				(int16_t *) in_buf,
				BV16_FRAME_SIZE);

			//ms_error("BV16_Encode frames %d",i);
			in_buf += 80;
			om->b_wptr += 10;
		}

		mblk_set_timestamp_info(om,s->ts);
		ms_queue_put(f->outputs[0],om);
		s->ts+=sizeof(buf)/2;
	}

}
示例#18
0
static void alaw_enc_process(MSFilter *obj){
	AlawEncData *dt=(AlawEncData*)obj->data;
	MSBufferizer *bz=dt->bz;
	uint8_t buffer[2240];
	int frame_per_packet=2;
	int size_of_pcm=320;

	mblk_t *m;
	
	if (dt->ptime>=10)
	{
		frame_per_packet = dt->ptime/10;
	}

	if (frame_per_packet<=0)
		frame_per_packet=1;
	if (frame_per_packet>14) /* 7*20 == 140 ms max */
		frame_per_packet=14;

	size_of_pcm = 160*frame_per_packet; /* ex: for 20ms -> 160*2==320 */

	while((m=ms_queue_get(obj->inputs[0]))!=NULL){
		ms_bufferizer_put(bz,m);
	}
	while (ms_bufferizer_read(bz,buffer,size_of_pcm)==size_of_pcm){
		mblk_t *o=allocb(size_of_pcm/2,0);
		int i;
		for (i=0;i<size_of_pcm/2;i++){
			*o->b_wptr=Snack_Lin2Alaw(((int16_t*)buffer)[i]);
			o->b_wptr++;
		}
		ms_bufferizer_fill_current_metas(bz, o);
		mblk_set_timestamp_info(o,dt->ts);
		dt->ts+=size_of_pcm/2;
		ms_queue_put(obj->outputs[0],o);
	}
}
示例#19
0
/*	inputs[0]= reference signal from far end (sent to soundcard)
 *	inputs[1]= near speech & echo signal	(read from soundcard)
 *	outputs[0]=  is a copy of inputs[0] to be sent to soundcard
 *	outputs[1]=  near end speech, echo removed - towards far end
*/
static void speex_ec_process(MSFilter *f){
	SpeexECState *s=(SpeexECState*)f->data;
	int nbytes=s->framesize*2;
	mblk_t *refm;
	uint8_t *ref,*echo;
	
	if (s->bypass_mode) {
		while((refm=ms_queue_get(f->inputs[0]))!=NULL){
			ms_queue_put(f->outputs[0],refm);
		}
		while((refm=ms_queue_get(f->inputs[1]))!=NULL){
			ms_queue_put(f->outputs[1],refm);
		}
		return;
	}
	
	if (f->inputs[0]!=NULL){
		if (s->echostarted){
			while((refm=ms_queue_get(f->inputs[0]))!=NULL){
				refm=audio_flow_controller_process(&s->afc,refm);
				if (refm){
					mblk_t *cp=dupmsg(refm);
					ms_bufferizer_put(&s->delayed_ref,cp);
					ms_bufferizer_put(&s->ref,refm);
				}
			}
		}else{
			ms_warning("Getting reference signal but no echo to synchronize on.");
			ms_queue_flush(f->inputs[0]);
		}
	}

	ms_bufferizer_put_from_queue(&s->echo,f->inputs[1]);
	
	ref=(uint8_t*)alloca(nbytes);
	echo=(uint8_t*)alloca(nbytes);
	while (ms_bufferizer_read(&s->echo,echo,nbytes)==nbytes){
		mblk_t *oecho=allocb(nbytes,0);
		int avail;
		int avail_samples;

		if (!s->echostarted) s->echostarted=TRUE;
		if ((avail=ms_bufferizer_get_avail(&s->delayed_ref))<((s->nominal_ref_samples*2)+nbytes)){
			/*we don't have enough to read in a reference signal buffer, inject silence instead*/
			avail=nbytes;
			refm=allocb(nbytes,0);
			memset(refm->b_wptr,0,nbytes);
			refm->b_wptr+=nbytes;
			ms_bufferizer_put(&s->delayed_ref,refm);
			ms_queue_put(f->outputs[0],dupmsg(refm));
			if (!s->using_zeroes){
				ms_warning("Not enough ref samples, using zeroes");
				s->using_zeroes=TRUE;
			}
		}else{
			if (s->using_zeroes){
				ms_message("Samples are back.");
				s->using_zeroes=FALSE;
			}
			/* read from our no-delay buffer and output */
			refm=allocb(nbytes,0);
			if (ms_bufferizer_read(&s->ref,refm->b_wptr,nbytes)==0){
				ms_fatal("Should never happen");
			}
			refm->b_wptr+=nbytes;
			ms_queue_put(f->outputs[0],refm);
		}

		/*now read a valid buffer of delayed ref samples*/
		if (ms_bufferizer_read(&s->delayed_ref,ref,nbytes)==0){
			ms_fatal("Should never happen");
		}
		avail-=nbytes;
		avail_samples=avail/2;
		/*ms_message("avail=%i",avail_samples);*/
		if (avail_samples<s->min_ref_samples || s->min_ref_samples==-1){
			s->min_ref_samples=avail_samples;
		}
		
#ifdef EC_DUMP
		if (s->reffile)
			fwrite(ref,nbytes,1,s->reffile);
		if (s->echofile)
			fwrite(echo,nbytes,1,s->echofile);
#endif
		speex_echo_cancellation(s->ecstate,(short*)echo,(short*)ref,(short*)oecho->b_wptr);
		speex_preprocess_run(s->den, (short*)oecho->b_wptr);
#ifdef EC_DUMP
		if (s->cleanfile)
			fwrite(oecho->b_wptr,nbytes,1,s->cleanfile);
#endif
		oecho->b_wptr+=nbytes;
		ms_queue_put(f->outputs[1],oecho);
	}
	
	/*verify our ref buffer does not become too big, meaning that we are receiving more samples than we are sending*/
	if ((((uint32_t)(f->ticker->time - s->flow_control_time)) >= flow_control_interval_ms) && (s->min_ref_samples != -1)) {
		int diff=s->min_ref_samples-s->nominal_ref_samples;
		if (diff>(nbytes/2)){
			int purge=diff-(nbytes/2);
			ms_warning("echo canceller: we are accumulating too much reference signal, need to throw out %i samples",purge);
			audio_flow_controller_set_target(&s->afc,purge,(flow_control_interval_ms*s->samplerate)/1000);
		}
		s->min_ref_samples=-1;
		s->flow_control_time = f->ticker->time;
	}
}
示例#20
0
static void ms_opus_enc_process(MSFilter *f) {
	OpusEncData *d = (OpusEncData *)f->data;
	mblk_t *im;
	mblk_t *om = NULL;
	int i;
	int frameNumber, packet_size;
	uint8_t *signalFrameBuffer = NULL;
	uint8_t *codedFrameBuffer[MAX_INPUT_FRAMES];
	OpusRepacketizer *rp = opus_repacketizer_create();
	opus_int32 ret = 0;
	opus_int32 totalLength = 0;
	int frame_size = d->samplerate * FRAME_LENGTH / 1000; /* in samples */

	// lock the access while getting ptime
	ms_filter_lock(f);
	frameNumber = d->ptime/FRAME_LENGTH; /* encode 20ms frames, ptime is a multiple of 20ms */
	packet_size = d->samplerate * d->ptime / 1000; /* in samples */
	ms_filter_unlock(f);


	while ((im = ms_queue_get(f->inputs[0])) != NULL) {
		ms_bufferizer_put(d->bufferizer, im);
	}

	for (i=0; i<MAX_INPUT_FRAMES; i++) {
		codedFrameBuffer[i]=NULL;
	}
	while (ms_bufferizer_get_avail(d->bufferizer) >= (d->channels * packet_size * SIGNAL_SAMPLE_SIZE)) {
		totalLength = 0;
		opus_repacketizer_init(rp);
		for (i=0; i<frameNumber; i++) { /* encode 20ms by 20ms and repacketize all of them together */
			if (!codedFrameBuffer[i]) codedFrameBuffer[i] = ms_malloc(MAX_BYTES_PER_FRAME); /* the repacketizer need the pointer to packet to remain valid, so we shall have a buffer for each coded frame */
			if (!signalFrameBuffer) signalFrameBuffer = ms_malloc(frame_size * SIGNAL_SAMPLE_SIZE * d->channels);

			ms_bufferizer_read(d->bufferizer, signalFrameBuffer, frame_size * SIGNAL_SAMPLE_SIZE * d->channels);
			ret = opus_encode(d->state, (opus_int16 *)signalFrameBuffer, frame_size, codedFrameBuffer[i], MAX_BYTES_PER_FRAME);
			if (ret < 0) {
				ms_error("Opus encoder error: %s", opus_strerror(ret));
				break;
			}
			if (ret > 0) {
				int err = opus_repacketizer_cat(rp, codedFrameBuffer[i], ret); /* add the encoded frame into the current packet */
				if (err != OPUS_OK) {
					ms_error("Opus repacketizer error: %s", opus_strerror(err));
					break;
				}
				totalLength += ret;
			}
		}

		if (ret > 0) {
			om = allocb(totalLength+frameNumber + 1, 0); /* opus repacktizer API: allocate at leat number of frame + size of all data added before */
			ret = opus_repacketizer_out(rp, om->b_wptr, totalLength+frameNumber);

			om->b_wptr += ret;
			mblk_set_timestamp_info(om, d->ts);
			ms_queue_put(f->outputs[0], om);
			d->ts += packet_size*48000/d->samplerate; /* RFC payload RTP opus 03 - section 4: RTP timestamp multiplier : WARNING works only with sr at 48000 */
			ret = 0;
		}
	}

	opus_repacketizer_destroy(rp);

	if (signalFrameBuffer != NULL) {
		ms_free(signalFrameBuffer);
	}
	for (i=0; i<frameNumber; i++) {
		if (codedFrameBuffer[i] != NULL) {
			ms_free(codedFrameBuffer[i]);
		}
	}
}
示例#21
0
static void ca_put(CAData *d, mblk_t *m){
	ms_mutex_lock(&d->mutex);
	ms_bufferizer_put(d->bufferizer,m);
	ms_mutex_unlock(&d->mutex);
}
示例#22
0
static void * alsa_write_thread(void *p){
	AlsaReadData *ad=(AlsaReadData*)p;
	int samples=(160*ad->rate)/8000;
	int err;
	int count=0;
	mblk_t *om=NULL;
	struct timeval timeout;
	if (ad->handle==NULL && ad->pcmdev!=NULL){
		ad->handle=alsa_open_r(ad->pcmdev,16,ad->nchannels==2,ad->rate);
	}
	if (ad->handle==NULL) return NULL;

	while (ad->read_started)
	  {
	    count = alsa_can_read(ad->handle,samples);
	    if (count==24)
	      { /* keep this value for this driver */ }
	    else if (count<=0)
	      {
		count = samples;
	      }
	    else if (count>0)
	      {
		//ms_warning("%i count", count);
		//count = samples;
	      }

	    int size=count*2;
	    om=allocb(size,0);

	    if ((err=alsa_read(ad->handle,om->b_wptr,count))<=0)
	      {
		ms_warning("nothing to read");
		//ms_warning("Fail to read samples %i", count);
		continue;
	      }
	    //ms_warning(" read %i", err);
	    
	    size=err*2;
	    om->b_wptr+=size;

	    ms_mutex_lock(&ad->mutex);
	    ms_bufferizer_put(ad->bufferizer,om);
	    ms_mutex_unlock(&ad->mutex);

	    if (count==24)
	      {
		timeout.tv_sec = 0;
		timeout.tv_usec = 2000;
		select(0, 0, NULL, NULL, &timeout );
	      }
	    else
	      {
		/* select will be less active than locking on "read" */
		timeout.tv_sec = 0;
		timeout.tv_usec = 5000;
		select(0, 0, NULL, NULL, &timeout );
	      }
	  }

	if (ad->handle!=NULL) snd_pcm_close(ad->handle);
	ad->handle=NULL;
	return NULL;
}
示例#23
0
static void au_write_put(AUWrite *d, mblk_t *m) {
    ms_mutex_lock(&d->common.mutex);
    ms_bufferizer_put(d->buffer,m);
    ms_mutex_unlock(&d->common.mutex);
}
示例#24
0
static void oss_put(MSSndCard *card, mblk_t *m){
	OssData *d=(OssData*)card->data;
	ms_mutex_lock(&d->mutex);
	ms_bufferizer_put(d->bufferizer,m);
	ms_mutex_unlock(&d->mutex);
}
示例#25
0
static void winsnd_put(MSSndCard *card, mblk_t *m){
	WinSndData *d=(WinSndData*)card->data;
	ms_mutex_lock(&d->mutex);
	ms_bufferizer_put(d->bufferizer,m);
	ms_mutex_unlock(&d->mutex);
}