Removed narrowband 256x8 codebook from build.
[speexdsp.git] / src / speexenc.c
1 /* Copyright (C) 2002 Jean-Marc Valin 
2    File: speexenc.c
3
4    This library is free software; you can redistribute it and/or
5    modify it under the terms of the GNU Lesser General Public
6    License as published by the Free Software Foundation; either
7    version 2.1 of the License, or (at your option) any later version.
8    
9    This library is distributed in the hope that it will be useful,
10    but WITHOUT ANY WARRANTY; without even the implied warranty of
11    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12    Lesser General Public License for more details.
13    
14    You should have received a copy of the GNU Lesser General Public
15    License along with this library; if not, write to the Free Software
16    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
17 */
18
19 #include <stdio.h>
20 #include <unistd.h>
21 #include <getopt.h>
22 #include <stdlib.h>
23 #include <string.h>
24
25 #include "speex.h"
26 #include <ogg/ogg.h>
27
28 /*Write an Ogg page to a file pointer*/
29 int oe_write_page(ogg_page *page, FILE *fp)
30 {
31    int written;
32    written = fwrite(page->header,1,page->header_len, fp);
33    written += fwrite(page->body,1,page->body_len, fp);
34    
35    return written;
36 }
37
38 #define MAX_FRAME_SIZE 2000
39 #define MAX_FRAME_BYTES 1000
40
41 void usage()
42 {
43    fprintf (stderr, "speexenc [options] <input file> <output file>\n");
44    fprintf (stderr, "options:\n");
45    fprintf (stderr, "\t--narrowband -n    Narrowband (8 kHz) input file\n"); 
46    fprintf (stderr, "\t--wideband   -w    Wideband (16 kHz) input file\n"); 
47    fprintf (stderr, "\t--help       -h    This help\n"); 
48    fprintf (stderr, "\t--version    -v    Version information\n"); 
49    fprintf (stderr, "\nInput must be raw audio (no header), 16 bits\n"); 
50 }
51
52 void version()
53 {
54    fprintf (stderr, "Speex encoder version " VERSION "\n");
55 }
56
57 int main(int argc, char **argv)
58 {
59    int c;
60    int option_index = 0;
61    int narrowband=0, wideband=0;
62    char *inFile, *outFile;
63    FILE *fin, *fout;
64    short in[MAX_FRAME_SIZE];
65    float input[MAX_FRAME_SIZE];
66    int frame_size;
67    int i,nbBytes;
68    SpeexMode *mode=NULL;
69    void *st;
70    FrameBits bits;
71    char cbits[MAX_FRAME_BYTES];
72    struct option long_options[] =
73    {
74       {"wideband", no_argument, NULL, 0},
75       {"narrowband", no_argument, NULL, 0},
76       {"help", no_argument, NULL, 0},
77       {"version", no_argument, NULL, 0},
78       {0, 0, 0, 0}
79    };
80
81    ogg_stream_state os;
82    ogg_page              og;
83    ogg_packet            op;
84    int bytes_written, ret, result;
85    int id=0;
86
87    /*Process command-line options*/
88    while(1)
89    {
90       c = getopt_long (argc, argv, "nwhv",
91                        long_options, &option_index);
92       if (c==-1)
93          break;
94       
95       switch(c)
96       {
97       case 0:
98          if (strcmp(long_options[option_index].name,"narrowband")==0)
99             narrowband=1;
100          else if (strcmp(long_options[option_index].name,"wideband")==0)
101                wideband=1;
102          else if (strcmp(long_options[option_index].name,"help")==0)
103          {
104             usage();
105             exit(0);
106          } else if (strcmp(long_options[option_index].name,"version")==0)
107          {
108             version();
109             exit(0);
110          }
111          break;
112       case 'n':
113          narrowband=1;
114          break;
115       case 'h':
116          usage();
117          break;
118       case 'v':
119          version();
120          exit(0);
121          break;
122       case 'w':
123          wideband=1;
124          break;
125       case '?':
126          usage();
127          exit(1);
128          break;
129       }
130    }
131    if (argc-optind!=2)
132    {
133       usage();
134       exit(1);
135    }
136    inFile=argv[optind];
137    outFile=argv[optind+1];
138
139    /*Initialize Ogg stream struct*/
140    if (ogg_stream_init(&os, 0)==-1)
141    {
142       fprintf(stderr,"Stream init failed\n");
143       exit(1);
144    }
145
146    if (wideband && narrowband)
147    {
148       fprintf (stderr,"Cannot specify both wideband and narrowband at the same time\n");
149       exit(1);
150    };
151    if (!wideband)
152       narrowband=1;
153    if (narrowband)
154       mode=&speex_nb_mode;
155    if (wideband)
156       mode=&speex_wb_mode;
157
158    /*Initialize Speex encoder*/
159    st = encoder_init(mode);
160
161    if (strcmp(inFile, "-")==0)
162       fin=stdin;
163    else 
164    {
165       fin = fopen(inFile, "r");
166       if (!fin)
167       {
168          perror(inFile);
169          exit(1);
170       }
171    }
172    if (strcmp(outFile,"-")==0)
173       fout=stdout;
174    else 
175    {
176       fout = fopen(outFile, "w");
177       if (!fout)
178       {
179          perror(outFile);
180          exit(1);
181       }
182    }
183
184    /*Write header (format will change)*/
185    {
186
187       if (narrowband)
188          op.packet = (unsigned char *)"speex narrowband";
189       if (wideband)
190          op.packet = (unsigned char *)"speex wideband**";
191       op.bytes = 16;
192       op.b_o_s = 1;
193       op.e_o_s = 0;
194       op.granulepos = 0;
195       op.packetno = 0;
196       ogg_stream_packetin(&os, &op);
197
198       while((result = ogg_stream_flush(&os, &og)))
199       {
200          if(!result) break;
201          ret = oe_write_page(&og, fout);
202          if(ret != og.header_len + og.body_len)
203          {
204             fprintf (stderr,"Failed writing header to output stream\n");
205             exit(1);
206          }
207          else
208             bytes_written += ret;
209       }
210    }
211
212    frame_size=mode->frameSize;
213
214    /*Main encoding loop (one frame per iteration)*/
215    while (1)
216    {
217       id++;
218       /*Read input audio*/
219       fread(in, sizeof(short), frame_size, fin);
220       if (feof(fin))
221          break;
222       for (i=0;i<frame_size;i++)
223          input[i]=in[i];
224       /*Encode current frame*/
225       encode(st, input, &bits);
226
227       /*if (id%5!=0)
228         continue;*/
229       nbBytes = speex_bits_write(&bits, cbits, 500);
230       speex_bits_reset(&bits);
231       op.packet = (unsigned char *)cbits;
232       op.bytes = nbBytes;
233       op.b_o_s = 0;
234       op.e_o_s = 0;
235       op.granulepos = id;
236       op.packetno = id;
237       ogg_stream_packetin(&os, &op);
238
239       /*Write all new pages (not likely 0 or 1)*/
240       while (ogg_stream_pageout(&os,&og))
241       {
242          ret = oe_write_page(&og, fout);
243          if(ret != og.header_len + og.body_len)
244          {
245             fprintf (stderr,"Failed writing header to output stream\n");
246             exit(1);
247          }
248          else
249             bytes_written += ret;
250       }
251    }
252    
253    op.packet = (unsigned char *)"END OF STREAM";
254    op.bytes = 13;
255    op.b_o_s = 0;
256    op.e_o_s = 1;
257    op.granulepos = id+1;
258    op.packetno = id+1;
259    ogg_stream_packetin(&os, &op);
260    /*Flush all pages left to be written*/
261    while (ogg_stream_flush(&os, &og))
262    {
263       ret = oe_write_page(&og, fout);
264       if(ret != og.header_len + og.body_len)
265       {
266          fprintf (stderr,"Failed writing header to output stream\n");
267          exit(1);
268       }
269       else
270          bytes_written += ret;
271    }
272    
273
274    encoder_destroy(st);
275
276    ogg_stream_clear(&os);
277
278    exit(0);
279    return 1;
280 }
281