Beispiel #1
0
/* not really necessary to call, but if someone is doing in-place ffts, they may want to free the 
   buffers from CHECKBUF
 */ 
void kiss_fft_cleanup(void)
{
    speex_free(scratchbuf);
    scratchbuf = NULL;
    nscratchbuf=0;
    speex_free(tmpbuf);
    tmpbuf=NULL;
    ntmpbuf=0;
}
Beispiel #2
0
void spx_drft_clear(struct drft_lookup *l)
{
	if (l) {
		if (l->trigcache)
			speex_free(l->trigcache);
		if (l->splitcache)
			speex_free(l->splitcache);
	}
}
Beispiel #3
0
void vorbis_psy_destroy(VorbisPsy *p)
{
  if(p){
    spx_drft_clear(&p->lookup);
    if(p->bark)
      speex_free(p->bark);
    if(p->noiseoffset)
      speex_free(p->noiseoffset);
    if(p->window)
      speex_free(p->window);
    memset(p,0,sizeof(*p));
    speex_free(p);
  }
}
Beispiel #4
0
EXPORT int jitter_buffer_get_another(JitterBuffer * jitter,
				     JitterBufferPacket * packet)
{
	int i, j;
	for (i = 0; i < SPEEX_JITTER_MAX_BUFFER_SIZE; i++) {
		if (jitter->packets[i].data
		    && jitter->packets[i].timestamp ==
		    jitter->last_returned_timestamp)
			break;
	}
	if (i != SPEEX_JITTER_MAX_BUFFER_SIZE) {
		/* Copy packet */
		packet->len = jitter->packets[i].len;
		if (jitter->destroy) {
			packet->data = jitter->packets[i].data;
		} else {
			for (j = 0; j < (int)packet->len; j++)
				packet->data[j] = jitter->packets[i].data[j];
			/* Remove packet */
			speex_free(jitter->packets[i].data);
		}
		jitter->packets[i].data = NULL;
		packet->timestamp = jitter->packets[i].timestamp;
		packet->span = jitter->packets[i].span;
		packet->sequence = jitter->packets[i].sequence;
		packet->user_data = jitter->packets[i].user_data;
		return JITTER_BUFFER_OK;
	} else {
		packet->data = NULL;
		packet->len = 0;
		packet->span = 0;
		return JITTER_BUFFER_MISSING;
	}
}
Beispiel #5
0
EXPORT void speex_decorrelate_destroy(SpeexDecorrState *st)
{
#ifdef VORBIS_PSYCHO
   vorbis_psy_destroy(st->psy);
   speex_free(st->wola_mem);
   speex_free(st->curve);
#endif
   speex_free(st->buff);
   speex_free(st->ring);
   speex_free(st->ringID);
   speex_free(st->alpha);
   speex_free(st->vorbis_win);
   speex_free(st->order);
   speex_free(st->y);
   speex_free(st);
}
Beispiel #6
0
/** Reset jitter buffer */
EXPORT void jitter_buffer_reset(JitterBuffer * jitter)
{
	int i;
	for (i = 0; i < SPEEX_JITTER_MAX_BUFFER_SIZE; i++) {
		if (jitter->packets[i].data) {
			if (jitter->destroy)
				jitter->destroy(jitter->packets[i].data);
			else
				speex_free(jitter->packets[i].data);
			jitter->packets[i].data = NULL;
		}
	}
	/* Timestamp is actually undefined at this point */
	jitter->pointer_timestamp = 0;
	jitter->next_stop = 0;
	jitter->reset_state = 1;
	jitter->lost_count = 0;
	jitter->buffered = 0;
	jitter->auto_tradeoff = 32000;

	for (i = 0; i < MAX_BUFFERS; i++) {
		tb_init(&jitter->_tb[i]);
		jitter->timeBuffers[i] = &jitter->_tb[i];
	}
	/*fprintf (stderr, "reset\n"); */
}
Beispiel #7
0
/** Destroy jitter buffer */
EXPORT void jitter_buffer_destroy(JitterBuffer *jitter)
{
   if (jitter)
   {
      jitter_buffer_reset(jitter);
      speex_free(jitter);
   }
}
EXPORT SpeexHeader *speex_packet_to_header(char *packet, int size)
{
   int i;
   SpeexHeader *le_header;
   const char *h = "Speex   ";

   /*FIXME: Do we allow larger headers?*/
   if (size < (int)sizeof(SpeexHeader))
   {
      speex_notify("Speex header too small");
      return NULL;
   }


   for (i=0;i<8;i++)
      if (packet[i]!=h[i])
      {
         /* This doesn't look like a Speex file */
         return NULL;
      }

   le_header = (SpeexHeader*)speex_alloc(sizeof(SpeexHeader));
   
   SPEEX_COPY(le_header, (SpeexHeader*)packet, 1);
   
   /*Make sure everything is converted correctly from little-endian*/
   ENDIAN_SWITCH(le_header->speex_version_id);
   ENDIAN_SWITCH(le_header->header_size);
   ENDIAN_SWITCH(le_header->rate);
   ENDIAN_SWITCH(le_header->mode);
   ENDIAN_SWITCH(le_header->mode_bitstream_version);
   ENDIAN_SWITCH(le_header->nb_channels);
   ENDIAN_SWITCH(le_header->bitrate);
   ENDIAN_SWITCH(le_header->frame_size);
   ENDIAN_SWITCH(le_header->vbr);
   ENDIAN_SWITCH(le_header->frames_per_packet);
   ENDIAN_SWITCH(le_header->extra_headers);

   if (le_header->mode >= SPEEX_NB_MODES || le_header->mode < 0)
   {
      speex_notify("Invalid mode specified in Speex header");
      speex_free (le_header);
      return NULL;
   }

   if (le_header->nb_channels>2)
      le_header->nb_channels = 2;
   if (le_header->nb_channels<1)
      le_header->nb_channels = 1;

   return le_header;

}
Beispiel #9
0
void filterbank_destroy(FilterBank *bank)
{
   speex_free(bank->bank_left);
   speex_free(bank->bank_right);
   speex_free(bank->filter_left);
   speex_free(bank->filter_right);
#ifndef FIXED_POINT
   speex_free(bank->scaling);
#endif
   speex_free(bank);
}
Beispiel #10
0
/** Reset jitter buffer */
void jitter_buffer_reset(JitterBuffer *jitter)
{
   int i;
   for (i=0;i<SPEEX_JITTER_MAX_BUFFER_SIZE;i++)
   {
      if (jitter->buf[i])
      {
         speex_free(jitter->buf[i]);
         jitter->buf[i] = NULL;
      }
   }
   /* Timestamp is actually undefined at this point */
   jitter->pointer_timestamp = 0;
   jitter->current_timestamp = 0;
   jitter->reset_state = 1;
   jitter->lost_count = 0;
   jitter->loss_rate = 0;
   for (i=0;i<MAX_MARGIN;i++)
   {
      jitter->shortterm_margin[i] = 0;
      jitter->longterm_margin[i] = 0;
   }
   /*fprintf (stderr, "reset\n");*/
}
Beispiel #11
0
EXPORT void speex_stereo_state_destroy(SpeexStereoState * stereo)
{
	speex_free(stereo);
}
Beispiel #12
0
/** 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
}
Beispiel #13
0
/** Get one packet from the jitter buffer */
int jitter_buffer_get(JitterBuffer *jitter, JitterBufferPacket *packet, spx_uint32_t *start_offset)
{
   int i, j;
   float late_ratio_short;
   float late_ratio_long;
   float ontime_ratio_short;
   float ontime_ratio_long;
   float early_ratio_short;
   float early_ratio_long;
   int chunk_size;
   int incomplete = 0;
   
   if (LT32(jitter->current_timestamp+jitter->tick_size, jitter->pointer_timestamp))
   {
      jitter->current_timestamp = jitter->pointer_timestamp;
      speex_warning("did you forget to call jitter_buffer_tick() by any chance?");
   }
   /*fprintf (stderr, "get packet %d %d\n", jitter->pointer_timestamp, jitter->current_timestamp);*/

   /* FIXME: This should be only what remaining of the current tick */
   chunk_size = jitter->tick_size;
   
   /* Compiling arrival statistics */
   
   late_ratio_short = 0;
   late_ratio_long = 0;
   for (i=0;i<LATE_BINS;i++)
   {
      late_ratio_short += jitter->shortterm_margin[i];
      late_ratio_long += jitter->longterm_margin[i];
   }
   ontime_ratio_short = jitter->shortterm_margin[LATE_BINS];
   ontime_ratio_long = jitter->longterm_margin[LATE_BINS];
   early_ratio_short = early_ratio_long = 0;
   for (i=LATE_BINS+1;i<MAX_MARGIN;i++)
   {
      early_ratio_short += jitter->shortterm_margin[i];
      early_ratio_long += jitter->longterm_margin[i];
   }
   if (0&&jitter->pointer_timestamp%1000==0)
   {
      /*fprintf (stderr, "%f %f %f %f %f %f\n", early_ratio_short, early_ratio_long, ontime_ratio_short, ontime_ratio_long, late_ratio_short, late_ratio_long);*/
      /*fprintf (stderr, "%f %f\n", early_ratio_short + ontime_ratio_short + late_ratio_short, early_ratio_long + ontime_ratio_long + late_ratio_long);*/
   }
   
   /* Adjusting the buffering */
   
   if (late_ratio_short > .1 || late_ratio_long > .03)
   {
      /* If too many packets are arriving late */
      jitter->shortterm_margin[MAX_MARGIN-1] += jitter->shortterm_margin[MAX_MARGIN-2];
      jitter->longterm_margin[MAX_MARGIN-1] += jitter->longterm_margin[MAX_MARGIN-2];
      for (i=MAX_MARGIN-3;i>=0;i--)
      {
         jitter->shortterm_margin[i+1] = jitter->shortterm_margin[i];
         jitter->longterm_margin[i+1] = jitter->longterm_margin[i];         
      }
      jitter->shortterm_margin[0] = 0;
      jitter->longterm_margin[0] = 0;            
      jitter->pointer_timestamp -= jitter->tick_size;
      jitter->current_timestamp -= jitter->tick_size;
      /*fprintf (stderr, "i");*/
      /*fprintf (stderr, "interpolate (getting some slack)\n");*/
   } else if (late_ratio_short + ontime_ratio_short < .005 && late_ratio_long + ontime_ratio_long < .01 && early_ratio_short > .8)
   {
      /* Many frames arriving early */
      jitter->shortterm_margin[0] += jitter->shortterm_margin[1];
      jitter->longterm_margin[0] += jitter->longterm_margin[1];
      for (i=1;i<MAX_MARGIN-1;i++)
      {
         jitter->shortterm_margin[i] = jitter->shortterm_margin[i+1];
         jitter->longterm_margin[i] = jitter->longterm_margin[i+1];         
      }
      jitter->shortterm_margin[MAX_MARGIN-1] = 0;
      jitter->longterm_margin[MAX_MARGIN-1] = 0;      
      /*fprintf (stderr, "drop frame\n");*/
      /*fprintf (stderr, "d");*/
      jitter->pointer_timestamp += jitter->tick_size;
      jitter->current_timestamp += jitter->tick_size;
      /*fprintf (stderr, "dropping packet (getting more aggressive)\n");*/
   }
   
   /* Searching for the packet that fits best */
   
   /* Search the buffer for a packet with the right timestamp and spanning the whole current chunk */
   for (i=0;i<SPEEX_JITTER_MAX_BUFFER_SIZE;i++)
   {
      if (jitter->buf[i] && jitter->timestamp[i]==jitter->pointer_timestamp && GE32(jitter->timestamp[i]+jitter->span[i],jitter->pointer_timestamp+chunk_size))
         break;
   }
   
   /* If no match, try for an "older" packet that still spans (fully) the current chunk */
   if (i==SPEEX_JITTER_MAX_BUFFER_SIZE)
   {
      for (i=0;i<SPEEX_JITTER_MAX_BUFFER_SIZE;i++)
      {
         if (jitter->buf[i] && jitter->timestamp[i]<=jitter->pointer_timestamp && GE32(jitter->timestamp[i]+jitter->span[i],jitter->pointer_timestamp+chunk_size))
            break;
      }
   }
   
   /* If still no match, try for an "older" packet that spans part of the current chunk */
   if (i==SPEEX_JITTER_MAX_BUFFER_SIZE)
   {
      for (i=0;i<SPEEX_JITTER_MAX_BUFFER_SIZE;i++)
      {
         if (jitter->buf[i] && jitter->timestamp[i]<=jitter->pointer_timestamp && GT32(jitter->timestamp[i]+jitter->span[i],jitter->pointer_timestamp))
            break;
      }
   }
   
   /* If still no match, try for earliest packet possible */
   if (i==SPEEX_JITTER_MAX_BUFFER_SIZE)
   {
      int found = 0;
      spx_uint32_t best_time=0;
      int best_span=0;
      int besti=0;
      for (i=0;i<SPEEX_JITTER_MAX_BUFFER_SIZE;i++)
      {
         /* check if packet starts within current chunk */
         if (jitter->buf[i] && LT32(jitter->timestamp[i],jitter->pointer_timestamp+chunk_size) && GE32(jitter->timestamp[i],jitter->pointer_timestamp))
         {
            if (!found || LT32(jitter->timestamp[i],best_time) || (jitter->timestamp[i]==best_time && GT32(jitter->span[i],best_span)))
            {
               best_time = jitter->timestamp[i];
               best_span = jitter->span[i];
               besti = i;
               found = 1;
            }
         }
      }
      if (found)
      {
         i=besti;
         incomplete = 1;
         /*fprintf (stderr, "incomplete: %d %d %d %d\n", jitter->timestamp[i], jitter->pointer_timestamp, chunk_size, jitter->span[i]);*/
      }
   }

   /* If we find something */
   if (i!=SPEEX_JITTER_MAX_BUFFER_SIZE)
   {
      /* We (obviously) haven't lost this packet */
      jitter->lost_count = 0;
      jitter->loss_rate = .999*jitter->loss_rate;
      /* Check for potential overflow */
      packet->len = jitter->len[i];
      /* Copy packet */
      for (j=0;j<(int)packet->len;j++)
         packet->data[j] = jitter->buf[i][j];
      /* Remove packet */
      speex_free(jitter->buf[i]);
      jitter->buf[i] = NULL;
      /* Set timestamp and span (if requested) */
      if (start_offset)
         *start_offset = jitter->timestamp[i]-jitter->pointer_timestamp;
      packet->timestamp = jitter->timestamp[i];
      packet->span = jitter->span[i];
      /* Point at the end of the current packet */
      jitter->pointer_timestamp = jitter->timestamp[i]+jitter->span[i];
      if (incomplete)
         return JITTER_BUFFER_INCOMPLETE;
      else
         return JITTER_BUFFER_OK;
   }
   
   
   /* If we haven't found anything worth returning */
   /*fprintf (stderr, "not found\n");*/
   jitter->lost_count++;
   /*fprintf (stderr, "m");*/
   /*fprintf (stderr, "lost_count = %d\n", jitter->lost_count);*/
   jitter->loss_rate = .999*jitter->loss_rate + .001;
   if (start_offset)
      *start_offset = 0;
   packet->timestamp = jitter->pointer_timestamp;
   packet->span = jitter->tick_size;
   jitter->pointer_timestamp += chunk_size;
   packet->len = 0;
   return JITTER_BUFFER_MISSING;

}
Beispiel #14
0
void *AudioStreamPlaybackSpeex::process_header(ogg_packet *op, int *frame_size, int *rate, int *nframes, int *channels, int *extra_headers) {

	SpeexHeader *header;
	int modeID;

	header = speex_packet_to_header((char *)op->packet, op->bytes);
	if (!header) {
		OS::get_singleton()->printerr("Cannot read header\n");
		return NULL;
	}
	if (header->mode >= SPEEX_NB_MODES) {
		OS::get_singleton()->printerr("Mode number %d does not (yet/any longer) exist in this version\n",
				header->mode);
		return NULL;
	}

	modeID = header->mode;

	const SpeexMode *mode = speex_lib_get_mode(modeID);

	if (header->speex_version_id > 1) {
		OS::get_singleton()->printerr("This file was encoded with Speex bit-stream version %d, which I don't know how to decode\n", header->speex_version_id);
		return NULL;
	}

	if (mode->bitstream_version < header->mode_bitstream_version) {
		OS::get_singleton()->printerr("The file was encoded with a newer version of Speex. You need to upgrade in order to play it.\n");
		return NULL;
	}
	if (mode->bitstream_version > header->mode_bitstream_version) {
		OS::get_singleton()->printerr("The file was encoded with an older version of Speex. You would need to downgrade the version in order to play it.\n");
		return NULL;
	}

	void *state = speex_decoder_init(mode);
	if (!state) {
		OS::get_singleton()->printerr("Decoder initialization failed.\n");
		return NULL;
	}
	//speex_decoder_ctl(state, SPEEX_SET_ENH, &enh_enabled);
	speex_decoder_ctl(state, SPEEX_GET_FRAME_SIZE, frame_size);

	if (!*rate)
		*rate = header->rate;

	speex_decoder_ctl(state, SPEEX_SET_SAMPLING_RATE, rate);

	*nframes = header->frames_per_packet;

	*channels = header->nb_channels;

	if (*channels != 1) {
		OS::get_singleton()->printerr("Only MONO speex streams supported\n");
		return NULL;
	}

	*extra_headers = header->extra_headers;

	speex_free(header);
	return state;
}
Beispiel #15
0
void sb_encoder_destroy(void *state)
{
   SBEncState *st=(SBEncState*)state;

   speex_encoder_destroy(st->st_low);
#if !(defined(VAR_ARRAYS) || defined (USE_ALLOCA))
   /*speex_free_scratch(st->stack);*/
#endif

   speex_free(st->high);

   speex_free(st->h0_mem);
   speex_free(st->h1_mem);

   speex_free(st->old_lsp);
   speex_free(st->old_qlsp);
   speex_free(st->interp_qlpc);
   speex_free(st->pi_gain);
   speex_free(st->exc_rms);

   speex_free(st->mem_sp);
   speex_free(st->mem_sp2);
   speex_free(st->mem_sw);

   
   speex_free(st);
}
Beispiel #16
0
/** Get one packet from the jitter buffer */
EXPORT int jitter_buffer_get(JitterBuffer * jitter, JitterBufferPacket * packet,
			     spx_int32_t desired_span,
			     spx_int32_t * start_offset)
{
	int i;
	unsigned int j;
	spx_int16_t opt;

	if (start_offset != NULL)
		*start_offset = 0;

	/* Syncing on the first call */
	if (jitter->reset_state) {
		int found = 0;
		/* Find the oldest packet */
		spx_uint32_t oldest = 0;
		for (i = 0; i < SPEEX_JITTER_MAX_BUFFER_SIZE; i++) {
			if (jitter->packets[i].data
			    && (!found
				|| LT32(jitter->packets[i].timestamp,
					oldest))) {
				oldest = jitter->packets[i].timestamp;
				found = 1;
			}
		}
		if (found) {
			jitter->reset_state = 0;
			jitter->pointer_timestamp = oldest;
			jitter->next_stop = oldest;
		} else {
			packet->timestamp = 0;
			packet->span = jitter->interp_requested;
			return JITTER_BUFFER_MISSING;
		}
	}

	jitter->last_returned_timestamp = jitter->pointer_timestamp;

	if (jitter->interp_requested != 0) {
		packet->timestamp = jitter->pointer_timestamp;
		packet->span = jitter->interp_requested;

		/* Increment the pointer because it got decremented in the delay update */
		jitter->pointer_timestamp += jitter->interp_requested;
		packet->len = 0;
		/*fprintf (stderr, "Deferred interpolate\n"); */

		jitter->interp_requested = 0;

		jitter->buffered = packet->span - desired_span;

		return JITTER_BUFFER_INSERTION;
	}

	/* Searching for the packet that fits best */

	/* Search the buffer for a packet with the right timestamp and spanning the whole current chunk */
	for (i = 0; i < SPEEX_JITTER_MAX_BUFFER_SIZE; i++) {
		if (jitter->packets[i].data
		    && jitter->packets[i].timestamp == jitter->pointer_timestamp
		    && GE32(jitter->packets[i].timestamp +
			    jitter->packets[i].span,
			    jitter->pointer_timestamp + desired_span))
			break;
	}

	/* If no match, try for an "older" packet that still spans (fully) the current chunk */
	if (i == SPEEX_JITTER_MAX_BUFFER_SIZE) {
		for (i = 0; i < SPEEX_JITTER_MAX_BUFFER_SIZE; i++) {
			if (jitter->packets[i].data
			    && LE32(jitter->packets[i].timestamp,
				    jitter->pointer_timestamp)
			    && GE32(jitter->packets[i].timestamp +
				    jitter->packets[i].span,
				    jitter->pointer_timestamp + desired_span))
				break;
		}
	}

	/* If still no match, try for an "older" packet that spans part of the current chunk */
	if (i == SPEEX_JITTER_MAX_BUFFER_SIZE) {
		for (i = 0; i < SPEEX_JITTER_MAX_BUFFER_SIZE; i++) {
			if (jitter->packets[i].data
			    && LE32(jitter->packets[i].timestamp,
				    jitter->pointer_timestamp)
			    && GT32(jitter->packets[i].timestamp +
				    jitter->packets[i].span,
				    jitter->pointer_timestamp))
				break;
		}
	}

	/* If still no match, try for earliest packet possible */
	if (i == SPEEX_JITTER_MAX_BUFFER_SIZE) {
		int found = 0;
		spx_uint32_t best_time = 0;
		int best_span = 0;
		int besti = 0;
		for (i = 0; i < SPEEX_JITTER_MAX_BUFFER_SIZE; i++) {
			/* check if packet starts within current chunk */
			if (jitter->packets[i].data
			    && LT32(jitter->packets[i].timestamp,
				    jitter->pointer_timestamp + desired_span)
			    && GE32(jitter->packets[i].timestamp,
				    jitter->pointer_timestamp)) {
				if (!found
				    || LT32(jitter->packets[i].timestamp,
					    best_time)
				    || (jitter->packets[i].timestamp ==
					best_time
					&& GT32(jitter->packets[i].span,
						best_span))) {
					best_time =
					    jitter->packets[i].timestamp;
					best_span = jitter->packets[i].span;
					besti = i;
					found = 1;
				}
			}
		}
		if (found) {
			i = besti;
			/*fprintf (stderr, "incomplete: %d %d %d %d\n", jitter->packets[i].timestamp, jitter->pointer_timestamp, chunk_size, jitter->packets[i].span); */
		}
	}

	/* If we find something */
	if (i != SPEEX_JITTER_MAX_BUFFER_SIZE) {
		spx_int32_t offset;

		/* We (obviously) haven't lost this packet */
		jitter->lost_count = 0;

		/* In this case, 0 isn't as a valid timestamp */
		if (jitter->arrival[i] != 0) {
			update_timings(jitter,
				       ((spx_int32_t) jitter->packets[i].
					timestamp) -
				       ((spx_int32_t) jitter->arrival[i]) -
				       jitter->buffer_margin);
		}

		/* Copy packet */
		if (jitter->destroy) {
			packet->data = jitter->packets[i].data;
			packet->len = jitter->packets[i].len;
		} else {
			if (jitter->packets[i].len > packet->len) {
				speex_warning_int
				    ("jitter_buffer_get(): packet too large to fit. Size is",
				     jitter->packets[i].len);
			} else {
				packet->len = jitter->packets[i].len;
			}
			for (j = 0; j < packet->len; j++)
				packet->data[j] = jitter->packets[i].data[j];
			/* Remove packet */
			speex_free(jitter->packets[i].data);
		}
		jitter->packets[i].data = NULL;
		/* Set timestamp and span (if requested) */
		offset =
		    (spx_int32_t) jitter->packets[i].timestamp -
		    (spx_int32_t) jitter->pointer_timestamp;
		if (start_offset != NULL)
			*start_offset = offset;
		else if (offset != 0)
			speex_warning_int
			    ("jitter_buffer_get() discarding non-zero start_offset",
			     offset);

		packet->timestamp = jitter->packets[i].timestamp;
		jitter->last_returned_timestamp = packet->timestamp;

		packet->span = jitter->packets[i].span;
		packet->sequence = jitter->packets[i].sequence;
		packet->user_data = jitter->packets[i].user_data;
		/* Point to the end of the current packet */
		jitter->pointer_timestamp =
		    jitter->packets[i].timestamp + jitter->packets[i].span;

		jitter->buffered = packet->span - desired_span;

		if (start_offset != NULL)
			jitter->buffered += *start_offset;

		return JITTER_BUFFER_OK;
	}

	/* If we haven't found anything worth returning */

	/*fprintf (stderr, "not found\n"); */
	jitter->lost_count++;
	/*fprintf (stderr, "m"); */
	/*fprintf (stderr, "lost_count = %d\n", jitter->lost_count); */

	opt = compute_opt_delay(jitter);

	/* Should we force an increase in the buffer or just do normal interpolation? */
	if (opt < 0) {
		/* Need to increase buffering */

		/* Shift histogram to compensate */
		shift_timings(jitter, -opt);

		packet->timestamp = jitter->pointer_timestamp;
		packet->span = -opt;
		/* Don't move the pointer_timestamp forward */
		packet->len = 0;

		jitter->buffered = packet->span - desired_span;
		return JITTER_BUFFER_INSERTION;
		/*jitter->pointer_timestamp -= jitter->delay_step; */
		/*fprintf (stderr, "Forced to interpolate\n"); */
	} else {
		/* Normal packet loss */
		packet->timestamp = jitter->pointer_timestamp;

		desired_span =
		    ROUND_DOWN(desired_span, jitter->concealment_size);
		packet->span = desired_span;
		jitter->pointer_timestamp += desired_span;
		packet->len = 0;

		jitter->buffered = packet->span - desired_span;
		return JITTER_BUFFER_MISSING;
		/*fprintf (stderr, "Normal loss\n"); */
	}

}
Beispiel #17
0
/** 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;
	}

}
Beispiel #18
0
EXPORT void speex_header_free(void *ptr)
{
   speex_free(ptr);
}
Beispiel #19
0
EXPORT void speex_buffer_destroy(SpeexBuffer *st)
{
   speex_free(st->data);
   speex_free(st);
}
Beispiel #20
0
void speex_preprocess_state_destroy(SpeexPreprocessState *st)
{
   speex_free(st->frame);
   speex_free(st->ps);
   speex_free(st->gain2);
   speex_free(st->window);
   speex_free(st->noise);
   speex_free(st->reverb_estimate);
   speex_free(st->old_ps);
   speex_free(st->gain);
   speex_free(st->prior);
   speex_free(st->post);
   speex_free(st->loudness_weight);
   speex_free(st->echo_noise);

   speex_free(st->S);
   speex_free(st->Smin);
   speex_free(st->Stmp);
   speex_free(st->update_prob);
   speex_free(st->zeta);

   speex_free(st->noise_bands);
   speex_free(st->noise_bands2);
   speex_free(st->speech_bands);
   speex_free(st->speech_bands2);

   speex_free(st->inbuf);
   speex_free(st->outbuf);

   spx_drft_clear(st->fft_lookup);
   speex_free(st->fft_lookup);

   speex_free(st);
}
Beispiel #21
0
/** Destroys an echo canceller state */
void speex_echo_state_destroy(SpeexEchoState *st)
{
    spx_drft_clear(st->fft_lookup);
    speex_free(st->fft_lookup);
    speex_free(st->x);
    speex_free(st->d);
    speex_free(st->y);
    speex_free(st->last_y);
    speex_free(st->Yps);
    speex_free(st->Yf);
    speex_free(st->Rf);
    speex_free(st->Xf);
    speex_free(st->fratio);
    speex_free(st->regul);

    speex_free(st->X);
    speex_free(st->D);
    speex_free(st->Y);
    speex_free(st->E);
    speex_free(st->W);
    speex_free(st->PHI);
    speex_free(st->power);
    speex_free(st->power_1);
    speex_free(st->grad);

    speex_free(st);
}
Beispiel #22
0
/** Destroys an echo canceller state */
EXPORT void speex_echo_state_destroy(SpeexEchoState *st)
{
   spx_fft_destroy(st->fft_table);

   speex_free(st->e);
   speex_free(st->x);
   speex_free(st->input);
   speex_free(st->y);
   speex_free(st->last_y);
   speex_free(st->Yf);
   speex_free(st->Rf);
   speex_free(st->Xf);
   speex_free(st->Yh);
   speex_free(st->Eh);

   speex_free(st->X);
   speex_free(st->Y);
   speex_free(st->E);
   speex_free(st->W);
#ifdef TWO_PATH
   speex_free(st->foreground);
#endif
   speex_free(st->PHI);
   speex_free(st->power);
   speex_free(st->power_1);
   speex_free(st->window);
   speex_free(st->prop);
   speex_free(st->wtmp);
#ifdef FIXED_POINT
   speex_free(st->wtmp2);
#endif
   speex_free(st->memX);
   speex_free(st->memD);
   speex_free(st->memE);
   speex_free(st->notch_mem);

   speex_free(st->play_buf);
   speex_free(st);
   
#ifdef DUMP_ECHO_CANCEL_DATA
   fclose(rFile);
   fclose(pFile);
   fclose(oFile);
   rFile = pFile = oFile = NULL;
#endif
}