//*****************************************************************************
//
//! This function decodes a single frame of Speex encoded audio.
//!
//! \param pui8InBuffer is the buffer that contains the Speex encoded audio.
//! \param ui32InSize is the number of valid bytes in the \e pui8InBuffer
//! buffer.
//! \param pui8OutBuffer is a pointer to the buffer to store decoded audio.
//! \param ui32OutSize is the size of the buffer pointed to by the
//! \e pui8OutBuffer pointer.
//!
//! This function will take a buffer of Speex encoded audio and decode it into
//! raw PCM audio.  The \e pui16InBuffer parameter should contain a single
//! frame encoded Speex audio.  The \e pui8OutBuffer will contain the decoded
//! audio after returning from this function.
//!
//! \return This function returns the number of decoded bytes in the
//! \e pui8OutBuffer buffer.
//
//*****************************************************************************
int32_t
SpeexDecode(uint8_t *pui8InBuffer, uint32_t ui32InSize, uint8_t *pui8OutBuffer,
            uint32_t ui32OutSize)
{
    int32_t i32Bytes;

    //
    // Read in the bit stream to the Speex library.
    //
    speex_bits_read_from(&g_sSpeexDecoder.sBits, (char *)pui8InBuffer,
                         ui32InSize);

    //
    // Decode one frame of data.
    //
    i32Bytes = speex_decode_int(g_sSpeexDecoder.pvState,
                                &g_sSpeexDecoder.sBits,
                                (int16_t *)pui8OutBuffer);

    return(i32Bytes);
}
Пример #2
0
JNIEXPORT jint JNICALL Java_com_speex_Speex_decode(JNIEnv *env,
		jobject obj, jbyteArray encoded, jshortArray lin, jint size) {

	jbyte buffer[dec_frame_size];
	jshort output_buffer[size];
	jsize encoded_length = size;
	int nsamples = (size - 1) / dec_frame_size + 1;
    int i, offset = 0, tot_shorts = 0;

	if (!codec_open)
	return 0;

	speex_bits_reset(&dbits);

	// 把数据写入buffer
    for(i = 0; i < nsamples; i++){
        if(offset + i * dec_frame_size + dec_frame_size > size) {
        	env->GetByteArrayRegion(encoded, offset + i * dec_frame_size,
        			size - (offset + i * dec_frame_size), buffer);
        	speex_bits_read_from(&dbits, (char *) buffer, size - (offset + i * dec_frame_size));
        } else {
        	env->GetByteArrayRegion(encoded, offset + i * dec_frame_size,
        			dec_frame_size, buffer);
        	speex_bits_read_from(&dbits, (char *) buffer, dec_frame_size);
        }
    }
//	env->GetByteArrayRegion(encoded, 0, encoded_length, buffer);
//	// buffer数据写入dbits
//	speex_bits_read_fdrom(&dbits, (char *) buffer, encoded_length);

    // dbits数据写入output_buffer
	speex_decode_int(dec_state, &dbits, output_buffer);
	// TODO
	env->SetShortArrayRegion(lin, 0, encoded_length, output_buffer);
	/*env->SetShortArrayRegion(lin, 0, dec_frame_size, output_buffer);*/

	/*return (jint) dec_frame_size;*/
	/*return (jint) encoded_length;*/
	return (jint) encoded_length;
}
Пример #3
0
tsk_size_t tdav_codec_speex_decode(tmedia_codec_t* self, const void* in_data, tsk_size_t in_size, void** out_data, tsk_size_t* out_max_size, const tsk_object_t* proto_hdr)
{
	int ret;
	tsk_size_t out_size = 0;
	tdav_codec_speex_t* speex = (tdav_codec_speex_t*)self;

	if(!self || !in_data || !in_size || !out_data){
		TSK_DEBUG_ERROR("Invalid parameter");
		return 0;
	}

	// initializes the bit-stream 
	speex_bits_read_from(&speex->decoder.bits, (char*)in_data, in_size);

	do{
		// performs decode() 
		if((ret = speex_decode_int(speex->decoder.state, &speex->decoder.bits, speex->decoder.buffer))){
			TSK_DEBUG_ERROR("Failed to decode the buffer. retcode=%d", ret);
			break;
		}

		if(*out_max_size <(out_size + speex->decoder.size)){
			if((*out_data = tsk_realloc(*out_data, (out_size + speex->decoder.size)))){
				*out_max_size = (out_size + speex->decoder.size);
			}
			else{
				*out_max_size = 0;
				return 0;
			}
		}

		// copy output buffer 
		memcpy(&((uint8_t*)*out_data)[out_size], speex->decoder.buffer, speex->decoder.size);
		out_size += speex->decoder.size;
	}
	while(speex_bits_remaining(&speex->decoder.bits) >= 5);
	

	return out_size;
}
Пример #4
0
/* 
 * Recover lost frame.
 */
static pj_status_t  spx_codec_recover(pjmedia_codec *codec, 
				      unsigned output_buf_len, 
				      struct pjmedia_frame *output)
{
    struct spx_private *spx;
    unsigned count;

    /* output_buf_len is unreferenced when building in Release mode */
    PJ_UNUSED_ARG(output_buf_len);

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

    count = spx_factory.speex_param[spx->param_id].clock_rate * 20 / 1000;
    pj_assert(count <= output_buf_len/2);

    /* Recover packet loss */
    speex_decode_int(spx->dec, NULL, (spx_int16_t*) output->buf);

    output->size = count * 2;

    return PJ_SUCCESS;
}
Пример #5
0
static int codec_drv_control(
		ErlDrvData handle,
		unsigned int command,
		char *buf, int len,
		char **rbuf, int rlen)
{
	codec_data* d = (codec_data*)handle;

	int i;
	int ret = 0;
	ErlDrvBinary *out;
	*rbuf = NULL;
	float frame[FRAME_SIZE];
	char cbits[200];

	switch(command) {
		case CMD_ENCODE:
			for (i=0; i < len / 2; i++){
				frame[i] = (buf[2*i] & 0xff) | (buf[2*i+1] << 8);
			}
			speex_bits_reset(&d->bits);
			speex_encode(d->estate, frame, &d->bits);
			ret = speex_bits_write(&d->bits, cbits, 200);
			out = driver_alloc_binary(ret);
			memcpy(out->orig_bytes, cbits, ret);
			*rbuf = (char *) out;
			break;
		 case CMD_DECODE:
			out = driver_alloc_binary(2*FRAME_SIZE);
			speex_bits_read_from(&d->bits, buf, len);
			speex_decode_int(d->dstate, &d->bits, (spx_int16_t *)out->orig_bytes);
			ret = 2*FRAME_SIZE;
			*rbuf = (char *) out;
			break;
		 default:
			break;
	}
	return ret;
}
JNIEXPORT jshortArray JNICALL Java_com_purplefrog_speexjni_SpeexDecoder_decode
  (JNIEnv *env, jclass cls, jint slot, jbyteArray input_frame_)
{
    if (throwIfBadSlot(env, slot))
	return;

    struct Slot * gob = slots.slots[slot];

    int frame_length = (*env)->GetArrayLength(env, input_frame_);

    int frame_size;
    speex_decoder_ctl(gob->state, SPEEX_GET_FRAME_SIZE, &frame_size);

    //

    char* input_frame = (*env)->GetByteArrayElements(env, input_frame_, 0);
    
    speex_bits_read_from(&gob->bits, input_frame, frame_length);

    (*env)->ReleaseByteArrayElements(env, input_frame_, input_frame, 0);

    //

    jshortArray rval;
    rval = (*env)->NewShortArray(env, frame_size);
    if (rval==0) {
	throwOutOfMemoryError(env, "failed to allocate speex output frame");
	return;
    }

    short* output_frame = (*env)->GetShortArrayElements(env, rval, 0);

    speex_decode_int(gob->state, &gob->bits, output_frame);

    (*env)->ReleaseShortArrayElements(env, rval, output_frame, 0);

    return rval;
}
static int libspeex_decode_frame(AVCodecContext *avctx,
                                 void *data, int *data_size,
                                 AVPacket *avpkt)
{
	const uint8_t *buf = avpkt->data;
	int buf_size = avpkt->size;
	LibSpeexContext *s = avctx->priv_data;
	int16_t *output = data, *end;
	int i, num_samples;

	num_samples = s->frame_size * avctx->channels;
	end = output + *data_size / sizeof(*output);

	speex_bits_read_from(&s->bits, buf, buf_size);

	for (i = 0; speex_bits_remaining(&s->bits) && output + num_samples < end; i++)
	{
		int ret = speex_decode_int(s->dec_state, &s->bits, output);
		if (ret <= -2)
		{
			av_log(avctx, AV_LOG_ERROR, "Error decoding Speex frame.\n");
			return -1;
		}
		else if (ret == -1)
			// end of stream
			break;

		if (avctx->channels == 2)
			speex_decode_stereo_int(output, s->frame_size, &s->stereo);

		output += num_samples;
	}

	avctx->frame_size = s->frame_size * i;
	*data_size = avctx->channels * avctx->frame_size * sizeof(*output);
	return buf_size;
}
Пример #8
0
/*
 * Decode frame.
 */
static pj_status_t spx_codec_decode( pjmedia_codec *codec, 
				     const struct pjmedia_frame *input,
				     unsigned output_buf_len, 
				     struct pjmedia_frame *output)
{
    struct spx_private *spx;
    unsigned samples_per_frame;

    spx = (struct spx_private*) codec->codec_data;
    samples_per_frame=spx_factory.speex_param[spx->param_id].samples_per_frame;

    PJ_ASSERT_RETURN(output_buf_len >= samples_per_frame << 1,
		     PJMEDIA_CODEC_EPCMTOOSHORT);

    if (input->type != PJMEDIA_FRAME_TYPE_AUDIO) {
	pjmedia_zero_samples((pj_int16_t*)output->buf, samples_per_frame);
	output->size = samples_per_frame << 1;
	output->timestamp.u64 = input->timestamp.u64;
	output->type = PJMEDIA_FRAME_TYPE_AUDIO;
	return PJ_SUCCESS;
    }

    /* Copy the data into the bit-stream struct */
    speex_bits_read_from(&spx->dec_bits, (char*)input->buf, (int)input->size);
    
    /* Set Speex dec_bits pointer to the start bit of the frame */
    speex_bits_advance(&spx->dec_bits, input->bit_info);

    /* Decode the data */
    speex_decode_int(spx->dec, &spx->dec_bits, (spx_int16_t*)output->buf);

    output->type = PJMEDIA_FRAME_TYPE_AUDIO;
    output->size = samples_per_frame << 1;
    output->timestamp.u64 = input->timestamp.u64;

    return PJ_SUCCESS;
}
Пример #9
0
uint16 SpeexPlugin::decode(uint8 *payload, uint16 payload_size, int16 *pcm_buf,
		uint16 pcm_buf_size) throw(OperationNotPerfomedException) {
	int retval;
	int speex_frame_size;

	if (!decoder || !decoder->state)
		throw OperationNotPerfomedException("Decoder not initialized");

	speex_decoder_ctl(decoder->state, SPEEX_GET_FRAME_SIZE, &speex_frame_size);

	if (pcm_buf_size < speex_frame_size)
		throw OperationNotPerfomedException("The buffer is not large enough");

	//	if (usingEchoCancellation && echoCapturedLast) {
	//		uint32 samplesize = getSampleSize();
	//		spx_int16_t *input_buf = new spx_int16_t[samplesize / 2];
	//
	//		for (int i = 0; i < getSampleSize() / 2; i++) {
	//			input_buf[i] = sample_buf[i];
	//		}
	//
	//		speex_echo_capture(echocancellation, input_buf, sample_buf);
	//		echoCapturedLast = false;
	//		delete input_buf;
	//	}

	speex_bits_read_from(&decoder->bits, reinterpret_cast<char *> (payload),
			payload_size);
	retval = speex_decode_int(decoder->state, &decoder->bits, pcm_buf);

	if (retval < 0) {
		throw OperationNotPerfomedException("Error on decode frame");
	}

	return speex_frame_size;
}
Пример #10
0
int main(int argc, char **argv)
{
//	char *outFile;
//	FILE *fout;
	FILE *fout=NULL;
	int channels=1;       
	int rate=16000;
	
	/*Holds the audio that will be written to file (16 bits per sample)*/
	short out[FRAME_SIZE];
	/*Speex handle samples as float, so we need an array of floats*/
	short output[FRAME_SIZE];
	char cbits[1500];
	int nbBytes;
	/*Holds the state of the decoder*/
	void *state;
	/*Holds bits so they can be read and written to by the Speex routines*/
	SpeexBits bits;
	int i, tmp;
	
	fout = out_file_open("", rate, &channels);
	
	/*Create a new decoder state in narrowband mode*/
	state = speex_decoder_init(&speex_wb_mode);

	/*Set the perceptual enhancement on*/
	tmp=1;
	speex_decoder_ctl(state, SPEEX_SET_ENH, &tmp);

int frame_size;
   speex_decoder_ctl(state, SPEEX_GET_FRAME_SIZE, &frame_size); 
   
//	outFile = argv[1];
//	fout = fopen(outFile, "w");

	/*Initialization of the structure that holds the bits*/
	speex_bits_init(&bits);
	while (1)
	{
		/*Read the size encoded by sampleenc, this part will likely be
		different in your application*/
		fread(&nbBytes, sizeof(int), 1, stdin);
		fprintf (stderr, "nbBytes: %d\n", nbBytes);
		if (feof(stdin))
		break;

		/*Read the "packet" encoded by sampleenc*/
		fread(cbits, 1, nbBytes, stdin);
		/*Copy the data into the bit-stream struct*/
		speex_bits_read_from(&bits, cbits, nbBytes);

		int nFrames = 1;
		while(nFrames<= FRAMES_PER_RTP_PACKET){
			/*Decode the data*/
			speex_decode_int(state, &bits, output);
	//		speex_decode(state, &bits, output);

			/*Copy from float to short (16 bits) for output*/
		//	for (i=0;i<frame_size;i++)
		//		out[i]=output[i];

			/*Write the decoded audio to file*/
			fwrite(output, sizeof(short), FRAME_SIZE, fout);
			fflush(fout);
			
			nFrames++;
		}			
	}

  if (fout != NULL)
      fclose(fout);  
	  
	/*Destroy the decoder state*/
	speex_decoder_destroy(state);
	/*Destroy the bit-stream truct*/
	speex_bits_destroy(&bits);
//	fclose(fout);
	return 0;

}
Пример #11
0
void speex_decoder::decode(void const* data, size_t size, void* output)
{
    speex_bits_read_from(&bits_, const_cast<char*>(static_cast<char const*>(data)), size);
    speex_decode_int(decoder_state_, &bits_, static_cast<spx_int16_t*>(output));
}
Пример #12
0
void *receive_audio(void *data)
{
	struct connection_data conn = *((struct connection_data *)data);	
	struct sockaddr_in other = conn.other; 
	char buffer[512];
	char compressed[SPEEX_FRAME_SIZE];
	short audio_samples[SPEEX_FRAME_SIZE];	
	int sockfd = conn.udp_sock_tx; /* Descriptor for UDP socket */
	/* receive data from socket, add to buffer */
	int addrlen = sizeof other;
	int rc;
	/* variables for speex */
        SpeexBits bits;
        void *state; /* For holding encoder state */
        int tmp;
	int nbytes;
	int i;

	int ret;
        unsigned int rate = 8000;
        int size;
        short playback_samples[SAMPLES_PER_PERIOD];
        int fd;
        int frame_size = 2;

	snd_pcm_t *handle;
        snd_pcm_hw_params_t *params;
        /* write many data at a time to device */
        /* the value of 5512 comes from aplay, investigate
         * why it is so */
	int buffer_size = SAMPLES_PER_PERIOD * sizeof(short);

        printf("rate is =%d \n", rate);

	dbg("Preparing audio playback");
        ret = voip_init_pcm(&handle, &params, &buffer_size, &rate, PLAYBACK);
        
	if (ret < 0) {
		fprintf(stderr,
			"Failed to prepare audio system\n");
		goto rcv_audio_end;
	}

	printf("Pointer address to handle=%p \n", &handle);
        printf("Pointer to handle=%p \n", handle);
        printf("Pointer to params=%p \n", params);
	
	dbg("Preparing speex for de-compression");
        state = speex_decoder_init(&speex_nb_mode);
	tmp = 1;
        speex_decoder_ctl(state, SPEEX_SET_ENH, &tmp);
        speex_bits_init(&bits);

	while(1) {
		memset(audio_samples, 0, sizeof audio_samples);
		memset(compressed, 0, sizeof compressed);
		memset(buffer, 0, sizeof buffer);
		printf("Waiting for data\n");
		if ((rc = recvfrom(sockfd, buffer, sizeof buffer, 0,
				(struct sockaddr *)&other, &addrlen)) < 0) {
			fprintf(stderr,
				"Unable to receive audio data: %s \n",
				strerror(errno));
			goto rcv_sock_close;
		}
		printf("Received %d compressed bytes on UDP socket \n", rc);

		for (i = 0; i < 5; i++) {
			speex_bits_reset(&bits);
			/* each encoded speex frame takes 38 bytes */
			memcpy(compressed, buffer + i * 38, 38);

                	speex_bits_read_from(&bits, compressed, 38);
		
			/* Decode here */
                	speex_decode_int(state, &bits, audio_samples);	
		
			ring_write(rbuff, (char *)audio_samples, sizeof audio_samples);

		}
		ret = ring_read(rbuff, (char *)audio_samples, buffer_size);
		if ( ret != buffer_size) {
                        fprintf(stderr,
                                "short read: read %d bytes \n", ret);
                }
                printf("Playing audio \n");
                /* write frames in one period to device */
                ret = voip_playback(handle, buffer_size / frame_size, audio_samples);
	}

        voip_end_pcm(handle);
	/* Destroy the encoder state */
        speex_decoder_destroy(state);
        /* Destroy the bits-packing */
        speex_bits_destroy(&bits);

rcv_sock_close:
	close(sockfd);	

rcv_audio_end:
        pthread_exit(NULL);
}
Пример #13
0
int main(int argc, char **argv)
{
   char *outFile;
   char *inFile[1];
// FILE *fout;
   FILE *fin[1];
   /*Holds the audio that will be written to file (16 bits per sample)*/
   short out[FRAME_SIZE];

    //int i;
    int result, length, tot_len;

    /*保存编码的状态*/         
    static void *stateDecode; 
   /*保存字节因此他们可以被speex常规读写*/
    static SpeexBits bitsDecode;
   //模式寄存器
    static const SpeexMode *mode=NULL;
   //解码器的采样频率
    static int speexFrequency = SAMPLERATE; //编码器的采样率
   /*得到的缓冲区的大小*/  
    static spx_int32_t frame_size; 
   /*得到的缓冲区的大小*/
   //static int channe = CHANNELS;
    /*得到是立体声*/
    //static SpeexStereoState stereo = SPEEX_STEREO_STATE_INIT; //单声到 立体声

   /* 初始话IP端口结构*/
#if (SAMPLERATE == 8000)
    mode = speex_lib_get_mode (SPEEX_MODEID_NB); //宽带编码
#elif (SAMPLERATE == 16000)
    mode = speex_lib_get_mode (SPEEX_MODEID_WB); //宽带编码
#elif (SAMPLERATE == 32000)
    mode = speex_lib_get_mode (SPEEX_MODEID_UWB); //宽带编码
#endif
    //mode = speex_lib_get_mode (SPEEX_MODEID_UWB); //在宽带模式解码


    stateDecode = speex_decoder_init(mode);      //新建一个解码器 

    speex_encoder_ctl(stateDecode, SPEEX_GET_FRAME_SIZE, &frame_size); //得到缓冲区大小

    speex_decoder_ctl(stateDecode, SPEEX_SET_SAMPLING_RATE, &speexFrequency); //设置解码器的采样频率

    speex_bits_init(&bitsDecode); //初始解码器

   char cbits[200];
   int nbBytes;
   /*Holds the state of the decoder*/
   //void *state;
   /*Holds bits so they can be read and written to by the Speex routines*/
   //SpeexBits bits;
   int i, tmp;
   int rc;

   printf("%s: start\n", __func__);


#if (SOUND_INTERFACE == SOUND_OSS)
	  init_oss_play();
#elif (SOUND_INTERFACE == SOUND_ALSA)
	 init_alsa_play();
#endif
   /*Create a new decoder state in narrowband mode*/
   stateDecode = speex_decoder_init(&speex_uwb_mode);

   /*Set the perceptual enhancement on*/
   tmp=1;
   speex_decoder_ctl(stateDecode, SPEEX_SET_ENH, &tmp);
   //printf("%s: 22222222\n", __func__);
	 inFile[0]	= argv[1];
	 //inFile[1]	= argv[2];	 
//   outFile = argv[1];
   //fout = fopen(outFile, "w");
   fin[0] = fopen(inFile[0], "r");//打开输入的spx文件
   
   if(fin[0] ==NULL)
   {
     perror("打开文件错误");
     exit(1);
   }
   
   //printf("%s: 3333333\n", __func__);
   /*Initialization of the structure that holds the bits*/
   speex_bits_init(&bitsDecode);
   //printf("%s: 4444444\n", __func__);   
   while (1)
   {   //printf("%s: 55555\n", __func__);
      //printf("%s: 1111111\n", __func__);
speex_bits_reset(&bitsDecode); 
      /*Read the size encoded by sampleenc, this part will likely be 
        different in your application*/
      fread(&nbBytes, sizeof(int), 1, fin[0]);
      fprintf (stderr, "nbBytes: %d\n", nbBytes);
      if (feof(fin[0]))
         break;
         //printf("%s: 666\n", __func__);
      /*Read the "packet" encoded by sampleenc*/
      fread(cbits, 1, nbBytes, fin[0]);
      /*Copy the data into the bit-stream struct*/
      speex_bits_read_from(&bitsDecode, cbits, nbBytes);

      /*Decode the data*/
      speex_decode_int(stateDecode, &bitsDecode, out);
#if 0
      /*Copy from float to short (16 bits) for output*/
      for (i=0;i<FRAME_SIZE;i++)
         out[i]=output[i];
   //printf("%s: 88888\n", __func__);
      /*Write the decoded audio to file*/
      //fwrite(out, sizeof(short), FRAME_SIZE, fout);
#endif 


#if (SOUND_INTERFACE == SOUND_OSS)
      rc = write(fdsoundplay, out, (SAMPLERATE/1000*READMSFORONCE)*sizeof(short));
      if(rc != (SAMPLERATE/1000*READMSFORONCE)*sizeof(short))
      {
          printf("写入数据长度与预期不符合\n");
      }
#elif (SOUND_INTERFACE == SOUND_ALSA)
      rc = snd_pcm_writei(handle, out, (SAMPLERATE/1000*READMSFORONCE)); 
         //printf("%s: 99999\n", __func__);

            if (rc == -EPIPE) 
            {
                /* EPIPE means underrun */
                fprintf(stderr, "underrun occurred\n");
                snd_pcm_prepare(handle);
            } 
            else if (rc < 0) 
            {
                fprintf(stderr, "error from writei: %s\n", snd_strerror(rc));
                        
                rc = xrun_recovery(handle, rc);             
                if (rc < 0) 
                {
                    printf("Write error: %s\n", snd_strerror(rc));
                    //return -1;
                }                   
            }  
            else if (rc != (int)(SAMPLERATE/1000*READMSFORONCE)) 
            {
                fprintf(stderr, "short write, write %d frames\n", rc);
            }
#endif
   }
   
printf("end\n");
   /*Destroy the decoder state*/
   speex_decoder_destroy(stateDecode);
   /*Destroy the bit-stream truct*/
   speex_bits_destroy(&bitsDecode);
   fclose(fin[0]);
   return 0;
}
Пример #14
0
int main(int argc, char **argv)
{
   char *inFile, *outFile, *bitsFile;
   FILE *fin, *fout, *fbits=NULL;
   short in_short[FRAME_SIZE];
   short out_short[FRAME_SIZE];
   float sigpow,errpow,snr, seg_snr=0;
   int snr_frames = 0;
   char cbits[200];
   int nbBits;
   int i;
   void *st;
   void *dec;
   SpeexBits bits;
   spx_int32_t tmp;
   int bitCount=0;
   spx_int32_t skip_group_delay;
   SpeexCallback callback;

   sigpow = 0;
   errpow = 0;

   st = speex_encoder_init(speex_lib_get_mode(SPEEX_MODEID_WB));
   dec = speex_decoder_init(speex_lib_get_mode(SPEEX_MODEID_WB));

   callback.callback_id = SPEEX_INBAND_CHAR;
   callback.func = speex_std_char_handler;
   callback.data = stderr;
   speex_decoder_ctl(dec, SPEEX_SET_HANDLER, &callback);

   callback.callback_id = SPEEX_INBAND_MODE_REQUEST;
   callback.func = speex_std_mode_request_handler;
   callback.data = st;
   speex_decoder_ctl(dec, SPEEX_SET_HANDLER, &callback);

   tmp=1;
   speex_decoder_ctl(dec, SPEEX_SET_ENH, &tmp);
   tmp=0;
   speex_encoder_ctl(st, SPEEX_SET_VBR, &tmp);
   tmp=8;
   speex_encoder_ctl(st, SPEEX_SET_QUALITY, &tmp);
   tmp=3;
   speex_encoder_ctl(st, SPEEX_SET_COMPLEXITY, &tmp);
   /*tmp=3;
   speex_encoder_ctl(st, SPEEX_SET_HIGH_MODE, &tmp);
   tmp=6;
   speex_encoder_ctl(st, SPEEX_SET_LOW_MODE, &tmp);
*/

   speex_encoder_ctl(st, SPEEX_GET_LOOKAHEAD, &skip_group_delay);
   speex_decoder_ctl(dec, SPEEX_GET_LOOKAHEAD, &tmp);
   skip_group_delay += tmp;


   if (argc != 4 && argc != 3)
   {
      fprintf (stderr, "Usage: encode [in file] [out file] [bits file]\nargc = %d", argc);
      exit(1);
   }
   inFile = argv[1];
   fin = fopen(inFile, "rb");
   outFile = argv[2];
   fout = fopen(outFile, "wb+");
   if (argc==4)
   {
      bitsFile = argv[3];
      fbits = fopen(bitsFile, "wb");
   }
   speex_bits_init(&bits);
   while (!feof(fin))
   {
      fread(in_short, sizeof(short), FRAME_SIZE, fin);
      if (feof(fin))
         break;
      speex_bits_reset(&bits);

      speex_encode_int(st, in_short, &bits);
      nbBits = speex_bits_write(&bits, cbits, 200);
      bitCount+=bits.nbBits;

      if (argc==4)
         fwrite(cbits, 1, nbBits, fbits);
      speex_bits_rewind(&bits);

      speex_decode_int(dec, &bits, out_short);
      speex_bits_reset(&bits);

      fwrite(&out_short[skip_group_delay], sizeof(short), FRAME_SIZE-skip_group_delay, fout);
      skip_group_delay = 0;
   }
   fprintf (stderr, "Total encoded size: %d bits\n", bitCount);
   speex_encoder_destroy(st);
   speex_decoder_destroy(dec);
   speex_bits_destroy(&bits);

   rewind(fin);
   rewind(fout);

   while ( FRAME_SIZE == fread(in_short, sizeof(short), FRAME_SIZE, fin) 
           &&
           FRAME_SIZE ==  fread(out_short, sizeof(short), FRAME_SIZE,fout) )
   {
	float s=0, e=0;
        for (i=0;i<FRAME_SIZE;++i) {
            s += (float)in_short[i] * in_short[i];
            e += ((float)in_short[i]-out_short[i]) * ((float)in_short[i]-out_short[i]);
        }
	seg_snr += 10*log10((s+160)/(e+160));
	sigpow += s;
	errpow += e;
	snr_frames++;
   }
   fclose(fin);
   fclose(fout);

   snr = 10 * log10( sigpow / errpow );
   seg_snr /= snr_frames;
   fprintf(stderr,"SNR = %f\nsegmental SNR = %f\n",snr, seg_snr);

#ifdef FIXED_DEBUG
   printf ("Total: %f MIPS\n", (float)(1e-6*50*spx_mips/snr_frames));
#endif
   
   return 1;
}
Пример #15
0
int do_decode(int client, int server, esd_format_t format, int speed, char* ident)
{
	/* Decoder specific variables */
	void *dec_state;
	SpeexBits bits;
	const SpeexMode* mode = NULL;
	int frame_size, frame_size2;
	SpeexCallback callback;
	SpeexStereoState stereo = SPEEX_STEREO_STATE_INIT;
	unsigned int do_sync_seq;
	
	/* Configuration variables */
	/* FIXME: Depend on NX setting and read from network */
	int modeID = SPEEX_MODEID_UWB;
	
	/* Encoder initialisation */
	speex_bits_init(&bits);
	mode = speex_lib_get_mode (modeID);
	dec_state=speex_decoder_init(mode);
	
	speex_decoder_ctl(dec_state, SPEEX_SET_SAMPLING_RATE, &speed);

	if (format & ESD_STEREO)
	{
		callback.callback_id = SPEEX_INBAND_STEREO;
		callback.func = speex_std_stereo_request_handler;
		callback.data = &stereo;
		speex_decoder_ctl(dec_state, SPEEX_SET_HANDLER, &callback);
	}
	speex_decoder_ctl(dec_state, SPEEX_GET_FRAME_SIZE, &frame_size);
	
	frame_size2=frame_size*((format & ESD_STEREO)?2:1);

	/* Lower the latency a bit */
	//do_sockopts(client, 200);
	do_sockopts(server, frame_size2 * (((format & ESD_BITS16)?16:8) / 8));
	//esd_set_socket_buffers(server, format, speed, 44100);
	//
	
	/* Get do_sync_seq from encoder */
	if (do_read_complete(client, &do_sync_seq, sizeof(do_sync_seq)) != sizeof(do_sync_seq))
		goto out;

	/* Main decoding loop */

	while (1)
	{
		unsigned int seqNr = 0;
		int nbBytes;
		char input[MAX_FRAME_BYTES+1];
		short output[MAX_FRAME_SIZE+1];
		
		if (do_read_complete(client, &seqNr, sizeof(seqNr)) != sizeof(seqNr))
			break;
#ifdef DEBUG	
		fprintf(stderr, "SeqNr: %d\n", seqNr);
#endif

		if (seqNr % do_sync_seq == 0)
			if (write(client, &seqNr, sizeof(seqNr)) != sizeof(seqNr))
				break;
		
		if (do_read_complete(client, &nbBytes, sizeof(nbBytes)) != sizeof(nbBytes))
			break;
		if (do_read_complete(client, input, nbBytes) != nbBytes)
			break;

		speex_bits_read_from(&bits, input, nbBytes); 
		speex_decode_int(dec_state, &bits, output);
		
		if (format & ESD_STEREO)
			speex_decode_stereo_int(output, frame_size, &stereo);
	
		if (do_write_samples(server, output, frame_size2, ((format & ESD_BITS16)?16:8)) != frame_size2)
			break;
	}

out:
	/* Decoder shutdown */
	speex_bits_destroy(&bits); 

	speex_decoder_destroy(dec_state);

	return 0;
}
Пример #16
0
void RakVoice::OnVoiceData(Packet *packet)
{
	bool objectExists;
	unsigned index;
	unsigned short packetMessageNumber, messagesSkipped;
	VoiceChannel *channel;
	char tempOutput[2048];
	unsigned int i;
	// 1 byte for ID, 2 bytes(short) for message number
	static const int headerSize=sizeof(unsigned char) + sizeof(unsigned short);

	index = voiceChannels.GetIndexFromKey(packet->guid, &objectExists);
	if (objectExists)
	{
		SpeexBits speexBits;
		speex_bits_init(&speexBits);
		channel=voiceChannels[index];
		memcpy(&packetMessageNumber, packet->data+1, sizeof(unsigned short));

		// Intentional overflow
		messagesSkipped=packetMessageNumber-channel->incomingMessageNumber;
		if (messagesSkipped > ((unsigned short)-1)/2)
		{
#ifdef PRINT_DEBUG_INFO
			printf("--- UNDERFLOW ---\n");
#endif
			// Underflow, just ignore it
			return;
		}
#ifdef PRINT_DEBUG_INFO
		if (messagesSkipped>0)
			printf("%i messages skipped\n", messagesSkipped);
#endif
		// Don't do more than 100 ms of messages skipped.  Discard the rest.
		int maxSkip = (int)(100.0f / (float) sampleRate);
		for (i=0; i < (unsigned) messagesSkipped && i < (unsigned) maxSkip; i++)
		{
			speex_decode_int(channel->dec_state, 0, (spx_int16_t*)tempOutput);

			// Write to buffer a 'message skipped' interpolation
			WriteOutputToChannel(channel, tempOutput);
		}
	
		channel->incomingMessageNumber=packetMessageNumber+1;

		// Write to incomingBuffer the decoded data
		speex_bits_read_from(&speexBits, (char*)(packet->data+headerSize), packet->length-headerSize);
		speex_decode_int(channel->dec_state, &speexBits, (spx_int16_t*)tempOutput);

#ifdef _DEBUG
		{
			/*
			printf("Out: ");
			if (channel->remoteIsShortSampleType)
			{
				short *blah = (short*) tempOutput;
				for (int p=0; p < 5; p++)
				{
					printf("%.i ", blah[p]);
				}
			}
			else
			{
				float *blah = (float*) tempOutput;
				for (int p=0; p < 5; p++)
				{
					printf("%.3f ", blah[p]);
				}
			}
			
			printf("\n");
			*/
		}
#endif

		// Write to buffer
		WriteOutputToChannel(channel, tempOutput);

		speex_bits_destroy(&speexBits);
	}
}
Пример #17
0
void main()
{
   char *outFile, *bitsFile;
   FILE *fout, *fbits=NULL;
#ifndef DECODE_ONLY
   char *inFile;
   FILE *fin;
#endif
#if 0
   char *dbgoutFile;
   FILE *fdbgout;
#endif
   short out_short[FRAME_SIZE];
#ifndef DECODE_ONLY
   short in_short[FRAME_SIZE];
   float sigpow,errpow,snr, seg_snr=0;
   int snr_frames = 0;
   int nbBits;
   int i;
#endif
   char cbits[200];
   void *st;
   void *dec;
   SpeexBits bits;
   int tmp;
   int bitCount=0;
   int skip_group_delay;
   SpeexCallback callback;

#ifndef DECODE_ONLY
   sigpow = 0;
   errpow = 0;
#endif

#ifdef MANUAL_ALLOC
	spxGlobalHeapPtr = spxHeap;
	spxGlobalHeapEnd = spxHeap + sizeof(spxHeap);

	spxGlobalScratchPtr = spxScratch;
	spxGlobalScratchEnd = spxScratch + sizeof(spxScratch);
#endif
   st = speex_encoder_init(&speex_nb_mode);
#ifdef MANUAL_ALLOC
	spxGlobalScratchPtr = spxScratch;		/* Reuse scratch for decoder */
#endif
   dec = speex_decoder_init(&speex_nb_mode);

   callback.callback_id = SPEEX_INBAND_CHAR;
   callback.func = speex_std_char_handler;
   callback.data = stderr;
   speex_decoder_ctl(dec, SPEEX_SET_HANDLER, &callback);

   callback.callback_id = SPEEX_INBAND_MODE_REQUEST;
   callback.func = speex_std_mode_request_handler;
   callback.data = st;
   speex_decoder_ctl(dec, SPEEX_SET_HANDLER, &callback);

   tmp=0;
   speex_decoder_ctl(dec, SPEEX_SET_ENH, &tmp);
   tmp=0;
   speex_encoder_ctl(st, SPEEX_SET_VBR, &tmp);
   tmp=4;
   speex_encoder_ctl(st, SPEEX_SET_QUALITY, &tmp);
   tmp=1;
   speex_encoder_ctl(st, SPEEX_SET_COMPLEXITY, &tmp);

   speex_mode_query(&speex_nb_mode, SPEEX_MODE_FRAME_SIZE, &tmp);
   fprintf (stderr, "frame size: %d\n", tmp);
   skip_group_delay = tmp / 2;

#ifdef DECODE_ONLY
   bitsFile = "e:\\speextrunktest\\samples\\malebitsin54.dat";
   fbits = fopen(bitsFile, "rb");
#else
   bitsFile = "e:\\speextrunktest\\samples\\malebits.dat";
   fbits = fopen(bitsFile, "wb");
#endif
   inFile = "e:\\speextrunktest\\samples\\male.snd";
   fin = fopen(inFile, "rb");
   outFile = "e:\\speextrunktest\\samples\\maleout.snd";
   fout = fopen(outFile, "wb+");
#if 0
   dbgoutFile = "e:\\speextrunktest\\samples\\maledbgout.snd";
   fdbgout = fopen(dbgoutFile, "wb+");
#endif
 
   speex_bits_init(&bits);
#ifndef DECODE_ONLY
   while (!feof(fin))
   {
      fread(in_short, sizeof(short), FRAME_SIZE, fin);
#if 0
      fwrite(in_short, sizeof(short), FRAME_SIZE, fdbgout);
#endif
      if (feof(fin))
         break;
      speex_bits_reset(&bits);

      speex_encode_int(st, in_short, &bits);
      nbBits = speex_bits_write(&bits, cbits, 200);
      bitCount+=bits.nbBits;

      fwrite(cbits, 1, nbBits, fbits);
      speex_bits_rewind(&bits);

#else /* DECODE_ONLY */
   while (!feof(fbits))
   {
      fread(cbits, 1, 20, fbits);

      if (feof(fbits))
         break;

      speex_bits_read_from(&bits, cbits, 20);
      bitCount+=160;
#endif
      
      speex_decode_int(dec, &bits, out_short);
      speex_bits_reset(&bits);

      fwrite(&out_short[skip_group_delay], sizeof(short), FRAME_SIZE-skip_group_delay, fout);
      skip_group_delay = 0;
#if 1
   fprintf (stderr, "Bits so far: %d \n", bitCount);
#endif
   }
   fprintf (stderr, "Total encoded size: %d bits\n", bitCount);
   speex_encoder_destroy(st);
   speex_decoder_destroy(dec);

#ifndef DECODE_ONLY
   rewind(fin);
   rewind(fout);

   while ( FRAME_SIZE == fread(in_short, sizeof(short), FRAME_SIZE, fin) 
           &&
           FRAME_SIZE ==  fread(out_short, sizeof(short), FRAME_SIZE,fout) )
   {
	float s=0, e=0;
        for (i=0;i<FRAME_SIZE;++i) {
            s += (float)in_short[i] * in_short[i];
            e += ((float)in_short[i]-out_short[i]) * ((float)in_short[i]-out_short[i]);
        }
	seg_snr += 10*log10((s+160)/(e+160));
	sigpow += s;
	errpow += e;
	snr_frames++;
   }
   fclose(fin);
#endif
   fclose(fout);
   fclose(fbits);

#ifndef DECODE_ONLY
   snr = 10 * log10( sigpow / errpow );
   seg_snr /= snr_frames;
   fprintf(stderr,"SNR = %f\nsegmental SNR = %f\n",snr, seg_snr);

#ifdef FIXED_DEBUG
   printf ("Total: %f MIPS\n", (float)(1e-6*50*spx_mips/snr_frames));
#endif
#endif   
}
Пример #18
0
static GstFlowReturn
speex_dec_chain_parse_data (GstSpeexDec * dec, GstBuffer * buf,
    GstClockTime timestamp, GstClockTime duration)
{
  GstFlowReturn res = GST_FLOW_OK;
  gint i, fpp;
  guint size;
  guint8 *data;
  SpeexBits *bits;

  if (!dec->frame_duration)
    goto not_negotiated;

  if (timestamp != -1) {
    dec->segment.last_stop = timestamp;
  } else {
    timestamp = dec->segment.last_stop;
  }

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

    /* send data to the bitstream */
    speex_bits_read_from (&dec->bits, (char *) data, size);

    fpp = 0;
    bits = &dec->bits;

    GST_DEBUG_OBJECT (dec, "received buffer of size %u, fpp %d", size, fpp);
  } else {
    /* concealment data, pass NULL as the bits parameters */
    GST_DEBUG_OBJECT (dec, "creating concealment data");
    fpp = dec->header->frames_per_packet;
    bits = NULL;
  }


  /* now decode each frame, catering for unknown number of them (e.g. rtp) */
  for (i = 0; (!fpp || i < fpp) && (!bits || speex_bits_remaining (bits) > 0);
      i++) {
    GstBuffer *outbuf;
    gint16 *out_data;
    gint ret;

    GST_LOG_OBJECT (dec, "decoding frame %d/%d", i, fpp);

    res = gst_pad_alloc_buffer_and_set_caps (dec->srcpad,
        GST_BUFFER_OFFSET_NONE, dec->frame_size * dec->header->nb_channels * 2,
        GST_PAD_CAPS (dec->srcpad), &outbuf);

    if (res != GST_FLOW_OK) {
      GST_DEBUG_OBJECT (dec, "buf alloc flow: %s", gst_flow_get_name (res));
      return res;
    }

    out_data = (gint16 *) GST_BUFFER_DATA (outbuf);

    ret = speex_decode_int (dec->state, bits, out_data);
    if (ret == -1) {
      /* uh? end of stream */
      GST_WARNING_OBJECT (dec, "Unexpected end of stream found");
      gst_buffer_unref (outbuf);
      outbuf = NULL;
      break;
    } else if (ret == -2) {
      GST_WARNING_OBJECT (dec, "Decoding error: corrupted stream?");
      gst_buffer_unref (outbuf);
      outbuf = NULL;
      break;
    }

    if (bits && speex_bits_remaining (bits) < 0) {
      GST_WARNING_OBJECT (dec, "Decoding overflow: corrupted stream?");
      gst_buffer_unref (outbuf);
      outbuf = NULL;
      break;
    }
    if (dec->header->nb_channels == 2)
      speex_decode_stereo_int (out_data, dec->frame_size, dec->stereo);

    GST_BUFFER_TIMESTAMP (outbuf) = timestamp;
    GST_BUFFER_DURATION (outbuf) = dec->frame_duration;

    dec->segment.last_stop += dec->frame_duration;
    timestamp = dec->segment.last_stop;

    GST_LOG_OBJECT (dec, "pushing buffer with ts=%" GST_TIME_FORMAT ", dur=%"
        GST_TIME_FORMAT, GST_TIME_ARGS (timestamp),
        GST_TIME_ARGS (dec->frame_duration));

    res = gst_pad_push (dec->srcpad, outbuf);

    if (res != GST_FLOW_OK) {
      GST_DEBUG_OBJECT (dec, "flow: %s", gst_flow_get_name (res));
      break;
    }
  }

  return res;

  /* ERRORS */
not_negotiated:
  {
    GST_ELEMENT_ERROR (dec, CORE, NEGOTIATION, (NULL),
        ("decoder not initialized"));
    return GST_FLOW_NOT_NEGOTIATED;
  }
}
Пример #19
0
static GstFlowReturn
gst_speex_dec_parse_data (GstSpeexDec * dec, GstBuffer * buf)
{
  GstFlowReturn res = GST_FLOW_OK;
  gint i, fpp;
  SpeexBits *bits;
  GstMapInfo map;

  if (!dec->frame_duration)
    goto not_negotiated;

  if (G_LIKELY (gst_buffer_get_size (buf))) {
    /* send data to the bitstream */
    gst_buffer_map (buf, &map, GST_MAP_READ);
    speex_bits_read_from (&dec->bits, (gchar *) map.data, map.size);
    gst_buffer_unmap (buf, &map);

    fpp = dec->header->frames_per_packet;
    bits = &dec->bits;

    GST_DEBUG_OBJECT (dec, "received buffer of size %" G_GSIZE_FORMAT
        ", fpp %d, %d bits", map.size, fpp, speex_bits_remaining (bits));
  } else {
    /* FIXME ? actually consider how much concealment is needed */
    /* concealment data, pass NULL as the bits parameters */
    GST_DEBUG_OBJECT (dec, "creating concealment data");
    fpp = dec->header->frames_per_packet;
    bits = NULL;
  }

  /* now decode each frame, catering for unknown number of them (e.g. rtp) */
  for (i = 0; i < fpp; i++) {
    GstBuffer *outbuf;
    gboolean corrupted = FALSE;
    gint ret;

    GST_LOG_OBJECT (dec, "decoding frame %d/%d, %d bits remaining", i, fpp,
        bits ? speex_bits_remaining (bits) : -1);
#if 0
    res =
        gst_pad_alloc_buffer_and_set_caps (GST_AUDIO_DECODER_SRC_PAD (dec),
        GST_BUFFER_OFFSET_NONE, dec->frame_size * dec->header->nb_channels * 2,
        GST_PAD_CAPS (GST_AUDIO_DECODER_SRC_PAD (dec)), &outbuf);

    if (res != GST_FLOW_OK) {
      GST_DEBUG_OBJECT (dec, "buf alloc flow: %s", gst_flow_get_name (res));
      return res;
    }
#endif
    /* FIXME, we can use a bufferpool because we have fixed size buffers. We
     * could also use an allocator */
    outbuf =
        gst_buffer_new_allocate (NULL,
        dec->frame_size * dec->header->nb_channels * 2, NULL);

    gst_buffer_map (outbuf, &map, GST_MAP_WRITE);
    ret = speex_decode_int (dec->state, bits, (spx_int16_t *) map.data);

    if (ret == -1) {
      /* uh? end of stream */
      GST_WARNING_OBJECT (dec, "Unexpected end of stream found");
      corrupted = TRUE;
    } else if (ret == -2) {
      GST_WARNING_OBJECT (dec, "Decoding error: corrupted stream?");
      corrupted = TRUE;
    }

    if (bits && speex_bits_remaining (bits) < 0) {
      GST_WARNING_OBJECT (dec, "Decoding overflow: corrupted stream?");
      corrupted = TRUE;
    }
    if (dec->header->nb_channels == 2)
      speex_decode_stereo_int ((spx_int16_t *) map.data, dec->frame_size,
          dec->stereo);

    gst_buffer_unmap (outbuf, &map);

    if (!corrupted) {
      res = gst_audio_decoder_finish_frame (GST_AUDIO_DECODER (dec), outbuf, 1);
    } else {
      res = gst_audio_decoder_finish_frame (GST_AUDIO_DECODER (dec), NULL, 1);
      gst_buffer_unref (outbuf);
    }

    if (res != GST_FLOW_OK) {
      GST_DEBUG_OBJECT (dec, "flow: %s", gst_flow_get_name (res));
      break;
    }
  }

  return res;

  /* ERRORS */
not_negotiated:
  {
    GST_ELEMENT_ERROR (dec, CORE, NEGOTIATION, (NULL),
        ("decoder not initialized"));
    return GST_FLOW_NOT_NEGOTIATED;
  }
}
Пример #20
0
//function decodes input buffer of length bytes, and stores output in out
void decode(char* in, char* out, int bytes){
  speex_bits_read_from(&dec_bits, in, bytes);
  speex_decode_int(dec_state, &dec_bits, (short*)out);
}
Пример #21
0
int AudioStreamPlaybackSpeex::mix(int16_t *p_buffer, int p_frames) {

	//printf("update, loops %i, read ofs %i\n", (int)loops, read_ofs);
	//printf("playing %i, paused %i\n", (int)playing, (int)paused);

	if (!active || !playing || !data.size())
		return 0;

	/*
	if (read_ofs >= data.size()) {
		if (loops) {
			reload();
			++loop_count;
		} else {
			return;
		};
	};
	*/

	int todo = p_frames;
	if (todo < page_size) {
		return 0;
	};

	int eos = 0;

	while (todo > page_size) {

		int ret = 0;
		while ((todo > page_size && packets_available && !eos) || (ret = ogg_sync_pageout(&oy, &og)) == 1) {

			if (!packets_available) {
				/*Add page to the bitstream*/
				ogg_stream_pagein(&os, &og);
				page_granule = ogg_page_granulepos(&og);
				page_nb_packets = ogg_page_packets(&og);
				packet_no = 0;
				if (page_granule > 0 && frame_size) {
					skip_samples = page_nb_packets * frame_size * nframes - (page_granule - last_granule);
					if (ogg_page_eos(&og))
						skip_samples = -skip_samples;
					/*else if (!ogg_page_bos(&og))
					skip_samples = 0;*/
				} else {
					skip_samples = 0;
				}

				last_granule = page_granule;
				packets_available = true;
			}
			/*Extract all available packets*/
			while (todo > page_size && !eos) {

				if (ogg_stream_packetout(&os, &op) != 1) {
					packets_available = false;
					break;
				}

				packet_no++;

				/*End of stream condition*/
				if (op.e_o_s)
					eos = 1;

				/*Copy Ogg packet to Speex bitstream*/
				speex_bits_read_from(&bits, (char *)op.packet, op.bytes);

				for (int j = 0; j != nframes; j++) {

					int16_t *out = p_buffer;

					int ret;
					/*Decode frame*/
					ret = speex_decode_int(st, &bits, out);

					/*for (i=0;i<frame_size*channels;i++)
					  printf ("%d\n", (int)output[i]);*/

					if (ret == -1) {
						printf("decode returned -1\n");
						break;
					};
					if (ret == -2) {
						OS::get_singleton()->printerr("Decoding error: corrupted stream?\n");
						break;
					}
					if (speex_bits_remaining(&bits) < 0) {
						OS::get_singleton()->printerr("Decoding overflow: corrupted stream?\n");
						break;
					}
					//if (channels==2)
					//	speex_decode_stereo_int(output, frame_size, &stereo);

					/*Convert to short and save to output file*/
					for (int i = 0; i < frame_size * stream_channels; i++) {
						out[i] = le_short(out[i]);
					}

					{

						int new_frame_size = frame_size;

						/*printf ("packet %d %d\n", packet_no, skip_samples);*/
						if (packet_no == 1 && j == 0 && skip_samples > 0) {
							/*printf ("chopping first packet\n");*/
							new_frame_size -= skip_samples;
						}
						if (packet_no == page_nb_packets && skip_samples < 0) {
							int packet_length = nframes * frame_size + skip_samples;
							new_frame_size = packet_length - j * frame_size;
							if (new_frame_size < 0)
								new_frame_size = 0;
							if (new_frame_size > frame_size)
								new_frame_size = frame_size;
							/*printf ("chopping end: %d %d %d\n", new_frame_size, packet_length, packet_no);*/
						}

						p_buffer += new_frame_size * stream_channels;
						todo -= new_frame_size;
					}
				}
			};
		};
		//todo = get_todo();

		//todo is still greater than page size, can write more
		if (todo > page_size || eos) {
			if (read_ofs < data.size()) {

				//char *buf;
				int nb_read = MIN(data.size() - read_ofs, READ_CHUNK);

				/*Get the ogg buffer for writing*/
				char *ogg_dst = ogg_sync_buffer(&oy, nb_read);
				/*Read bitstream from input file*/
				copymem(ogg_dst, &data[read_ofs], nb_read);
				read_ofs += nb_read;
				ogg_sync_wrote(&oy, nb_read);
			} else {
				if (loops) {
					reload();
					++loop_count;
					//break;
				} else {
					playing = false;
					unload();
					break;
				};
			}
		};
	};

	return p_frames - todo;
};
Пример #22
0
int main(int argc, char **argv)
{
	if (argc != 3)
	{
		fprintf(stdout, "Usage:%s input.speex output.pcm\n", argv[0]);
		fprintf(stdout, "\t input.speex is audio data encoded by speex, output.pcm is audio raw data.\n");
		return -1;
	}

	char *infile;
	char *outfile;
	FILE *fin;
	FILE *fout;
	/*Speex handle samples as float, so we need an array of floats*/
	short output[FRAME_SIZE];
	char cbits[200];
	int nbBytes;
	/*Holds the state of the decoder*/
	void *state;
	/*Holds bits so they can be read and written to by the Speex routines*/
	SpeexBits bits;
	int tmp;
	int ret = 0;

	/*Create a new decoder state in narrowband mode*/
	state = speex_decoder_init(&speex_wb_mode);

	/*Set the perceptual enhancement on*/
	tmp = 1;
	speex_decoder_ctl(state, SPEEX_SET_ENH, &tmp);

	infile = argv[1];
	fin = fopen(infile, "r");

	outfile = argv[2];
	fout = fopen(outfile, "w+");

	/*Initialization of the structure that holds the bits*/
	speex_bits_init(&bits);
	while(1)
	{
		/*Read the size encoded by sampleenc, this part will likely be
		  different in your application*/
		fread(&nbBytes, sizeof(int), 1, fin);
		//fprintf(stderr, "nbBytes: %d\n", nbBytes);
		if (feof(fin))
			break;

		/*Read the "packet" encoded by sampleenc*/
		fread(cbits, 1, nbBytes, fin);
		/*Copy the data into the bit-stream struct*/
		speex_bits_read_from(&bits, cbits, nbBytes);

		while (true)
		{
			/*Decode the data*/
			ret = speex_decode_int(state, &bits, output);

			if (!ret)
			{
				/*Write the decoded audio to file*/
				fwrite(output, sizeof(short), FRAME_SIZE, fout);
			}
			else
			{
				break;
			}
		}
	}

	/*Destroy the decoder state*/
	speex_decoder_destroy(state);
	/*Destroy the bit-stream struct*/
	speex_bits_destroy(&bits);
	fclose(fin);
	fclose(fout);
	return 0;
}
Пример #23
0
/*****************************************************************************
 * ProcessPacket: processes a Speex packet.
 *****************************************************************************/
static void *ProcessPacket( decoder_t *p_dec, ogg_packet *p_oggpacket,
                            block_t **pp_block )
{
    decoder_sys_t *p_sys = p_dec->p_sys;
    block_t *p_block = *pp_block;

    if( p_block && p_block->i_flags & BLOCK_FLAG_DISCONTINUITY )
        Flush( p_dec );

    /* Date management */
    if( p_block && p_block->i_pts > VLC_TS_INVALID &&
        p_block->i_pts != date_Get( &p_sys->end_date ) )
    {
        date_Set( &p_sys->end_date, p_block->i_pts );
    }

    if( !date_Get( &p_sys->end_date ) )
    {
        /* We've just started the stream, wait for the first PTS. */
        if( p_block ) block_Release( p_block );
        return NULL;
    }

    *pp_block = NULL; /* To avoid being fed the same packet again */

    if( p_sys->b_packetizer )
    {
        if ( p_sys->p_header->frames_per_packet > 1 )
        {
            short *p_frame_holder = NULL;
            int i_bits_before = 0, i_bits_after = 0, i_bytes_in_speex_frame = 0,
                i_pcm_output_size = 0, i_bits_in_speex_frame = 0;
            block_t *p_new_block = NULL;

            i_pcm_output_size = p_sys->p_header->frame_size;
            p_frame_holder = (short*)xmalloc( sizeof(short)*i_pcm_output_size );

            speex_bits_read_from( &p_sys->bits, (char*)p_oggpacket->packet,
                p_oggpacket->bytes);
            i_bits_before = speex_bits_remaining( &p_sys->bits );
            speex_decode_int(p_sys->p_state, &p_sys->bits, p_frame_holder);
            i_bits_after = speex_bits_remaining( &p_sys->bits );

            i_bits_in_speex_frame = i_bits_before - i_bits_after;
            i_bytes_in_speex_frame = ( i_bits_in_speex_frame +
                (8 - (i_bits_in_speex_frame % 8)) )
                / 8;

            p_new_block = block_Alloc( i_bytes_in_speex_frame );
            memset( p_new_block->p_buffer, 0xff, i_bytes_in_speex_frame );

            /*
             * Copy the first frame in this packet to a new packet.
             */
            speex_bits_rewind( &p_sys->bits );
            speex_bits_write( &p_sys->bits,
                (char*)p_new_block->p_buffer,
                (int)i_bytes_in_speex_frame );

            /*
             * Move the remaining part of the original packet (subsequent
             * frames, if there are any) into the beginning
             * of the original packet so
             * they are preserved following the realloc.
             * Note: Any bits that
             * remain in the initial packet
             * are "filler" if they do not constitute
             * an entire byte.
             */
            if ( i_bits_after > 7 )
            {
                /* round-down since we rounded-up earlier (to include
             * the speex terminator code.
             */
                i_bytes_in_speex_frame--;
                speex_bits_write( &p_sys->bits,
                    (char*)p_block->p_buffer,
                    p_block->i_buffer - i_bytes_in_speex_frame );
                p_block = block_Realloc( p_block,
                    0,
                    p_block->i_buffer-i_bytes_in_speex_frame );
                *pp_block = p_block;
            }
            else
            {
                speex_bits_reset( &p_sys->bits );
            }

            free( p_frame_holder );
            return SendPacket( p_dec, p_new_block);
        }
        else
        {
                return SendPacket( p_dec, p_block );
        }
    }
    else
    {
        block_t *p_aout_buffer = DecodePacket( p_dec, p_oggpacket );

        if( p_block )
            block_Release( p_block );
        return p_aout_buffer;
    }
}
Пример #24
0
int
_v3_audio_decode(
        v3_handle v3h,
        /* payload input */
        int16_t index,
        int16_t format,
        v3_coder *coder,
        const uint8_t *data,
        int32_t datalen,
        /* pcm output */
        uint8_t *pcm,
        uint32_t *pcmlen,
        /* optional args */
        uint32_t *rate,
        uint8_t *channels) {
    uint32_t maxpcmlen;
    int ret = V3_OK;

    _v3_enter(v3h, __func__);

    if (!coder || !data || !datalen || !pcm || !pcmlen || (pcmlen && !*pcmlen)) {
        _v3_leave(v3h, __func__);
        return V3_FAILURE;
    }

    maxpcmlen = *pcmlen;
    *pcmlen = 0;
    if (channels) {
        *channels = 1;
    }

    if (coder->state && (coder->index != index || coder->format != format)) {
        _v3_coder_destroy(v3h, coder);
    }
    switch (index) {
#ifdef HAVE_GSM
      case 0:
        {
            const v3_codec *codec = v3_codec_get(index, format);
            int opt = 1;

            _v3_debug(v3h, V3_DBG_INFO, "decoding %i bytes of gsm to pcm @ %u", datalen, codec->rate);
            if (!coder->state) {
                if (!(coder->state = gsm_create())) {
                    _v3_debug(v3h, V3_DBG_INFO, "failed to create gsm decoder");
                    ret = V3_FAILURE;
                    break;
                }
                _v3_debug(v3h, V3_DBG_MEMORY, "initialized gsm decoder state");
                gsm_option(coder->state, GSM_OPT_WAV49, &opt);
                coder->index = index;
                coder->format = format;
                coder->encoder = false;
            }
            while ((datalen -= 65) >= 0 && *pcmlen + codec->framesize <= maxpcmlen) {
                if (gsm_decode(coder->state, (void *)data, (void *)pcm) ||
                    gsm_decode(coder->state, (void *)data+33, (void *)pcm+(codec->framesize/2))) {
                    _v3_debug(v3h, V3_DBG_INFO, "failed to decode gsm packet");
                }
                data    += 65;
                pcm     += codec->framesize;
                *pcmlen += codec->framesize;
            }
            if (rate) {
                *rate = codec->rate;
            }
        }
        break;
#endif
#ifdef HAVE_OPUS
      case 1:
      case 2:
        {
            const v3_codec *codec = v3_codec_get(index, format);
            int tmp;

            _v3_debug(v3h, V3_DBG_INFO, "decoding %i bytes of opus to pcm @ %u", datalen, codec->rate);
            if (!coder->state) {
                if (!(coder->state = opus_decoder_create(codec->rate, 2, &tmp))) {
                    _v3_debug(v3h, V3_DBG_INFO, "failed to create opus decoder: %s", opus_strerror(tmp));
                    ret = V3_FAILURE;
                    break;
                }
                _v3_debug(v3h, V3_DBG_MEMORY, "initialized opus decoder state");
                coder->index = index;
                coder->format = format;
                coder->encoder = false;
            }
            if ((tmp = opus_decode(coder->state, data, datalen, (void *)pcm, maxpcmlen / sizeof(int16_t), 0)) <= 0) {
                _v3_debug(v3h, V3_DBG_INFO, "failed to decode opus packet");
            }
            *pcmlen += tmp * sizeof(int16_t) * 2;
            if (rate) {
                *rate = codec->rate;
            }
            if (channels) {
                *channels = 2;
            }
        }
        break;
#endif
#ifdef HAVE_SPEEX
      case 3:
        {
            const v3_codec *codec = v3_codec_get(index, format);
            uint16_t framesize;
            SpeexBits bits;

            _v3_debug(v3h, V3_DBG_INFO, "decoding %i bytes of speex to pcm @ %u", datalen, codec->rate);
            if (!coder->state) {
                switch (codec->rate) {
                  case 8000:
                    coder->state = speex_decoder_init(&speex_nb_mode);
                    break;
                  case 16000:
                    coder->state = speex_decoder_init(&speex_wb_mode);
                    break;
                  case 32000:
                    coder->state = speex_decoder_init(&speex_uwb_mode);
                    break;
                }
                if (!coder->state) {
                    _v3_debug(v3h, V3_DBG_INFO, "failed to create speex decoder");
                    ret = V3_FAILURE;
                    break;
                }
                _v3_debug(v3h, V3_DBG_MEMORY, "initialized speex decoder state");
                coder->index = index;
                coder->format = format;
                coder->encoder = false;
            }
            datalen -= sizeof(uint16_t) * 2;
            if (datalen < 0) {
                _v3_debug(v3h, V3_DBG_INFO, "received a malformed speex packet");
                ret = V3_MALFORM;
                break;
            }
            data += sizeof(uint16_t) * 2;
            speex_bits_init(&bits);
            while (datalen) {
                framesize = ntohs(*(uint16_t *)data);
                datalen -= framesize + sizeof(uint16_t);
                if (!framesize || datalen < 0 || *pcmlen + codec->framesize > maxpcmlen) {
                    _v3_debug(v3h, V3_DBG_INFO, "received a malformed speex packet");
                    ret = V3_MALFORM;
                    break;
                }
                data += sizeof(uint16_t);
                speex_bits_read_from(&bits, (void *)data, framesize);
                speex_decode_int(coder->state, &bits, (void *)pcm);
                speex_bits_reset(&bits);
                data    += framesize;
                pcm     += codec->framesize;
                *pcmlen += codec->framesize;
            }
            speex_bits_destroy(&bits);
            if (rate) {
                *rate = codec->rate;
            }
        }
        break;
#endif
      default:
        (void)rate, (void)maxpcmlen;
        _v3_debug(v3h, V3_DBG_INFO, "unsupported codec: index: %i | format: %i", index, format);
        ret = V3_FAILURE;
        break;
    }

    _v3_leave(v3h, __func__);
    return ret;
}
Пример #25
0
static void dec_process(MSFilter *f){
	DecState *s=(DecState*)f->data;
	mblk_t *im;
	mblk_t *om;
	int err=-2;
	SpeexBits bits;
	int bytes=s->frsz*2;
	bool_t bits_initd=FALSE;

	while((im=ms_queue_get(f->inputs[0]))!=NULL){
		int rem_bits=(im->b_wptr-im->b_rptr)*8;

		if (!bits_initd) {
			speex_bits_init(&bits);
			bits_initd=TRUE;
		}else speex_bits_reset(&bits);

		speex_bits_read_from(&bits,(char*)im->b_rptr,im->b_wptr-im->b_rptr);

		/* support for multiple frame  in one RTP packet */
 		do{
			om=allocb(bytes,0);
			mblk_meta_copy(im, om);
			err=speex_decode_int(s->state,&bits,(int16_t*)om->b_wptr);
			om->b_wptr+=bytes;

			if (err==0){
				ms_queue_put(f->outputs[0],om);
				if (s->sample_time==0) s->sample_time=f->ticker->time;
				s->sample_time+=20;
				if (s->plc_count>0){
					// ms_warning("Did speex packet loss concealment during %i ms",s->plc_count*20);
					s->plc_count=0;
				}

			}else {
				if (err==-1)
					ms_warning("speex end of stream");
				else if (err==-2)
					ms_warning("speex corrupted stream");
				freemsg(om);
			}
		}while((rem_bits= speex_bits_remaining(&bits))>10);
		freemsg(im);
	}
	if (s->plc && s->sample_time!=0 && f->ticker->time>=s->sample_time){
		/* we should output a frame but no packet were decoded
		 thus do packet loss concealment*/
		om=allocb(bytes,0);
		err=speex_decode_int(s->state,NULL,(int16_t*)om->b_wptr);
		om->b_wptr+=bytes;
		mblk_set_plc_flag(om, 1);
		ms_queue_put(f->outputs[0],om);

		s->sample_time+=20;
		s->plc_count++;
		if (s->plc_count>=plc_max){
			s->sample_time=0;
		}
	}
	if (bits_initd) speex_bits_destroy(&bits);
}
static GstFlowReturn
gst_speex_dec_parse_data (GstSpeexDec * dec, GstBuffer * buf)
{
  GstFlowReturn res = GST_FLOW_OK;
  gint i, fpp;
  guint size;
  guint8 *data;
  SpeexBits *bits;

  if (!dec->frame_duration)
    goto not_negotiated;

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

    /* send data to the bitstream */
    speex_bits_read_from (&dec->bits, (char *) data, size);

    fpp = dec->header->frames_per_packet;
    bits = &dec->bits;

    GST_DEBUG_OBJECT (dec, "received buffer of size %u, fpp %d, %d bits",
        size, fpp, speex_bits_remaining (bits));
  } else {
    /* FIXME ? actually consider how much concealment is needed */
    /* concealment data, pass NULL as the bits parameters */
    GST_DEBUG_OBJECT (dec, "creating concealment data");
    fpp = dec->header->frames_per_packet;
    bits = NULL;
  }

  /* now decode each frame, catering for unknown number of them (e.g. rtp) */
  for (i = 0; i < fpp; i++) {
    GstBuffer *outbuf;
    gint16 *out_data;
    gint ret;

    GST_LOG_OBJECT (dec, "decoding frame %d/%d, %d bits remaining", i, fpp,
        bits ? speex_bits_remaining (bits) : -1);

    res =
        gst_pad_alloc_buffer_and_set_caps (GST_AUDIO_DECODER_SRC_PAD (dec),
        GST_BUFFER_OFFSET_NONE, dec->frame_size * dec->header->nb_channels * 2,
        GST_PAD_CAPS (GST_AUDIO_DECODER_SRC_PAD (dec)), &outbuf);

    if (res != GST_FLOW_OK) {
      GST_DEBUG_OBJECT (dec, "buf alloc flow: %s", gst_flow_get_name (res));
      return res;
    }

    out_data = (gint16 *) GST_BUFFER_DATA (outbuf);

    ret = speex_decode_int (dec->state, bits, out_data);
    if (ret == -1) {
      /* uh? end of stream */
      if (fpp == 0 && speex_bits_remaining (bits) < 8) {
        /* if we did not know how many frames to expect, then we get this
           at the end if there are leftover bits to pad to the next byte */
        GST_DEBUG_OBJECT (dec, "Discarding leftover bits");
      } else {
        GST_WARNING_OBJECT (dec, "Unexpected end of stream found");
      }
      gst_audio_decoder_finish_frame (GST_AUDIO_DECODER (dec), NULL, 1);
      gst_buffer_unref (outbuf);
    } else if (ret == -2) {
      GST_WARNING_OBJECT (dec, "Decoding error: corrupted stream?");
      gst_audio_decoder_finish_frame (GST_AUDIO_DECODER (dec), NULL, 1);
      gst_buffer_unref (outbuf);
    }

    if (bits && speex_bits_remaining (bits) < 0) {
      GST_WARNING_OBJECT (dec, "Decoding overflow: corrupted stream?");
      gst_audio_decoder_finish_frame (GST_AUDIO_DECODER (dec), NULL, 1);
      gst_buffer_unref (outbuf);
    }
    if (dec->header->nb_channels == 2)
      speex_decode_stereo_int (out_data, dec->frame_size, dec->stereo);

    res = gst_audio_decoder_finish_frame (GST_AUDIO_DECODER (dec), outbuf, 1);

    if (res != GST_FLOW_OK) {
      GST_DEBUG_OBJECT (dec, "flow: %s", gst_flow_get_name (res));
      break;
    }
  }

  return res;

  /* ERRORS */
not_negotiated:
  {
    GST_ELEMENT_ERROR (dec, CORE, NEGOTIATION, (NULL),
        ("decoder not initialized"));
    return GST_FLOW_NOT_NEGOTIATED;
  }
}
Пример #27
0
/* this is called for each file to process */
enum codec_status codec_run(void)
{
    int error = CODEC_ERROR;

    SpeexBits bits;
    int eof = 0;
    spx_ogg_sync_state oy;
    spx_ogg_page og;
    spx_ogg_packet op;
    spx_ogg_stream_state os;
    spx_int64_t page_granule = 0;
    spx_int64_t cur_granule = 0;
    int enh_enabled = 1;
    int nframes = 2;
    int eos = 0;
    SpeexStereoState *stereo;
    int channels = -1;
    int samplerate = ci->id3->frequency;
    int extra_headers = 0;
    int stream_init = 0;
    /* rockbox: comment 'set but unused' variables
    int page_nb_packets;
    */
    int frame_size;
    int packet_count = 0;
    int lookahead;
    int headerssize = 0;
    unsigned long strtoffset = ci->id3->offset;
    void *st = NULL;
    int j = 0;
    intptr_t param;

    memset(&bits, 0, sizeof(bits));
    memset(&oy, 0, sizeof(oy));

    /* Ogg handling still uses mallocs, so reset the malloc buffer per track */
    if (codec_init()) {
        goto exit;
    }

    ci->seek_buffer(0);
    ci->set_elapsed(0);

    stereo = speex_stereo_state_init();
    spx_ogg_sync_init(&oy);
    spx_ogg_alloc_buffer(&oy,2*CHUNKSIZE);

    codec_set_replaygain(ci->id3);

    eof = 0;
    while (!eof) {
        enum codec_command_action action = ci->get_command(&param);

        if (action == CODEC_ACTION_HALT)
            break;

        /*seek (seeks to the page before the position) */
        if (action == CODEC_ACTION_SEEK_TIME) {
            if(samplerate!=0&&packet_count>1){
                LOGF("Speex seek page:%lld,%lld,%ld,%lld,%d\n",
                     ((spx_int64_t)param/1000) *
                     (spx_int64_t)samplerate,
                     page_granule, param,
                     (page_granule/samplerate)*1000, samplerate);

                speex_seek_page_granule(((spx_int64_t)param/1000) *
                                        (spx_int64_t)samplerate,
                                        page_granule, &oy, headerssize);
            }

            ci->set_elapsed(param);
            ci->seek_complete();
        }

next_page:
        /*Get the ogg buffer for writing*/
        if(get_more_data(&oy)<1){/*read error*/
            goto done;
        }

        /* Loop for all complete pages we got (most likely only one) */
        while (spx_ogg_sync_pageout(&oy, &og) == 1) {
            int packet_no;
            if (stream_init == 0) {
                spx_ogg_stream_init(&os, spx_ogg_page_serialno(&og));
                stream_init = 1;
            }

            /* Add page to the bitstream */
            spx_ogg_stream_pagein(&os, &og);

            page_granule = spx_ogg_page_granulepos(&og);
            /* page_nb_packets = spx_ogg_page_packets(&og); */

            cur_granule = page_granule;

            /* Extract all available packets */
            packet_no=0;

            while (!eos && spx_ogg_stream_packetout(&os, &op)==1){
                /* If first packet, process as Speex header */
                if (packet_count==0){
                    st = process_header(&op, enh_enabled, &frame_size,
                                         &samplerate, &nframes, &channels,
                                         stereo, &extra_headers);

                    speex_decoder_ctl(st, SPEEX_GET_LOOKAHEAD, &lookahead);
                    if (!nframes)
                        nframes=1;

                    if (!st){
                        goto done;
                    }

                    ci->configure(DSP_SET_FREQUENCY, ci->id3->frequency);
                    ci->configure(DSP_SET_SAMPLE_DEPTH, 16);
                    if (channels == 2) {
                        ci->configure(DSP_SET_STEREO_MODE, STEREO_INTERLEAVED);
                    } else if (channels == 1) {
                        ci->configure(DSP_SET_STEREO_MODE, STEREO_MONO);
                    }

                    /* Speex header in its own page, add the whole page
                       headersize */
                    headerssize += og.header_len+og.body_len;

                } else if (packet_count<=1+extra_headers){
                    /* add packet to headersize */
                    headerssize += op.bytes;

                    /* Ignore extra headers */
                } else {
                    if (packet_count <= 2+extra_headers) {
                        if (strtoffset) {
                            ci->seek_buffer(strtoffset);
                            spx_ogg_sync_reset(&oy);
                            packet_count++;
                            goto next_page;
                        }
                    }
                    packet_no++;

                    if (op.e_o_s) /* End of stream condition */
                        eos=1;

                    /* Set Speex bitstream to point to Ogg packet */
                    speex_bits_set_bit_buffer(&bits, (char *)op.packet,
                                                     op.bytes);
                    for (j = 0; j != nframes; j++){
                        int ret;

                        /* Decode frame */
                        ret = speex_decode_int(st, &bits, output);

                        if (ret == -1)
                            break;

                        if (ret == -2)
                            break;

                        if (speex_bits_remaining(&bits) < 0)
                            break;

                        if (channels == 2)
                            speex_decode_stereo_int(output, frame_size, stereo);

                        if (frame_size > 0) {
                            spx_int16_t *frame_start = output + lookahead;

                            if (channels == 2)
                                frame_start += lookahead;
                            ci->pcmbuf_insert(frame_start, NULL,
                                              frame_size - lookahead);
                            lookahead = 0;
                            /* 2 bytes/sample */
                            cur_granule += frame_size / 2;

                            ci->set_offset((long) ci->curpos);

                            ci->set_elapsed((samplerate == 0) ? 0 :
                                             cur_granule * 1000 / samplerate);
                         }
                    }
                }
                packet_count++;
            }
        }
    }

    error = CODEC_OK;
done:
    /* Clean things up for the next track */
    speex_bits_destroy(&bits);

    if (st)
        speex_decoder_destroy(st);

    if (stream_init)
       spx_ogg_stream_destroy(&os);

    spx_ogg_sync_destroy(&oy);

exit:
    return error;
}
Пример #28
0
/*
=====================
CL_ParseVoip

A VoIP message has been received from the server
=====================
*/
static
void CL_ParseVoip( msg_t *msg )
{
	static short decoded[ 4096 ]; // !!! FIXME: don't hardcode.

	const int    sender = MSG_ReadShort( msg );
	const int    generation = MSG_ReadByte( msg );
	const int    sequence = MSG_ReadLong( msg );
	const int    frames = MSG_ReadByte( msg );
	const int    packetsize = MSG_ReadShort( msg );
	const int    flags = MSG_ReadBits( msg, VOIP_FLAGCNT );
	char         encoded[ 1024 ];
	int          seqdiff = sequence - clc.voipIncomingSequence[ sender ];
	int          written = 0;
	int          i;

	Com_DPrintf( "VoIP: %d-byte packet from client %d\n", packetsize, sender );

	if ( sender < 0 )
	{
		return; // short/invalid packet, bail.
	}
	else if ( generation < 0 )
	{
		return; // short/invalid packet, bail.
	}
	else if ( sequence < 0 )
	{
		return; // short/invalid packet, bail.
	}
	else if ( frames < 0 )
	{
		return; // short/invalid packet, bail.
	}
	else if ( packetsize < 0 )
	{
		return; // short/invalid packet, bail.
	}

	if ( packetsize > sizeof( encoded ) )  // overlarge packet?
	{
		int bytesleft = packetsize;

		while ( bytesleft )
		{
			int br = bytesleft;

			if ( br > sizeof( encoded ) )
			{
				br = sizeof( encoded );
			}

			MSG_ReadData( msg, encoded, br );
			bytesleft -= br;
		}

		return; // overlarge packet, bail.
	}

	if ( !clc.speexInitialized )
	{
		MSG_ReadData( msg, encoded, packetsize );  // skip payload.
		return; // can't handle VoIP without libspeex!
	}
	else if ( sender >= MAX_CLIENTS )
	{
		MSG_ReadData( msg, encoded, packetsize );  // skip payload.
		return; // bogus sender.
	}
	else if ( CL_ShouldIgnoreVoipSender( sender ) )
	{
		MSG_ReadData( msg, encoded, packetsize );  // skip payload.
		return; // Channel is muted, bail.
	}

	// !!! FIXME: make sure data is narrowband? Does decoder handle this?

	Com_DPrintf( "VoIP: packet accepted!\n" );

	// This is a new "generation" ... a new recording started, reset the bits.
	if ( generation != clc.voipIncomingGeneration[ sender ] )
	{
		Com_DPrintf( "VoIP: new generation %d!\n", generation );
		speex_bits_reset( &clc.speexDecoderBits[ sender ] );
		clc.voipIncomingGeneration[ sender ] = generation;
		seqdiff = 0;
	}
	else if ( seqdiff < 0 ) // we're ahead of the sequence?!
	{
		// This shouldn't happen unless the packet is corrupted or something.
		Com_DPrintf( "VoIP: misordered sequence! %d < %d!\n",
		             sequence, clc.voipIncomingSequence[ sender ] );
		// reset the bits just in case.
		speex_bits_reset( &clc.speexDecoderBits[ sender ] );
		seqdiff = 0;
	}
	else if ( seqdiff > 100 ) // more than 2 seconds of audio dropped?
	{
		// just start over.
		Com_DPrintf( "VoIP: Dropped way too many (%d) frames from client #%d\n",
		             seqdiff, sender );
		speex_bits_reset( &clc.speexDecoderBits[ sender ] );
		seqdiff = 0;
	}

	if ( seqdiff != 0 )
	{
		Com_DPrintf( "VoIP: Dropped %d frames from client #%d\n",
		             seqdiff, sender );

		// tell speex that we're missing frames...
		for ( i = 0; i < seqdiff; i++ )
		{
			assert( ( written + clc.speexFrameSize ) * 2 < sizeof( decoded ) );
			speex_decode_int( clc.speexDecoder[ sender ], NULL, decoded + written );
			written += clc.speexFrameSize;
		}
	}

	for ( i = 0; i < frames; i++ )
	{
		const int len = MSG_ReadByte( msg );

		if ( len < 0 )
		{
			Com_DPrintf( "VoIP: Short packet!\n" );
			break;
		}

		MSG_ReadData( msg, encoded, len );

		// shouldn't happen, but just in case...
		if ( ( written + clc.speexFrameSize ) * 2 > sizeof( decoded ) )
		{
			Com_DPrintf( "VoIP: playback %d bytes, %d samples, %d frames\n",
			             written * 2, written, i );

			CL_PlayVoip( sender, written, ( const byte * ) decoded, flags );
			written = 0;
		}

		speex_bits_read_from( &clc.speexDecoderBits[ sender ], encoded, len );
		speex_decode_int( clc.speexDecoder[ sender ],
		                  &clc.speexDecoderBits[ sender ], decoded + written );

#if 0
		static FILE *encio = NULL;

		if ( encio == NULL ) { encio = fopen( "voip-incoming-encoded.bin", "wb" ); }

		if ( encio != NULL ) { fwrite( encoded, len, 1, encio ); fflush( encio ); }

		static FILE *decio = NULL;

		if ( decio == NULL ) { decio = fopen( "voip-incoming-decoded.bin", "wb" ); }

		if ( decio != NULL ) { fwrite( decoded + written, clc.speexFrameSize * 2, 1, decio ); fflush( decio ); }

#endif

		written += clc.speexFrameSize;
	}

	Com_DPrintf( "VoIP: playback %d bytes, %d samples, %d frames\n",
	             written * 2, written, i );

	if ( written > 0 )
	{
		CL_PlayVoip( sender, written, ( const byte * ) decoded, flags );
	}

	clc.voipIncomingSequence[ sender ] = sequence + frames;
}
Пример #29
0
static int speex_decode_frame(AVCodecContext *avctx,
                        void *data, int *data_size,
                        uint8_t* buf, int buf_size)
{
    SpeexContext *s = avctx->priv_data;
    int ret, bits_remaining, used = 0, bits_remaining_before;

	av_log(avctx,AV_LOG_DEBUG,"speexdec: out: %p %p(%d), in: %p, %d\n",
		data, data_size, data_size?*data_size:0,buf,buf_size);
	if (data)
	{    
	    /* we'll save this info to log later */
	    bits_remaining_before = bits_remaining = speex_bits_remaining(&s->bits);
	    
	    *data_size = 0;
	
	    /* We are not interpolating a frame */
	    if (buf)
	    {    
	        if (bits_remaining > 0)
	        {
	            speex_bits_read_whole_bytes(&s->bits, (char*) buf, buf_size);
	        }
	        else
	        {
	            /*Copy buf to Speex bitstream*/
	            speex_bits_read_from(&s->bits, (char*) buf, buf_size);
	        }
	    } // end if we are not interpolating a frame
	        
	    ret = speex_decode_int(s->st, buf ? &s->bits : NULL, data);
	
	    switch (ret)
	    {
	    case -2:
	        av_log(avctx, AV_LOG_ERROR, "Error: corrupted speex stream\n");
	        speex_bits_reset(&s->bits);
	        return -1;
	
	    case -1:
	        /* no frame has been decoded, return bytes used */
	        //av_log(avctx, AV_LOG_INFO, "Warning: no samples have been decoded (end of stream)\n");
	        speex_bits_rewind(&s->bits);
	        return buf_size;
	
	    default:    
	
	        if (buf)
	        {
	            /* Calculate how many bytes we've used */
	            bits_remaining = speex_bits_remaining(&s->bits);
	        
	            if (bits_remaining < 0)
	            {
	                //av_log(avctx, AV_LOG_DEBUG, "Warning: decoding overflow, need more data (%d used)\n", buf_size);
	                
	                speex_bits_rewind(&s->bits);
	                
	                return buf_size;
	            }
	                
	            used = buf_size - (bits_remaining / 8);
	        }
	        else
	        {
	            av_log(avctx, AV_LOG_DEBUG, "Info: interpolating a lost frame\n");
	        }            
	        
	        *data_size = avctx->frame_size * avctx->channels * sizeof(short);
	            
	        if (avctx->channels == 2)
	            speex_decode_stereo_int(data, avctx->frame_size, &s->stereo);
	        
	        if (avctx->debug & FF_DEBUG_BITSTREAM)
	        {
	            int bitrate;
	            speex_decoder_ctl(s->st, SPEEX_GET_BITRATE, &bitrate);
	            
	            av_log(avctx, AV_LOG_DEBUG, "Speex: decoder used: %d/%d bytes, output: %d bytes, bitrate: %d bps (remaining in stream: %.1f bytes after %d bits)\n", 
	                    used, buf_size, *data_size, bitrate, (float) bits_remaining / 8, bits_remaining_before);
	        }
	        
	        speex_bits_reset(&s->bits);
	        
	        break;
	    }
    }
    else
    {
		speex_bits_reset(&s->bits);    	
    }
               
    return used;
}
Пример #30
0
void SndSysSpeexSoundStream::AdvancePosition(size_t frame_delta)
{
  if (m_bPaused || m_bPlaybackReadComplete || frame_delta==0)
    return;

  // Figure out how many bytes we need to fill for this advancement
  size_t needed_bytes = frame_delta * (m_RenderFormat.Bits/8) * m_RenderFormat.Channels;

  // If we need more space than is available in the whole cyclic buffer, then we already underbuffered, reduce to just 1 cycle full
  if ((size_t)needed_bytes > m_pCyclicBuffer->GetLength())
    needed_bytes=(size_t)(m_pCyclicBuffer->GetLength() & 0x7FFFFFFF);

  // Free space in the cyclic buffer if necessary
  if ((size_t)needed_bytes > m_pCyclicBuffer->GetFreeBytes())
    m_pCyclicBuffer->AdvanceStartValue(needed_bytes - (size_t)(m_pCyclicBuffer->GetFreeBytes() & 0x7FFFFFFF));

  // Fill in leftover decoded data if needed
  if (m_PreparedDataBufferUsage > 0)
    needed_bytes-=CopyBufferBytes(needed_bytes);

  while (needed_bytes > 0)
  {
    if(newPage)
    {
      if(ogg_sync_pageout(&oy, &og) != 1)
      {
        // Mark as complete if not looping.
        if (!m_bLooping)
        {
          m_bPlaybackReadComplete = true;
        }

        // Reset stream.
        ResetPosition();

        return;
      }

      if (!stream_init)
      {
        ogg_stream_init(&os, ogg_page_serialno(&og));
        stream_init = true;
      }

      if (ogg_page_serialno(&og) != os.serialno)
      {
        ogg_stream_reset_serialno(&os, ogg_page_serialno(&og));
      }

      ogg_stream_pagein(&os, &og);
      newPage = false;
    }

    if(ogg_stream_packetout(&os, &op) != 1)
    {
      newPage = true;
      continue;
    }

    // First packets contain header data.
    if(packet_count == 0)
    {
      if(header)
      {
        speex_header_free(header);
      }

      header = speex_packet_to_header((char*)op.packet, op.bytes);
      // const_cast for version compatibility.
      SpeexMode* mode = const_cast<SpeexMode*>(speex_lib_get_mode (header->mode));
      state = speex_decoder_init(mode);
      speex_decoder_ctl(state, SPEEX_SET_SAMPLING_RATE, &header->rate);

      m_OutputFrequency=m_NewOutputFrequency;

      // Create the pcm sample converter if it's not yet created
      if (m_pPCMConverter == 0)
        m_pPCMConverter = new PCMSampleConverter (
        m_RenderFormat.Channels, m_RenderFormat.Bits,
        m_RenderFormat.Freq);

      // Calculate the size of one source sample
      int source_sample_size = m_RenderFormat.Channels * m_RenderFormat.Bits;

      // Calculate the needed buffer size for this conversion
      int needed_buffer = (m_pPCMConverter->GetRequiredOutputBufferMultiple (
        m_RenderFormat.Channels, m_RenderFormat.Bits, m_OutputFrequency) * 
        (4096 + source_sample_size))/1024;

      // Allocate a new buffer.
      if (m_PreparedDataBufferSize < needed_buffer)
      {
        delete[] m_pPreparedDataBuffer;
        m_pPreparedDataBuffer = new char[needed_buffer];
        m_PreparedDataBufferSize=needed_buffer;
      }
    }

    if(packet_count++ < uint(2+header->extra_headers))
    {
      continue;
    }

    // Read and decode.
    speex_bits_read_from(&bits, (char*)op.packet, op.bytes);
    speex_decode_int(state, &bits, (int16*)m_pPreparedDataBuffer);

    // Frame size is in shorts.
    speex_decoder_ctl(state, SPEEX_GET_FRAME_SIZE, &m_PreparedDataBufferUsage);
    m_PreparedDataBufferUsage *= sizeof(short);

    if (m_PreparedDataBufferUsage > 0)
      needed_bytes -= CopyBufferBytes (needed_bytes);
  }
}