e5d32fb42aae6fd3d0c2892c23c5bd60339fa1df
[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 int oe_write_page(ogg_page *page, FILE *fp)
29 {
30         int written;
31         written = fwrite(page->header,1,page->header_len, fp);
32         written += fwrite(page->body,1,page->body_len, fp);
33
34         return written;
35 }
36
37 #define MAX_FRAME_SIZE 2000
38 #define MAX_FRAME_BYTES 1000
39
40 void usage()
41 {
42    fprintf (stderr, "speexenc [options] <input file> <output file>\n");
43    fprintf (stderr, "options:\n");
44    fprintf (stderr, "\t--narrowband -n    Narrowband (8 kHz) input file\n"); 
45    fprintf (stderr, "\t--wideband   -w    Wideband (16 kHz) input file\n"); 
46    fprintf (stderr, "\t--help       -h    This help\n"); 
47    fprintf (stderr, "\t--version    -v    Version information\n"); 
48    fprintf (stderr, "\nInput must be raw audio (no header), 16 bits\n"); 
49 }
50
51 void version()
52 {
53    fprintf (stderr, "Speex encoder version " VERSION "\n");
54 }
55
56 int main(int argc, char **argv)
57 {
58    int c;
59    int option_index = 0;
60    int narrowband=0, wideband=0;
61    char *inFile, *outFile;
62    FILE *fin, *fout;
63    short in[MAX_FRAME_SIZE];
64    float input[MAX_FRAME_SIZE];
65    int frame_size;
66    int i,nbBytes;
67    SpeexMode *mode=NULL;
68    void *st;
69    FrameBits bits;
70    char cbits[MAX_FRAME_BYTES];
71    struct option long_options[] =
72    {
73       {"wideband", no_argument, NULL, 0},
74       {"narrowband", no_argument, NULL, 0},
75       {"help", no_argument, NULL, 0},
76       {"version", no_argument, NULL, 0},
77       {0, 0, 0, 0}
78    };
79
80    ogg_stream_state os;
81    ogg_page              og;
82    ogg_packet            op;
83    int bytes_written, ret, result;
84    int id=0;
85
86    /*Process command-line options*/
87    while(1)
88    {
89       c = getopt_long (argc, argv, "nwhv",
90                        long_options, &option_index);
91       if (c==-1)
92          break;
93       
94       switch(c)
95       {
96       case 0:
97          if (strcmp(long_options[option_index].name,"narrowband")==0)
98             narrowband=1;
99          else if (strcmp(long_options[option_index].name,"wideband")==0)
100                wideband=1;
101          else if (strcmp(long_options[option_index].name,"help")==0)
102          {
103             usage();
104             exit(0);
105          } else if (strcmp(long_options[option_index].name,"version")==0)
106          {
107             version();
108             exit(0);
109          }
110          break;
111       case 'n':
112          narrowband=1;
113          break;
114       case 'h':
115          usage();
116          break;
117       case 'v':
118          version();
119          exit(0);
120          break;
121       case 'w':
122          wideband=1;
123          break;
124       case '?':
125          usage();
126          exit(1);
127          break;
128       }
129    }
130    if (argc-optind!=2)
131    {
132       usage();
133       exit(1);
134    }
135    inFile=argv[optind];
136    outFile=argv[optind+1];
137
138    /*Initialize Ogg stream struct*/
139    if (ogg_stream_init(&os, 0)==-1)
140    {
141       fprintf(stderr,"Stream init failed\n");
142       exit(1);
143    }
144
145    if (wideband && narrowband)
146    {
147       fprintf (stderr,"Cannot specify both wideband and narrowband at the same time\n");
148       exit(1);
149    };
150    if (!wideband)
151       narrowband=1;
152    if (narrowband)
153       mode=&speex_nb_mode;
154    if (wideband)
155       mode=&speex_wb_mode;
156
157    /*Initialize Speex encoder*/
158    st = encoder_init(mode);
159
160    if (strcmp(inFile, "-")==0)
161       fin=stdin;
162    else 
163    {
164       fin = fopen(inFile, "r");
165       if (!fin)
166       {
167          perror(inFile);
168          exit(1);
169       }
170    }
171    if (strcmp(outFile,"-")==0)
172       fout=stdout;
173    else 
174    {
175       fout = fopen(outFile, "w");
176       if (!fout)
177       {
178          perror(outFile);
179          exit(1);
180       }
181    }
182
183    /*Write header (format will change)*/
184    {
185
186       if (narrowband)
187          op.packet = (unsigned char *)"speex narrowband";
188       if (wideband)
189          op.packet = (unsigned char *)"speex wideband**";
190       op.bytes = 16;
191       op.b_o_s = 1;
192       op.e_o_s = 0;
193       op.granulepos = 0;
194       op.packetno = 0;
195       ogg_stream_packetin(&os, &op);
196
197       while((result = ogg_stream_flush(&os, &og)))
198       {
199          if(!result) break;
200          ret = oe_write_page(&og, fout);
201          if(ret != og.header_len + og.body_len)
202          {
203             fprintf (stderr,"Failed writing header to output stream\n");
204             exit(1);
205          }
206          else
207             bytes_written += ret;
208       }
209    }
210
211    frame_size=mode->frameSize;
212
213    /*Main encoding loop (one frame per iteration)*/
214    while (1)
215    {
216       id++;
217       /*Read input audio*/
218       fread(in, sizeof(short), frame_size, fin);
219       if (feof(fin))
220          break;
221       for (i=0;i<frame_size;i++)
222          input[i]=in[i];
223       /*Encode current frame*/
224       encode(st, input, &bits);
225
226       /*if (id%5!=0)
227         continue;*/
228       nbBytes = speex_bits_write(&bits, cbits, 500);
229       speex_bits_reset(&bits);
230       op.packet = (unsigned char *)cbits;
231       op.bytes = nbBytes;
232       op.b_o_s = 0;
233       op.e_o_s = 0;
234       op.granulepos = id;
235       op.packetno = id;
236       ogg_stream_packetin(&os, &op);
237
238       while (ogg_stream_pageout(&os,&og))
239       {
240          ret = oe_write_page(&og, fout);
241          if(ret != og.header_len + og.body_len)
242          {
243             fprintf (stderr,"Failed writing header to output stream\n");
244             exit(1);
245          }
246          else
247             bytes_written += ret;
248       }
249    }
250    
251    op.packet = (unsigned char *)"END OF STREAM";
252    op.bytes = 13;
253    op.b_o_s = 0;
254    op.e_o_s = 1;
255    op.granulepos = id+1;
256    op.packetno = id+1;
257    ogg_stream_packetin(&os, &op);
258    while (ogg_stream_flush(&os, &og))
259    {
260       ret = oe_write_page(&og, fout);
261       if(ret != og.header_len + og.body_len)
262       {
263          fprintf (stderr,"Failed writing header to output stream\n");
264          exit(1);
265       }
266       else
267          bytes_written += ret;
268    }
269    
270
271    encoder_destroy(st);
272
273    ogg_stream_clear(&os);
274
275    exit(0);
276    return 1;
277 }
278