예제 #1
0
int maintestjitter()
{
   char buffer[65536];
   JitterBufferPacket in, out;
   int i;
   
   JitterBuffer *jb = jitter_buffer_init(10);
   
   out.data = buffer;
   
   /* Frozen sender case */
   jitterFill(jb);
   for(i=0;i<100;++i) {
     out.len = 65536;
     jitter_buffer_get(jb, &out, 10, NULL);
     jitter_buffer_tick(jb);
   }
   synthIn(&in, 100, 1);
   jitter_buffer_put(jb, &in);
   out.len = 65536;
   if (jitter_buffer_get(jb, &out, 10, NULL) != JITTER_BUFFER_OK) {
     printf("Failed frozen sender resynchronize\n");
   } else {
     printf("Frozen sender: Jitter %d\n", out.timestamp - 100*10);
   }
   return 0;
}
예제 #2
0
void speex_jitter_put(SpeexJitter *jitter, char *packet, int len, int timestamp)
{
   JitterBufferPacket p;
   p.data = packet;
   p.len = len;
   p.timestamp = timestamp;
   p.span = jitter->frame_size;
   jitter_buffer_put(jitter->packets, &p);
}
예제 #3
0
JNIEXPORT void JNICALL Native_NATIVE(jitter_1buffer_1put)
	(JNIEnv *env, jclass that, jlong arg0, jobject arg1)
{
	JitterBufferPacket _arg1, *lparg1=NULL;
	Native_NATIVE_ENTER(env, that, Native_jitter_1buffer_1put_FUNC);
	if (arg1) if ((lparg1 = getJitterBufferPacketFields(env, arg1, &_arg1)) == NULL) goto fail;
	jitter_buffer_put((JitterBuffer *)(intptr_t)arg0, lparg1);
fail:
	Native_NATIVE_EXIT(env, that, Native_jitter_1buffer_1put_FUNC);
}
void speex_jitter_put(SpeexJitter *jitter, char *packet, int len, int timestamp, void* userData)
{
   JitterBufferPacket p;
   p.data = packet;
   p.len = len;
   p.timestamp = timestamp;
   p.span = jitter->frame_size;
   p.user_data = (spx_uint32_t)userData;
   
   jitter_buffer_put(jitter->packets, &p);
}
예제 #5
0
void AudioOutputSpeech::addFrameToBuffer(const QByteArray &qbaPacket, unsigned int iSeq) {
	QMutexLocker lock(&qmJitter);

	if (qbaPacket.size() < 2)
		return;

	PacketDataStream pds(qbaPacket);

	pds.next();

	int frames = 0;
	unsigned int header = 0;
	do {
		header = static_cast<unsigned char>(pds.next());
		frames++;
		pds.skip(header & 0x7f);
	} while ((header & 0x80) && pds.isValid());

	if (pds.isValid()) {
		JitterBufferPacket jbp;
		jbp.data = const_cast<char *>(qbaPacket.constData());
		jbp.len = qbaPacket.size();
		jbp.span = iFrameSize * frames;
		jbp.timestamp = iFrameSize * iSeq;

#ifdef REPORT_JITTER
		if (g.s.bUsage && (umtType != MessageHandler::UDPVoiceSpeex) && p && ! p->qsHash.isEmpty() && (p->qlTiming.count() < 3000)) {
			QMutexLocker qml(& p->qmTiming);

			ClientUser::JitterRecord jr;
			jr.iSequence = iSeq;
			jr.iFrames = frames;
			jr.uiElapsed = p->tTiming.restart();

			if (! p->qlTiming.isEmpty()) {
				jr.iFrames -= p->iFrames;
				jr.iSequence -= p->iSequence + p->iFrames;
			}
			p->iFrames = frames;
			p->iSequence = iSeq;

			p->qlTiming.append(jr);
		}
#endif

		jitter_buffer_put(jbJitter, &jbp);
	}
}
예제 #6
0
void AudioInput::addEcho(const void *data, unsigned int nsamp) {
	while (nsamp > 0) {
		unsigned int left = qMin(nsamp, iEchoLength - iEchoFilled);

		imfEcho(pfEchoInput + iEchoFilled, data, left, iEchoChannels);

		iEchoFilled += left;
		nsamp -= left;

		if (nsamp > 0) {
			if (eEchoFormat == SampleFloat)
				data = reinterpret_cast<const float *>(data) + left * iEchoChannels;
			else
				data = reinterpret_cast<const short *>(data) + left * iEchoChannels;
		}

		if (iEchoFilled == iEchoLength) {
			iEchoFilled = 0;

			STACKVAR(short, outbuff, iFrameSize);
			float *ptr = srsEcho ? pfOutput : pfEchoInput;
			if (srsEcho) {
				spx_uint32_t inlen = iEchoLength;
				spx_uint32_t outlen = iFrameSize;
				speex_resampler_process_float(srsEcho, 0, pfEchoInput, &inlen, pfOutput, &outlen);
			}
			const float mul = 32768.f;
			for (int j=0;j<iFrameSize;++j)
				outbuff[j] = static_cast<short>(ptr[j] * mul);

			JitterBufferPacket jbp;
			jbp.data = reinterpret_cast<char *>(outbuff);
			jbp.len = iFrameSize * sizeof(short);
			jbp.timestamp = ++iJitterSeq * 10;
			jbp.span = 10;
			jbp.sequence = static_cast<unsigned short>(iJitterSeq);
			jbp.user_data = 0;

			jitter_buffer_put(jb, &jbp);
		}
	}
}
예제 #7
0
void jitterFill(JitterBuffer *jb) {
   char buffer[65536];
   JitterBufferPacket in, out;
   int i;

   out.data = buffer;
   
   jitter_buffer_reset(jb);

   for(i=0;i<100;++i) {
     synthIn(&in, i, 1);
     jitter_buffer_put(jb, &in);
     
     out.len = 65536;
     if (jitter_buffer_get(jb, &out, 10, NULL) != JITTER_BUFFER_OK) {
       printf("Fill test failed iteration %d\n", i);
     }
     if (out.timestamp != i * 10) {
       printf("Fill test expected %d got %d\n", i*10, out.timestamp);
     }
     jitter_buffer_tick(jb);
   }
}
예제 #8
0
static int tdav_speex_jitterbuffer_put(tmedia_jitterbuffer_t* self, void* data, tsk_size_t data_size, const tsk_object_t* proto_hdr)
{
	tdav_speex_jitterbuffer_t *jb = (tdav_speex_jitterbuffer_t *)self;
    const trtp_rtp_header_t* rtp_hdr;
    JitterBufferPacket jb_packet;
	static uint16_t seq_num = 0;

    if(!data || !data_size || !proto_hdr){
        TSK_DEBUG_ERROR("Invalid parameter");
        return -1;
    }
    
    if(!jb->state){
        TSK_DEBUG_ERROR("Invalid state");
        return -2;
    }
    
    rtp_hdr = TRTP_RTP_HEADER(proto_hdr);

	jb_packet.user_data = 0;
	jb_packet.span = jb->frame_duration;
	jb_packet.len = jb->x_data_size;
    
	if(jb->x_data_size == data_size){ /* ptime match */
		jb_packet.data = data;
		jb_packet.sequence = rtp_hdr->seq_num;
		jb_packet.timestamp = (rtp_hdr->seq_num * jb_packet.span);
		jitter_buffer_put(jb->state, &jb_packet);
	}
	else{ /* ptime mismatch */
		tsk_size_t i;
		jb_packet.sequence = 0; // Ignore
		if((jb->buff.index + data_size) > jb->buff.size){
			if(!(jb->buff.ptr = tsk_realloc(jb->buff.ptr, (jb->buff.index + data_size)))){
				jb->buff.size = 0;
				jb->buff.index = 0;
				return 0;
			}
			jb->buff.size = (jb->buff.index + data_size);
		}

		memcpy(&jb->buff.ptr[jb->buff.index], data, data_size);
		jb->buff.index += data_size;

		if(jb->buff.index >= jb->x_data_size){
			tsk_size_t copied = 0;
			for(i = 0; (i + jb->x_data_size) <= jb->buff.index; i += jb->x_data_size){
				jb_packet.data = (char*)&jb->buff.ptr[i];
				jb_packet.timestamp = (++jb->fake_seqnum * jb_packet.span);// reassembled pkt will have fake seqnum
				jitter_buffer_put(jb->state, &jb_packet);
				copied += jb->x_data_size;
			}
			if(copied == jb->buff.index){
				// all copied
				jb->buff.index = 0;
			}
			else{
				memmove(&jb->buff.ptr[0], &jb->buff.ptr[copied], (jb->buff.index - copied));
				jb->buff.index -= copied;
			}
		}
	}
    
    return 0;
}
예제 #9
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;
}