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; }
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); }
/* * 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; }
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); }
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; }
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; }
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; }