bool SFB::Audio::OggSpeexDecoder::_Open(CFErrorRef *error) { // Initialize Ogg data struct ogg_sync_init(&mOggSyncState); // Get the ogg buffer for writing char *data = ogg_sync_buffer(&mOggSyncState, READ_SIZE_BYTES); // Read bitstream from input file ssize_t bytesRead = (ssize_t)GetInputSource().Read(data, READ_SIZE_BYTES); if(-1 == bytesRead) { if(error) { SFB::CFString description(CFCopyLocalizedString(CFSTR("The file “%@” could not be read."), "")); SFB::CFString failureReason(CFCopyLocalizedString(CFSTR("Read error"), "")); SFB::CFString recoverySuggestion(CFCopyLocalizedString(CFSTR("Unable to read from the input file."), "")); *error = CreateErrorForURL(Decoder::ErrorDomain, Decoder::InputOutputError, description, mInputSource->GetURL(), failureReason, recoverySuggestion); } ogg_sync_destroy(&mOggSyncState); return false; } // Tell the sync layer how many bytes were written to its internal buffer int result = ogg_sync_wrote(&mOggSyncState, bytesRead); if(-1 == result) { if(error) { SFB::CFString description(CFCopyLocalizedString(CFSTR("The file “%@” is not a valid Ogg file."), "")); SFB::CFString failureReason(CFCopyLocalizedString(CFSTR("Not an Ogg file"), "")); SFB::CFString recoverySuggestion(CFCopyLocalizedString(CFSTR("The file's extension may not match the file's type."), "")); *error = CreateErrorForURL(Decoder::ErrorDomain, Decoder::InputOutputError, description, mInputSource->GetURL(), failureReason, recoverySuggestion); } ogg_sync_destroy(&mOggSyncState); return false; } // Turn the data we wrote into an ogg page result = ogg_sync_pageout(&mOggSyncState, &mOggPage); if(1 != result) { if(error) { SFB::CFString description(CFCopyLocalizedString(CFSTR("The file “%@” is not a valid Ogg file."), "")); SFB::CFString failureReason(CFCopyLocalizedString(CFSTR("Not an Ogg file"), "")); SFB::CFString recoverySuggestion(CFCopyLocalizedString(CFSTR("The file's extension may not match the file's type."), "")); *error = CreateErrorForURL(Decoder::ErrorDomain, Decoder::InputOutputError, description, mInputSource->GetURL(), failureReason, recoverySuggestion); } ogg_sync_destroy(&mOggSyncState); return false; } // Initialize the stream and grab the serial number ogg_stream_init(&mOggStreamState, ogg_page_serialno(&mOggPage)); // Get the first Ogg page result = ogg_stream_pagein(&mOggStreamState, &mOggPage); if(0 != result) { if(error) { SFB::CFString description(CFCopyLocalizedString(CFSTR("The file “%@” is not a valid Ogg file."), "")); SFB::CFString failureReason(CFCopyLocalizedString(CFSTR("Not an Ogg file"), "")); SFB::CFString recoverySuggestion(CFCopyLocalizedString(CFSTR("The file's extension may not match the file's type."), "")); *error = CreateErrorForURL(Decoder::ErrorDomain, Decoder::InputOutputError, description, mInputSource->GetURL(), failureReason, recoverySuggestion); } ogg_sync_destroy(&mOggSyncState); return false; } // Get the first packet (should be the header) from the page ogg_packet op; result = ogg_stream_packetout(&mOggStreamState, &op); if(1 != result) { if(error) { SFB::CFString description(CFCopyLocalizedString(CFSTR("The file “%@” is not a valid Ogg file."), "")); SFB::CFString failureReason(CFCopyLocalizedString(CFSTR("Not an Ogg file"), "")); SFB::CFString recoverySuggestion(CFCopyLocalizedString(CFSTR("The file's extension may not match the file's type."), "")); *error = CreateErrorForURL(Decoder::ErrorDomain, Decoder::InputOutputError, description, mInputSource->GetURL(), failureReason, recoverySuggestion); } ogg_sync_destroy(&mOggSyncState); return false; } if(op.bytes >= 5 && !memcmp(op.packet, "Speex", 5)) mSpeexSerialNumber = mOggStreamState.serialno; ++mOggPacketCount; // Convert the packet to the Speex header SpeexHeader *header = speex_packet_to_header((char *)op.packet, (int)op.bytes); if(nullptr == header) { if(error) { SFB::CFString description(CFCopyLocalizedString(CFSTR("The file “%@” is not a valid Ogg Speex file."), "")); SFB::CFString failureReason(CFCopyLocalizedString(CFSTR("Not an Ogg Speex file"), "")); SFB::CFString recoverySuggestion(CFCopyLocalizedString(CFSTR("The file's extension may not match the file's type."), "")); *error = CreateErrorForURL(Decoder::ErrorDomain, Decoder::FileFormatNotRecognizedError, description, mInputSource->GetURL(), failureReason, recoverySuggestion); } ogg_sync_destroy(&mOggSyncState); return false; } else if(SPEEX_NB_MODES <= header->mode) { if(error) { SFB::CFString description(CFCopyLocalizedString(CFSTR("The Speex mode in the file “%@” is not supported."), "")); SFB::CFString failureReason(CFCopyLocalizedString(CFSTR("Unsupported Ogg Speex file mode"), "")); SFB::CFString recoverySuggestion(CFCopyLocalizedString(CFSTR("This file may have been encoded with a newer version of Speex."), "")); *error = CreateErrorForURL(Decoder::ErrorDomain, Decoder::FileFormatNotSupportedError, description, mInputSource->GetURL(), failureReason, recoverySuggestion); } speex_header_free(header); header = nullptr; ogg_sync_destroy(&mOggSyncState); return false; } const SpeexMode *mode = speex_lib_get_mode(header->mode); if(mode->bitstream_version != header->mode_bitstream_version) { if(error) { SFB::CFString description(CFCopyLocalizedString(CFSTR("The Speex version in the file “%@” is not supported."), "")); SFB::CFString failureReason(CFCopyLocalizedString(CFSTR("Unsupported Ogg Speex file version"), "")); SFB::CFString recoverySuggestion(CFCopyLocalizedString(CFSTR("This file was encoded with a different version of Speex."), "")); *error = CreateErrorForURL(Decoder::ErrorDomain, Decoder::FileFormatNotSupportedError, description, mInputSource->GetURL(), failureReason, recoverySuggestion); } speex_header_free(header); header = nullptr; ogg_sync_destroy(&mOggSyncState); return false; } // Initialize the decoder mSpeexDecoder = speex_decoder_init(mode); if(nullptr== mSpeexDecoder) { if(error) { SFB::CFString description(CFCopyLocalizedString(CFSTR("Unable to initialize the Speex decoder."), "")); SFB::CFString failureReason(CFCopyLocalizedString(CFSTR("Error initializing Speex decoder"), "")); SFB::CFString recoverySuggestion(CFCopyLocalizedString(CFSTR("An unknown error occurred."), "")); *error = CreateErrorForURL(Decoder::ErrorDomain, Decoder::InputOutputError, description, mInputSource->GetURL(), failureReason, recoverySuggestion); } speex_header_free(header); header = nullptr; ogg_sync_destroy(&mOggSyncState); return false; } speex_decoder_ctl(mSpeexDecoder, SPEEX_SET_SAMPLING_RATE, &header->rate); mSpeexFramesPerOggPacket = (0 == header->frames_per_packet ? 1 : header->frames_per_packet); mExtraSpeexHeaderCount = (UInt32)header->extra_headers; // Initialize the speex bit-packing data structure speex_bits_init(&mSpeexBits); // Initialize the stereo mode mSpeexStereoState = speex_stereo_state_init(); if(2 == header->nb_channels) { SpeexCallback callback; callback.callback_id = SPEEX_INBAND_STEREO; callback.func = speex_std_stereo_request_handler; callback.data = mSpeexStereoState; speex_decoder_ctl(mSpeexDecoder, SPEEX_SET_HANDLER, &callback); } // Canonical Core Audio format mFormat.mFormatID = kAudioFormatLinearPCM; mFormat.mFormatFlags = kAudioFormatFlagsNativeFloatPacked | kAudioFormatFlagIsNonInterleaved; mFormat.mBitsPerChannel = 8 * sizeof(float); mFormat.mSampleRate = header->rate; mFormat.mChannelsPerFrame = (UInt32)header->nb_channels; mFormat.mBytesPerPacket = (mFormat.mBitsPerChannel / 8); mFormat.mFramesPerPacket = 1; mFormat.mBytesPerFrame = mFormat.mBytesPerPacket * mFormat.mFramesPerPacket; mFormat.mReserved = 0; // Set up the source format mSourceFormat.mFormatID = 'SPEE'; mSourceFormat.mSampleRate = header->rate; mSourceFormat.mChannelsPerFrame = (UInt32)header->nb_channels; switch(header->nb_channels) { case 1: mChannelLayout = ChannelLayout::ChannelLayoutWithTag(kAudioChannelLayoutTag_Mono); break; case 2: mChannelLayout = ChannelLayout::ChannelLayoutWithTag(kAudioChannelLayoutTag_Stereo); break; } speex_header_free(header); header = nullptr; // Allocate the buffer list spx_int32_t speexFrameSize = 0; speex_decoder_ctl(mSpeexDecoder, SPEEX_GET_FRAME_SIZE, &speexFrameSize); if(!mBufferList.Allocate(mFormat, (UInt32)speexFrameSize)) { if(error) *error = CFErrorCreate(kCFAllocatorDefault, kCFErrorDomainPOSIX, ENOMEM, nullptr); speex_stereo_state_destroy(mSpeexStereoState); mSpeexStereoState = nullptr; speex_decoder_destroy(mSpeexDecoder); mSpeexDecoder = nullptr; speex_bits_destroy(&mSpeexBits); ogg_sync_destroy(&mOggSyncState); return false; } for(UInt32 i = 0; i < mBufferList->mNumberBuffers; ++i) mBufferList->mBuffers[i].mDataByteSize = 0; return true; }
int main(int argc, char *argv[]) { FILE *fin, *fout; char *filename; short samples[FRAME_SIZE]; SpeexBits bits; void *state; /* For holding encoder state */ int quality; char bytes[FRAME_SIZE]; int nbytes = 0; /* stores number of bytes in frame*/ int tmp; if (argc<2) { printf("Please specify the compressed audio file\r\n"); return EXIT_FAILURE; } filename = argv[1]; fin = fopen(filename, "r"); if (!fin) { printf("Unable to open file %s : %s \r\n", filename, strerror(errno)); return EXIT_FAILURE; } /* Create encoder 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); speex_bits_init(&bits); fout = fopen("audio.dec", "w"); if (!fout) { printf("Unable to write file audio.dec : %s \r\n", strerror(errno)); } while (1) { /* Read the size of encoded frame */ fread(&nbytes, sizeof(int), 1, fin); if(feof(fin)) break; fread(bytes, sizeof(char), nbytes, fin); printf("Number of bytes to de-compress: %d \n", nbytes); speex_bits_reset(&bits); speex_bits_read_from(&bits, bytes, nbytes); /* Decode here */ speex_decode_int(state, &bits, samples); /* Write decoded samples to output file */ fwrite(samples, sizeof(short), FRAME_SIZE, fout); } free: printf("Freeing up resources \r\n"); /* Destroy the encoder state */ speex_decoder_destroy(state); /* Destroy the bits-packing */ speex_bits_destroy(&bits); fclose(fin); fclose(fout); return 0; }
Phone::Phone(int mc) { maxcall = mc; calls = new Call*[maxcall]; for (int i=0; i<maxcall; i++) calls[i] = NULL; call_number = 0; connections = 0; recorder = new Recorder(); player = new Player(); timer = new QTimer(this); recBuffer = NULL; ready = 0; enc_state = NULL; /* * FIXME * The speex_mode_query() can give ony the frame size, but no sampling rate. * So we must create a useless decoder here, fetch the informations and then destroy it. * To fix this as soon as speex will add the speex_mode_query for sampling rate. */ void *dec_state = speex_decoder_init(&speex_uwb_mode); int enh = 1; speex_decoder_ctl(dec_state, SPEEX_SET_ENH, &enh); speex_decoder_ctl(dec_state, SPEEX_GET_SAMPLING_RATE, &play_rate); speex_decoder_ctl(dec_state, SPEEX_GET_FRAME_SIZE, &play_frame_size); speex_decoder_destroy(dec_state); agc = false; agc_sw = false; agc_hw = false; peak = 0.f; amp = 1.f; agc_step = 0.f; agc_level = 0.f; agc_err = 0.f; inport = IHU_DEFAULT_INPORT; recording = false; playing = false; listening = false; ringing = false; notifier = NULL; tcpserver = NULL; sd = -1; rec_status = RECORDER_STATUS_STOP; play_status = PLAYER_STATUS_STOP; if ((out = (char *) malloc(MAXBUFSIZE))==NULL) throw Error(Error::IHU_ERR_MEMORY); if ((buffer = (float *) malloc(MAXBUFSIZE*sizeof(float)))==NULL) throw Error(Error::IHU_ERR_MEMORY); if ((prebuffer = (float *) malloc(REC_BUFSIZE*sizeof(float)))==NULL) throw Error(Error::IHU_ERR_MEMORY); if ((playBuffer = (float *) malloc(play_frame_size*2*sizeof(float)))==NULL) throw Error(Error::IHU_ERR_MEMORY); connect( recorder, SIGNAL(warning(QString)), this, SLOT(warning(QString)) ); connect( recorder, SIGNAL(data(float*, int)), this, SLOT(processAudioSamples(float*,int)) ); connect( player, SIGNAL(warning(QString)), this, SLOT(warning(QString)) ); connect( timer, SIGNAL(timeout()), this, SLOT(playCallback()) ); }
void gviSpeexFreeDecoder(GVDecoderData data) { // destory the decoder state speex_decoder_destroy((void *)data); }
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_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+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; }
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; }