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