void speex_init_header(SpeexHeader *header, int rate, int nb_channels, const SpeexMode *m) { int i; const char *h="Speex "; /* strncpy(header->speex_string, "Speex ", 8); strncpy(header->speex_version, SPEEX_VERSION, SPEEX_HEADER_VERSION_LENGTH-1); header->speex_version[SPEEX_HEADER_VERSION_LENGTH-1]=0; */ for (i=0;i<8;i++) header->speex_string[i]=h[i]; for (i=0;i<SPEEX_HEADER_VERSION_LENGTH-1 && SPEEX_VERSION[i];i++) header->speex_version[i]=SPEEX_VERSION[i]; for (;i<SPEEX_HEADER_VERSION_LENGTH;i++) header->speex_version[i]=0; header->speex_version_id = 1; header->header_size = sizeof(SpeexHeader); header->rate = rate; header->mode = m->modeID; header->mode_bitstream_version = m->bitstream_version; if (m->modeID<0) speex_warning("This mode is meant to be used alone"); header->nb_channels = nb_channels; header->bitrate = -1; speex_mode_query(m, SPEEX_MODE_FRAME_SIZE, &header->frame_size); header->vbr = 0; header->frames_per_packet = 0; header->extra_headers = 0; header->reserved1 = 0; header->reserved2 = 0; }
static void dec_preprocess(MSFilter *f){ DecState *s=(DecState*)f->data; const SpeexMode *mode=NULL; int modeid; switch(s->rate){ case 8000: modeid = SPEEX_MODEID_NB; /* rate = 8000Hz */ break; case 16000: modeid = SPEEX_MODEID_WB; /* rate = 16000Hz */ break; /* should be supported in the future */ case 32000: modeid = SPEEX_MODEID_UWB; /* rate = 32000Hz */ break; default: ms_error("Unsupported rate for speex decoder (back to default rate=8000)."); modeid=SPEEX_MODEID_NB; } /* warning: speex_lib_get_mode() is not available on speex<1.1.12 */ mode = speex_lib_get_mode(modeid); s->state=speex_decoder_init(mode); speex_mode_query(mode,SPEEX_MODE_FRAME_SIZE,&s->frsz); if (s->penh==1) speex_decoder_ctl (s->state, SPEEX_SET_ENH, &s->penh); s->sample_time=0; }
void ms_speex_dec_init_core(MSSpeexDec *obj,const SpeexMode *mode) { int pf=1; obj->speex_state=speex_decoder_init(mode); speex_bits_init(&obj->bits); /* enable the perceptual post filter */ speex_decoder_ctl(obj->speex_state,SPEEX_SET_PF, &pf); speex_mode_query(mode, SPEEX_MODE_FRAME_SIZE, &obj->frame_size); obj->initialized=1; }
void ms_speex_dec_class_init(MSSpeexDecClass *klass) { gint frame_size=0; ms_filter_class_init(MS_FILTER_CLASS(klass)); /* use the largest frame size to configure fifos */ speex_mode_query(&speex_wb_mode, SPEEX_MODE_FRAME_SIZE, &frame_size); MS_FILTER_CLASS(klass)->process=(MSFilterProcessFunc)ms_speex_dec_process; MS_FILTER_CLASS(klass)->setup=(MSFilterSetupFunc)ms_speex_dec_setup; MS_FILTER_CLASS(klass)->unsetup=(MSFilterSetupFunc)ms_speex_dec_unsetup; MS_FILTER_CLASS(klass)->destroy=(MSFilterDestroyFunc)ms_speex_dec_destroy; MS_FILTER_CLASS(klass)->set_property=(MSFilterPropertyFunc)ms_speex_dec_set_property; ms_filter_class_set_name(MS_FILTER_CLASS(klass),"SpeexDecoder"); MS_FILTER_CLASS(klass)->info=(MSFilterInfo*)&speex_info; MS_FILTER_CLASS(klass)->max_foutputs=1; MS_FILTER_CLASS(klass)->max_qinputs=1; MS_FILTER_CLASS(klass)->w_maxgran=frame_size*2; ms_trace("ms_speex_dec_class_init: w_maxgran is %i.",MS_FILTER_CLASS(klass)->w_maxgran); }
/* 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; }
static block_t *DecodeRtpSpeexPacket( decoder_t *p_dec, block_t **pp_block ) { block_t *p_speex_bit_block = *pp_block; decoder_sys_t *p_sys = p_dec->p_sys; block_t *p_aout_buffer; int i_decode_ret; unsigned int i_speex_frame_size; if ( !p_speex_bit_block || p_speex_bit_block->i_pts <= VLC_TS_INVALID ) return NULL; /* If the SpeexBits buffer size is 0 (a default value), we know that a proper initialization has not yet been done. */ if ( p_sys->bits.buf_size==0 ) { p_sys->p_header = malloc(sizeof(SpeexHeader)); if ( !p_sys->p_header ) { msg_Err( p_dec, "Could not allocate a Speex header."); return NULL; } const SpeexMode *mode = speex_lib_get_mode((p_sys->rtp_rate / 8000) >> 1); speex_init_header( p_sys->p_header,p_sys->rtp_rate, 1, mode ); speex_bits_init( &p_sys->bits ); p_sys->p_state = speex_decoder_init( mode ); if ( !p_sys->p_state ) { msg_Err( p_dec, "Could not allocate a Speex decoder." ); free( p_sys->p_header ); return NULL; } /* Assume that variable bit rate is enabled. Also assume that there is only one frame per packet. */ p_sys->p_header->vbr = 1; p_sys->p_header->frames_per_packet = 1; p_dec->fmt_out.audio.i_channels = p_sys->p_header->nb_channels; p_dec->fmt_out.audio.i_physical_channels = p_dec->fmt_out.audio.i_original_channels = pi_channels_maps[p_sys->p_header->nb_channels]; p_dec->fmt_out.audio.i_rate = p_sys->p_header->rate; if ( speex_mode_query( &speex_nb_mode, SPEEX_MODE_FRAME_SIZE, &i_speex_frame_size ) ) { msg_Err( p_dec, "Could not determine the frame size." ); speex_decoder_destroy( p_sys->p_state ); free( p_sys->p_header ); return NULL; } p_dec->fmt_out.audio.i_bytes_per_frame = i_speex_frame_size; date_Init(&p_sys->end_date, p_sys->p_header->rate, 1); }
static void enc_preprocess(MSFilter *f){ SpeexEncState *s=(SpeexEncState*)f->data; const SpeexMode *mode=NULL; int _mode=0; switch(s->rate){ case 8000: _mode = SPEEX_MODEID_NB; /* rate = 8000Hz */ break; case 16000: _mode = SPEEX_MODEID_WB; /* rate = 16000Hz */ break; /* should be supported in the future */ case 32000: _mode = SPEEX_MODEID_UWB; /* rate = 32000Hz */ break; default: ms_error("Unsupported rate for speex encoder (back to default rate=8000)."); s->rate=8000; } /* warning: speex_lib_get_mode() is not available on speex<1.1.12 */ mode = speex_lib_get_mode(_mode); if (mode==NULL) return; s->state=speex_encoder_init(mode); if (s->vbr==1) { if (speex_encoder_ctl(s->state,SPEEX_SET_VBR,&s->vbr)!=0){ ms_error("Could not set vbr mode to speex encoder."); } /* implicit VAD */ speex_encoder_ctl (s->state, SPEEX_SET_DTX, &s->vbr); } else if (s->vbr==2) { int vad=1; /* VAD */ speex_encoder_ctl (s->state, SPEEX_SET_VAD, &vad); speex_encoder_ctl (s->state, SPEEX_SET_DTX, &vad); } else if (s->cng==1) { speex_encoder_ctl (s->state, SPEEX_SET_VAD, &s->cng); } if (s->rate==8000){ //+------+---------------+-------------+ //| mode | Speex quality | bit-rate | //+------+---------------+-------------+ //| 1 | 0 | 2.15 kbit/s | //| 2 | 2 | 5.95 kbit/s | //| 3 | 3 or 4 | 8.00 kbit/s | //| 4 | 5 or 6 | 11.0 kbit/s | //| 5 | 7 or 8 | 15.0 kbit/s | //| 6 | 9 | 18.2 kbit/s | //| 7 | 10 | 24.6 kbit/s | //| 8 | 1 | 3.95 kbit/s | //+------+---------------+-------------+ if (s->mode<=0 || s->mode>8) s->mode = 3; /* default mode */ if (s->mode==1) s->bitrate = 2150; else if (s->mode==2) s->bitrate = 5950; else if (s->mode==3) s->bitrate = 8000; else if (s->mode==4) s->bitrate = 11000; else if (s->mode==5) s->bitrate = 15000; else if (s->mode==6) s->bitrate = 18200; else if (s->mode==7) s->bitrate = 24600; else if (s->mode==8) s->bitrate = 3950; if (s->bitrate!=-1){ if (speex_encoder_ctl(s->state,SPEEX_SET_BITRATE,&s->bitrate)!=0){ ms_error("Could not set bitrate %i to speex encoder.",s->bitrate); } } } else if (s->rate==16000 || s->rate==32000){ //+------+---------------+-------------------+------------------------+ //| mode | Speex quality | wideband bit-rate | ultra wideband | //| | | | bit-rate | //+------+---------------+-------------------+------------------------+ //| 0 | 0 | 3.95 kbit/s | 5.75 kbit/s | //| 1 | 1 | 5.75 kbit/s | 7.55 kbit/s | //| 2 | 2 | 7.75 kbit/s | 9.55 kbit/s | //| 3 | 3 | 9.80 kbit/s | 11.6 kbit/s | //| 4 | 4 | 12.8 kbit/s | 14.6 kbit/s | //| 5 | 5 | 16.8 kbit/s | 18.6 kbit/s | //| 6 | 6 | 20.6 kbit/s | 22.4 kbit/s | //| 7 | 7 | 23.8 kbit/s | 25.6 kbit/s | //| 8 | 8 | 27.8 kbit/s | 29.6 kbit/s | //| 9 | 9 | 34.2 kbit/s | 36.0 kbit/s | //| 10 | 10 | 42.2 kbit/s | 44.0 kbit/s | //+------+---------------+-------------------+------------------------+ int q=0; if (s->mode<0 || s->mode>10) s->mode = 8; /* default mode */ q=s->mode; if (speex_encoder_ctl(s->state,SPEEX_SET_QUALITY,&q)!=0){ ms_error("Could not set quality %i to speex encoder.",q); } } apply_max_bitrate(s); speex_mode_query(mode,SPEEX_MODE_FRAME_SIZE,&s->frame_size); }
static int speex_encode_init(AVCodecContext *avctx) { SpeexContext *s = avctx->priv_data; SpeexMode* mode = NULL; int opt = 1; int vbr_enabled; /* default speex complexity (see speexenc.c) */ s->complexity = SPEEX_COMPLEXITY_DEFAULT; switch (avctx->codec->id) { case CODEC_ID_SPEEX: if (avctx->sample_rate > 48000) { av_log(avctx, AV_LOG_ERROR, "Error: sampling rate too high: %d Hz, try down-sampling\n", avctx->sample_rate); return -1; } else if (avctx->sample_rate > 25000) { mode = (SpeexMode*) &speex_uwb_mode; } else if (avctx->sample_rate > 12500) { mode = (SpeexMode*) &speex_wb_mode; } else if (avctx->sample_rate >= 6000) { mode = (SpeexMode*) &speex_nb_mode; } else { av_log(avctx, AV_LOG_ERROR, "Error: sampling rate too low: %d Hz\n", avctx->sample_rate); return -1; } if (avctx->sample_rate != 8000 && avctx->sample_rate != 16000 && avctx->sample_rate != 32000) av_log(avctx, AV_LOG_INFO, "Warning: speex is only optimized for 8, 16 and 32 kHz. It will still work at %d Hz but your mileage may vary\n", avctx->sample_rate); if (avctx->channels < 1 || avctx->channels > 2) { av_log(avctx, AV_LOG_ERROR, "Error: invalid number of channels: %d, only mono or stereo is supported\n", avctx->channels); return -1; } /* we support encoding more than a frame in a single call, but is has to be multiple of speex native frame_size */ speex_mode_query(mode, SPEEX_MODE_FRAME_SIZE, &avctx->frame_size); /*Initialize Speex encoder*/ speex_bits_init(&s->bits); s->st = speex_encoder_init(mode); speex_encoder_ctl(s->st, SPEEX_SET_COMPLEXITY, &s->complexity); speex_encoder_ctl(s->st, SPEEX_SET_SAMPLING_RATE, &avctx->sample_rate); speex_encoder_ctl(s->st, SPEEX_GET_LOOKAHEAD, &s->lookahead); vbr_enabled = (avctx->flags & CODEC_FLAG_QSCALE) ? 1 : 0; if (avctx->global_quality) { if (vbr_enabled) { float fquality = avctx->global_quality; speex_encoder_ctl(s->st, SPEEX_SET_VBR_QUALITY, &fquality); } else { speex_encoder_ctl(s->st, SPEEX_SET_QUALITY, &avctx->global_quality); } } if (avctx->bit_rate && vbr_enabled) { if (avctx->global_quality) av_log(avctx, AV_LOG_INFO, "Warning: vbr: bitrate option is overriding global_quality\n"); speex_encoder_ctl(s->st, SPEEX_SET_BITRATE, &avctx->bit_rate); } if (!avctx->global_quality) { if (vbr_enabled) { float fquality; speex_encoder_ctl(s->st, SPEEX_GET_VBR_QUALITY, &fquality); avctx->global_quality = (int) fquality; } } if (vbr_enabled) { speex_encoder_ctl(s->st, SPEEX_SET_VBR, &opt); if (avctx->rc_max_rate) { speex_encoder_ctl(s->st, SPEEX_SET_ABR, &avctx->rc_max_rate); } } else if (avctx->flags2 & CODEC_FLAG2_SPEEX_CNG) { speex_encoder_ctl(s->st, SPEEX_SET_VAD, &opt); } if (avctx->flags2 & CODEC_FLAG2_SPEEX_DTX) { if ((avctx->flags2 & CODEC_FLAG2_SPEEX_CNG) || vbr_enabled) { speex_encoder_ctl(s->st, SPEEX_SET_DTX, &opt); } else { av_log(avctx, AV_LOG_INFO, "Warning: dtx is useless without cng or vbr\n"); } } else if (vbr_enabled && (avctx->flags2 & CODEC_FLAG2_SPEEX_CNG)) { av_log(avctx, AV_LOG_INFO, "Warning: cng is already implied by vbr\n"); } av_log(avctx, AV_LOG_INFO, "Speex: encoder is set to %d hz audio (%d channels) at %d bps (vbr: %d, abr: %d) using (%s) mode (quality %d, framesize: %d samples, lookahead: %d, cng: %d, dtx: %d)\n", avctx->sample_rate, avctx->channels, avctx->bit_rate, vbr_enabled, avctx->rc_max_rate, mode->modeName, avctx->global_quality, avctx->frame_size, s->lookahead, avctx->flags2 & CODEC_FLAG2_SPEEX_CNG ? 1 : 0, avctx->flags2 & CODEC_FLAG2_SPEEX_DTX ? 1 : 0); break; default: return -1; } // end switch codec type return 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 }
int main(int argc, char **argv) { char *inFile, *outFile, *bitsFile; FILE *fin, *fout, *fbits=NULL; short in[FRAME_SIZE]; float input[FRAME_SIZE], bak[FRAME_SIZE], bak2[FRAME_SIZE]; char cbits[200]; int nbBits; int i; void *st; void *dec; SpeexBits bits; int tmp; int bitCount=0; SpeexCallback callback; for (i=0;i<FRAME_SIZE;i++) bak2[i]=0; st = speex_encoder_init(&speex_nb_mode); 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=8; 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); 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, "r"); outFile = argv[2]; fout = fopen(outFile, "w"); if (argc==4) { bitsFile = argv[3]; fbits = fopen(bitsFile, "w"); } speex_bits_init(&bits); while (!feof(fin)) { fread(in, sizeof(short), FRAME_SIZE, fin); if (feof(fin)) break; for (i=0;i<FRAME_SIZE;i++) bak[i]=input[i]=in[i]; speex_bits_reset(&bits); /* speex_bits_pack(&bits, 14, 5); speex_bits_pack(&bits, SPEEX_INBAND_CHAR, 4); speex_bits_pack(&bits, 'A', 8); speex_bits_pack(&bits, 14, 5); speex_bits_pack(&bits, SPEEX_INBAND_MODE_REQUEST, 4); speex_bits_pack(&bits, 7, 4); speex_bits_pack(&bits, 15, 5); speex_bits_pack(&bits, 2, 4); speex_bits_pack(&bits, 0, 16); */ speex_encode(st, input, &bits); nbBits = speex_bits_write(&bits, cbits, 200); bitCount+=bits.nbBits; printf ("Encoding frame in %d bits\n", nbBits*8); if (argc==4) fwrite(cbits, 1, nbBits, fbits); { float enoise=0, esig=0, snr; for (i=0;i<FRAME_SIZE;i++) { enoise+=(bak2[i]-input[i])*(bak2[i]-input[i]); esig += bak2[i]*bak2[i]; } snr = 10*log10((esig+1)/(enoise+1)); printf ("real SNR = %f\n", snr); } speex_bits_rewind(&bits); speex_decode(dec, &bits, input); /* Save the bits here */ for (i=0;i<FRAME_SIZE;i++) { if (input[i]>32000) input[i]=32000; else if (input[i]<-32000) input[i]=-32000; } speex_bits_reset(&bits); for (i=0;i<FRAME_SIZE;i++) in[i]=(short)input[i]; for (i=0;i<FRAME_SIZE;i++) bak2[i]=bak[i]; fwrite(in, sizeof(short), FRAME_SIZE, fout); } fprintf (stderr, "Total encoded size: %d bits\n", bitCount); speex_encoder_destroy(st); speex_decoder_destroy(dec); return 1; }
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 in_float[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; int tmp; int bitCount=0; int skip_group_delay; SpeexCallback callback; sigpow = 0; errpow = 0; st = speex_encoder_init(&speex_wb_mode); dec = speex_decoder_init(&speex_wb_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=8; speex_encoder_ctl(st, SPEEX_SET_QUALITY, &tmp); tmp=2; 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_mode_query(&speex_wb_mode, SPEEX_MODE_FRAME_SIZE, &tmp); fprintf (stderr, "frame size: %d\n", tmp); skip_group_delay = 223; 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, "r"); outFile = argv[2]; fout = fopen(outFile, "w+"); if (argc==4) { bitsFile = argv[3]; fbits = fopen(bitsFile, "w"); } speex_bits_init(&bits); while (!feof(fin)) { fread(in_short, sizeof(short), FRAME_SIZE, fin); if (feof(fin)) break; for (i=0;i<FRAME_SIZE;i++) in_float[i]=in_short[i]; 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); 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; }
void* universal_speex_init(const char* fmt, int isDecoder, int samplerate, struct MppCodecFmtpInfoV1_2* pCodecInfo) { const SpeexMode *pSpeexMode; if (pCodecInfo == NULL) { return NULL; } /* Fill general codec information */ pCodecInfo->signalingCodec = FALSE; /* It could do PLC, but wrapper should be fixed to support it. */ pCodecInfo->packetLossConcealment = CODEC_PLC_INTERNAL; /* It could do DTX+CNG, but wrapper should be fixed to support it. */ pCodecInfo->vadCng = CODEC_CNG_NONE; /* Get Speex mode for given sample rate */ switch (samplerate) { case 8000: pSpeexMode = speex_lib_get_mode(SPEEX_MODEID_NB); break; case 16000: pSpeexMode = speex_lib_get_mode(SPEEX_MODEID_WB); break; case 32000: pSpeexMode = speex_lib_get_mode(SPEEX_MODEID_UWB); break; default: assert(!"Wrong Speex sampling rate setting!"); } if (isDecoder) { int tmp; struct speex_codec_data_decoder *pSpeexDec; /* Preparing decoder */ pSpeexDec = (struct speex_codec_data_decoder *)malloc(sizeof(struct speex_codec_data_decoder)); if (!pSpeexDec) { return NULL; } pSpeexDec->mpDecoderState = NULL; pSpeexDec->mNumSamplesPerFrame = 0; /* Init decoder */ pSpeexDec->mpDecoderState = speex_decoder_init(pSpeexMode); /* It makes the decoded speech deviate further from the original, * but it sounds subjectively better.*/ tmp = 1; speex_decoder_ctl(pSpeexDec->mpDecoderState,SPEEX_SET_ENH,&tmp); /* Get number of samples in one frame */ speex_decoder_ctl(pSpeexDec->mpDecoderState,SPEEX_GET_FRAME_SIZE,&pSpeexDec->mNumSamplesPerFrame); /* Get decoder lookahead */ speex_decoder_ctl(pSpeexDec->mpDecoderState,SPEEX_GET_LOOKAHEAD,&pCodecInfo->algorithmicDelay); /* Fill codec information, specific to concrete Speex settings */ pCodecInfo->numSamplesPerFrame = pSpeexDec->mNumSamplesPerFrame; switch (samplerate) { case 8000: pCodecInfo->minBitrate = 3950; pCodecInfo->maxBitrate = 24600; pCodecInfo->minFrameBytes = (79/*bits/frame*/+7)/8; pCodecInfo->maxFrameBytes = (492/*bits/frame*/+7)/8; break; case 16000: pCodecInfo->minBitrate = 3950; pCodecInfo->maxBitrate = 42200; pCodecInfo->minFrameBytes = (79/*bits/frame*/+7)/8; pCodecInfo->maxFrameBytes = (844/*bits/frame*/+7)/8; break; case 32000: pCodecInfo->minBitrate = 5750; pCodecInfo->maxBitrate = 44000; pCodecInfo->minFrameBytes = (115/*bits/frame*/+7)/8; pCodecInfo->maxFrameBytes = (880/*bits/frame*/+7)/8; break; } return pSpeexDec; } else { struct speex_codec_data_encoder *pSpeexEnc; int mode = getFmtpValueRange(fmt, "mode", -1, 2, 8); pSpeexEnc = (struct speex_codec_data_encoder *)malloc(sizeof(struct speex_codec_data_encoder)); if (!pSpeexEnc) { return NULL; } pSpeexEnc->mpEncoderState = NULL; pSpeexEnc->mDoVad = 0; pSpeexEnc->mDoDtx = 0; pSpeexEnc->mDoVbr = 0; pSpeexEnc->mBufferLoad = 0; pSpeexEnc->mDoPreprocess = FALSE; pSpeexEnc->mpPreprocessState = NULL; pSpeexEnc->mDoDenoise = 0; pSpeexEnc->mDoAgc = 0; pSpeexEnc->mMode = mode; if (samplerate == 8000 && pSpeexEnc->mMode == 2) { pSpeexEnc->mDoPreprocess = TRUE; } /* Preparing encoder */ pSpeexEnc->mpEncoderState = speex_encoder_init(pSpeexMode); /* Setting wanted mode */ if (pSpeexEnc->mMode > -1) { speex_encoder_ctl(pSpeexEnc->mpEncoderState, SPEEX_SET_MODE,&pSpeexEnc->mMode); } // Enable wanted extensions. speex_encoder_ctl(pSpeexEnc->mpEncoderState, SPEEX_SET_VAD, &pSpeexEnc->mDoVad); speex_encoder_ctl(pSpeexEnc->mpEncoderState, SPEEX_SET_DTX, &pSpeexEnc->mDoDtx); speex_encoder_ctl(pSpeexEnc->mpEncoderState, SPEEX_SET_VBR, &pSpeexEnc->mDoVbr); if(pSpeexEnc->mDoPreprocess) { pSpeexEnc->mpPreprocessState = speex_preprocess_state_init(160, samplerate); speex_preprocess_ctl(pSpeexEnc->mpPreprocessState, SPEEX_PREPROCESS_SET_DENOISE, &pSpeexEnc->mDoDenoise); speex_preprocess_ctl(pSpeexEnc->mpPreprocessState, SPEEX_PREPROCESS_SET_AGC, &pSpeexEnc->mDoAgc); } /* Get codec frame size */ speex_encoder_ctl(pSpeexEnc->mpEncoderState, SPEEX_GET_FRAME_SIZE, &pSpeexEnc->mNumSamplesPerFrame); /* Get encoder lookahead */ speex_encoder_ctl(pSpeexEnc->mpEncoderState,SPEEX_GET_LOOKAHEAD,&pCodecInfo->algorithmicDelay); /* Fill codec information, specific to concrete Speex settings */ pCodecInfo->numSamplesPerFrame = pSpeexEnc->mNumSamplesPerFrame; if (mode > -1) { pCodecInfo->minFrameBytes = mode; pCodecInfo->maxFrameBytes = mode; } else { switch (samplerate) { case 8000: pCodecInfo->minFrameBytes = 8; pCodecInfo->maxFrameBytes = 7; speex_mode_query(pSpeexMode, SPEEX_SUBMODE_BITS_PER_FRAME, &pCodecInfo->minFrameBytes); speex_mode_query(pSpeexMode, SPEEX_SUBMODE_BITS_PER_FRAME, &pCodecInfo->maxFrameBytes); pCodecInfo->minFrameBytes = (pCodecInfo->minFrameBytes/*bits/frame*/+7)/8; pCodecInfo->maxFrameBytes = (pCodecInfo->maxFrameBytes/*bits/frame*/+7)/8; pCodecInfo->minBitrate = pCodecInfo->minFrameBytes*8/*bits/byte*/*50/*frames/sec*/; pCodecInfo->maxBitrate = pCodecInfo->maxFrameBytes*8/*bits/byte*/*50/*frames/sec*/; break; /* case 16000: case 32000: pCodecInfo->minFrameBytes = 0; pCodecInfo->maxFrameBytes = 10; break;*/ case 16000: pCodecInfo->minBitrate = 3950; pCodecInfo->maxBitrate = 42200; //pCodecInfo->numSamplesPerFrame = 16000; pCodecInfo->minFrameBytes = (79/*bits/frame*/+7)/8; pCodecInfo->maxFrameBytes = (844/*bits/frame*/+7)/8; break; case 32000: pCodecInfo->minBitrate = 5750; pCodecInfo->maxBitrate = 44000; //pCodecInfo->numSamplesPerFrame = 32000; pCodecInfo->minFrameBytes = (115/*bits/frame*/+7)/8; pCodecInfo->maxFrameBytes = (880/*bits/frame*/+7)/8; break; } } return pSpeexEnc; } }
static block_t *DecodeRtpSpeexPacket( decoder_t *p_dec, block_t **pp_block ) { block_t *p_speex_bit_block = *pp_block; decoder_sys_t *p_sys = p_dec->p_sys; block_t *p_aout_buffer; int i_decode_ret; unsigned int i_speex_frame_size; if ( !p_speex_bit_block || p_speex_bit_block->i_pts <= VLC_TS_INVALID ) return NULL; /* If the SpeexBits buffer size is 0 (a default value), we know that a proper initialization has not yet been done. */ if ( p_sys->bits.buf_size==0 ) { p_sys->p_header = (SpeexHeader *)malloc(sizeof(SpeexHeader)); if ( !p_sys->p_header ) { msg_Err( p_dec, "Could not allocate a Speex header."); return NULL; } speex_init_header( p_sys->p_header,p_sys->rtp_rate,1,&speex_nb_mode ); speex_bits_init( &p_sys->bits ); p_sys->p_state = speex_decoder_init( &speex_nb_mode ); if ( !p_sys->p_state ) { msg_Err( p_dec, "Could not allocate a Speex decoder." ); free( p_sys->p_header ); return NULL; } /* Assume that variable bit rate is enabled. Also assume that there is only one frame per packet. */ p_sys->p_header->vbr = 1; p_sys->p_header->frames_per_packet = 1; p_dec->fmt_out.audio.i_channels = p_sys->p_header->nb_channels; p_dec->fmt_out.audio.i_physical_channels = p_dec->fmt_out.audio.i_original_channels = pi_channels_maps[p_sys->p_header->nb_channels]; p_dec->fmt_out.audio.i_rate = p_sys->p_header->rate; if ( speex_mode_query( &speex_nb_mode, SPEEX_MODE_FRAME_SIZE, &i_speex_frame_size ) ) { msg_Err( p_dec, "Could not determine the frame size." ); speex_decoder_destroy( p_sys->p_state ); free( p_sys->p_header ); return NULL; } p_dec->fmt_out.audio.i_bytes_per_frame = i_speex_frame_size; date_Init(&p_sys->end_date, p_sys->p_header->rate, 1); } /* If the SpeexBits are initialized but there is still no header, an error must be thrown. */ if ( !p_sys->p_header ) { msg_Err( p_dec, "There is no valid Speex header found." ); return NULL; } *pp_block = NULL; if ( !date_Get( &p_sys->end_date ) ) date_Set( &p_sys->end_date, p_speex_bit_block->i_dts ); /* Ask for a new audio output buffer and make sure we get one. */ p_aout_buffer = decoder_NewAudioBuffer( p_dec, p_sys->p_header->frame_size ); if ( !p_aout_buffer || p_aout_buffer->i_buffer == 0 ) { msg_Err(p_dec, "Oops: No new buffer was returned!"); return NULL; } /* Read the Speex payload into the SpeexBits buffer. */ speex_bits_read_from( &p_sys->bits, (char*)p_speex_bit_block->p_buffer, p_speex_bit_block->i_buffer ); /* Decode the input and ensure that no errors were encountered. */ i_decode_ret = speex_decode_int( p_sys->p_state, &p_sys->bits, (int16_t*)p_aout_buffer->p_buffer ); if ( i_decode_ret < 0 ) { msg_Err( p_dec, "Decoding failed. Perhaps we have a bad stream?" ); return NULL; } /* Handle date management on the audio output buffer. */ p_aout_buffer->i_pts = date_Get( &p_sys->end_date ); p_aout_buffer->i_length = date_Increment( &p_sys->end_date, p_sys->p_header->frame_size ) - p_aout_buffer->i_pts; p_sys->i_frame_in_packet++; block_Release( p_speex_bit_block ); return p_aout_buffer; }