bool SpeexFile::Open(const ACE_TString& filename, int bandmode, bool vbr) { switch(bandmode) { case SPEEX_MODEID_NB : speex_init_header(&m_spx_header, 8000, 1, speex_lib_get_mode(SPEEX_MODEID_NB)); break; case SPEEX_MODEID_WB : speex_init_header(&m_spx_header, 16000, 1, speex_lib_get_mode(SPEEX_MODEID_WB)); break; case SPEEX_MODEID_UWB : speex_init_header(&m_spx_header, 32000, 1, speex_lib_get_mode(SPEEX_MODEID_UWB)); break; default: assert(0); return false; } m_spx_header.frames_per_packet = 1; m_spx_header.nb_channels = 1; m_spx_header.vbr = vbr; SpeexEncoder enc; if(!enc.Initialize(bandmode, 2, 5)) { Close(); return false; } spx_int32_t lookahead = 0; enc.GetOption(SPEEX_GET_LOOKAHEAD, lookahead); if(!m_speex.Open(m_spx_header, lookahead)) { Close(); return false; } if(!m_ogg.Open(filename)) { Close(); return false; } //write remaining audio headers int ret; while(m_speex.FlushPageOut(m_aud_page)>0) { ret = m_ogg.WriteOggPage(m_aud_page); assert(ret>=0); } return true; }
static int CreateDefaultHeader( decoder_t *p_dec ) { ogg_packet oggpacket; SpeexHeader *p_header = malloc( sizeof(SpeexHeader) ); if( !p_header ) return VLC_ENOMEM; const int rate = p_dec->fmt_in.audio.i_rate; const unsigned i_mode = (rate / 8000) >> 1; const SpeexMode *mode; int ret = VLC_SUCCESS; oggpacket.packet = NULL; switch( rate ) { case 8000: case 16000: case 32000: mode = speex_lib_get_mode( i_mode ); break; default: msg_Err( p_dec, "Unexpected rate %d", rate ); ret = VLC_EGENERIC; goto cleanup; } speex_init_header( p_header, rate, p_dec->fmt_in.audio.i_channels, mode ); p_header->frames_per_packet = 160 << i_mode; oggpacket.packet = (unsigned char *) speex_header_to_packet( p_header, (int *) &oggpacket.bytes ); if( !oggpacket.packet ) { ret = VLC_ENOMEM; goto cleanup; } oggpacket.b_o_s = 1; oggpacket.e_o_s = 0; oggpacket.granulepos = -1; oggpacket.packetno = 0; ret = ProcessInitialHeader( p_dec, &oggpacket ); if( ret != VLC_SUCCESS ) { msg_Err( p_dec, "default Speex header is corrupted" ); } cleanup: free( oggpacket.packet ); free( p_header ); return ret; }
void Ihu2Spx::setup(QString filename, const SpeexMode *mode, int rate, int fsize) { if (fout) fclose(fout); filename.append(IHU_SPX_EXT); fout = fopen(filename.ascii(), "wb"); if (fout) { total_samples = 0; bytes_written = 0; id = -1; frame_size = fsize; if (ogg_stream_init(&os, rand())==-1) throw Error(QString("stream init failed")); speex_init_header(&header, rate, 1, mode); header.frames_per_packet = 1; op.packet = (unsigned char *)speex_header_to_packet(&header, (int*)&(op.bytes)); op.b_o_s = 1; op.e_o_s = 0; op.granulepos = 0; op.packetno = 0; ogg_stream_packetin(&os, &op); free(op.packet); op.packet = (unsigned char *)comments; op.bytes = comments_length; op.b_o_s = 0; op.e_o_s = 0; op.granulepos = 0; op.packetno = 1; ogg_stream_packetin(&os, &op); while((result = ogg_stream_flush(&os, &og))) { if(!result) break; ret = oe_write_page(&og, fout); if(ret != og.header_len + og.body_len) throw Error(QString("failed writing header to output stream")); else bytes_written += ret; } } else { throw Error(QString("%1: %2").arg(filename).arg(strerror(errno))); } }
static int speex_output_open(const char *fname, const char *comment) { Speex_ctx *ctx; int fd; if (!(speex_ctx = (Speex_ctx *)calloc(sizeof(Speex_ctx), 1))) { ctl->cmsg(CMSG_ERROR, VERB_NORMAL, "%s", strerror(errno)); return -1; } ctx = speex_ctx; /* init id */ ctx->in_bytes = ctx->out_bytes = 0; ctx->ogg_packetid = -1; ctx->channels = (dpm.encoding & PE_MONO) ? 1 : 2; if(strcmp(fname, "-") == 0) { fd = 1; /* data to stdout */ if(comment == NULL) comment = "(stdout)"; } else { /* Open the audio file */ fd = open(fname, FILE_OUTPUT_MODE); if (fd < 0) { ctl->cmsg(CMSG_ERROR, VERB_NORMAL, "%s: %s", fname, strerror(errno)); return -1; } } /*Initialize Ogg stream struct*/ if (ogg_seqnum == 0) { srand(time(NULL)); ogg_seqnum = rand(); } if (ogg_stream_init(&ctx->os, ogg_seqnum++) == -1) { ctl->cmsg(CMSG_ERROR, VERB_NORMAL, "Ogg stream init failed\n"); return -1; } if (!speex_mode_preset()) return -1; speex_init_header(&ctx->header, dpm.rate, 1, ctx->mode); ctx->header.nb_channels = ctx->channels; ctx->header.frames_per_packet = ctx->nframes = speex_options.nframes; ctx->state = speex_encoder_init(ctx->mode); /*Set the quality to 8 (15 kbps)*/ speex_encoder_ctl(ctx->state, SPEEX_SET_QUALITY, &speex_options.quality); if(strcmp(fname, "-") == 0) { fd = 1; /* data to stdout */ if(comment == NULL) comment = "(stdout)"; } else { /* Open the audio file */ fd = open(fname, FILE_OUTPUT_MODE); if(fd < 0) { ctl->cmsg(CMSG_ERROR, VERB_NORMAL, "%s: %s", fname, strerror(errno)); return -1; } if(comment == NULL) comment = fname; } write_ogg_header(ctx, fd, (char *)comment); speex_encoder_ctl(ctx->state, SPEEX_GET_FRAME_SIZE, &ctx->frame_size); speex_encoder_ctl(ctx->state, SPEEX_SET_COMPLEXITY, &speex_options.complexity); speex_encoder_ctl(ctx->state, SPEEX_SET_SAMPLING_RATE, &dpm.rate); if (speex_options.vbr) { speex_encoder_ctl(ctx->state, SPEEX_SET_VBR, &speex_options.vbr); } else if (speex_options.vad) { speex_encoder_ctl(ctx->state, SPEEX_SET_VAD, &speex_options.vad); } if (speex_options.dtx) speex_encoder_ctl(ctx->state, SPEEX_SET_DTX, &speex_options.dtx); if (speex_options.dtx && !(speex_options.vbr || speex_options.abr || speex_options.vad)) { ctl->cmsg(CMSG_ERROR, VERB_NORMAL, "--speex-dtx is useless without --speex-vad, --speex-vbr or --speex-abr"); } else if ((speex_options.vbr || speex_options.abr) && (speex_options.vad)) { ctl->cmsg(CMSG_ERROR, VERB_NORMAL, "--speex-vad is already implied by --speex-vbr or --speex-abr"); } if (speex_options.abr) { speex_encoder_ctl(ctx->state, SPEEX_SET_ABR, &speex_options.abr); } speex_bits_init(&ctx->bits); ctx->input = (float *)safe_malloc(sizeof(float) * MAX_FRAME_SIZE * ctx->channels); ctx->input_idx = 0; return fd; }
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 gboolean gst_speex_enc_setup (GstSpeexEnc * enc) { enc->setup = FALSE; switch (enc->mode) { case GST_SPEEX_ENC_MODE_UWB: GST_LOG_OBJECT (enc, "configuring for requested UWB mode"); enc->speex_mode = (SpeexMode *) & speex_uwb_mode; break; case GST_SPEEX_ENC_MODE_WB: GST_LOG_OBJECT (enc, "configuring for requested WB mode"); enc->speex_mode = (SpeexMode *) & speex_wb_mode; break; case GST_SPEEX_ENC_MODE_NB: GST_LOG_OBJECT (enc, "configuring for requested NB mode"); enc->speex_mode = (SpeexMode *) & speex_nb_mode; break; case GST_SPEEX_ENC_MODE_AUTO: /* fall through */ GST_LOG_OBJECT (enc, "finding best mode"); default: break; } if (enc->rate > 25000) { if (enc->mode == GST_SPEEX_ENC_MODE_AUTO) { GST_LOG_OBJECT (enc, "selected UWB mode for samplerate %d", enc->rate); enc->speex_mode = (SpeexMode *) & speex_uwb_mode; } else { if (enc->speex_mode != &speex_uwb_mode) { gst_speex_enc_set_last_msg (enc, "Warning: suggest to use ultra wide band mode for this rate"); } } } else if (enc->rate > 12500) { if (enc->mode == GST_SPEEX_ENC_MODE_AUTO) { GST_LOG_OBJECT (enc, "selected WB mode for samplerate %d", enc->rate); enc->speex_mode = (SpeexMode *) & speex_wb_mode; } else { if (enc->speex_mode != &speex_wb_mode) { gst_speex_enc_set_last_msg (enc, "Warning: suggest to use wide band mode for this rate"); } } } else { if (enc->mode == GST_SPEEX_ENC_MODE_AUTO) { GST_LOG_OBJECT (enc, "selected NB mode for samplerate %d", enc->rate); enc->speex_mode = (SpeexMode *) & speex_nb_mode; } else { if (enc->speex_mode != &speex_nb_mode) { gst_speex_enc_set_last_msg (enc, "Warning: suggest to use narrow band mode for this rate"); } } } if (enc->rate != 8000 && enc->rate != 16000 && enc->rate != 32000) { gst_speex_enc_set_last_msg (enc, "Warning: speex is optimized for 8, 16 and 32 KHz"); } speex_init_header (&enc->header, enc->rate, 1, enc->speex_mode); enc->header.frames_per_packet = enc->nframes; enc->header.vbr = enc->vbr; enc->header.nb_channels = enc->channels; /*Initialize Speex encoder */ enc->state = speex_encoder_init (enc->speex_mode); speex_encoder_ctl (enc->state, SPEEX_GET_FRAME_SIZE, &enc->frame_size); speex_encoder_ctl (enc->state, SPEEX_SET_COMPLEXITY, &enc->complexity); speex_encoder_ctl (enc->state, SPEEX_SET_SAMPLING_RATE, &enc->rate); if (enc->vbr) speex_encoder_ctl (enc->state, SPEEX_SET_VBR_QUALITY, &enc->quality); else { gint tmp = floor (enc->quality); speex_encoder_ctl (enc->state, SPEEX_SET_QUALITY, &tmp); } if (enc->bitrate) { if (enc->quality >= 0.0 && enc->vbr) { gst_speex_enc_set_last_msg (enc, "Warning: bitrate option is overriding quality"); } speex_encoder_ctl (enc->state, SPEEX_SET_BITRATE, &enc->bitrate); } if (enc->vbr) { gint tmp = 1; speex_encoder_ctl (enc->state, SPEEX_SET_VBR, &tmp); } else if (enc->vad) { gint tmp = 1; speex_encoder_ctl (enc->state, SPEEX_SET_VAD, &tmp); } if (enc->dtx) { gint tmp = 1; speex_encoder_ctl (enc->state, SPEEX_SET_DTX, &tmp); } if (enc->dtx && !(enc->vbr || enc->abr || enc->vad)) { gst_speex_enc_set_last_msg (enc, "Warning: dtx is useless without vad, vbr or abr"); } else if ((enc->vbr || enc->abr) && (enc->vad)) { gst_speex_enc_set_last_msg (enc, "Warning: vad is already implied by vbr or abr"); } if (enc->abr) { speex_encoder_ctl (enc->state, SPEEX_SET_ABR, &enc->abr); } speex_encoder_ctl (enc->state, SPEEX_GET_LOOKAHEAD, &enc->lookahead); GST_LOG_OBJECT (enc, "we have frame size %d, lookahead %d", enc->frame_size, enc->lookahead); enc->setup = TRUE; return TRUE; }
int main(int argc, char **argv) { int nb_samples, total_samples=0, nb_encoded; int c; int option_index = 0; char *inFile, *outFile; FILE *fin, *fout; short input[MAX_FRAME_SIZE]; spx_int32_t frame_size; int quiet=0; spx_int32_t vbr_enabled=0; spx_int32_t vbr_max=0; int abr_enabled=0; spx_int32_t vad_enabled=0; spx_int32_t dtx_enabled=0; int nbBytes; const SpeexMode *mode=NULL; int modeID = -1; void *st; SpeexBits bits; char cbits[MAX_FRAME_BYTES]; int with_skeleton = 0; struct option long_options[] = { {"wideband", no_argument, NULL, 0}, {"ultra-wideband", no_argument, NULL, 0}, {"narrowband", no_argument, NULL, 0}, {"vbr", no_argument, NULL, 0}, {"vbr-max-bitrate", required_argument, NULL, 0}, {"abr", required_argument, NULL, 0}, {"vad", no_argument, NULL, 0}, {"dtx", no_argument, NULL, 0}, {"quality", required_argument, NULL, 0}, {"bitrate", required_argument, NULL, 0}, {"nframes", required_argument, NULL, 0}, {"comp", required_argument, NULL, 0}, #ifdef USE_SPEEXDSP {"denoise", no_argument, NULL, 0}, {"agc", no_argument, NULL, 0}, #endif {"no-highpass", no_argument, NULL, 0}, {"skeleton",no_argument,NULL, 0}, {"help", no_argument, NULL, 0}, {"quiet", no_argument, NULL, 0}, {"le", no_argument, NULL, 0}, {"be", no_argument, NULL, 0}, {"8bit", no_argument, NULL, 0}, {"16bit", no_argument, NULL, 0}, {"stereo", no_argument, NULL, 0}, {"rate", required_argument, NULL, 0}, {"version", no_argument, NULL, 0}, {"version-short", no_argument, NULL, 0}, {"comment", required_argument, NULL, 0}, {"author", required_argument, NULL, 0}, {"title", required_argument, NULL, 0}, {"print-rate", no_argument, NULL, 0}, {0, 0, 0, 0} }; int print_bitrate=0; spx_int32_t rate=0; spx_int32_t size; int chan=1; int fmt=16; spx_int32_t quality=-1; float vbr_quality=-1; int lsb=1; ogg_stream_state os; ogg_stream_state so; /* ogg stream for skeleton bitstream */ ogg_page og; ogg_packet op; int bytes_written=0, ret, result; int id=-1; SpeexHeader header; int nframes=1; spx_int32_t complexity=3; const char* speex_version; char vendor_string[64]; char *comments; int comments_length; int close_in=0, close_out=0; int eos=0; spx_int32_t bitrate=0; double cumul_bits=0, enc_frames=0; char first_bytes[12]; int wave_input=0; spx_int32_t tmp; #ifdef USE_SPEEXDSP SpeexPreprocessState *preprocess = NULL; int denoise_enabled=0, agc_enabled=0; #endif int highpass_enabled=1; int output_rate=0; spx_int32_t lookahead = 0; speex_lib_ctl(SPEEX_LIB_GET_VERSION_STRING, (void*)&speex_version); snprintf(vendor_string, sizeof(vendor_string), "Encoded with Speex %s", speex_version); comment_init(&comments, &comments_length, vendor_string); /*Process command-line options*/ while(1) { c = getopt_long (argc, argv, "nwuhvV", long_options, &option_index); if (c==-1) break; switch(c) { case 0: if (strcmp(long_options[option_index].name,"narrowband")==0) { modeID = SPEEX_MODEID_NB; } else if (strcmp(long_options[option_index].name,"wideband")==0) { modeID = SPEEX_MODEID_WB; } else if (strcmp(long_options[option_index].name,"ultra-wideband")==0) { modeID = SPEEX_MODEID_UWB; } else if (strcmp(long_options[option_index].name,"vbr")==0) { vbr_enabled=1; } else if (strcmp(long_options[option_index].name,"vbr-max-bitrate")==0) { vbr_max=atoi(optarg); if (vbr_max<1) { fprintf (stderr, "Invalid VBR max bit-rate value: %d\n", vbr_max); exit(1); } } else if (strcmp(long_options[option_index].name,"abr")==0) { abr_enabled=atoi(optarg); if (!abr_enabled) { fprintf (stderr, "Invalid ABR value: %d\n", abr_enabled); exit(1); } } else if (strcmp(long_options[option_index].name,"vad")==0) { vad_enabled=1; } else if (strcmp(long_options[option_index].name,"dtx")==0) { dtx_enabled=1; } else if (strcmp(long_options[option_index].name,"quality")==0) { quality = atoi (optarg); vbr_quality=atof(optarg); } else if (strcmp(long_options[option_index].name,"bitrate")==0) { bitrate = atoi (optarg); } else if (strcmp(long_options[option_index].name,"nframes")==0) { nframes = atoi (optarg); if (nframes<1) nframes=1; if (nframes>10) nframes=10; } else if (strcmp(long_options[option_index].name,"comp")==0) { complexity = atoi (optarg); #ifdef USE_SPEEXDSP } else if (strcmp(long_options[option_index].name,"denoise")==0) { denoise_enabled=1; } else if (strcmp(long_options[option_index].name,"agc")==0) { agc_enabled=1; #endif } else if (strcmp(long_options[option_index].name,"no-highpass")==0) { highpass_enabled=0; } else if (strcmp(long_options[option_index].name,"skeleton")==0) { with_skeleton=1; } else if (strcmp(long_options[option_index].name,"help")==0) { usage(); exit(0); } else if (strcmp(long_options[option_index].name,"quiet")==0) { quiet = 1; } else if (strcmp(long_options[option_index].name,"version")==0) { version(); exit(0); } else if (strcmp(long_options[option_index].name,"version-short")==0) { version_short(); exit(0); } else if (strcmp(long_options[option_index].name,"print-rate")==0) { output_rate=1; } else if (strcmp(long_options[option_index].name,"le")==0) { lsb=1; } else if (strcmp(long_options[option_index].name,"be")==0) { lsb=0; } else if (strcmp(long_options[option_index].name,"8bit")==0) { fmt=8; } else if (strcmp(long_options[option_index].name,"16bit")==0) { fmt=16; } else if (strcmp(long_options[option_index].name,"stereo")==0) { chan=2; } else if (strcmp(long_options[option_index].name,"rate")==0) { rate=atoi (optarg); } else if (strcmp(long_options[option_index].name,"comment")==0) { if (!strchr(optarg, '=')) { fprintf (stderr, "Invalid comment: %s\n", optarg); fprintf (stderr, "Comments must be of the form name=value\n"); exit(1); } comment_add(&comments, &comments_length, NULL, optarg); } else if (strcmp(long_options[option_index].name,"author")==0) { comment_add(&comments, &comments_length, "author=", optarg); } else if (strcmp(long_options[option_index].name,"title")==0) { comment_add(&comments, &comments_length, "title=", optarg); } break; case 'n': modeID = SPEEX_MODEID_NB; break; case 'h': usage(); exit(0); break; case 'v': version(); exit(0); break; case 'V': print_bitrate=1; break; case 'w': modeID = SPEEX_MODEID_WB; break; case 'u': modeID = SPEEX_MODEID_UWB; break; case '?': usage(); exit(1); break; } } if (argc-optind!=2) { usage(); exit(1); } inFile=argv[optind]; outFile=argv[optind+1]; /*Initialize Ogg stream struct*/ srand(time(NULL)); if (ogg_stream_init(&os, rand())==-1) { fprintf(stderr,"Error: stream init failed\n"); exit(1); } if (with_skeleton && ogg_stream_init(&so, rand())==-1) { fprintf(stderr,"Error: stream init failed\n"); exit(1); } if (strcmp(inFile, "-")==0) { #if defined WIN32 || defined _WIN32 _setmode(_fileno(stdin), _O_BINARY); #elif defined OS2 _fsetmode(stdin,"b"); #endif fin=stdin; } else { fin = fopen(inFile, "rb"); if (!fin) { perror(inFile); exit(1); } close_in=1; } { if (fread(first_bytes, 1, 12, fin) != 12) { perror("short file"); exit(1); } if (strncmp(first_bytes,"RIFF",4)==0 || strncmp(first_bytes,"riff",4)==0) { if (read_wav_header(fin, &rate, &chan, &fmt, &size)==-1) exit(1); wave_input=1; lsb=1; /* CHECK: exists big-endian .wav ?? */ } } if (modeID==-1 && !rate) { /* By default, use narrowband/8 kHz */ modeID = SPEEX_MODEID_NB; rate=8000; } else if (modeID!=-1 && rate) { mode = speex_lib_get_mode (modeID); if (rate>48000) { fprintf (stderr, "Error: sampling rate too high: %d Hz, try down-sampling\n", rate); exit(1); } else if (rate>25000) { if (modeID != SPEEX_MODEID_UWB) { fprintf (stderr, "Warning: Trying to encode in %s at %d Hz. I'll do it but I suggest you try ultra-wideband instead\n", mode->modeName , rate); } } else if (rate>12500) { if (modeID != SPEEX_MODEID_WB) { fprintf (stderr, "Warning: Trying to encode in %s at %d Hz. I'll do it but I suggest you try wideband instead\n", mode->modeName , rate); } } else if (rate>=6000) { if (modeID != SPEEX_MODEID_NB) { fprintf (stderr, "Warning: Trying to encode in %s at %d Hz. I'll do it but I suggest you try narrowband instead\n", mode->modeName , rate); } } else { fprintf (stderr, "Error: sampling rate too low: %d Hz\n", rate); exit(1); } } else if (modeID==-1) { if (rate>48000) { fprintf (stderr, "Error: sampling rate too high: %d Hz, try down-sampling\n", rate); exit(1); } else if (rate>25000) { modeID = SPEEX_MODEID_UWB; } else if (rate>12500) { modeID = SPEEX_MODEID_WB; } else if (rate>=6000) { modeID = SPEEX_MODEID_NB; } else { fprintf (stderr, "Error: Sampling rate too low: %d Hz\n", rate); exit(1); } } else if (!rate) { if (modeID == SPEEX_MODEID_NB) rate=8000; else if (modeID == SPEEX_MODEID_WB) rate=16000; else if (modeID == SPEEX_MODEID_UWB) rate=32000; } if (!quiet) if (rate!=8000 && rate!=16000 && rate!=32000) fprintf (stderr, "Warning: Speex is only optimized for 8, 16 and 32 kHz. It will still work at %d Hz but your mileage may vary\n", rate); if (!mode) mode = speex_lib_get_mode (modeID); speex_init_header(&header, rate, 1, mode); header.frames_per_packet=nframes; header.vbr=vbr_enabled; header.nb_channels = chan; { char *st_string="mono"; if (chan==2) st_string="stereo"; if (!quiet) fprintf (stderr, "Encoding %d Hz audio using %s mode (%s)\n", header.rate, mode->modeName, st_string); } /*fprintf (stderr, "Encoding %d Hz audio at %d bps using %s mode\n", header.rate, mode->bitrate, mode->modeName);*/ /*Initialize Speex encoder*/ st = speex_encoder_init(mode); if (strcmp(outFile,"-")==0) { #if defined WIN32 || defined _WIN32 _setmode(_fileno(stdout), _O_BINARY); #endif fout=stdout; } else { fout = fopen(outFile, "wb"); if (!fout) { perror(outFile); exit(1); } close_out=1; } speex_encoder_ctl(st, SPEEX_GET_FRAME_SIZE, &frame_size); speex_encoder_ctl(st, SPEEX_SET_COMPLEXITY, &complexity); speex_encoder_ctl(st, SPEEX_SET_SAMPLING_RATE, &rate); if (quality >= 0) { if (vbr_enabled) { if (vbr_max>0) speex_encoder_ctl(st, SPEEX_SET_VBR_MAX_BITRATE, &vbr_max); speex_encoder_ctl(st, SPEEX_SET_VBR_QUALITY, &vbr_quality); } else speex_encoder_ctl(st, SPEEX_SET_QUALITY, &quality); } if (bitrate) { if (quality >= 0 && vbr_enabled) fprintf (stderr, "Warning: --bitrate option is overriding --quality\n"); speex_encoder_ctl(st, SPEEX_SET_BITRATE, &bitrate); } if (vbr_enabled) { tmp=1; speex_encoder_ctl(st, SPEEX_SET_VBR, &tmp); } else if (vad_enabled) { tmp=1; speex_encoder_ctl(st, SPEEX_SET_VAD, &tmp); } if (dtx_enabled) speex_encoder_ctl(st, SPEEX_SET_DTX, &tmp); if (dtx_enabled && !(vbr_enabled || abr_enabled || vad_enabled)) { fprintf (stderr, "Warning: --dtx is useless without --vad, --vbr or --abr\n"); } else if ((vbr_enabled || abr_enabled) && (vad_enabled)) { fprintf (stderr, "Warning: --vad is already implied by --vbr or --abr\n"); } if (with_skeleton) { fprintf (stderr, "Warning: Enabling skeleton output may cause some decoders to fail.\n"); } if (abr_enabled) { speex_encoder_ctl(st, SPEEX_SET_ABR, &abr_enabled); } speex_encoder_ctl(st, SPEEX_SET_HIGHPASS, &highpass_enabled); speex_encoder_ctl(st, SPEEX_GET_LOOKAHEAD, &lookahead); #ifdef USE_SPEEXDSP if (denoise_enabled || agc_enabled) { preprocess = speex_preprocess_state_init(frame_size, rate); speex_preprocess_ctl(preprocess, SPEEX_PREPROCESS_SET_DENOISE, &denoise_enabled); speex_preprocess_ctl(preprocess, SPEEX_PREPROCESS_SET_AGC, &agc_enabled); lookahead += frame_size; } #endif /* first packet should be the skeleton header. */ if (with_skeleton) { add_fishead_packet(&so); if ((ret = flush_ogg_stream_to_file(&so, fout))) { fprintf (stderr,"Error: failed skeleton (fishead) header to output stream\n"); exit(1); } else bytes_written += ret; } /*Write header*/ { int packet_size; op.packet = (unsigned char *)speex_header_to_packet(&header, &packet_size); op.bytes = packet_size; op.b_o_s = 1; op.e_o_s = 0; op.granulepos = 0; op.packetno = 0; ogg_stream_packetin(&os, &op); free(op.packet); while((result = ogg_stream_flush(&os, &og))) { if(!result) break; ret = oe_write_page(&og, fout); if(ret != og.header_len + og.body_len) { fprintf (stderr,"Error: failed writing header to output stream\n"); exit(1); } else bytes_written += ret; } op.packet = (unsigned char *)comments; op.bytes = comments_length; op.b_o_s = 0; op.e_o_s = 0; op.granulepos = 0; op.packetno = 1; ogg_stream_packetin(&os, &op); } /* fisbone packet should be write after all bos pages */ if (with_skeleton) { add_fisbone_packet(&so, os.serialno, &header); if ((ret = flush_ogg_stream_to_file(&so, fout))) { fprintf (stderr,"Error: failed writing skeleton (fisbone )header to output stream\n"); exit(1); } else bytes_written += ret; } /* writing the rest of the speex header packets */ while((result = ogg_stream_flush(&os, &og))) { if(!result) break; ret = oe_write_page(&og, fout); if(ret != og.header_len + og.body_len) { fprintf (stderr,"Error: failed writing header to output stream\n"); exit(1); } else bytes_written += ret; } free(comments); /* write the skeleton eos packet */ if (with_skeleton) { add_eos_packet_to_stream(&so); if ((ret = flush_ogg_stream_to_file(&so, fout))) { fprintf (stderr,"Error: failed writing skeleton header to output stream\n"); exit(1); } else bytes_written += ret; } speex_bits_init(&bits); if (!wave_input) { nb_samples = read_samples(fin,frame_size,fmt,chan,lsb,input, first_bytes, NULL); } else { nb_samples = read_samples(fin,frame_size,fmt,chan,lsb,input, NULL, &size); } if (nb_samples==0) eos=1; total_samples += nb_samples; nb_encoded = -lookahead; /*Main encoding loop (one frame per iteration)*/ while (!eos || total_samples>nb_encoded) { id++; /*Encode current frame*/ if (chan==2) speex_encode_stereo_int(input, frame_size, &bits); #ifdef USE_SPEEXDSP if (preprocess) speex_preprocess(preprocess, input, NULL); #endif speex_encode_int(st, input, &bits); nb_encoded += frame_size; if (print_bitrate) { int tmp; char ch=13; speex_encoder_ctl(st, SPEEX_GET_BITRATE, &tmp); fputc (ch, stderr); cumul_bits += tmp; enc_frames += 1; if (!quiet) { if (vad_enabled || vbr_enabled || abr_enabled) fprintf (stderr, "Bitrate is use: %d bps (average %d bps) ", tmp, (int)(cumul_bits/enc_frames)); else fprintf (stderr, "Bitrate is use: %d bps ", tmp); if (output_rate) printf ("%d\n", tmp); } } if (wave_input) { nb_samples = read_samples(fin,frame_size,fmt,chan,lsb,input, NULL, &size); } else { nb_samples = read_samples(fin,frame_size,fmt,chan,lsb,input, NULL, NULL); } if (nb_samples==0) { eos=1; } if (eos && total_samples<=nb_encoded) op.e_o_s = 1; else op.e_o_s = 0; total_samples += nb_samples; if ((id+1)%nframes!=0) continue; speex_bits_insert_terminator(&bits); nbBytes = speex_bits_write(&bits, cbits, MAX_FRAME_BYTES); speex_bits_reset(&bits); op.packet = (unsigned char *)cbits; op.bytes = nbBytes; op.b_o_s = 0; /*Is this redundent?*/ if (eos && total_samples<=nb_encoded) op.e_o_s = 1; else op.e_o_s = 0; op.granulepos = (id+1)*frame_size-lookahead; if (op.granulepos>total_samples) op.granulepos = total_samples; /*printf ("granulepos: %d %d %d %d %d %d\n", (int)op.granulepos, id, nframes, lookahead, 5, 6);*/ op.packetno = 2+id/nframes; ogg_stream_packetin(&os, &op); /*Write all new pages (most likely 0 or 1)*/ while (ogg_stream_pageout(&os,&og)) { ret = oe_write_page(&og, fout); if(ret != og.header_len + og.body_len) { fprintf (stderr,"Error: failed writing header to output stream\n"); exit(1); } else bytes_written += ret; } } if ((id+1)%nframes!=0) { while ((id+1)%nframes!=0) { id++; speex_bits_pack(&bits, 15, 5); } nbBytes = speex_bits_write(&bits, cbits, MAX_FRAME_BYTES); op.packet = (unsigned char *)cbits; op.bytes = nbBytes; op.b_o_s = 0; op.e_o_s = 1; op.granulepos = (id+1)*frame_size-lookahead; if (op.granulepos>total_samples) op.granulepos = total_samples; op.packetno = 2+id/nframes; ogg_stream_packetin(&os, &op); } /*Flush all pages left to be written*/ while (ogg_stream_flush(&os, &og)) { ret = oe_write_page(&og, fout); if(ret != og.header_len + og.body_len) { fprintf (stderr,"Error: failed writing header to output stream\n"); exit(1); } else bytes_written += ret; } speex_encoder_destroy(st); speex_bits_destroy(&bits); ogg_stream_clear(&os); if (close_in) fclose(fin); if (close_out) fclose(fout); return 0; }
int SpeexEncoder::Initialize(const char* filename, char* modeInput, int channels, int pcmRate) { char *comments; int comments_length; fprintf(stderr, "SpeexEncoder: Initialize\n"); SpeexHeader header; fprintf(stderr, "modeInput: %s\n", modeInput); if (modeInput != NULL){ if (strcmp(modeInput, "narrowband") == 0) { modeID = SPEEX_MODEID_NB; } else if (strcmp(modeInput, "wideband") == 0) { modeID = SPEEX_MODEID_WB; } else if (strcmp(modeInput, "ultra-wideband") == 0) { modeID = SPEEX_MODEID_UWB; } } if (channels > 0){ chan = channels; } speex_lib_ctl(SPEEX_LIB_GET_VERSION_STRING, (void*)&speex_version); snprintf(vendor_string, sizeof(vendor_string), "Encoded with Speex %s", speex_version); comment_init(&comments, &comments_length, vendor_string); comment_add(&comments, &comments_length, "TITLE=", "saa1"); comment_add(&comments, &comments_length, "AUTHOR=", "uptivity"); comment_add(&comments, &comments_length, "FORMATTYPE=", (char*)speex_version); comment_add(&comments, &comments_length, "DURATION=", "00000"); /*Initialize Ogg stream struct*/ srand(time(NULL)); if (ogg_stream_init(&os, rand()) == -1) { fprintf(stderr, "Error: stream init failed\n"); exit(1); } rate = pcmRate; if (modeID == -1 ) { /* By default, use narrowband/8 kHz */ modeID = SPEEX_MODEID_NB; if (pcmRate < 0){ rate = 8000; } } if (pcmRate < 0){ if (modeID == SPEEX_MODEID_NB) rate = 8000; else if (modeID == SPEEX_MODEID_WB) rate = 16000; else if (modeID == SPEEX_MODEID_UWB) rate = 32000; } if (!mode) mode = speex_lib_get_mode(modeID); speex_init_header(&header, rate, 1, mode); header.frames_per_packet = 1; header.vbr = 0; header.nb_channels = chan; { char *st_string = "mono"; if (chan == 2) st_string = "stereo"; fprintf(stderr, "Encoding %d Hz audio using %s mode (%s)\n", header.rate, mode->modeName, st_string); } /*Initialize Speex encoder*/ st = speex_encoder_init(mode); fout = fopen(filename, "wb"); if (!fout) { perror(filename); exit(1); } speex_encoder_ctl(st, SPEEX_GET_FRAME_SIZE, &frame_size); speex_encoder_ctl(st, SPEEX_SET_COMPLEXITY, &complexity); speex_encoder_ctl(st, SPEEX_SET_SAMPLING_RATE, &rate); if (quality >= 0) { speex_encoder_ctl(st, SPEEX_SET_QUALITY, &quality); } speex_encoder_ctl(st, SPEEX_GET_LOOKAHEAD, &lookahead); /*Write header*/ { int packet_size; op.packet = (unsigned char *)speex_header_to_packet(&header, &packet_size); op.bytes = packet_size; op.b_o_s = 1; op.e_o_s = 0; op.granulepos = 0; op.packetno = 0; // submit the packet to the ogg streaming layer ogg_stream_packetin(&os, &op); free(op.packet); while ((result = ogg_stream_flush(&os, &og))) { if (!result) break; ret = oe_write_page(&og, fout); if (ret != og.header_len + og.body_len) { fprintf(stderr, "Error: failed writing header to output stream\n"); exit(1); } else bytes_written += ret; } op.packet = (unsigned char *)comments; op.bytes = comments_length; op.b_o_s = 0; op.e_o_s = 0; op.granulepos = 0; op.packetno = 1; ogg_stream_packetin(&os, &op); durationIndex = bytes_written + os.header_fill + os.body_fill - 5; } /* writing the rest of the speex header packets */ while ((result = ogg_stream_flush(&os, &og))) { if (!result) break; ret = oe_write_page(&og, fout); if (ret != og.header_len + og.body_len) { fprintf(stderr, "Error: failed writing header to output stream\n"); exit(1); } else bytes_written += ret; } free(comments); speex_bits_init(&bits); 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 = (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; }