speexenc.c
资源名称:tcpmp.rar [点击查看]
上传用户:wstnjxml
上传日期:2014-04-03
资源大小:7248k
文件大小:26k
源码类别:
Windows CE
开发平台:
C/C++
- /* Copyright (C) 2002-2003 Jean-Marc Valin
- File: speexenc.c
- Redistribution and use in source and binary forms, with or without
- modification, are permitted provided that the following conditions
- are met:
- - Redistributions of source code must retain the above copyright
- notice, this list of conditions and the following disclaimer.
- - Redistributions in binary form must reproduce the above copyright
- notice, this list of conditions and the following disclaimer in the
- documentation and/or other materials provided with the distribution.
- - Neither the name of the Xiph.org Foundation nor the names of its
- contributors may be used to endorse or promote products derived from
- this software without specific prior written permission.
- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR
- CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
- LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
- NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
- #ifdef HAVE_CONFIG_H
- # include "config.h"
- #endif
- #include <stdio.h>
- #if !defined WIN32 && !defined _WIN32
- #include <unistd.h>
- #include <getopt.h>
- #endif
- #ifndef HAVE_GETOPT_LONG
- #include "getopt_win.h"
- #endif
- #include <stdlib.h>
- #include <string.h>
- #include <time.h>
- #include <speex/speex.h>
- #include <ogg/ogg.h>
- #include "wav_io.h"
- #include <speex/speex_header.h>
- #include <speex/speex_stereo.h>
- #include <speex/speex_preprocess.h>
- #if defined WIN32 || defined _WIN32
- #include "getopt_win.h"
- /* We need the following two to set stdout to binary */
- #include <io.h>
- #include <fcntl.h>
- #endif
- void comment_init(char **comments, int* length, char *vendor_string);
- void comment_add(char **comments, int* length, char *tag, char *val);
- /*Write an Ogg page to a file pointer*/
- int oe_write_page(ogg_page *page, FILE *fp)
- {
- int written;
- written = fwrite(page->header,1,page->header_len, fp);
- written += fwrite(page->body,1,page->body_len, fp);
- return written;
- }
- #define MAX_FRAME_SIZE 2000
- #define MAX_FRAME_BYTES 2000
- /* Convert input audio bits, endians and channels */
- static int read_samples(FILE *fin,int frame_size, int bits, int channels, int lsb, short * input, char *buff, int *size)
- {
- unsigned char in[MAX_FRAME_BYTES*2];
- int i;
- short *s;
- int nb_read;
- if (size && *size<=0)
- {
- return 0;
- }
- /*Read input audio*/
- if (size)
- *size -= bits/8*channels*frame_size;
- if (buff)
- {
- for (i=0;i<12;i++)
- in[i]=buff[i];
- nb_read = fread(in+12,1,bits/8*channels*frame_size-12, fin) + 12;
- if (size)
- *size += 12;
- } else {
- nb_read = fread(in,1,bits/8*channels* frame_size, fin);
- }
- nb_read /= bits/8*channels;
- /*fprintf (stderr, "%dn", nb_read);*/
- if (nb_read==0)
- return 0;
- s=(short*)in;
- if(bits==8)
- {
- /* Convert 8->16 bits */
- for(i=frame_size*channels-1;i>=0;i--)
- {
- s[i]=(in[i]<<8)^0x8000;
- }
- } else
- {
- /* convert to our endian format */
- for(i=0;i<frame_size*channels;i++)
- {
- if(lsb)
- s[i]=le_short(s[i]);
- else
- s[i]=be_short(s[i]);
- }
- }
- /* FIXME: This is probably redundent now */
- /* copy to float input buffer */
- for (i=0;i<frame_size*channels;i++)
- {
- input[i]=(short)s[i];
- }
- for (i=nb_read*channels;i<frame_size*channels;i++)
- {
- input[i]=0;
- }
- return nb_read;
- }
- void version()
- {
- printf ("speexenc (Speex encoder) version " SPEEX_VERSION " (compiled " __DATE__ ")n");
- printf ("Copyright (C) 2002-2003 Jean-Marc Valinn");
- }
- void version_short()
- {
- printf ("speexenc version " SPEEX_VERSION "n");
- printf ("Copyright (C) 2002-2003 Jean-Marc Valinn");
- }
- void usage()
- {
- printf ("Usage: speexenc [options] input_file output_filen");
- printf ("n");
- printf ("Encodes input_file using Speex. It can read the WAV or raw files.n");
- printf ("n");
- printf ("input_file can be:n");
- printf (" filename.wav wav filen");
- printf (" filename.* Raw PCM file (any extension other than .wav)n");
- printf (" - stdinn");
- printf ("n");
- printf ("output_file can be:n");
- printf (" filename.spx Speex filen");
- printf (" - stdoutn");
- printf ("n");
- printf ("Options:n");
- printf (" -n, --narrowband Narrowband (8 kHz) input filen");
- printf (" -w, --wideband Wideband (16 kHz) input filen");
- printf (" -u, --ultra-wideband "Ultra-wideband" (32 kHz) input filen");
- printf (" --quality n Encoding quality (0-10), default 8n");
- printf (" --bitrate n Encoding bit-rate (use bit-rate n or lower)n");
- printf (" --vbr Enable variable bit-rate (VBR)n");
- printf (" --abr rate Enable average bit-rate (ABR) at rate bpsn");
- printf (" --vad Enable voice activity detection (VAD)n");
- printf (" --dtx Enable file-based discontinuous transmission (DTX)n");
- printf (" --comp n Set encoding complexity (0-10), default 3n");
- printf (" --nframes n Number of frames per Ogg packet (1-10), default 1n");
- printf (" --denoise Denoise the input before encodingn");
- printf (" --agc Apply adaptive gain control (AGC) before encodingn");
- printf (" --comment Add the given string as an extra comment. This may ben");
- printf (" used multiple timesn");
- printf (" --author Author of this trackn");
- printf (" --title Title for this trackn");
- printf (" -h, --help This helpn");
- printf (" -v, --version Version informationn");
- printf (" -V Verbose mode (show bit-rate)n");
- printf ("Raw input options:n");
- printf (" --rate n Sampling rate for raw inputn");
- printf (" --stereo Consider raw input as stereon");
- printf (" --le Raw input is little-endiann");
- printf (" --be Raw input is big-endiann");
- printf (" --8bit Raw input is 8-bit unsignedn");
- printf (" --16bit Raw input is 16-bit signedn");
- printf ("Default raw PCM input is 16-bit, little-endian, monon");
- printf ("n");
- printf ("More information is available from the Speex site: http://www.speex.orgn");
- printf ("n");
- printf ("Please report bugs to the mailing list `speex-dev@xiph.org'.n");
- }
- 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];
- int frame_size;
- int quiet=0;
- int vbr_enabled=0;
- int abr_enabled=0;
- int vad_enabled=0;
- int dtx_enabled=0;
- int nbBytes;
- const SpeexMode *mode=NULL;
- int modeID = -1;
- void *st;
- SpeexBits bits;
- char cbits[MAX_FRAME_BYTES];
- 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},
- {"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},
- {"denoise", no_argument, NULL, 0},
- {"agc", 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},
- {0, 0, 0, 0}
- };
- int print_bitrate=0;
- int rate=0, size;
- int chan=1;
- int fmt=16;
- int quality=-1;
- float vbr_quality=-1;
- int lsb=1;
- ogg_stream_state os;
- ogg_page og;
- ogg_packet op;
- int bytes_written=0, ret, result;
- int id=-1;
- SpeexHeader header;
- int nframes=1;
- int complexity=3;
- char *vendor_string = "Encoded with Speex " SPEEX_VERSION;
- char *comments;
- int comments_length;
- int close_in=0, close_out=0;
- int eos=0;
- int bitrate=0;
- double cumul_bits=0, enc_frames=0;
- char first_bytes[12];
- int wave_input=0;
- int tmp;
- SpeexPreprocessState *preprocess = NULL;
- int denoise_enabled=0, agc_enabled=0;
- int lookahead = 0;
- 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,"abr")==0)
- {
- abr_enabled=atoi(optarg);
- if (!abr_enabled)
- {
- fprintf (stderr, "Invalid ABR value: %dn", 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);
- } 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;
- } 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,"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: %sn", optarg);
- fprintf (stderr, "Comments must be of the form name=valuen");
- 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 failedn");
- exit(1);
- }
- if (strcmp(inFile, "-")==0)
- {
- #if defined WIN32 || defined _WIN32
- _setmode(_fileno(stdin), _O_BINARY);
- #endif
- fin=stdin;
- }
- else
- {
- fin = fopen(inFile, "rb");
- if (!fin)
- {
- perror(inFile);
- exit(1);
- }
- close_in=1;
- }
- {
- fread(first_bytes, 1, 12, fin);
- 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)
- {
- if (rate>48000)
- {
- fprintf (stderr, "Error: sampling rate too high: %d Hz, try down-samplingn", 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 insteadn", 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 insteadn", 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 insteadn", mode->modeName , rate);
- }
- } else {
- fprintf (stderr, "Error: sampling rate too low: %d Hzn", rate);
- exit(1);
- }
- } else if (modeID==-1)
- {
- if (rate>48000)
- {
- fprintf (stderr, "Error: sampling rate too high: %d Hz, try down-samplingn", 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 Hzn", 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 varyn", rate);
- 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 moden",
- 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)
- 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 --qualityn");
- 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 --abrn");
- } else if ((vbr_enabled || abr_enabled) && (vad_enabled))
- {
- fprintf (stderr, "Warning: --vad is already implied by --vbr or --abrn");
- }
- if (abr_enabled)
- {
- speex_encoder_ctl(st, SPEEX_SET_ABR, &abr_enabled);
- }
- speex_encoder_ctl(st, SPEEX_GET_LOOKAHEAD, &lookahead);
- 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;
- }
- /*Write header*/
- {
- 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)
- {
- fprintf (stderr,"Error: failed writing header to output streamn");
- exit(1);
- }
- else
- bytes_written += ret;
- }
- }
- free(comments);
- 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);
- if (preprocess)
- speex_preprocess(preprocess, input, NULL);
- 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 (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 %dn", (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 streamn");
- 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 streamn");
- 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;
- }
- /*
- Comments will be stored in the Vorbis style.
- It is describled in the "Structure" section of
- http://www.xiph.org/ogg/vorbis/doc/v-comment.html
- The comment header is decoded as follows:
- 1) [vendor_length] = read an unsigned integer of 32 bits
- 2) [vendor_string] = read a UTF-8 vector as [vendor_length] octets
- 3) [user_comment_list_length] = read an unsigned integer of 32 bits
- 4) iterate [user_comment_list_length] times {
- 5) [length] = read an unsigned integer of 32 bits
- 6) this iteration's user comment = read a UTF-8 vector as [length] octets
- }
- 7) [framing_bit] = read a single bit as boolean
- 8) if ( [framing_bit] unset or end of packet ) then ERROR
- 9) done.
- If you have troubles, please write to ymnk@jcraft.com.
- */
- #define readint(buf, base) (((buf[base+3]<<24)&0xff000000)|
- ((buf[base+2]<<16)&0xff0000)|
- ((buf[base+1]<<8)&0xff00)|
- (buf[base]&0xff))
- #define writeint(buf, base, val) do{ buf[base+3]=((val)>>24)&0xff;
- buf[base+2]=((val)>>16)&0xff;
- buf[base+1]=((val)>>8)&0xff;
- buf[base]=(val)&0xff;
- }while(0)
- void comment_init(char **comments, int* length, char *vendor_string)
- {
- int vendor_length=strlen(vendor_string);
- int user_comment_list_length=0;
- int len=4+vendor_length+4;
- char *p=(char*)malloc(len);
- if(p==NULL){
- }
- writeint(p, 0, vendor_length);
- memcpy(p+4, vendor_string, vendor_length);
- writeint(p, 4+vendor_length, user_comment_list_length);
- *length=len;
- *comments=p;
- }
- void comment_add(char **comments, int* length, char *tag, char *val)
- {
- char* p=*comments;
- int vendor_length=readint(p, 0);
- int user_comment_list_length=readint(p, 4+vendor_length);
- int tag_len=(tag?strlen(tag):0);
- int val_len=strlen(val);
- int len=(*length)+4+tag_len+val_len;
- p=(char*)realloc(p, len);
- if(p==NULL){
- }
- writeint(p, *length, tag_len+val_len); /* length of comment */
- if(tag) memcpy(p+*length+4, tag, tag_len); /* comment */
- memcpy(p+*length+4+tag_len, val, val_len); /* comment */
- writeint(p, 4+vendor_length, user_comment_list_length+1);
- *comments=p;
- *length=len;
- }
- #undef readint
- #undef writeint