/*! \brief convert and store into outbuf */ static int speextolin_framein(struct ast_trans_pvt *pvt, struct ast_frame *f) { struct speex_coder_pvt *tmp = pvt->pvt; /* Assuming there's space left, decode into the current buffer at the tail location. Read in as many frames as there are */ int x; int res; int16_t *dst = pvt->outbuf.i16; /* XXX fout is a temporary buffer, may have different types */ #ifdef _SPEEX_TYPES_H spx_int16_t fout[1024]; #else float fout[1024]; #endif if (f->datalen == 0) { /* Native PLC interpolation */ if (pvt->samples + tmp->framesize > BUFFER_SAMPLES) { ast_log(LOG_WARNING, "Out of buffer space\n"); return -1; } #ifdef _SPEEX_TYPES_H speex_decode_int(tmp->speex, NULL, dst + pvt->samples); #else speex_decode(tmp->speex, NULL, fout); for (x=0;x<tmp->framesize;x++) { dst[pvt->samples + x] = (int16_t)fout[x]; } #endif pvt->samples += tmp->framesize; pvt->datalen += 2 * tmp->framesize; /* 2 bytes/sample */ return 0; } /* Read in bits */ speex_bits_read_from(&tmp->bits, f->data.ptr, f->datalen); for (;;) { #ifdef _SPEEX_TYPES_H res = speex_decode_int(tmp->speex, &tmp->bits, fout); #else res = speex_decode(tmp->speex, &tmp->bits, fout); #endif if (res < 0) break; if (pvt->samples + tmp->framesize > BUFFER_SAMPLES) { ast_log(LOG_WARNING, "Out of buffer space\n"); return -1; } for (x = 0 ; x < tmp->framesize; x++) dst[pvt->samples + x] = (int16_t)fout[x]; pvt->samples += tmp->framesize; pvt->datalen += 2 * tmp->framesize; /* 2 bytes/sample */ } return 0; }
// renyang - 替音訊解碼 void Call::decodeAudioData(char *buf, int len) { #ifdef REN_DEBUG qWarning("Call::decodeAudioData()"); #endif if (dec_state) { // renyang - Initializes the bit-stream from the data in an area of memory // renyang - 把一連串的buf轉到bit-stream speex_bits_read_from(&bits, buf, len); // renyang - 把bits解碼到outBuffer(為float型態) // renyang - 當<0表示解碼失敗 if (speex_decode(dec_state, &bits, outBuffer) < 0) { emit warning("Warning: wrong decryption key or stream corrupted!"); disableDecrypt(); } else { // renyang - 來到這裡表示解碼成功 // renyang - 把解碼之後的音訊(outBuffer)放到soundBuffer中 putData(outBuffer, frame_size); } } }
int main(int argc, char **argv) { char *outFile; FILE *fout; /*Holds the audio that will be written to file (16 bits per sample)*/ short out[FRAME_SIZE]; /*Speex handle samples as float, so we need an array of floats*/ float output[FRAME_SIZE]; char cbits[200]; int nbBytes; /*Holds the state of the decoder*/ void *state; /*Holds bits so they can be read and written to by the Speex routines*/ SpeexBits bits; int i, tmp; /*Create a new decoder state in narrowband mode*/ state = speex_decoder_init(&speex_nb_mode); /*Set the perceptual enhancement on*/ tmp=1; speex_decoder_ctl(state, SPEEX_SET_ENH, &tmp); outFile = argv[1]; fout = fopen(outFile, "w"); /*Initialization of the structure that holds the bits*/ speex_bits_init(&bits); while (1) { /*Read the size encoded by sampleenc, this part will likely be different in your application*/ fread(&nbBytes, sizeof(int), 1, stdin); fprintf (stderr, "nbBytes: %d\n", nbBytes); if (feof(stdin)) break; /*Read the "packet" encoded by sampleenc*/ fread(cbits, 1, nbBytes, stdin); /*Copy the data into the bit-stream struct*/ speex_bits_read_from(&bits, cbits, nbBytes); /*Decode the data*/ speex_decode(state, &bits, output); /*Copy from float to short (16 bits) for output*/ for (i=0;i<FRAME_SIZE;i++) out[i]=output[i]; /*Write the decoded audio to file*/ fwrite(out, sizeof(short), FRAME_SIZE, fout); } /*Destroy the decoder state*/ speex_decoder_destroy(state); /*Destroy the bit-stream truct*/ speex_bits_destroy(&bits); fclose(fout); return 0; }
void decode(int header) { FILE * fin = fopen("audiopacket2.spx", "r"); FILE * fout = fopen("decoded_audio.raw", "w"); int i; short out[FRAME_SIZE]; float output[FRAME_SIZE]; char cbits[331-20]; SpeexBits bits; void * state; state = speex_decoder_init(&speex_nb_mode); speex_bits_init(&bits); while(1) { if(feof(fin)) break; /* on lit 307 octets (un paquet) vers cbits */ fread(cbits, 1, 331-20, fin); /* on le copie vers une structure bit-stream */ speex_bits_read_from(&bits, cbits+header, 331-20-header); /* on decode */ speex_decode(state, &bits, output); for(i=0 ; i< FRAME_SIZE ; i++) out[i]= output[i]; fwrite(out, sizeof(short), FRAME_SIZE, fout); } }
Boolean CASpeexDecoder::GenerateFrames() { Boolean ret = true; int result; mBDCStatus = kBDCStatusOK; SpeexFramePacket &sfp = mSpeexFPList.front(); speex_bits_read_from(&mSpeexBits, reinterpret_cast<char*> (mBDCBuffer.GetData()), sfp.bytes); if (sfp.frames > 0 && (sfp.frames - mSpeexHeader.frame_size * mSpeexHeader.frames_per_packet > 0)) { UInt32 zeroBytes = mOutputFormat.FramesToBytes(sfp.frames - mSpeexHeader.frame_size * mSpeexHeader.frames_per_packet); memset(mOutBuffer + mOutBufferUsedSize, 0, zeroBytes); mOutBufferUsedSize += zeroBytes; } for (SInt32 i = 0; i < mSpeexHeader.frames_per_packet; i++) { if (mOutputFormat.mFormatFlags & kAudioFormatFlagsNativeFloatPacked != 0) result = speex_decode(mSpeexDecoderState, &mSpeexBits, reinterpret_cast<float*> (mOutBuffer + mOutBufferUsedSize)); else result = speex_decode_int(mSpeexDecoderState, &mSpeexBits, reinterpret_cast<spx_int16_t*> (mOutBuffer + mOutBufferUsedSize)); if (result < 0) { mBDCStatus = kBDCStatusAbort; return false; } if (mSpeexHeader.nb_channels == 2) { if (mOutputFormat.mFormatFlags & kAudioFormatFlagsNativeFloatPacked != 0) speex_decode_stereo(reinterpret_cast<float*> (mOutBuffer + mOutBufferUsedSize), mSpeexHeader.frame_size, &mSpeexStereoState); else speex_decode_stereo_int(reinterpret_cast<spx_int16_t*> (mOutBuffer + mOutBufferUsedSize), mSpeexHeader.frame_size, &mSpeexStereoState); } mOutBufferUsedSize += mOutputFormat.FramesToBytes(mSpeexHeader.frame_size); } if (sfp.frames == 0) { mNumFrames += mSpeexHeader.frame_size * mSpeexHeader.frames_per_packet; } else if (sfp.frames > 0) { mNumFrames += sfp.frames; if (mSpeexHeader.frame_size * mSpeexHeader.frames_per_packet - sfp.frames != 0) mOutBufferStart += mOutputFormat.FramesToBytes(mSpeexHeader.frame_size * mSpeexHeader.frames_per_packet - sfp.frames); } else { mNumFrames -= sfp.frames; } mBDCBuffer.Zap(sfp.bytes); mSpeexFPList.erase(mSpeexFPList.begin()); return ret; }
void *os_sound_start_thread(void *_ca) { jcall_t *ca = (jcall_t*)_ca; char data_in[160]; short sp_data_in_s[640]; float sp_data_in_f[640]; int have_more; int timestamp = 0; int i; while (ca->enable_audio != -1) { memset(data_in, 0, 160); /* receive ONE packet */ i = rtp_session_recv_with_ts(ca->rtp_session, data_in, 160, timestamp, &have_more); speex_bits_reset(&ca->dec_speex_bits); speex_bits_read_from(&ca->dec_speex_bits, data_in, i); while(1) { int k; k = speex_decode(ca->speex_dec, &ca->dec_speex_bits, sp_data_in_f); if (k==-2) { exit(0); } else if (k==-1) { break; } else if (k==0) { int j; for (j=0;j<ca->speex_fsize;j++) { if (sp_data_in_f[j]>32767) sp_data_in_f[j]=32767; if (sp_data_in_f[j]<-32767) sp_data_in_f[j]=-32767; sp_data_in_s[j] = (short) sp_data_in_f[j]; } write(fd, sp_data_in_s, ca->speex_fsize); } } timestamp += 160; } return NULL; }
void gviSpeexDecodeSet(GVSample * out, const GVByte * in, GVDecoderData data) { int rcode; int i; // read the data into the bits speex_bits_read_from(&gviSpeexBits, (char *)in, gviSpeexEncodedFrameSize); // decode it rcode = speex_decode((void *)data, &gviSpeexBits, gviSpeexBuffer); GS_ASSERT(rcode == 0); // convert the output from floats for(i = 0 ; i < gviSpeexSamplesPerFrame ; i++) out[i] = (GVSample)gviSpeexBuffer[i]; }
void gviSpursSpeexDecodeAdd(SpursSpeexTaskOutput *spuTaskOut) { char *inBuffer; float *speexBuffer; short *outBuffer; int rcode; unsigned int i; //spuDebugPrintf("[Speex][SPU] allocating buffers for decoding\n"); speexBuffer = (float *)memalign(16, gviSpursSpeexTaskDesc.mOutputBufferSize * sizeof(float)); outBuffer = (short *)memalign(16, gviSpursSpeexTaskDesc.mOutputBufferSize * sizeof(short)); inBuffer = (char *)memalign(16, gviSpursSpeexTaskDesc.mInputBufferSize); memset(speexBuffer, 0, gviSpursSpeexTaskDesc.mOutputBufferSize * sizeof(float)); memset(outBuffer, 0, gviSpursSpeexTaskDesc.mOutputBufferSize); memset(inBuffer, 0, gviSpursSpeexTaskDesc.mInputBufferSize * sizeof(short)); //spuDebugPrintf("[Speex][SPU] done allocating, getting input data, inbuffer size: %d\n", gSpuSampleTaskDesc.mInputBufferSize); cellDmaGet(inBuffer, (uint64_t)gviSpursSpeexTaskDesc.mInputBuffer, gviSpursSpeexTaskDesc.mInputBufferSize, DMA_TAG(1), 0,0); cellDmaWaitTagStatusAll(DMA_MASK(1)); // spuDebugPrintf("[Speex][SPU] done getting input data, preparing for speex to decode\n"); // read the data into the bits // (re)initialize the bits struct speex_bits_init_buffer(&gviSpursSpeexBits,gviSpursSpeexBitsBuffer,sizeof(gviSpursSpeexBitsBuffer)); speex_bits_read_from(&gviSpursSpeexBits, (char *)inBuffer, gviSpursSpeexTaskDesc.mEncodedFrameSize); // decode it rcode = speex_decode((void *)gviSpursSpeexStateBuffer, &gviSpursSpeexBits, speexBuffer); assert(rcode == 0); //spuDebugPrintf("[Speex][SPU] done with speex decode\n"); // convert the output from floats for(i = 0 ; i < gviSpursSpeexTaskDesc.mOutputBufferSize ; i++) outBuffer[i] = (short)speexBuffer[i]; //spuDebugPrintf("[Speex][SPU] transferring data back\n"); cellDmaPut(outBuffer, (uint64_t)gviSpursSpeexTaskDesc.mOutputBuffer, gviSpursSpeexTaskDesc.mOutputBufferSize * sizeof(short), DMA_TAG(1), 0, 0); cellDmaWaitTagStatusAll(DMA_MASK(1)); //spuDebugPrintf("[Speex][SPU] done transferring data back\n"); free(speexBuffer); free(inBuffer); free(outBuffer); spuTaskOut->mSpeexReturnCode = 0; }
hsBool plSpeex::Decode(uint8_t *data, int size, int numFrames, int *numOutputBytes, short *out) { if(!fInitialized) return false; *numOutputBytes = 0; hsReadOnlyStream stream( size, data ); float *speexOutput = new float[fFrameSize]; // holds output from speex short *pOut = out; // pointer to output short buffer // create buffer for input data uint8_t *frameData = new uint8_t[fFrameSize]; // holds the current frames data to be decoded uint8_t frameLen; // holds the length of the current frame being decoded. // Decode data for (int i = 0; i < numFrames; i++) { stream.ReadLE( &frameLen ); // read the length of the current frame to be decoded stream.Read( frameLen, frameData ); // read the data memset(speexOutput, 0, fFrameSize * sizeof(float)); speex_bits_read_from(fBits, (char *)frameData, frameLen); // give data to speex speex_decode(fDecoderState, fBits, speexOutput); // decode data for(int j = 0; j < fFrameSize; j++) { pOut[j] = (short)(speexOutput[j]); // convert floats to shorts } pOut += fFrameSize; } delete[] frameData; delete[] speexOutput; *numOutputBytes = (numFrames * fFrameSize) * sizeof(short); // length of decoded voice data(out) in bytes if(*numOutputBytes == 0) return false; return true; }
void gviSpursSpeexDecodeSet(SpursSpeexTaskOutput *spuTaskOut) { char *inBuffer; float *speexBuffer; short *outBuffer; int rcode; unsigned int i; speexBuffer = (float *)memalign(16, gviSpursSpeexTaskDesc.mOutputBufferSize * sizeof(float)); outBuffer = (short *)memalign(16, gviSpursSpeexTaskDesc.mOutputBufferSize * sizeof(short)); inBuffer = (char *)memalign(16, gviSpursSpeexTaskDesc.mInputBufferSize); memset(speexBuffer, 0, gviSpursSpeexTaskDesc.mOutputBufferSize * sizeof(float)); memset(inBuffer, 0, gviSpursSpeexTaskDesc.mOutputBufferSize * sizeof(short)); memset(outBuffer, 0, gviSpursSpeexTaskDesc.mInputBufferSize); cellDmaGet(inBuffer, (uint64_t)gviSpursSpeexTaskDesc.mInputBuffer, gviSpursSpeexTaskDesc.mInputBufferSize, DMA_TAG(1), 0,0); cellDmaWaitTagStatusAll(DMA_MASK(1)); // read the data into the bits speex_bits_read_from(&gviSpursSpeexBits, (char *)inBuffer, gviSpursSpeexTaskDesc.mEncodedFrameSize); // decode it rcode = speex_decode((void *)gviSpursSpeexStateBuffer, &gviSpursSpeexBits, speexBuffer); assert(rcode == 0); // convert the output from floats for(i = 0 ; i < gviSpursSpeexTaskDesc.mOutputBufferSize ; i++) // Expanded to remove warnings in VS2K5 outBuffer[i] = (short)speexBuffer[i]; cellDmaPut(outBuffer, (uint64_t)gviSpursSpeexTaskDesc.mOutputBuffer, gviSpursSpeexTaskDesc.mOutputBufferSize * sizeof(short), DMA_TAG(1), 0, 0); cellDmaWaitTagStatusAll(DMA_MASK(1)); free(speexBuffer); free(inBuffer); free(outBuffer); spuTaskOut->mSpeexReturnCode = 0; }
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; }
void speex_jitter_get(SpeexJitter *jitter, short *out) { int i; int ret; /* Handle frame interpolation (receiving too fast) */ if (jitter->interp_frame) { speex_decode(jitter->dec, NULL, out); jitter->interp_frame = 0; return; } /* Increment timestamp */ jitter->pointer_timestamp += jitter->frame_time; /* Handle frame dropping (receiving too fast) */ if (jitter->drop_frame) { jitter->pointer_timestamp += jitter->frame_time; jitter->drop_frame = 0; } /* Send zeros while we fill in the buffer */ if (jitter->pointer_timestamp<0) { for (i=0;i<jitter->frame_size;i++) out[i]=0; return; } /* Search the buffer for a packet with the right timestamp */ for (i=0;i<SPEEX_JITTER_MAX_BUFFER_SIZE;i++) { if (jitter->len[i]!=-1 && jitter->timestamp[i]==jitter->pointer_timestamp) break; } if (i==SPEEX_JITTER_MAX_BUFFER_SIZE) { /* No packet found */ if (jitter->valid_bits) { /* Try decoding last received packet */ ret = speex_decode(jitter->dec, &jitter->current_packet, out); if (ret == 0) return; else jitter->valid_bits = 0; } /*Packet is late or lost*/ speex_decode(jitter->dec, NULL, out); } else { /* Found the right packet */ speex_bits_read_from(&jitter->current_packet, jitter->buf[i], jitter->len[i]); jitter->len[i]=-1; /* Decode packet */ ret = speex_decode(jitter->dec, &jitter->current_packet, out); if (ret == 0) { jitter->valid_bits = 1; } else { /* Error while decoding */ for (i=0;i<jitter->frame_size;i++) out[i]=0; } } }
static gint xmms_speex_read (xmms_xform_t *xform, gpointer buf, gint len, xmms_error_t *err) { gint ret = 0, n; gfloat outfloat [2000]; gint16 *outbuf = (gint16 *) buf; xmms_speex_data_t *data; xmms_error_t error; SpeexStereoState stereo = SPEEX_STEREO_STATE_INIT; g_return_val_if_fail (xform, -1); data = xmms_xform_private_data_get (xform); g_return_val_if_fail (data, -1); /* convert from bytes to samples */ len /= 2; /* first, copy already decoded samples over if we have any. */ if (data->samples_count) { n = MIN (data->samples_count, len); memcpy (outbuf, data->samples_start, n * 2); data->samples_count -= n; if (!data->samples_count) { data->samples_start = data->samples_buf; } else { data->samples_start += n; } /* convert from samples to bytes */ return n * 2; } while (42) { gint samples_per_frame; samples_per_frame = data->speexheader->frame_size * data->speexheader->nb_channels; while (ogg_stream_packetout (&data->stream_state, &data->ogg_packet) == 1) { gint frame; speex_bits_read_from (&data->speex_bits, (char *)data->ogg_packet.packet, data->ogg_packet.bytes); for (frame = 0; frame < data->speexheader->frames_per_packet; frame++) { gint cnt; speex_decode (data->speex_state, &data->speex_bits, outfloat); if (data->speexheader->nb_channels == 2) { speex_decode_stereo (outfloat, data->speexheader->frame_size,&stereo); } n = MIN (samples_per_frame, len); /* copy as many samples to the output buffer as * possible. */ for (cnt = 0; cnt < n; cnt++) { *outbuf++ = outfloat[cnt]; len--; ret += 2; } /* store the remaining samples for later use */ for (; cnt < samples_per_frame; cnt++) { data->samples_buf[data->samples_count++] = outfloat[cnt]; } } return ret; } /* Need more data */ do { gint ret; data->ogg_data = ogg_sync_buffer (&data->sync_state, 200); ret = xmms_xform_read (xform, data->ogg_data, 200, &error); ogg_sync_wrote (&data->sync_state, ret); if (ret <= 0) { return ret; } } while (ogg_sync_pageout (&data->sync_state, &data->ogg_page) != 1); ogg_stream_pagein (&data->stream_state, &data->ogg_page); } }
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; for (i=0;i<FRAME_SIZE;i++) bak2[i]=0; st = speex_encoder_init(&speex_uwb_mode); dec = speex_decoder_init(&speex_uwb_mode); tmp=0; /*speex_decoder_ctl(dec, SPEEX_SET_ENH, &tmp); tmp=0; speex_encoder_ctl(st, SPEEX_SET_VBR, &tmp); tmp=10; speex_encoder_ctl(st, SPEEX_SET_QUALITY, &tmp); tmp=3; speex_encoder_ctl(st, SPEEX_SET_COMPLEXITY, &tmp); tmp=3; speex_encoder_ctl(st, SPEEX_SET_HIGH_MODE, &tmp); tmp=6; speex_encoder_ctl(st, SPEEX_SET_LOW_MODE, &tmp); */ 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_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); speex_bits_destroy(&bits); fclose(fin); fclose(fout); 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_uwb_mode); dec = speex_decoder_init(&speex_uwb_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=7; 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 = 509; 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(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(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+1)/(e+1)); 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; }
UInt32 OggSpeexDecoder::ReadAudio(AudioBufferList *bufferList, UInt32 frameCount) { if(!IsOpen() || NULL == bufferList || bufferList->mNumberBuffers != mFormat.mChannelsPerFrame || 0 == frameCount) return 0; UInt32 framesRead = 0; // Reset output buffer data size for(UInt32 i = 0; i < bufferList->mNumberBuffers; ++i) bufferList->mBuffers[i].mDataByteSize = 0; for(;;) { UInt32 framesRemaining = frameCount - framesRead; UInt32 framesToSkip = static_cast<UInt32>(bufferList->mBuffers[0].mDataByteSize / sizeof(float)); UInt32 framesInBuffer = static_cast<UInt32>(mBufferList->mBuffers[0].mDataByteSize / sizeof(float)); UInt32 framesToCopy = std::min(framesInBuffer, framesRemaining); // Copy data from the buffer to output for(UInt32 i = 0; i < mBufferList->mNumberBuffers; ++i) { float *floatBuffer = static_cast<float *>(bufferList->mBuffers[i].mData); memcpy(floatBuffer + framesToSkip, mBufferList->mBuffers[i].mData, framesToCopy * sizeof(float)); bufferList->mBuffers[i].mDataByteSize += static_cast<UInt32>(framesToCopy * sizeof(float)); // Move remaining data in buffer to beginning if(framesToCopy != framesInBuffer) { floatBuffer = static_cast<float *>(mBufferList->mBuffers[i].mData); memmove(floatBuffer, floatBuffer + framesToCopy, (framesInBuffer - framesToCopy) * sizeof(float)); } mBufferList->mBuffers[i].mDataByteSize -= static_cast<UInt32>(framesToCopy * sizeof(float)); } framesRead += framesToCopy; // All requested frames were read if(framesRead == frameCount) break; // EOS reached if(mSpeexEOSReached) break; // Attempt to process the desired number of packets unsigned packetsDesired = 1; while(0 < packetsDesired && !mSpeexEOSReached) { // Process any packets in the current page while(0 < packetsDesired && !mSpeexEOSReached) { // Grab a packet from the streaming layer ogg_packet oggPacket; int result = ogg_stream_packetout(&mOggStreamState, &oggPacket); if(-1 == result) { LOGGER_ERR("org.sbooth.AudioEngine.AudioDecoder.OggSpeex", "Ogg Speex decoding error: Ogg loss of streaming"); break; } // If result is 0, there is insufficient data to assemble a packet if(0 == result) break; // Otherwise, we got a valid packet for processing if(1 == result) { if(5 <= oggPacket.bytes && !memcmp(oggPacket.packet, "Speex", 5)) mSpeexSerialNumber = mOggStreamState.serialno; if(-1 == mSpeexSerialNumber || mOggStreamState.serialno != mSpeexSerialNumber) break; // Ignore the following: // - Speex comments in packet #2 // - Extra headers (optionally) in packets 3+ if(1 != mOggPacketCount && 1 + mExtraSpeexHeaderCount <= mOggPacketCount) { // Detect Speex EOS if(oggPacket.e_o_s && mOggStreamState.serialno == mSpeexSerialNumber) mSpeexEOSReached = true; // SPEEX_GET_FRAME_SIZE is in samples spx_int32_t speexFrameSize; speex_decoder_ctl(mSpeexDecoder, SPEEX_GET_FRAME_SIZE, &speexFrameSize); float buffer [(2 == mFormat.mChannelsPerFrame) ? 2 * speexFrameSize : speexFrameSize]; // Copy the Ogg packet to the Speex bitstream speex_bits_read_from(&mSpeexBits, (char *)oggPacket.packet, static_cast<int>(oggPacket.bytes)); // Decode each frame in the Speex packet for(spx_int32_t i = 0; i < mSpeexFramesPerOggPacket; ++i) { result = speex_decode(mSpeexDecoder, &mSpeexBits, buffer); // -1 indicates EOS if(-1 == result) break; else if(-2 == result) { LOGGER_ERR("org.sbooth.AudioEngine.AudioDecoder.OggSpeex", "Ogg Speex decoding error: possible corrupted stream"); break; } if(0 > speex_bits_remaining(&mSpeexBits)) { LOGGER_ERR("org.sbooth.AudioEngine.AudioDecoder.OggSpeex", "Ogg Speex decoding overflow: possible corrupted stream"); break; } // Normalize the values float maxSampleValue = 1u << 15; vDSP_vsdiv(buffer, 1, &maxSampleValue, buffer, 1, speexFrameSize); // Copy the frames from the decoding buffer to the output buffer, skipping over any frames already decoded framesInBuffer = static_cast<UInt32>(mBufferList->mBuffers[0].mDataByteSize / sizeof(float)); memcpy(static_cast<float *>(mBufferList->mBuffers[0].mData) + framesInBuffer, buffer, speexFrameSize * sizeof(float)); mBufferList->mBuffers[0].mDataByteSize += static_cast<UInt32>(speexFrameSize * sizeof(float)); // Process stereo channel, if present if(2 == mFormat.mChannelsPerFrame) { speex_decode_stereo(buffer, speexFrameSize, mSpeexStereoState); vDSP_vsdiv(buffer + speexFrameSize, 1, &maxSampleValue, buffer + speexFrameSize, 1, speexFrameSize); memcpy(static_cast<float *>(mBufferList->mBuffers[1].mData) + framesInBuffer, buffer + speexFrameSize, speexFrameSize * sizeof(float)); mBufferList->mBuffers[1].mDataByteSize += static_cast<UInt32>(speexFrameSize * sizeof(float)); } // Packet processing finished --packetsDesired; } } ++mOggPacketCount; } } // Grab a new Ogg page for processing, if necessary if(!mSpeexEOSReached && 0 < packetsDesired) { while(1 != ogg_sync_pageout(&mOggSyncState, &mOggPage)) { // Get the ogg buffer for writing char *data = ogg_sync_buffer(&mOggSyncState, READ_SIZE_BYTES); // Read bitstream from input file ssize_t bytesRead = GetInputSource()->Read(data, READ_SIZE_BYTES); if(-1 == bytesRead) { LOGGER_ERR("org.sbooth.AudioEngine.AudioDecoder.OggSpeex", "Unable to read from the input file"); break; } ogg_sync_wrote(&mOggSyncState, bytesRead); // No more data available from input file if(0 == bytesRead) break; } // Ensure all Ogg streams are read if(ogg_page_serialno(&mOggPage) != mOggStreamState.serialno) ogg_stream_reset_serialno(&mOggStreamState, ogg_page_serialno(&mOggPage)); // Get the resultant Ogg page int result = ogg_stream_pagein(&mOggStreamState, &mOggPage); if(0 != result) { LOGGER_ERR("org.sbooth.AudioEngine.AudioDecoder.OggSpeex", "Error reading Ogg page"); break; } } } } mCurrentFrame += framesRead; if(0 == framesRead && mSpeexEOSReached) mTotalFrames = mCurrentFrame; return framesRead; }
static int read_ogg_packet(OGGZ * oggz, oggz_packet * zp, long serialno, void * user_data) { ogg_packet * op = &zp->op; decoder_t * dec = (decoder_t *)user_data; speex_pdata_t * pd = (speex_pdata_t *)dec->pdata; if (pd->exploring && (pd->packetno == 0)) { /* Speex header */ int i; int ptr = 0; char speex_string[9]; int enh = 1; SpeexHeader * header; for (i = 0; i < 8; i++) { speex_string[i] = op->packet[ptr++]; } speex_string[i] = '\0'; if (strcmp(speex_string, "Speex ") != 0) { printf("read_ogg_packet(): Not a Speex stream\n"); pd->error = 1; return 0; } speex_bits_init(&(pd->bits)); header = speex_packet_to_header((char *)op->packet, op->bytes); if (!header) { printf("Cannot read Speex header\n"); pd->error = 1; return 0; } pd->mode = speex_mode_list[header->mode]; if (pd->mode->bitstream_version > header->mode_bitstream_version) { fprintf(stderr, "Unknown bitstream version! The file was encoded with an older version of Speex.\n" "You need to downgrade Speex in order to play it.\n"); pd->error = 1; return 0; } if (pd->mode->bitstream_version < header->mode_bitstream_version) { fprintf(stderr, "Unknown bitstream version! The file was encoded with a newer version of Speex.\n" "You need to upgrade Speex in order to play it.\n"); pd->error = 1; return 0; } pd->sample_rate = header->rate; pd->channels = header->nb_channels; pd->vbr = header->vbr; if (header->frames_per_packet != 0) pd->nframes = header->frames_per_packet; pd->decoder = speex_decoder_init(pd->mode); speex_decoder_ctl(pd->decoder, SPEEX_GET_FRAME_SIZE, &(pd->frame_size)); speex_decoder_ctl(pd->decoder, SPEEX_SET_ENH, &enh); } else if (pd->packetno >= 2) { int j; float output_frame[SPEEX_BUFSIZE]; pd->granulepos = op->granulepos; if (!pd->exploring) { speex_bits_read_from(&(pd->bits), (char *)op->packet, op->bytes); for (j = 0; j < pd->nframes; j++) { int k; speex_decode(pd->decoder, &(pd->bits), output_frame); for (k = 0; k < pd->frame_size * pd->channels; k++) { output_frame[k] /= 32768.0f; if (output_frame[k] > 1.0f) { output_frame[k] = 1.0f; } else if (output_frame[k] < -1.0f) { output_frame[k] = -1.0f; } } rb_write(pd->rb, (char *)output_frame, pd->channels * pd->frame_size * sample_size); } } } ++pd->packetno; return 0; }