Example #1
0
static int encode_speex(int16_t * input_frame, uint8_t nbframes, char * output, int bitrate) {
	int i, bytesToWrite, nbBytes;
  SpeexBits bits;
  void * state;
  long long total;

  speex_bits_init(&bits);
  state = speex_encoder_init(&speex_nb_mode);
  speex_encoder_ctl(state, SPEEX_SET_QUALITY, &bitrate);
  speex_bits_reset(&bits);
  
  total = 0;
  for(i=0;i<5*160;i++) {
    total += input_frame[i];
  }
  total /= (5*160);
  if(abs(total) < 10)
    return 0;

  for(i=0;i<5;i++) {
	  speex_encode_int(state, input_frame + (i*160), &bits);
  }

	bytesToWrite = speex_bits_nbytes(&bits);
  nbBytes = speex_bits_write(&bits, output, bytesToWrite);
  speex_bits_destroy(&bits);
  speex_decoder_destroy(state);
	return nbBytes;
}
Example #2
0
void AudioInput::flushCheck() {
	if (bPreviousVoice && iFrames < g.s.iFramesPerPacket)
		return;

	int flags = 0;
	if (g.iAltSpeak > 0)
		flags += MessageSpeex::AltSpeak;
	if (g.s.lmLoopMode == Settings::Server)
		flags += MessageSpeex::LoopBack;

	if (! bPreviousVoice)
		flags += MessageSpeex::EndSpeech;

	flags += (iFrames - 1) << 4;

	int len = speex_bits_nbytes(&sbBits);
	QByteArray qba(len + 1, 0);
	qba[0] = static_cast<unsigned char>(flags);

	speex_bits_write(&sbBits, qba.data() + 1, len);

	MessageSpeex msPacket;
	msPacket.qbaSpeexPacket = qba;
	msPacket.iSeq = iFrameCounter;

	if (g.s.lmLoopMode == Settings::Local) {
		LoopPlayer::lpLoopy.addFrame(qba, msPacket.iSeq);
	} else if (g.sh) {
		g.sh->sendMessage(&msPacket);
	}

	iFrames = 0;
	speex_bits_reset(&sbBits);
}
Example #3
0
/*
 * Encode frames.
 */
static pj_status_t spx_codec_encode( pjmedia_codec *codec, 
				     const struct pjmedia_frame *input,
				     unsigned output_buf_len, 
				     struct pjmedia_frame *output)
{
    struct spx_private *spx;
    unsigned samples_per_frame;
    int tx = 0;
    spx_int16_t *pcm_in = (spx_int16_t*)input->buf;
    pj_size_t nsamples;

    spx = (struct spx_private*) codec->codec_data;

    if (input->type != PJMEDIA_FRAME_TYPE_AUDIO) {
	output->size = 0;
	output->buf = NULL;
	output->timestamp = input->timestamp;
	output->type = input->type;
	return PJ_SUCCESS;
    }

    nsamples = input->size >> 1;
    samples_per_frame=spx_factory.speex_param[spx->param_id].samples_per_frame;

    PJ_ASSERT_RETURN(nsamples % samples_per_frame == 0, 
		     PJMEDIA_CODEC_EPCMFRMINLEN);

    /* Flush all the bits in the struct so we can encode a new frame */
    speex_bits_reset(&spx->enc_bits);

    /* Encode the frames */
    while (nsamples >= samples_per_frame) {
	tx += speex_encode_int(spx->enc, pcm_in, &spx->enc_bits);
	pcm_in += samples_per_frame;
	nsamples -= samples_per_frame;
    }

    /* Check if we need not to transmit the frame (DTX) */
    if (tx == 0) {
	output->buf = NULL;
	output->size = 0;
	output->timestamp.u64 = input->timestamp.u64;
	output->type = PJMEDIA_FRAME_TYPE_NONE;
	return PJ_SUCCESS;
    }

    /* Check size. */
    pj_assert(speex_bits_nbytes(&spx->enc_bits) <= (int)output_buf_len);

    /* Copy the bits to an array of char that can be written */
    output->size = speex_bits_write(&spx->enc_bits, 
				    (char*)output->buf, output_buf_len);
    output->type = PJMEDIA_FRAME_TYPE_AUDIO;
    output->timestamp = input->timestamp;

    return PJ_SUCCESS;
}
Example #4
0
int qSpeexEncode(QSpeexCodecPtr handle, void* samples, int sampleSize)
{
	int offset;

	speex_bits_reset(&handle->encBits);

	/** Floods the console **/
	/**   fprintf(stderr, "encoding bytes: \n");	**/
	for(offset=0; offset<sampleSize; offset+=handle->frameSize) {
		short* ptr = ((short*)samples) + offset;
		speex_encode_int(handle->encState, ptr, &handle->encBits);
	}
	speex_bits_insert_terminator(&handle->encBits);
	return speex_bits_nbytes(&handle->encBits);
}
Example #5
0
int universal_speex_encode(void* handle, const void* pAudioBuffer, 
                          unsigned cbAudioSamples, int* rSamplesConsumed, 
                          void* pCodedData, unsigned cbMaxCodedData, 
                          int* pcbCodedSize, unsigned* pbSendNow)
{
   struct speex_codec_data_encoder *mpSpeexEnc = 
      (struct speex_codec_data_encoder *)handle;
   assert(handle != NULL);

   memcpy(&mpSpeexEnc->mpBuffer[mpSpeexEnc->mBufferLoad], pAudioBuffer,
          SIZE_OF_SAMPLE * cbAudioSamples);
   mpSpeexEnc->mBufferLoad = mpSpeexEnc->mBufferLoad+cbAudioSamples;
   assert(mpSpeexEnc->mBufferLoad <= mpSpeexEnc->mNumSamplesPerFrame);

   // Check for necessary number of samples
   if(mpSpeexEnc->mBufferLoad == mpSpeexEnc->mNumSamplesPerFrame)
   {
      SpeexBits bits;

      // Wrap our buffer to speex bits structure
      speex_bits_init_buffer(&bits, pCodedData, cbMaxCodedData);

      // Preprocess data if requested
      if(mpSpeexEnc->mDoPreprocess)
         speex_preprocess(mpSpeexEnc->mpPreprocessState, mpSpeexEnc->mpBuffer, NULL);
      // Encode frame and append terminator
      speex_encode_int(mpSpeexEnc->mpEncoderState, mpSpeexEnc->mpBuffer, &bits);
      speex_bits_insert_terminator(&bits);

      // Tell that we've produced packet
      *pbSendNow = TRUE;
      *pcbCodedSize = speex_bits_nbytes(&bits);

      // Reset the buffer count.
      mpSpeexEnc->mBufferLoad = 0;
   }
   else
   {
      *pbSendNow = FALSE;
      *pcbCodedSize = 0;
   }

   *rSamplesConsumed = cbAudioSamples;

   return RPLG_SUCCESS;
}
Example #6
0
static GstFlowReturn
gst_speex_enc_encode (GstSpeexEnc * enc, gboolean flush)
{
  gint frame_size = enc->frame_size;
  gint bytes = frame_size * 2 * enc->channels;
  GstFlowReturn ret = GST_FLOW_OK;

  if (flush && gst_adapter_available (enc->adapter) % bytes != 0) {
    guint diff = gst_adapter_available (enc->adapter) % bytes;
    GstBuffer *buf = gst_buffer_new_and_alloc (diff);

    memset (GST_BUFFER_DATA (buf), 0, diff);
    gst_adapter_push (enc->adapter, buf);
  }

  while (gst_adapter_available (enc->adapter) >= bytes) {
    gint16 *data;
    gint outsize, written;
    GstBuffer *outbuf;

    data = (gint16 *) gst_adapter_take (enc->adapter, bytes);

    enc->samples_in += frame_size;

    GST_DEBUG_OBJECT (enc, "encoding %d samples (%d bytes)", frame_size, bytes);

    if (enc->channels == 2) {
      speex_encode_stereo_int (data, frame_size, &enc->bits);
    }
    speex_encode_int (enc->state, data, &enc->bits);

    g_free (data);

    enc->frameno++;
    enc->frameno_out++;

    if ((enc->frameno % enc->nframes) != 0)
      continue;

    speex_bits_insert_terminator (&enc->bits);
    outsize = speex_bits_nbytes (&enc->bits);

    ret = gst_pad_alloc_buffer_and_set_caps (enc->srcpad,
        GST_BUFFER_OFFSET_NONE, outsize, GST_PAD_CAPS (enc->srcpad), &outbuf);

    if ((GST_FLOW_OK != ret))
      goto done;

    written = speex_bits_write (&enc->bits,
        (gchar *) GST_BUFFER_DATA (outbuf), outsize);
    g_assert (written == outsize);
    speex_bits_reset (&enc->bits);

    GST_BUFFER_TIMESTAMP (outbuf) = enc->start_ts +
        gst_util_uint64_scale_int ((enc->frameno_out -
            enc->nframes) * frame_size - enc->lookahead, GST_SECOND, enc->rate);
    GST_BUFFER_DURATION (outbuf) =
        gst_util_uint64_scale_int (frame_size * enc->nframes, GST_SECOND,
        enc->rate);
    /* set gp time and granulepos; see gst-plugins-base/ext/ogg/README */
    GST_BUFFER_OFFSET_END (outbuf) = enc->granulepos_offset +
        ((enc->frameno_out) * frame_size - enc->lookahead);
    GST_BUFFER_OFFSET (outbuf) =
        gst_util_uint64_scale_int (GST_BUFFER_OFFSET_END (outbuf), GST_SECOND,
        enc->rate);

    ret = gst_speex_enc_push_buffer (enc, outbuf);

    if ((GST_FLOW_OK != ret) && (GST_FLOW_NOT_LINKED != ret))
      goto done;
  }

done:

  return ret;
}
Example #7
0
static GstFlowReturn
gst_speex_enc_encode (GstSpeexEnc * enc, GstBuffer * buf)
{
  gint frame_size = enc->frame_size;
  gint bytes = frame_size * 2 * enc->channels, samples;
  gint outsize, written, dtx_ret = 0;
  GstMapInfo map;
  guint8 *data, *data0 = NULL, *bdata;
  gsize bsize, size;
  GstBuffer *outbuf;
  GstFlowReturn ret = GST_FLOW_OK;

  if (G_LIKELY (buf)) {
    gst_buffer_map (buf, &map, GST_MAP_READ);
    bdata = map.data;
    bsize = map.size;

    if (G_UNLIKELY (bsize % bytes)) {
      GST_DEBUG_OBJECT (enc, "draining; adding silence samples");

      size = ((bsize / bytes) + 1) * bytes;
      data0 = data = g_malloc0 (size);
      memcpy (data, bdata, bsize);
      gst_buffer_unmap (buf, &map);
      bdata = NULL;
    } else {
      data = bdata;
      size = bsize;
    }
  } else {
    GST_DEBUG_OBJECT (enc, "nothing to drain");
    goto done;
  }

  samples = size / (2 * enc->channels);
  speex_bits_reset (&enc->bits);

  /* FIXME what about dropped samples if DTS enabled ?? */

  while (size) {
    GST_DEBUG_OBJECT (enc, "encoding %d samples (%d bytes)", frame_size, bytes);

    if (enc->channels == 2) {
      speex_encode_stereo_int ((gint16 *) data, frame_size, &enc->bits);
    }
    dtx_ret += speex_encode_int (enc->state, (gint16 *) data, &enc->bits);

    data += bytes;
    size -= bytes;
  }

  speex_bits_insert_terminator (&enc->bits);
  outsize = speex_bits_nbytes (&enc->bits);

  if (bdata)
    gst_buffer_unmap (buf, &map);

#if 0
  ret = gst_pad_alloc_buffer_and_set_caps (GST_AUDIO_ENCODER_SRC_PAD (enc),
      GST_BUFFER_OFFSET_NONE, outsize,
      GST_PAD_CAPS (GST_AUDIO_ENCODER_SRC_PAD (enc)), &outbuf);

  if ((GST_FLOW_OK != ret))
    goto done;
#endif
  outbuf = gst_buffer_new_allocate (NULL, outsize, NULL);
  gst_buffer_map (outbuf, &map, GST_MAP_WRITE);

  written = speex_bits_write (&enc->bits, (gchar *) map.data, outsize);

  if (G_UNLIKELY (written < outsize)) {
    GST_ERROR_OBJECT (enc, "short write: %d < %d bytes", written, outsize);
  } else if (G_UNLIKELY (written > outsize)) {
    GST_ERROR_OBJECT (enc, "overrun: %d > %d bytes", written, outsize);
    written = outsize;
  }
  gst_buffer_unmap (outbuf, &map);
  gst_buffer_resize (outbuf, 0, written);

  if (!dtx_ret)
    GST_BUFFER_FLAG_SET (outbuf, GST_BUFFER_FLAG_GAP);

  ret = gst_audio_encoder_finish_frame (GST_AUDIO_ENCODER (enc),
      outbuf, samples);

done:
  g_free (data0);
  return ret;
}
static GstFlowReturn
gst_speex_enc_encode (GstSpeexEnc * enc, GstBuffer * buf)
{
  gint frame_size = enc->frame_size;
  gint bytes = frame_size * 2 * enc->channels, samples, size;
  gint outsize, written, dtx_ret = 0;
  guint8 *data;
  GstBuffer *outbuf;
  GstFlowReturn ret = GST_FLOW_OK;

  if (G_LIKELY (buf)) {
    data = GST_BUFFER_DATA (buf);
    size = GST_BUFFER_SIZE (buf);

    if (G_UNLIKELY (size % bytes)) {
      GST_DEBUG_OBJECT (enc, "draining; adding silence samples");
      size = ((size / bytes) + 1) * bytes;
      data = g_malloc0 (size);
      memcpy (data, GST_BUFFER_DATA (buf), GST_BUFFER_SIZE (buf));
    }
  } else {
    GST_DEBUG_OBJECT (enc, "nothing to drain");
    goto done;
  }

  samples = size / (2 * enc->channels);
  speex_bits_reset (&enc->bits);

  /* FIXME what about dropped samples if DTS enabled ?? */

  while (size) {
    GST_DEBUG_OBJECT (enc, "encoding %d samples (%d bytes)", frame_size, bytes);

    if (enc->channels == 2) {
      speex_encode_stereo_int ((gint16 *) data, frame_size, &enc->bits);
    }
    dtx_ret += speex_encode_int (enc->state, (gint16 *) data, &enc->bits);

    data += bytes;
    size -= bytes;
  }

  speex_bits_insert_terminator (&enc->bits);
  outsize = speex_bits_nbytes (&enc->bits);

  ret = gst_pad_alloc_buffer_and_set_caps (GST_AUDIO_ENCODER_SRC_PAD (enc),
      GST_BUFFER_OFFSET_NONE, outsize,
      GST_PAD_CAPS (GST_AUDIO_ENCODER_SRC_PAD (enc)), &outbuf);

  if ((GST_FLOW_OK != ret))
    goto done;

  written = speex_bits_write (&enc->bits,
      (gchar *) GST_BUFFER_DATA (outbuf), outsize);

  if (G_UNLIKELY (written < outsize)) {
    GST_ERROR_OBJECT (enc, "short write: %d < %d bytes", written, outsize);
    GST_BUFFER_SIZE (outbuf) = written;
  } else if (G_UNLIKELY (written > outsize)) {
    GST_ERROR_OBJECT (enc, "overrun: %d > %d bytes", written, outsize);
  }

  if (!dtx_ret)
    GST_BUFFER_FLAG_SET (outbuf, GST_BUFFER_FLAG_GAP);

  ret = gst_audio_encoder_finish_frame (GST_AUDIO_ENCODER (enc),
      outbuf, samples);

done:
  return ret;
}