Example #1
0
int speex_inband_handler(SpeexBits *bits, SpeexCallback *callback_list, void *state)
{
   int id;
   SpeexCallback *callback;
   /*speex_bits_advance(bits, 5);*/
   id=speex_bits_unpack_unsigned(bits, 4);
   callback = callback_list+id;

   if (callback->func)
   {
      return callback->func(bits, state, callback->data);
   } else
      /*If callback is not registered, skip the right number of bits*/
   {
      int adv;
      if (id<2)
         adv = 1;
      else if (id<8)
         adv = 4;
      else if (id<10)
         adv = 8;
      else if (id<12)
         adv = 16;
      else if (id<14)
         adv = 32;
      else 
         adv = 64;
      speex_bits_advance(bits, adv);
   }
   return 0;
}
Example #2
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;
}
Example #3
0
/* This function will iterate frames & submodes in the Speex bits.
 * Returns 0 if a frame found, otherwise returns -1.
 */
int speex_get_next_frame(SpeexBits *bits)
{
    static const int inband_skip_table[NB_SUBMODES] =
       {1, 1, 4, 4, 4, 4, 4, 4, 8, 8, 16, 16, 32, 32, 64, 64 };
    static const int wb_skip_table[SB_SUBMODES] =
       {SB_SUBMODE_BITS+1, 36, 112, 192, 352, -1, -1, -1};

    unsigned submode;
    unsigned nb_count = 0;

    while (speex_bits_remaining(bits) >= 5) {
	unsigned wb_count = 0;
	unsigned bit_ptr = bits->bitPtr;
	unsigned char_ptr = bits->charPtr;

	/* WB frame */
	while ((speex_bits_remaining(bits) >= 4)
	    && speex_bits_unpack_unsigned(bits, 1))
	{
	    int advance;

	    submode = speex_bits_unpack_unsigned(bits, 3);
	    advance = wb_skip_table[submode];
	    if (advance < 0) {
		TRACE__((THIS_FUNC, "Invalid mode encountered. "
			 "The stream is corrupted."));
		return -1;
	    } 
	    TRACE__((THIS_FUNC, "WB layer skipped: %d bits", advance));
	    advance -= (SB_SUBMODE_BITS+1);
	    speex_bits_advance(bits, advance);

	    bit_ptr = bits->bitPtr;
	    char_ptr = bits->charPtr;

	    /* Consecutive subband frames may not exceed 2 frames */
	    if (++wb_count > 2)
		return -1;
	}

	/* End of bits, return the frame */
	if (speex_bits_remaining(bits) < 4) {
	    TRACE__((THIS_FUNC, "End of stream"));
	    return 0;
	}

	/* Stop iteration, return the frame */
	if (nb_count > 0) {
	    bits->bitPtr = bit_ptr;
	    bits->charPtr = char_ptr;
	    return 0;
	}

	/* Get control bits */
	submode = speex_bits_unpack_unsigned(bits, 4);
	TRACE__((THIS_FUNC, "Control bits: %d at %d", 
		 submode, bits->charPtr*8+bits->bitPtr));

	if (submode == 15) {
	    TRACE__((THIS_FUNC, "Found submode: terminator"));
	    return -1;
	} else if (submode == 14) {
	    /* in-band signal; next 4 bits contain signal id */
	    submode = speex_bits_unpack_unsigned(bits, 4);
	    TRACE__((THIS_FUNC, "Found submode: in-band %d bits", 
		     inband_skip_table[submode]));
	    speex_bits_advance(bits, inband_skip_table[submode]);
	} else if (submode == 13) {
	    /* user in-band; next 5 bits contain msg len */
	    submode = speex_bits_unpack_unsigned(bits, 5);
	    TRACE__((THIS_FUNC, "Found submode: user-band %d bytes", submode));
	    speex_bits_advance(bits, submode * 8);
	} else if (submode > 8) {
	    TRACE__((THIS_FUNC, "Unknown sub-mode %d", submode));
	    return -1;
	} else {
	    /* NB frame */
	    unsigned int advance = submode;
	    speex_mode_query(&speex_nb_mode, SPEEX_SUBMODE_BITS_PER_FRAME, &advance);
	    if (advance < 0) {
		TRACE__((THIS_FUNC, "Invalid mode encountered. "
			 "The stream is corrupted."));
		return -1;
	    }
	    TRACE__((THIS_FUNC, "Submode %d: %d bits", submode, advance));
	    advance -= (NB_SUBMODE_BITS+1);
	    speex_bits_advance(bits, advance);

	    ++nb_count;
	}
    }

    return 0;
}
Example #4
0
/* Default handler for user callbacks: skip it */
int speex_default_user_handler(SpeexBits *bits, void *state, void *data)
{
   int req_size = speex_bits_unpack_unsigned(bits, 4);
   speex_bits_advance(bits, 5+8*req_size);
   return 0;
}