コード例 #1
0
static int tdav_speex_jitterbuffer_reset(tmedia_jitterbuffer_t* self)
{
	tdav_speex_jitterbuffer_t *jitterbuffer = (tdav_speex_jitterbuffer_t *)self;
	if(jitterbuffer->state){
		jitter_buffer_reset(jitterbuffer->state);
	}
	return 0;
}
コード例 #2
0
ファイル: jitter.c プロジェクト: kballen/OBS_mic_dsp
/** Destroy jitter buffer */
EXPORT void jitter_buffer_destroy(JitterBuffer *jitter)
{
   if (jitter)
   {
      jitter_buffer_reset(jitter);
      speex_free(jitter);
   }
}
コード例 #3
0
static int tdav_speex_jitterbuffer_reset(tmedia_jitterbuffer_t* self)
{
	tdav_speex_jitterbuffer_t *jb = (tdav_speex_jitterbuffer_t *)self;
	if (jb->state) {
		jitter_buffer_reset(jb->state);
	}
	jb->num_pkt_in = 0;
	jb->num_pkt_miss = 0;
	return 0;
}
コード例 #4
0
ファイル: jitter.c プロジェクト: tibastral/symphonie
/** Initialise jitter buffer */
JitterBuffer *jitter_buffer_init(int tick)
{
   JitterBuffer *jitter = (JitterBuffer*)speex_alloc(sizeof(JitterBuffer));
   if (jitter)
   {
      int i;
      for (i=0;i<SPEEX_JITTER_MAX_BUFFER_SIZE;i++)
         jitter->buf[i]=NULL;
      jitter->tick_size = tick;
      jitter->buffer_margin = 1;
      jitter_buffer_reset(jitter);
   }
   return jitter;
}
コード例 #5
0
ファイル: jitter.c プロジェクト: 0359xiaodong/TeamTalk
/** Initialise jitter buffer */
EXPORT JitterBuffer *jitter_buffer_init(int step_size)
{
   JitterBuffer *jitter = (JitterBuffer*)speex_alloc(sizeof(JitterBuffer));
   if (jitter)
   {
      int i;
      spx_int32_t tmp;
      for (i=0;i<SPEEX_JITTER_MAX_BUFFER_SIZE;i++)
         jitter->packets[i].data=NULL;
      jitter->delay_step = step_size;
      jitter->concealment_size = step_size;
      /*FIXME: Should this be 0 or 1?*/
      jitter->buffer_margin = 0;
      jitter->late_cutoff = 50;
      jitter->destroy = NULL;
      jitter->latency_tradeoff = 0;
      jitter->auto_adjust = 1;
      tmp = 4;
      jitter_buffer_ctl(jitter, JITTER_BUFFER_SET_MAX_LATE_RATE, &tmp);
      jitter_buffer_reset(jitter);
   }
   return jitter;
}
コード例 #6
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);
   }
}
コード例 #7
0
ファイル: jitter.c プロジェクト: tibastral/symphonie
/** Put one packet into the jitter buffer */
void jitter_buffer_put(JitterBuffer *jitter, const JitterBufferPacket *packet)
{
   int i,j;
   spx_int32_t arrival_margin;
   /*fprintf (stderr, "put packet %d %d\n", timestamp, span);*/
   if (jitter->reset_state)
   {
      jitter->reset_state=0;
      jitter->pointer_timestamp = packet->timestamp;
      jitter->current_timestamp = packet->timestamp;
      /*fprintf(stderr, "reset to %d\n", timestamp);*/
   }
   
   /* Cleanup buffer (remove old packets that weren't played) */
   for (i=0;i<SPEEX_JITTER_MAX_BUFFER_SIZE;i++)
   {
      if (jitter->buf[i] && LE32(jitter->timestamp[i] + jitter->span[i], jitter->pointer_timestamp))
      {
         /*fprintf (stderr, "cleaned (not played)\n");*/
         speex_free(jitter->buf[i]);
         jitter->buf[i] = NULL;
      }
   }

   /*Find an empty slot in the buffer*/
   for (i=0;i<SPEEX_JITTER_MAX_BUFFER_SIZE;i++)
   {
      if (jitter->buf[i]==NULL)
         break;
   }

   /*fprintf(stderr, "%d %d %f\n", timestamp, jitter->pointer_timestamp, jitter->drift_average);*/
   /*No place left in the buffer*/
   if (i==SPEEX_JITTER_MAX_BUFFER_SIZE)
   {
      int earliest=jitter->timestamp[0];
      i=0;
      for (j=1;j<SPEEX_JITTER_MAX_BUFFER_SIZE;j++)
      {
         if (!jitter->buf[i] || LT32(jitter->timestamp[j],earliest))
         {
            earliest = jitter->timestamp[j];
            i=j;
         }
      }
      speex_free(jitter->buf[i]);
      jitter->buf[i]=NULL;
      if (jitter->lost_count>20)
      {
         jitter_buffer_reset(jitter);
      }
      /*fprintf (stderr, "Buffer is full, discarding earliest frame %d (currently at %d)\n", timestamp, jitter->pointer_timestamp);*/      
   }
   
   /* Copy packet in buffer */
   jitter->buf[i]=(char*)speex_alloc(packet->len);
   for (j=0;j<(int)packet->len;j++)
      jitter->buf[i][j]=packet->data[j];
   jitter->timestamp[i]=packet->timestamp;
   jitter->span[i]=packet->span;
   jitter->len[i]=packet->len;
   
   /* Adjust the buffer size depending on network conditions */
   arrival_margin = (packet->timestamp - jitter->current_timestamp) - jitter->buffer_margin*jitter->tick_size;
   
   if (arrival_margin >= -LATE_BINS*jitter->tick_size)
   {
      spx_int32_t int_margin;
      for (i=0;i<MAX_MARGIN;i++)
      {
         jitter->shortterm_margin[i] *= .98;
         jitter->longterm_margin[i] *= .995;
      }
      int_margin = LATE_BINS + arrival_margin/jitter->tick_size;
      if (int_margin>MAX_MARGIN-1)
         int_margin = MAX_MARGIN-1;
      if (int_margin>=0)
      {
         jitter->shortterm_margin[int_margin] += .02;
         jitter->longterm_margin[int_margin] += .005;
      }
   } else {
      
      /*fprintf (stderr, "way too late = %d\n", arrival_margin);*/
      if (jitter->lost_count>20)
      {
         jitter_buffer_reset(jitter);
      }
   }
#if 0 /* Enable to check how much is being buffered */
   if (rand()%1000==0)
   {
      int count = 0;
      for (j=0;j<SPEEX_JITTER_MAX_BUFFER_SIZE;j++)
      {
         if (jitter->buf[j])
            count++;
      }
      fprintf (stderr, "buffer_size = %d\n", count);
   }
#endif
}
コード例 #8
0
ファイル: jitter.c プロジェクト: CEPBEP/onion-phone
/** Put one packet into the jitter buffer */
EXPORT void jitter_buffer_put(JitterBuffer * jitter,
			      const JitterBufferPacket * packet)
{
	int i, j;
	int late;
	/*fprintf (stderr, "put packet %d %d\n", timestamp, span); */

	/* Cleanup buffer (remove old packets that weren't played) */
	if (!jitter->reset_state) {
		for (i = 0; i < SPEEX_JITTER_MAX_BUFFER_SIZE; i++) {
			/* Make sure we don't discard a "just-late" packet in case we want to play it next (if we interpolate). */
			if (jitter->packets[i].data
			    && LE32(jitter->packets[i].timestamp +
				    jitter->packets[i].span,
				    jitter->pointer_timestamp)) {
				/*fprintf (stderr, "cleaned (not played)\n"); */
				if (jitter->destroy)
					jitter->destroy(jitter->packets[i].
							data);
				else
					speex_free(jitter->packets[i].data);
				jitter->packets[i].data = NULL;
			}
		}
	}

	/*fprintf(stderr, "arrival: %d %d %d\n", packet->timestamp, jitter->next_stop, jitter->pointer_timestamp); */
	/* Check if packet is late (could still be useful though) */
	if (!jitter->reset_state && LT32(packet->timestamp, jitter->next_stop)) {
		update_timings(jitter,
			       ((spx_int32_t) packet->timestamp) -
			       ((spx_int32_t) jitter->next_stop) -
			       jitter->buffer_margin);
		late = 1;
	} else {
		late = 0;
	}

	/* For some reason, the consumer has failed the last 20 fetches. Make sure this packet is
	 * used to resync. */
	if (jitter->lost_count > 20) {
		jitter_buffer_reset(jitter);
	}

	/* Only insert the packet if it's not hopelessly late (i.e. totally useless) */
	if (jitter->reset_state
	    || GE32(packet->timestamp + packet->span + jitter->delay_step,
		    jitter->pointer_timestamp)) {

		/*Find an empty slot in the buffer */
		for (i = 0; i < SPEEX_JITTER_MAX_BUFFER_SIZE; i++) {
			if (jitter->packets[i].data == NULL)
				break;
		}

		/*No place left in the buffer, need to make room for it by discarding the oldest packet */
		if (i == SPEEX_JITTER_MAX_BUFFER_SIZE) {
			int earliest = jitter->packets[0].timestamp;
			i = 0;
			for (j = 1; j < SPEEX_JITTER_MAX_BUFFER_SIZE; j++) {
				if (!jitter->packets[i].data
				    || LT32(jitter->packets[j].timestamp,
					    earliest)) {
					earliest = jitter->packets[j].timestamp;
					i = j;
				}
			}
			if (jitter->destroy)
				jitter->destroy(jitter->packets[i].data);
			else
				speex_free(jitter->packets[i].data);
			jitter->packets[i].data = NULL;
			/*fprintf (stderr, "Buffer is full, discarding earliest frame %d (currently at %d)\n", timestamp, jitter->pointer_timestamp); */
		}

		/* Copy packet in buffer */
		if (jitter->destroy) {
			jitter->packets[i].data = packet->data;
		} else {
			jitter->packets[i].data =
			    (char *)speex_alloc(packet->len);
			for (j = 0; j < (int)packet->len; j++)
				jitter->packets[i].data[j] = packet->data[j];
		}
		jitter->packets[i].timestamp = packet->timestamp;
		jitter->packets[i].span = packet->span;
		jitter->packets[i].len = packet->len;
		jitter->packets[i].sequence = packet->sequence;
		jitter->packets[i].user_data = packet->user_data;
		if (jitter->reset_state || late)
			jitter->arrival[i] = 0;
		else
			jitter->arrival[i] = jitter->next_stop;
	}

}
コード例 #9
0
ファイル: jitter.c プロジェクト: fffonion/V8
/** Destroy jitter buffer */
void jitter_buffer_destroy(JitterBuffer *jitter)
{
   jitter_buffer_reset(jitter);
   free(jitter);
}
コード例 #10
0
ファイル: AudioInput.cpp プロジェクト: ArminW/re-whisper
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();
}
コード例 #11
0
PJ_DEF(void) jitter_buffer_flush(Jitter_Buffer *jitter_buffer) {
    jitter_buffer_reset(jitter_buffer);
}