示例#1
0
static guint
fill_queue (GstScaletempo * scaletempo, GstBuffer * buf_in, guint offset)
{
  GstScaletempoPrivate *p = GST_SCALETEMPO_GET_PRIVATE (scaletempo);
  guint bytes_in = GST_BUFFER_SIZE (buf_in) - offset;
  guint offset_unchanged = offset;

  if (p->bytes_to_slide > 0) {
    if (p->bytes_to_slide < p->bytes_queued) {
      guint bytes_in_move = p->bytes_queued - p->bytes_to_slide;
      memmove (p->buf_queue, p->buf_queue + p->bytes_to_slide, bytes_in_move);
      p->bytes_to_slide = 0;
      p->bytes_queued = bytes_in_move;
    } else {
      guint bytes_in_skip;
      p->bytes_to_slide -= p->bytes_queued;
      bytes_in_skip = MIN (p->bytes_to_slide, bytes_in);
      p->bytes_queued = 0;
      p->bytes_to_slide -= bytes_in_skip;
      offset += bytes_in_skip;
      bytes_in -= bytes_in_skip;
    }
  }

  if (bytes_in > 0) {
    guint bytes_in_copy = MIN (p->bytes_queue_max - p->bytes_queued, bytes_in);
    memcpy (p->buf_queue + p->bytes_queued,
        GST_BUFFER_DATA (buf_in) + offset, bytes_in_copy);
    p->bytes_queued += bytes_in_copy;
    offset += bytes_in_copy;
  }

  return offset - offset_unchanged;
}
示例#2
0
static guint
best_overlap_offset_float (GstScaletempo * scaletempo)
{
  GstScaletempoPrivate *p = GST_SCALETEMPO_GET_PRIVATE (scaletempo);
  gfloat *pw, *po, *ppc, *search_start;
  gfloat best_corr = G_MININT;
  guint best_off = 0;
  gint i, off;

  pw = p->table_window;
  po = p->buf_overlap;
  po += p->samples_per_frame;
  ppc = p->buf_pre_corr;
  for (i = p->samples_per_frame; i < p->samples_overlap; i++) {
    *ppc++ = *pw++ * *po++;
  }

  search_start = (gfloat *) p->buf_queue + p->samples_per_frame;
  for (off = 0; off < p->frames_search; off++) {
    gfloat corr = 0;
    gfloat *ps = search_start;
    ppc = p->buf_pre_corr;
    for (i = p->samples_per_frame; i < p->samples_overlap; i++) {
      corr += *ppc++ * *ps++;
    }
    if (corr > best_corr) {
      best_corr = corr;
      best_off = off;
    }
    search_start += p->samples_per_frame;
  }

  return best_off * p->bytes_per_frame;
}
示例#3
0
static void
output_overlap_s16 (GstScaletempo * scaletempo,
    gpointer buf_out, guint bytes_off)
{
  GstScaletempoPrivate *p = GST_SCALETEMPO_GET_PRIVATE (scaletempo);
  gint16 *pout = buf_out;
  gint32 *pb = p->table_blend;
  gint16 *po = p->buf_overlap;
  gint16 *pin = (gint16 *) (p->buf_queue + bytes_off);
  gint i;
  for (i = 0; i < p->samples_overlap; i++) {
    *pout++ = *po - ((*pb++ * (*po - *pin++)) >> 16);
    po++;
  }
}
示例#4
0
static guint
best_overlap_offset_s16 (GstScaletempo * scaletempo)
{
  GstScaletempoPrivate *p = GST_SCALETEMPO_GET_PRIVATE (scaletempo);
  gint32 *pw, *ppc;
  gint16 *po, *search_start;
  gint64 best_corr = G_MININT64;
  guint best_off = 0;
  guint off;
  glong i;

  pw = p->table_window;
  po = p->buf_overlap;
  po += p->samples_per_frame;
  ppc = p->buf_pre_corr;
  for (i = p->samples_per_frame; i < p->samples_overlap; i++) {
    *ppc++ = (*pw++ * *po++) >> 15;
  }

  search_start = (gint16 *) p->buf_queue + p->samples_per_frame;
  for (off = 0; off < p->frames_search; off++) {
    gint64 corr = 0;
    gint16 *ps = search_start;
    ppc = p->buf_pre_corr;
    ppc += p->samples_overlap - p->samples_per_frame;
    ps += p->samples_overlap - p->samples_per_frame;
    i = -((glong) p->samples_overlap - (glong) p->samples_per_frame);
    do {
      corr += ppc[i + 0] * ps[i + 0];
      corr += ppc[i + 1] * ps[i + 1];
      corr += ppc[i + 2] * ps[i + 2];
      corr += ppc[i + 3] * ps[i + 3];
      i += 4;
    } while (i < 0);
    if (corr > best_corr) {
      best_corr = corr;
      best_off = off;
    }
    search_start += p->samples_per_frame;
  }

  return best_off * p->bytes_per_frame;
}
示例#5
0
static guint
fill_queue (GstScaletempo * scaletempo, GstBuffer * buf_in, guint offset)
{
  GstScaletempoPrivate *p = GST_SCALETEMPO_GET_PRIVATE (scaletempo);
  guint bytes_in = gst_buffer_get_size (buf_in) - offset;
  guint offset_unchanged = offset;
  GstMapInfo map;

  gst_buffer_map (buf_in, &map, GST_MAP_READ);
  if (p->bytes_to_slide > 0) {
    if (p->bytes_to_slide < p->bytes_queued) {
      guint bytes_in_move = p->bytes_queued - p->bytes_to_slide;
      memmove (p->buf_queue, p->buf_queue + p->bytes_to_slide, bytes_in_move);
      p->bytes_to_slide = 0;
      p->bytes_queued = bytes_in_move;
    } else {
      guint bytes_in_skip;
      p->bytes_to_slide -= p->bytes_queued;
      bytes_in_skip = MIN (p->bytes_to_slide, bytes_in);
      p->bytes_queued = 0;
      p->bytes_to_slide -= bytes_in_skip;
      offset += bytes_in_skip;
      bytes_in -= bytes_in_skip;
    }
  }

  if (bytes_in > 0) {
    guint bytes_in_copy = MIN (p->bytes_queue_max - p->bytes_queued, bytes_in);
    memcpy (p->buf_queue + p->bytes_queued, map.data + offset, bytes_in_copy);
    p->bytes_queued += bytes_in_copy;
    offset += bytes_in_copy;
  }
  gst_buffer_unmap (buf_in, &map);

  return offset - offset_unchanged;
}
示例#6
0
static void
reinit_buffers (GstScaletempo * scaletempo)
{
  GstScaletempoPrivate *p = GST_SCALETEMPO_GET_PRIVATE (scaletempo);
  gint i, j;
  guint frames_overlap;
  guint new_size;

  guint frames_stride = p->ms_stride * p->sample_rate / 1000.0;
  p->bytes_stride = frames_stride * p->bytes_per_frame;

  /* overlap */
  frames_overlap = frames_stride * p->percent_overlap;
  if (frames_overlap < 1) {     /* if no overlap */
    p->bytes_overlap = 0;
    p->bytes_standing = p->bytes_stride;
    p->samples_standing = p->bytes_standing / p->bytes_per_sample;
    p->output_overlap = NULL;
  } else {
    guint prev_overlap = p->bytes_overlap;
    p->bytes_overlap = frames_overlap * p->bytes_per_frame;
    p->samples_overlap = frames_overlap * p->samples_per_frame;
    p->bytes_standing = p->bytes_stride - p->bytes_overlap;
    p->samples_standing = p->bytes_standing / p->bytes_per_sample;
    p->buf_overlap = g_realloc (p->buf_overlap, p->bytes_overlap);
    p->table_blend = g_realloc (p->table_blend, p->samples_overlap * 4);        /* sizeof (gint32|gfloat) */
    if (p->bytes_overlap > prev_overlap) {
      memset ((guint8 *) p->buf_overlap + prev_overlap, 0,
          p->bytes_overlap - prev_overlap);
    }
    if (p->use_int) {
      gint32 *pb = p->table_blend;
      gint64 blend = 0;
      for (i = 0; i < frames_overlap; i++) {
        gint32 v = blend / frames_overlap;
        for (j = 0; j < p->samples_per_frame; j++) {
          *pb++ = v;
        }
        blend += 65535;         /* 2^16 */
      }
      p->output_overlap = output_overlap_s16;
    } else {
      gfloat *pb = p->table_blend;
      gfloat t = (gfloat) frames_overlap;
      for (i = 0; i < frames_overlap; i++) {
        gfloat v = i / t;
        for (j = 0; j < p->samples_per_frame; j++) {
          *pb++ = v;
        }
      }
      p->output_overlap = output_overlap_float;
    }
  }

  /* best overlap */
  p->frames_search =
      (frames_overlap <= 1) ? 0 : p->ms_search * p->sample_rate / 1000.0;
  if (p->frames_search < 1) {   /* if no search */
    p->best_overlap_offset = NULL;
  } else {
    guint bytes_pre_corr = (p->samples_overlap - p->samples_per_frame) * 4;     /* sizeof (gint32|gfloat) */
    p->buf_pre_corr =
        g_realloc (p->buf_pre_corr, bytes_pre_corr + UNROLL_PADDING);
    p->table_window = g_realloc (p->table_window, bytes_pre_corr);
    if (p->use_int) {
      gint64 t = frames_overlap;
      gint32 n = 8589934588LL / (t * t);        /* 4 * (2^31 - 1) / t^2 */
      gint32 *pw;

      memset ((guint8 *) p->buf_pre_corr + bytes_pre_corr, 0, UNROLL_PADDING);
      pw = p->table_window;
      for (i = 1; i < frames_overlap; i++) {
        gint32 v = (i * (t - i) * n) >> 15;
        for (j = 0; j < p->samples_per_frame; j++) {
          *pw++ = v;
        }
      }
      p->best_overlap_offset = best_overlap_offset_s16;
    } else {