Exemple #1
0
static int codec_decoder(const struct PluginCodec_Definition * codec, 
                                           void * _context,
                                     const void * from, 
                                       unsigned * fromLen,
                                           void * to,         
                                       unsigned * toLen,
                                   unsigned int * flag)
{
  gsm context = (gsm)_context;

  if (*fromLen < BYTES_PER_FRAME)
    return 0;

  // if the packet is not 65 bytes long, assume it is frames of normal GSM
  if (*fromLen != 65) {

    int frames;

    if (*toLen < SAMPLES_PER_FRAME * 2)
      return 0;

    frames = MIN(*toLen / (SAMPLES_PER_FRAME * 2), (*fromLen / BYTES_PER_FRAME));

    if (frames == 0)
      return 0;

    {
      int opt = 0;
      gsm_option(context, GSM_OPT_WAV49, &opt);
    }

    *fromLen = frames * BYTES_PER_FRAME;
    *toLen   = frames * SAMPLES_PER_FRAME * 2;

    while (frames-- > 0) {
      gsm_decode(context, (void *)from, to);
      from = ((const char *)from) + BYTES_PER_FRAME;
      to   = ((char *)to) + SAMPLES_PER_FRAME * 2;
    }

    return 1;
  }

  // MS-GSM packets are always 65 bytes long, and consists of two GSM packets
  if (*toLen < MSGSM_SAMPLES_PER_FRAME * 2)
    return 0;
  {
    int opt = 1;
    gsm_option(context, GSM_OPT_WAV49, &opt);
  }

  gsm_decode(context, (unsigned char *)from,      (short *)to);
  gsm_decode(context, ((unsigned char *)from)+33, ((short *)to)+160);

  *toLen = MSGSM_SAMPLES_PER_FRAME * 2;

  return 1;
}
Exemple #2
0
static av_cold int libgsm_decode_init(AVCodecContext *avctx) {
  LibGSMDecodeContext *s = avctx->priv_data;

  avctx->channels       = 1;
  avctx->channel_layout = AV_CH_LAYOUT_MONO;
  if (!avctx->sample_rate)
    avctx->sample_rate = 8000;
  avctx->sample_fmt     = AV_SAMPLE_FMT_S16;

  s->state = gsm_create();

  switch(avctx->codec_id) {
  case AV_CODEC_ID_GSM:
    avctx->frame_size  = GSM_FRAME_SIZE;
    avctx->block_align = GSM_BLOCK_SIZE;
    break;
  case AV_CODEC_ID_GSM_MS: {
    int one = 1;
    gsm_option(s->state, GSM_OPT_WAV49, &one);
    avctx->frame_size  = 2 * GSM_FRAME_SIZE;
    avctx->block_align = GSM_MS_BLOCK_SIZE;
  }
  }

  return 0;
}
static void * create_codec(const struct PluginCodec_Definition * codec)
{
  int opt = (int)codec->userData;
  struct gsm_state * context = gsm_create();
  gsm_option(context, GSM_OPT_WAV49, &opt);
  return context;
}
Exemple #4
0
static void
gst_gsmenc_init (GstGSMEnc * gsmenc)
{
  gint use_wav49;

  /* create the sink and src pads */
  gsmenc->sinkpad =
      gst_pad_new_from_static_template (&gsmenc_sink_template, "sink");
  gst_pad_set_chain_function (gsmenc->sinkpad, gst_gsmenc_chain);
  gst_pad_set_setcaps_function (gsmenc->sinkpad, gst_gsmenc_setcaps);
  gst_element_add_pad (GST_ELEMENT (gsmenc), gsmenc->sinkpad);

  gsmenc->srcpad =
      gst_pad_new_from_static_template (&gsmenc_src_template, "src");
  gst_element_add_pad (GST_ELEMENT (gsmenc), gsmenc->srcpad);

  gsmenc->state = gsm_create ();

  /* turn off WAV49 handling */
  use_wav49 = 0;
  gsm_option (gsmenc->state, GSM_OPT_WAV49, &use_wav49);

  gsmenc->adapter = gst_adapter_new ();
  gsmenc->next_ts = 0;
}
static av_cold int libgsm_decode_init(AVCodecContext *avctx) {
    if (avctx->channels > 1) {
        av_log(avctx, AV_LOG_ERROR, "Mono required for GSM, got %d channels\n",
               avctx->channels);
        return -1;
    }

    if (!avctx->channels)
        avctx->channels = 1;

    if (!avctx->sample_rate)
        avctx->sample_rate = 8000;

    avctx->sample_fmt = AV_SAMPLE_FMT_S16;

    avctx->priv_data = gsm_create();

    switch(avctx->codec_id) {
    case CODEC_ID_GSM:
        avctx->frame_size  = GSM_FRAME_SIZE;
        avctx->block_align = GSM_BLOCK_SIZE;
        break;
    case CODEC_ID_GSM_MS: {
        int one = 1;
        gsm_option(avctx->priv_data, GSM_OPT_WAV49, &one);
        avctx->frame_size  = 2 * GSM_FRAME_SIZE;
        avctx->block_align = GSM_MS_BLOCK_SIZE;
        }
    }

    return 0;
}
Exemple #6
0
static gboolean
gst_gsmdec_sink_setcaps (GstPad * pad, GstCaps * caps)
{
    GstGSMDec *gsmdec;
    GstCaps *srccaps;
    GstStructure *s;
    gboolean ret = FALSE;

    gsmdec = GST_GSMDEC (gst_pad_get_parent (pad));

    s = gst_caps_get_structure (caps, 0);
    if (s == NULL)
        goto wrong_caps;

    /* figure out if we deal with plain or MSGSM */
    if (gst_structure_has_name (s, "audio/x-gsm"))
        gsmdec->use_wav49 = 0;
    else if (gst_structure_has_name (s, "audio/ms-gsm"))
        gsmdec->use_wav49 = 1;
    else
        goto wrong_caps;

    if (!gst_structure_get_int (s, "rate", &gsmdec->rate)) {
        GST_WARNING_OBJECT (gsmdec, "missing sample rate parameter from sink caps");
        goto beach;
    }

    /* MSGSM needs different framing */
    gsm_option (gsmdec->state, GSM_OPT_WAV49, &gsmdec->use_wav49);

    gsmdec->duration = gst_util_uint64_scale (ENCODED_SAMPLES,
                       GST_SECOND, gsmdec->rate);

    /* Setting up src caps based on the input sample rate. */
    srccaps = gst_caps_new_simple ("audio/x-raw-int",
                                   "endianness", G_TYPE_INT, G_BYTE_ORDER,
                                   "signed", G_TYPE_BOOLEAN, TRUE,
                                   "width", G_TYPE_INT, 16,
                                   "depth", G_TYPE_INT, 16,
                                   "rate", G_TYPE_INT, gsmdec->rate, "channels", G_TYPE_INT, 1, NULL);

    ret = gst_pad_set_caps (gsmdec->srcpad, srccaps);

    gst_caps_unref (srccaps);
    gst_object_unref (gsmdec);

    return ret;

    /* ERRORS */
wrong_caps:

    GST_ERROR_OBJECT (gsmdec, "invalid caps received");

beach:
    gst_object_unref (gsmdec);

    return ret;
}
Exemple #7
0
static void libgsm_flush(AVCodecContext *avctx) {
    LibGSMDecodeContext *s = avctx->priv_data;
    int one = 1;

    gsm_destroy(s->state);
    s->state = gsm_create();
    if (avctx->codec_id == CODEC_ID_GSM_MS)
        gsm_option(s->state, GSM_OPT_WAV49, &one);
}
Exemple #8
0
static int codec_decoder(const struct PluginCodec_Definition * codec, 
                                           void * _context,
                                     const void * from, 
                                       unsigned * fromLen,
                                           void * to,         
                                       unsigned * toLen,
                                   unsigned int * flag)
{
  gsm context = (gsm)_context;

  if (*fromLen < BYTES_PER_FRAME)
    return 0;

  // Unless the packet is 65 bytes long, it must be normal GSM
  if (*fromLen != 65) {
    if (*toLen < SAMPLES_PER_FRAME * 2)
      return 0;
    {
      int opt = 0;
      gsm_option(context, GSM_OPT_WAV49, &opt);
    }
    gsm_decode(context, (void *)from, to);
    *toLen = SAMPLES_PER_FRAME * 2;
    return 1;
  }

  // MS-GSM packets are always 65 bytes long, and consists of two GSM packets
  if (*toLen < MSGSM_SAMPLES_PER_FRAME * 2)
    return 0;
  {
    int opt = 1;
    gsm_option(context, GSM_OPT_WAV49, &opt);
  }

  gsm_decode(context, (unsigned char *)from,      (short *)to);
  gsm_decode(context, ((unsigned char *)from)+33, ((short *)to)+160);

  *toLen = MSGSM_SAMPLES_PER_FRAME * 2;

  return 1;
}
Exemple #9
0
static av_cold int libgsm_init(AVCodecContext *avctx) {
    if (avctx->channels > 1) {
        av_log(avctx, AV_LOG_ERROR, "Mono required for GSM, got %d channels\n",
               avctx->channels);
        return -1;
    }

    if(avctx->codec->decode){
        if(!avctx->channels)
            avctx->channels= 1;

        if(!avctx->sample_rate)
            avctx->sample_rate= 8000;

        avctx->sample_fmt = SAMPLE_FMT_S16;
    }else{
        if (avctx->sample_rate != 8000) {
            av_log(avctx, AV_LOG_ERROR, "Sample rate 8000Hz required for GSM, got %dHz\n",
                avctx->sample_rate);
            if(avctx->strict_std_compliance > FF_COMPLIANCE_INOFFICIAL)
                return -1;
        }
        if (avctx->bit_rate != 13000 /* Official */ &&
            avctx->bit_rate != 13200 /* Very common */ &&
            avctx->bit_rate != 0 /* Unknown; a.o. mov does not set bitrate when decoding */ ) {
            av_log(avctx, AV_LOG_ERROR, "Bitrate 13000bps required for GSM, got %dbps\n",
                avctx->bit_rate);
            if(avctx->strict_std_compliance > FF_COMPLIANCE_INOFFICIAL)
                return -1;
        }
    }

    avctx->priv_data = gsm_create();

    switch(avctx->codec_id) {
    case CODEC_ID_GSM:
        avctx->frame_size = GSM_FRAME_SIZE;
        avctx->block_align = GSM_BLOCK_SIZE;
        break;
    case CODEC_ID_GSM_MS: {
        int one = 1;
        gsm_option(avctx->priv_data, GSM_OPT_WAV49, &one);
        avctx->frame_size = 2*GSM_FRAME_SIZE;
        avctx->block_align = GSM_MS_BLOCK_SIZE;
        }
    }

    avctx->coded_frame= avcodec_alloc_frame();
    avctx->coded_frame->key_frame= 1;

    return 0;
}
GSMCodec::GSMCodec():AudioCodec()
{
    int     fast       = 0;
    int     wav        = 0;

    type=AudioCodec::GSM;
    numFrameSamples=160;
    frameLength=33;
    g = gsm_create();

//	gsm_option(g, GSM_OPT_FAST,    &fast);
    gsm_option(g, GSM_OPT_WAV49,   &wav);
}
Exemple #11
0
int	
wav_gsm610_writer_init (SF_PRIVATE *psf)
{	GSM610_PRIVATE	*pgsm610 ;
	int  true = 1, samplesperblock, bytespersec ;
	
	if (psf->mode != SF_MODE_WRITE)
		return SFE_BAD_MODE_RW ;

	if (! (pgsm610 = malloc (sizeof (GSM610_PRIVATE))))
		return SFE_MALLOC_FAILED ;
		
	psf->fdata = (void*) pgsm610 ;

	memset (pgsm610, 0, sizeof (GSM610_PRIVATE)) ;
	
	if (! (pgsm610->gsm_data = gsm_create ()))
		return SFE_MALLOC_FAILED ;
	gsm_option (pgsm610->gsm_data,  GSM_OPT_WAV49, &true) ;

	pgsm610->blockcount  = 0 ;
	pgsm610->samplecount = 0 ;
	
	samplesperblock = GSM610_SAMPLES ;
	bytespersec     = psf->sf.samplerate * GSM610_BLOCKSIZE / GSM610_SAMPLES ;
	
	if (bytespersec * GSM610_SAMPLES / GSM610_BLOCKSIZE < psf->sf.samplerate) 
		bytespersec ++ ;

	psf->datalength  = (psf->sf.samples / samplesperblock) * samplesperblock ;
	if (psf->sf.samples % samplesperblock)
		psf->datalength += samplesperblock ;

	wav_gsm610_write_header (psf) ;

#if defined(USE_LIBSND_ALL) || defined(USE_LIBSND_WRITE) 
	psf->write_short  = (func_short)   wav_gsm610_write_s ;
#endif
#if	defined(USE_LIBSND_ALL)
	psf->write_int    = (func_int)     wav_gsm610_write_i ;
	psf->write_float  = (func_float)   wav_gsm610_write_f ;
	psf->write_double = (func_double)  wav_gsm610_write_d ;
#endif
	
#if defined(USE_LIBSND_ALL)
	psf->seek_func    = NULL ; /* Not seekable */
#endif
	psf->close        = (func_close)   wav_gsm610_close ;
	psf->write_header = (func_wr_hdr)  wav_gsm610_write_header ;
					
	return 0 ;
} /* wav_gsm610_writer_init */
Exemple #12
0
static gboolean
gst_gsmdec_set_format (GstAudioDecoder * dec, GstCaps * caps)
{
  GstGSMDec *gsmdec;
  GstStructure *s;
  gboolean ret = FALSE;
  gint rate;
  GstAudioInfo info;

  gsmdec = GST_GSMDEC (dec);

  s = gst_caps_get_structure (caps, 0);
  if (s == NULL)
    goto wrong_caps;

  /* figure out if we deal with plain or MSGSM */
  if (gst_structure_has_name (s, "audio/x-gsm"))
    gsmdec->use_wav49 = 0;
  else if (gst_structure_has_name (s, "audio/ms-gsm"))
    gsmdec->use_wav49 = 1;
  else
    goto wrong_caps;

  gsmdec->needed = 33;

  if (!gst_structure_get_int (s, "rate", &rate)) {
    GST_WARNING_OBJECT (gsmdec, "missing sample rate parameter from sink caps");
    goto beach;
  }

  /* MSGSM needs different framing */
  gsm_option (gsmdec->state, GSM_OPT_WAV49, &gsmdec->use_wav49);

  /* Setting up src caps based on the input sample rate. */
  gst_audio_info_init (&info);
  gst_audio_info_set_format (&info, GST_AUDIO_FORMAT_S16, rate, 1, NULL);

  ret = gst_audio_decoder_set_output_format (dec, &info);

  return ret;

  /* ERRORS */
wrong_caps:

  GST_ERROR_OBJECT (gsmdec, "invalid caps received");

beach:

  return ret;
}
Exemple #13
0
static av_cold int libgsm_encode_init(AVCodecContext *avctx) {
    if (avctx->channels > 1) {
        av_log(avctx, AV_LOG_ERROR, "Mono required for GSM, got %d channels\n",
               avctx->channels);
        return -1;
    }

    if (avctx->sample_rate != 8000) {
        av_log(avctx, AV_LOG_ERROR, "Sample rate 8000Hz required for GSM, got %dHz\n",
               avctx->sample_rate);
        if (avctx->strict_std_compliance > FF_COMPLIANCE_UNOFFICIAL)
            return -1;
    }
    if (avctx->bit_rate != 13000 /* Official */ &&
        avctx->bit_rate != 13200 /* Very common */ &&
        avctx->bit_rate != 0 /* Unknown; a.o. mov does not set bitrate when decoding */ ) {
        av_log(avctx, AV_LOG_ERROR, "Bitrate 13000bps required for GSM, got %dbps\n",
               avctx->bit_rate);
        if (avctx->strict_std_compliance > FF_COMPLIANCE_UNOFFICIAL)
            return -1;
    }

    avctx->priv_data = gsm_create();
    if (!avctx->priv_data)
        goto error;

    switch(avctx->codec_id) {
    case CODEC_ID_GSM:
        avctx->frame_size = GSM_FRAME_SIZE;
        avctx->block_align = GSM_BLOCK_SIZE;
        break;
    case CODEC_ID_GSM_MS: {
        int one = 1;
        gsm_option(avctx->priv_data, GSM_OPT_WAV49, &one);
        avctx->frame_size = 2*GSM_FRAME_SIZE;
        avctx->block_align = GSM_MS_BLOCK_SIZE;
        }
    }

#if FF_API_OLD_ENCODE_AUDIO
    avctx->coded_frame= avcodec_alloc_frame();
    if (!avctx->coded_frame)
        goto error;
#endif

    return 0;
error:
    libgsm_encode_close(avctx);
    return -1;
}
static gboolean
gst_gsmenc_start (GstAudioEncoder * enc)
{
  GstGSMEnc *gsmenc = GST_GSMENC (enc);
  gint use_wav49;

  GST_DEBUG_OBJECT (enc, "start");

  gsmenc->state = gsm_create ();

  /* turn off WAV49 handling */
  use_wav49 = 0;
  gsm_option (gsmenc->state, GSM_OPT_WAV49, &use_wav49);

  return TRUE;
}
Exemple #15
0
int	
wav_gsm610_reader_init (SF_PRIVATE *psf, WAV_FMT *fmt)
{	GSM610_PRIVATE	*pgsm610 ;
	int  true = 1 ;
	
	psf->sf.seekable = SF_FALSE ;
	/*-psf->sf.seekable = SF_TRUE ;		-*/
#if defined(USE_LIBSND_ALL)
	psf->seek_func = (func_seek) wav_gsm610_seek ;
#endif

	psf->read_short  = (func_short)  wav_gsm610_read_s ;
#if	defined(USE_LIBSND_ALL)
	psf->read_int    = (func_int)    wav_gsm610_read_i ;
	psf->read_float  = (func_float)  wav_gsm610_read_f ;
	psf->read_double = (func_double) wav_gsm610_read_d ;
#endif

#if defined(USE_LIBSND_ALL) || defined(USE_LIBSND_WRITE) 
	if (psf->mode != SF_MODE_READ)
		return SFE_BAD_MODE_RW ;
#endif

	if (! (pgsm610 = malloc (sizeof (GSM610_PRIVATE))))
		return SFE_MALLOC_FAILED ;

	psf->fdata = (void*) pgsm610 ;

	memset (pgsm610, 0, sizeof (GSM610_PRIVATE)) ;

	if (! (pgsm610->gsm_data = gsm_create ()))
		return SFE_MALLOC_FAILED ;
	gsm_option (pgsm610->gsm_data,  GSM_OPT_WAV49, &true) ;

	if (psf->datalength % GSM610_BLOCKSIZE)
	{	psf_log_printf (psf, "*** Warning : data chunk seems to be truncated.\n") ;
		pgsm610->blocks = psf->datalength / GSM610_BLOCKSIZE + 1 ;
		}
	else
		pgsm610->blocks = psf->datalength / GSM610_BLOCKSIZE ;
	
	psf->sf.samples = GSM610_SAMPLES * pgsm610->blocks ;
	
	wav_gsm610_read_block (psf, pgsm610) ;	/* Read first block. */
	
	return 0 ;	
} /* wav_gsm610_reader_init */
SoftGSM::SoftGSM(
        const char *name,
        const OMX_CALLBACKTYPE *callbacks,
        OMX_PTR appData,
        OMX_COMPONENTTYPE **component)
    : SimpleSoftOMXComponent(name, callbacks, appData, component),
      mSignalledError(false) {

    CHECK(!strcmp(name, "OMX.google.gsm.decoder"));

    mGsm = gsm_create();
    CHECK(mGsm);
    int msopt = 1;
    gsm_option(mGsm, GSM_OPT_WAV49, &msopt);

    initPorts();
}
Exemple #17
0
static int init_gsm(bgav_stream_t * s)
  {
  int tmp;
  gsm_priv * priv;

  /* Allocate stuff */
  priv = calloc(1, sizeof(*priv));
  priv->gsm_state = gsm_create();
  s->decoder_priv = priv;

  if(s->data.audio.format.num_channels > 1)
    {
    bgav_log(s->opt, BGAV_LOG_ERROR, LOG_DOMAIN,
            "Multichannel GSM not supported");
    return 0;
    }

  if((s->fourcc == BGAV_WAVID_2_FOURCC(0x31)) ||
     (s->fourcc == BGAV_WAVID_2_FOURCC(0x32)))
    {
    priv->ms = 1;
    tmp = 1;
    gsm_option(priv->gsm_state, GSM_OPT_WAV49, &tmp);
    }

  /* Set format */
  s->data.audio.format.interleave_mode   = GAVL_INTERLEAVE_NONE;
  s->data.audio.format.sample_format     = GAVL_SAMPLE_S16;
  
  s->data.audio.format.samples_per_frame = priv->ms ? 2*GSM_FRAME_SAMPLES : GSM_FRAME_SAMPLES;
  gavl_set_channel_setup(&s->data.audio.format);
  
  priv->frame = gavl_audio_frame_create(&s->data.audio.format);

  if(priv->ms)
    gavl_metadata_set(&s->m, GAVL_META_FORMAT,
                      "MSGM");
  else
    gavl_metadata_set(&s->m, GAVL_META_FORMAT,
                      "GSM 6.10");
  return 1;
  }
int GSMCodec::Decode (BYTE *in,int inLen,WORD* out,int outLen)
{
    //Dependiendo de la longitud tenemos un tipo u otro
    if (inLen==33)
    {
        //GSM Clasico
        if (outLen<160)
            return 0;

        //Decodificamso
        if (gsm_decode(g,(gsm_byte *)in,(gsm_signal *)out)<0)
            return 0;

        return 160;
    } else if (inLen==65) {

        //ponemos el modo wav
        int wav=1;
        gsm_option(g, GSM_OPT_WAV49,   &wav);
        //GSM de M$ vienen 2 paquetes seguidos
        if (outLen<160*2)
            return 0;

        //Decodificamos el primero
        if (gsm_decode(g,(gsm_byte *)in,(gsm_signal *)out)<0)
            return 0;

        //Y el segundo
        if (gsm_decode(g,(gsm_byte *)&in[33],(gsm_signal *)&out[160])<0)
            return 0;

        return 160*2;

    }

    return 0;
}
Exemple #19
0
static int libgsm_init(AVCodecContext *avctx) {
    if (avctx->channels > 1 || avctx->sample_rate != 8000 || avctx->bit_rate != 13000)
        return -1;

    avctx->priv_data = gsm_create();

    switch(avctx->codec_id) {
    case CODEC_ID_GSM:
        avctx->frame_size = GSM_FRAME_SIZE;
        avctx->block_align = GSM_BLOCK_SIZE;
        break;
    case CODEC_ID_GSM_MS: {
        int one = 1;
        gsm_option(avctx->priv_data, GSM_OPT_WAV49, &one);
        avctx->frame_size = 2*GSM_FRAME_SIZE;
        avctx->block_align = GSM_MS_BLOCK_SIZE;
        }
    }

    avctx->coded_frame= avcodec_alloc_frame();
    avctx->coded_frame->key_frame= 1;

    return 0;
}
Exemple #20
0
int voice_open_ext(const char *pathname, int speed, int sample, int channels, int codec)
{
	int value;

	if (voice_fd != -1)
		return -1;

	if ((voice_fd = open(pathname, O_RDWR)) == -1)
		goto fail;

	if (ioctl(voice_fd, SNDCTL_DSP_SPEED, &speed) == -1)
		goto fail;

	if (ioctl(voice_fd, SNDCTL_DSP_SAMPLESIZE, &sample) == -1)
		goto fail;

	if (ioctl(voice_fd, SNDCTL_DSP_CHANNELS, &channels) == -1)
		goto fail;

	value = AFMT_S16_LE;

	if (ioctl(voice_fd, SNDCTL_DSP_SETFMT, &value) == -1)
		goto fail;

	if (codec & EKG_CODEC_GSM) {
#if HAVE_GSM
		gsm_signal tmp;

		if (read(voice_fd, &tmp, sizeof(tmp)) != sizeof(tmp))
			goto fail;

		if (!(voice_gsm_dec = gsm_create()) || !(voice_gsm_enc = gsm_create()))
			goto fail;

		value = 1;

		gsm_option(voice_gsm_dec, GSM_OPT_FAST, &value);
		gsm_option(voice_gsm_dec, GSM_OPT_VERBOSE, &value);
		gsm_option(voice_gsm_dec, GSM_OPT_LTP_CUT, &value);
		gsm_option(voice_gsm_enc, GSM_OPT_FAST, &value);
#else
		goto fail;
#endif
	}

	if (codec & EKG_CODEC_SPEEX) {
#if HAVE_SPEEX
		if (!(voice_speex_enc = speex_encoder_init(&speex_wb_mode)) ||
			!(voice_speex_dec = speex_decoder_init(&speex_wb_mode)))
		{
			goto fail;
		}

		speex_bits_init(&speex_enc_bits);
		speex_bits_init(&speex_dec_bits);
#else
		goto fail;
#endif
	}

	if (codec & EKG_CODEC_MELP) {
		goto fail;
	}

	return 0;

fail:
	voice_close();
	return -1;
}
Exemple #21
0
int
_v3_audio_encode(
        v3_handle v3h,
        /* pcm input */
        const uint8_t *pcm,
        uint32_t pcmlen,
        /* payload output */
        int16_t index,
        int16_t format,
        v3_coder *coder,
        uint8_t *data,
        uint32_t *datalen,
        /* optional args */
        uint8_t channels) {
    uint32_t maxdatalen;
    int ret = V3_OK;

    _v3_enter(v3h, __func__);

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

    maxdatalen = *datalen;
    *datalen = 0;
    channels = (channels == 2) ? 2 : 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;
            size_t ctr;

            _v3_debug(v3h, V3_DBG_INFO, "encoding %u bytes of pcm to gsm @ %u", pcmlen, codec->rate);
            if (!coder->state) {
                if (!(coder->state = gsm_create())) {
                    _v3_debug(v3h, V3_DBG_INFO, "failed to create gsm encoder");
                    ret = V3_FAILURE;
                    break;
                }
                gsm_option(coder->state, GSM_OPT_WAV49, &opt);
                coder->index = index;
                coder->format = format;
                coder->encoder = true;
            }
            for (ctr = 0; ctr < pcmlen / codec->framesize && *datalen + 65 <= maxdatalen; ++ctr) {
                gsm_encode(coder->state, (void *)pcm, (void *)data);
                gsm_encode(coder->state, (void *)pcm+(codec->framesize/2), (void *)data+32);
                pcm      += codec->framesize;
                data     += 65;
                *datalen += 65;
            }
        }
        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, "encoding %u bytes of pcm to opus @ %u", pcmlen, codec->rate);
            if (!coder->state || channels != coder->channels) {
                if (coder->state) {
                    opus_encoder_destroy(coder->state);
                    coder->state = NULL;
                    _v3_debug(v3h, V3_DBG_MEMORY, "released opus state");
                }
                if (!(coder->state = opus_encoder_create(codec->rate, channels, OPUS_APPLICATION_AUDIO, &tmp))) {
                    _v3_debug(v3h, V3_DBG_INFO, "failed to create opus encoder: %s", opus_strerror(tmp));
                    ret = V3_FAILURE;
                    break;
                }
                if ((tmp = opus_encoder_ctl(coder->state, OPUS_SET_COMPLEXITY(10))) != OPUS_OK) {
                    _v3_debug(v3h, V3_DBG_INFO, "opus_encoder_ctl: OPUS_SET_COMPLEXITY: %s", opus_strerror(tmp));
                    opus_encoder_destroy(coder->state);
                    coder->state = NULL;
                    ret = V3_FAILURE;
                    break;
                }
                if ((tmp = opus_encoder_ctl(coder->state, OPUS_SET_VBR(0))) != OPUS_OK) {
                    _v3_debug(v3h, V3_DBG_INFO, "opus_encoder_ctl: OPUS_SET_VBR: %s", opus_strerror(tmp));
                    opus_encoder_destroy(coder->state);
                    coder->state = NULL;
                    ret = V3_FAILURE;
                    break;
                }
                if ((tmp = opus_encoder_ctl(coder->state, OPUS_SET_BITRATE(((index == 1) ? 79 : 43) * 1000))) != OPUS_OK) {
                    _v3_debug(v3h, V3_DBG_INFO, "opus_encoder_ctl: OPUS_SET_BITRATE: %s", opus_strerror(tmp));
                    opus_encoder_destroy(coder->state);
                    coder->state = NULL;
                    ret = V3_FAILURE;
                    break;
                }
                coder->index = index;
                coder->format = format;
                coder->channels = channels;
                coder->encoder = true;
            }
            maxdatalen = (maxdatalen <= ((index == 1) ? 198 : 108)) ? maxdatalen : ((index == 1) ? 198 : 108);
            if ((tmp = opus_encode(coder->state, (void *)pcm, codec->framesize / sizeof(int16_t), (void *)data, maxdatalen)) <= 0) {
                _v3_debug(v3h, V3_DBG_INFO, "failed to encode opus packet");
            }
            *datalen = tmp;
        }
        break;
#endif
#ifdef HAVE_SPEEX
      case 3:
        {
            static const uint16_t maxspxbuf = 200;
            const v3_codec *codec = v3_codec_get(index, format);
            uint16_t framesize;
            SpeexBits bits;
            size_t ctr;

            _v3_debug(v3h, V3_DBG_INFO, "encoding %u bytes of pcm to speex @ %u", pcmlen, codec->rate);
            if (!coder->state) {
                switch (codec->rate) {
                  case 8000:
                    coder->state = speex_encoder_init(&speex_nb_mode);
                    break;
                  case 16000:
                    coder->state = speex_encoder_init(&speex_wb_mode);
                    break;
                  case 32000:
                    coder->state = speex_encoder_init(&speex_uwb_mode);
                    break;
                }
                if (!coder->state) {
                    _v3_debug(v3h, V3_DBG_INFO, "failed to create speex encoder");
                    ret = V3_FAILURE;
                    break;
                }
                speex_encoder_ctl(coder->state, SPEEX_SET_QUALITY, (void *)&codec->quality);
                coder->index = index;
                coder->format = format;
                coder->encoder = true;
            }
            *(uint16_t *)data = htons(pcmlen / codec->framesize);
            data     += sizeof(uint16_t);
            *datalen += sizeof(uint16_t);
            *(uint16_t *)data = htons(codec->framesize / sizeof(int16_t));
            data     += sizeof(uint16_t);
            *datalen += sizeof(uint16_t);
            speex_bits_init(&bits);
            for (ctr = 0; ctr < pcmlen / codec->framesize && *datalen + maxspxbuf <= maxdatalen; ++ctr) {
                speex_encode_int(coder->state, (void *)pcm, &bits);
                framesize = speex_bits_write(&bits, (void *)data + sizeof(uint16_t), maxspxbuf);
                speex_bits_reset(&bits);
                *(uint16_t *)data = htons(framesize);
                pcm      += codec->framesize;
                data     += sizeof(uint16_t) + framesize;
                *datalen += sizeof(uint16_t) + framesize;
            }
            speex_bits_destroy(&bits);
        }
        break;
#endif
      default:
        (void)maxdatalen;
        _v3_debug(v3h, V3_DBG_INFO, "unsupported codec: index: %i | format: %i", index, format);
        ret = V3_FAILURE;
        break;
    }

    _v3_leave(v3h, __func__);
    return ret;
}
/* ======================================================================== */
OSCL_EXPORT_REF PVWavParserReturnCode PV_Wav_Parser::InitWavParser(OSCL_wString& aClip, Oscl_FileServer* aFileSession)
{
    //buffer
    uint8 iBuffer[36];

    // If a WAV file is already open, close it first and delete the file pointer
    CleanupWAVFile();

    // Open the file (aClip)
    ipWAVFile = OSCL_NEW(Oscl_File, (4096));
    if (ipWAVFile == NULL)
    {
        return PVWAVPARSER_READ_ERROR;
    }

    if (ipWAVFile->Open(aClip.get_cstr(), (Oscl_File::MODE_READ | Oscl_File::MODE_BINARY), *aFileSession) != 0)
    {
        OSCL_DELETE(ipWAVFile);
        ipWAVFile = NULL;
        return PVWAVPARSER_READ_ERROR;
    }

    // Get file size at the very first time
    int32 filesize = 0;
    if (ipWAVFile->Seek(0, Oscl_File::SEEKEND))
    {
        CleanupWAVFile();
        return PVWAVPARSER_MISC_ERROR;
    }

    filesize = (TOsclFileOffsetInt32)ipWAVFile->Tell();

    if (filesize <= 0)
    {
        CleanupWAVFile();
        return PVWAVPARSER_MISC_ERROR;
    }

    if (ipWAVFile->Seek(0, Oscl_File::SEEKSET))
    {
        CleanupWAVFile();
        return PVWAVPARSER_MISC_ERROR;
    }
    int32 filepos = 0;

    // read 12 bytes of data for complete WAVE header including RIFF chunk dDescriptor

    uint32 bytesread = 0;
    if (ReadData(iBuffer, 12, bytesread) != PVWAVPARSER_OK)
    {
        CleanupWAVFile();
        return PVWAVPARSER_READ_ERROR;
    }
    if (bytesread != 12)
    {
        CleanupWAVFile();
        return PVWAVPARSER_READ_ERROR;
    }
    // Update file position counter by 36 bytes
    filepos += 12;

    // Check for RIFF/RIFX
    uint8* pBuffer = &iBuffer[0];
    if (pBuffer[0] == 'R' &&
            pBuffer[1] == 'I' &&
            pBuffer[2] == 'F' &&
            pBuffer[3] == 'F')
    {
        isLittleEndian = 1; // Little endian data
    }
    else if (pBuffer[0] == 'R' &&
             pBuffer[1] == 'I' &&
             pBuffer[2] == 'F' &&
             pBuffer[3] == 'X')
    {
        isLittleEndian = 0; // Big endian data
    }
    else
    {
        CleanupWAVFile();
        return PVWAVPARSER_UNSUPPORTED_FORMAT;
    }

    // If a .wav file is clipped manually , the ChunkSize would not relate to the file size. However, we
    // should still attempt to play that clip for the existing length of the file. To enforce the restriction,
    // we may opt to uncomment the following lines of code.

    // To read ChunkSize (in RIFF chunk descriptor) from little endian
    /*
    uint32 ChunkSize;

    ChunkSize = (((*(pBuffer + 7)) <<24)|((*(pBuffer + 6)) << 16)|((*(pBuffer + 5)) << 8)|(*(pBuffer + 4)));
    if((int32)ChunkSize!= (filesize - 8))
    {
        CleanupWAVFile();
        return PVWAVPARSER_MISC_ERROR;
    }
    */

    // Check for WAVE in Format field
    if (pBuffer[ 8] != 'W' ||
            pBuffer[ 9] != 'A' ||
            pBuffer[10] != 'V' ||
            pBuffer[11] != 'E')
    {
        CleanupWAVFile();
        return PVWAVPARSER_UNSUPPORTED_FORMAT;
    }

    uint32 SubChunk_Size = 0;

    bool fmtSubchunkFound = false;
    while (!fmtSubchunkFound)
    {
        // read 8 bytes from file to check for next subchunk
        bytesread = 0;
        if (ReadData(iBuffer, 8, bytesread) != PVWAVPARSER_OK)
        {
            CleanupWAVFile();
            return PVWAVPARSER_READ_ERROR;
        }
        if (bytesread != 8)
        {
            CleanupWAVFile();
            return PVWAVPARSER_READ_ERROR;
        }
        // Update file position counter by 8 bytes
        filepos += 8;
        uint8* pTempBuffer = &iBuffer[0];
        SubChunk_Size = (((*(pTempBuffer + 7)) << 24) | ((*(pTempBuffer + 6)) << 16) | ((*(pTempBuffer + 5)) << 8) | (*(pTempBuffer + 4)));

        // typecast filesize as uint32 - to get to this point, it MUST be
        // greater than 0.
        if ((filepos + SubChunk_Size) > (uint32)filesize)
        {
            CleanupWAVFile();
            return PVWAVPARSER_MISC_ERROR;
        }
        // Check for FMT subchunk
        if (pTempBuffer[0] != 'f' ||
                pTempBuffer[1] != 'm' ||
                pTempBuffer[2] != 't' ||
                pTempBuffer[3] != ' ')
        {
            // "fmt " chunk not found - Unknown subchunk
            filepos += SubChunk_Size;
            if (ipWAVFile->Seek(filepos, Oscl_File::SEEKSET))
            {
                CleanupWAVFile();
                return PVWAVPARSER_MISC_ERROR;
            }
        }
        else
            fmtSubchunkFound = true;
    }
    if (ReadData(iBuffer, 16, bytesread) != PVWAVPARSER_OK)
    {
        CleanupWAVFile();
        return PVWAVPARSER_READ_ERROR;
    }
    if (bytesread != 16)
    {
        CleanupWAVFile();
        return PVWAVPARSER_READ_ERROR;
    }
    filepos += 16;

    pBuffer = &iBuffer[0];

    AudioFormat = (unsigned short)(((*(pBuffer + 1)) << 8) | (*pBuffer));   // Save AudioFormat (PCM = 1)
    xLawTable = NULL;

    NumChannels = (unsigned short)(((*(pBuffer + 3)) << 8) | (*(pBuffer + 2))); // Save Number of Channels
    SampleRate = (((*(pBuffer + 7)) << 24) | ((*(pBuffer + 6)) << 16) | ((*(pBuffer + 5)) << 8) | (*(pBuffer + 4)));    //  Save Sampling rate
    ByteRate = (((*(pBuffer + 11)) << 24) | ((*(pBuffer + 10)) << 16) | ((*(pBuffer + 9)) << 8) | (*(pBuffer + 8)));    //  Save ByteRate ( == SampleRate*NumChannels*BitsPerSample/8)
    BlockAlign = (unsigned short)(((*(pBuffer + 13)) << 8) | (*(pBuffer + 12)));    //  Save BlockAlign ( == NumChannels*BitsPerSample/8)
    BitsPerSample = (unsigned short)(((*(pBuffer + 15)) << 8) | (*(pBuffer + 14))); //  Save BitsPerSample  (8 bits == 8, 16 bits == 16 etc.)
    BytesPerSample = (BitsPerSample + 7) / 8;  // compute (ceil(BitsPerSample/8))

    if(AudioFormat == PVWAV_GSM_610)
    {
        // Validate file parameters 
        if(NumChannels!= 1)
        {
            CleanupWAVFile();
            return PVWAVPARSER_UNSUPPORTED_FORMAT;
        }
    
        // Create our codec instance and store the handle
        if(!iGsmHandle)
        {
            gsm gsm_handle = gsm_create();
            iGsmHandle = (void *)gsm_handle;
        }
        // Configure the codec for "WAV" format, and reset the Frame Index/Frame Chain.
        // Frame Index is a flag to know whether to accept 33 or 32 bytes.  Frame Chain
        // is the remainder 0.5 bytes after the codec has decoded 32.5 bytes in a 33 byte
        // frame.
        if(iGsmHandle)
        {
            int option = 1;
            gsm_option((gsm)iGsmHandle, GSM_OPT_WAV49, &option);
            option=0;
            gsm_option((gsm)iGsmHandle, GSM_OPT_FRAME_INDEX, &option);
            gsm_option((gsm)iGsmHandle, GSM_OPT_FRAME_CHAIN, &option);
        }
        BytesPerSample = PVWAVGSM_BYTES_PER_SAMPLE;  
        BitsPerSample =  PVWAVGSM_BYTES_PER_SAMPLE*8;
    }

    // Check for SubChunk_Size (It should be 16 for PCM)
    // skip remaining bytes if any because we don't currently support any compressed audio formats
    if (SubChunk_Size != 16)
    {
        // seek ahead by Subchunk1_Size - 16
        filepos += SubChunk_Size - 16;
        if (ipWAVFile->Seek(filepos, Oscl_File::SEEKSET))
        {
            CleanupWAVFile();
            return PVWAVPARSER_MISC_ERROR;
        }
    }

    bool DataSubchunkFound = false;

    while (!DataSubchunkFound)
    {
        // read 8 bytes from file to check for next subchunk
        bytesread = 0;
        if (ReadData(iBuffer, 8, bytesread) != PVWAVPARSER_OK)
        {
            CleanupWAVFile();
            return PVWAVPARSER_READ_ERROR;
        }
        if (bytesread != 8)
        {
            CleanupWAVFile();
            return PVWAVPARSER_READ_ERROR;
        }
        // Update file position counter by 8 bytes
        filepos += 8;

        uint8* pTempBuffer = &iBuffer[0];

        //It means that some unknown subchunk is present
        // Calculate  SubChunk Size
        SubChunk_Size = (((*(pTempBuffer + 7)) << 24) | ((*(pTempBuffer + 6)) << 16) | ((*(pTempBuffer + 5)) << 8) | (*(pTempBuffer + 4)));

        // Check for DATA subchunk ID
        if (pTempBuffer[0] != 'd' ||
                pTempBuffer[1] != 'a' ||
                pTempBuffer[2] != 't' ||
                pTempBuffer[3] != 'a')
        {
            // we need to skip this many bytes
            filepos += SubChunk_Size;

            // seek file pointer to current file position
            if (ipWAVFile->Seek(filepos, Oscl_File::SEEKSET))
            {
                CleanupWAVFile();
                return PVWAVPARSER_MISC_ERROR;
            }
        }
        else
        {
            // data subchunk found

            // header size equals current file pos
            iHeaderSize = filepos;

            //data subchunk is found
            DataSubchunkFound = true;

            // Read data SubChunk Size (is number of bytes in data or PCMBytesPresent)
            PCMBytesPresent = SubChunk_Size;
            iEndOfDataSubChunkOffset = filepos + PCMBytesPresent; //This is where the DataSubChunk is supposed to end

            //(this check is required to avoid memory crash if any of BytesPerSample or NumChannels is '0')
            if (BytesPerSample && NumChannels)
            {
                NumSamples = ((PCMBytesPresent / (BytesPerSample)) / NumChannels);
            }
            if(AudioFormat == PVWAV_GSM_610)
            {
                NumSamples = PCMBytesPresent / PVWAVGSM_BYTES_PER_GSMFRAMEPAIR * PVWAVGSM_SAMPLES_PER_PCMFRAME * 2;
            }
        }
    }

    //return error if any of these value is not given in wav file header
    //(AudioFormat check is done at node level)
    if (!NumChannels || !NumSamples || !SampleRate || !BitsPerSample || !BytesPerSample || !ByteRate)
    {
        CleanupWAVFile();
        return PVWAVPARSER_UNSUPPORTED_FORMAT;  //any error fom parse will be handled as PVMFFailure at corresponsding node level
    }

    return PVWAVPARSER_OK;
}
Exemple #23
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;
}
Exemple #24
0
void WavDecoder::start()
{
    if (!d->initialized)
    {
        if (QIODevice::open(QIODevice::ReadWrite | QIODevice::Unbuffered))
        {
            if (d->inputDevice->read((char*)&d->header, sizeof(CombinedHeader)) == sizeof(CombinedHeader))
            {
                if (memcmp(&d->header.riff.descriptor.id, riffId, 4) == 0 &&
                    memcmp(&d->header.riff.type, waveId, 4) == 0 &&
                    memcmp(&d->header.wave.descriptor.id, fmtId, 4) == 0)
                {
                    if (d->header.wave.audioFormat == 1)
                    {
                        d->outputInfo.type = QMediaDevice::Info::PCM;
                        d->outputInfo.frequency = qFromLittleEndian<quint32>(d->header.wave.sampleRate);
                        d->outputInfo.bitsPerSample = qFromLittleEndian<quint16>(d->header.wave.bitsPerSample);
                        d->outputInfo.channels = qFromLittleEndian<quint16>(d->header.wave.numChannels);
                        d->outputInfo.volume = d->muted ? 0 : d->volume;

                        d->length = quint32((double(d->header.riff.descriptor.size) /
                                        d->outputInfo.frequency /
                                        d->outputInfo.channels /
                                        (d->outputInfo.bitsPerSample / 8)) * 1000);

                        qLog(Media) << "WavDecoder::start(); Info" <<
                                    d->outputInfo.frequency <<
                                    d->outputInfo.bitsPerSample <<
                                    d->outputInfo.channels <<
                                    "length:" << d->length;

                        emit lengthChanged(d->length);

                        d->initialized = true;
#ifdef WAVGSM_SUPPORTED
                    } else if(d->header.wave.audioFormat == 49) {
                        d->inputDevice->seek(60);
                        d->input_data = (char *)malloc(WAV_DECODER_BUFFER);
                        d->input_pos = d->input_data;
                        d->input_length = 0;
                        d->output_data = (char *)malloc(WAV_DECODER_BUFFER*6);
                        d->output_pos = d->output_data;
                        d->output_length = 0;
                        d->gsmhandle = gsm_create();
                        int value = 1;
                        gsm_option( d->gsmhandle, GSM_OPT_WAV49, &value );

                        d->outputInfo.type = QMediaDevice::Info::PCM;
                        d->outputInfo.frequency = qFromLittleEndian<quint32>(d->header.wave.sampleRate);
                        d->outputInfo.bitsPerSample = 16;
                        d->outputInfo.channels = qFromLittleEndian<quint16>(d->header.wave.numChannels);
                        d->outputInfo.volume = d->volume;
                        d->length = d->inputDevice->dataType().dataSize*1000/d->header.wave.sampleRate*64/13;
                        qLog(Media) << "WavDecoder::start(); Info" <<
                                    d->outputInfo.frequency <<
                                    d->outputInfo.bitsPerSample <<
                                    d->outputInfo.channels <<
                                    "length:" << d->length;

                        emit lengthChanged(d->length);
                        d->initialized = true;
#endif
                    } else {
                        qWarning("WAV file is in %d audio format, not supported!",d->header.wave.audioFormat);
                    }
                }
            }
        }
    }

    if (d->initialized)
    {
        if (d->state == QtopiaMedia::Stopped)
            seek(0);

        d->state = QtopiaMedia::Playing;

        emit readyRead();
        emit playerStateChanged(d->state);
    }
}