Exemplo n.º 1
0
void REM32(reg_t r1, reg_t r2, reg_t r3, reg_t scratch)
{
  MOV32(scratch, r2); 
  MOVIM32(r1, 0);

  EQ32(scratch+4, r3, R_ZERO);
  if (REG32(scratch+4))
  {
    goto _end;
  }

  GTE32(scratch+4, scratch, r3, scratch+16);
  GT32(scratch+8, scratch, R_ZERO);
  LAND32(scratch+12, scratch+4, scratch+8);
  while (REG32(scratch+12))
  {
    SUB32(scratch, scratch, r3);

    GTE32(scratch+4, scratch, r3, scratch+16);
    GT32(scratch+8, scratch, R_ZERO);
    LAND32(scratch+12, scratch+4, scratch+8);
  } 

  MOV32(r1, scratch);
_end:
  return;
}
Exemplo n.º 2
0
void MUL32(reg_t r1, reg_t r2, reg_t r3, reg_t scratch)
{
  MOV32(scratch, r2); 
  MOV32(scratch+4, r3); 

  //make sure this initialization is after r2 and r3 are already saved
  // otherwise, if r1 = r2 or r1 = r3, then we will have problems
  MOVIM32(r1, 0);

  GT32(scratch+8, r2, r3);
  if (REG32(scratch+8))
  {
    MOV32(scratch, r3);
    MOV32(scratch+4, r2);
  }

  
  GT32(scratch+8, scratch, R_ZERO);
  while (REG32(scratch+8))
  {
    ADD32(r1, r1, scratch+4);
    DEC32(scratch);
    GT32(scratch+8, scratch, R_ZERO);
  } 
}
Exemplo n.º 3
0
void LT32(reg_t r1, reg_t r2, reg_t r3)
{
  GT32(r1, r3, r2);
}
Exemplo n.º 4
0
void GTE32(reg_t r1, reg_t r2, reg_t r3, reg_t scratch)
{
  EQ32(r1, r2, r3);
  GT32(scratch, r2, r3);
  LOR32(r1, r1, scratch);  
}
Exemplo n.º 5
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;

}
Exemplo n.º 6
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"); */
	}

}