summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDominik Wenger <domonoky@googlemail.com>2007-12-14 16:04:38 +0000
committerDominik Wenger <domonoky@googlemail.com>2007-12-14 16:04:38 +0000
commited047d9db1dcee92afb8fe6bacb5d90ccb39481e (patch)
tree163bfbbf5316f4e92315c726516515eb4f04a120
parentb2f7c61f84191d3d15606400165efe931bb66d2a (diff)
downloadrockbox-ed047d9db1dcee92afb8fe6bacb5d90ccb39481e.tar.gz
rockbox-ed047d9db1dcee92afb8fe6bacb5d90ccb39481e.zip
refactor rbspeex, so we build a librbspeex.a for linking into rbutil.
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@15924 a1c6a512-1295-4272-9138-f99709370657
-rw-r--r--tools/rbspeex/Makefile19
-rw-r--r--tools/rbspeex/rbspeex.c261
-rw-r--r--tools/rbspeex/rbspeex.h34
-rw-r--r--tools/rbspeex/rbspeexdec.c14
-rw-r--r--tools/rbspeex/rbspeexenc.c221
5 files changed, 309 insertions, 240 deletions
diff --git a/tools/rbspeex/Makefile b/tools/rbspeex/Makefile
index f6e70def96..a2b6725f5d 100644
--- a/tools/rbspeex/Makefile
+++ b/tools/rbspeex/Makefile
@@ -26,7 +26,7 @@ endif
26# This sets up 'SRC' based on the files mentioned in SOURCES 26# This sets up 'SRC' based on the files mentioned in SOURCES
27SRC := $(shell cat $(SPEEXSRC)/SOURCES | $(CC) $(CFLAGS) -E -P - | grep -v "^\#") 27SRC := $(shell cat $(SPEEXSRC)/SOURCES | $(CC) $(CFLAGS) -E -P - | grep -v "^\#")
28 28
29SOURCES = $(SRC:%.c=$(SPEEXSRC)/%.c) rbspeexenc.c rbspeexdec.c 29SOURCES = $(SRC:%.c=$(SPEEXSRC)/%.c) rbspeex.c rbspeexenc.c rbspeexdec.c
30OBJS := $(SRC:%.c=%.o) 30OBJS := $(SRC:%.c=%.o)
31DEPFILE = dep-speex 31DEPFILE = dep-speex
32DIRS = 32DIRS =
@@ -49,23 +49,24 @@ $(DEPFILE): $(SOURCES)
49 done > $(DEPFILE); \ 49 done > $(DEPFILE); \
50 echo "oo" > /dev/null ) 50 echo "oo" > /dev/null )
51 51
52libspeex.a: $(OBJS) $(DEPFILE) 52librbspeex.a: $(OBJS) $(DEPFILE) rbspeex.o
53 @echo AR libspeex.a 53 @echo AR librbspeex.a
54 $(SILENT)$(AR) ruv $@ $+ > /dev/null 2>&1 54 $(AR) ruv $@ $+ > /dev/null 2>&1
55 55
56../rbspeexenc: $(OBJS) libspeex.a rbspeexenc.o 56../rbspeexenc: $(OBJS) rbspeexenc.o librbspeex.a
57 @echo Linking ../rbspeexenc 57 @echo Linking ../rbspeexenc
58 $(SILENT)$(CC) $(CFLAGS) -o ../rbspeexenc rbspeexenc.o libspeex.a -lm 58 $(SILENT)$(CC) $(CFLAGS) -o ../rbspeexenc rbspeexenc.o librbspeex.a -lm
59 59
60../rbspeexdec: $(OBJS) libspeex.a rbspeexdec.o 60../rbspeexdec: $(OBJS) librbspeex.a rbspeexdec.o
61 @echo Linking ../rbspeexdec 61 @echo Linking ../rbspeexdec
62 $(SILENT)$(CC) $(CFLAGS) -o ../rbspeexdec rbspeexdec.o libspeex.a -lm 62 $(SILENT)$(CC) $(CFLAGS) -o ../rbspeexdec rbspeexdec.o librbspeex.a -lm
63 63
64%.o: 64%.o:
65 @echo CC $< 65 @echo CC $<
66 $(SILENT)$(CC) $(CFLAGS) -c $< -o $@ 66 $(SILENT)$(CC) $(CFLAGS) -c $< -o $@
67 67
68
68clean: 69clean:
69 rm -f $(OBJS) libspeex.a rbspeexenc.o ../rbspeexenc dep-speex 70 rm -f $(OBJS) libspeex.a librbspeex.a rbspeexenc.o ../rbspeexenc dep-speex
70 71
71-include $(DEPFILE) 72-include $(DEPFILE)
diff --git a/tools/rbspeex/rbspeex.c b/tools/rbspeex/rbspeex.c
new file mode 100644
index 0000000000..e211b9606a
--- /dev/null
+++ b/tools/rbspeex/rbspeex.c
@@ -0,0 +1,261 @@
1/**************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 *
9 * Copyright (C) 2007 Thom Johansen
10 *
11 * All files in this archive are subject to the GNU General Public License.
12 * See the file COPYING in the source tree root for full license agreement.
13 *
14 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
15 * KIND, either express or implied.
16 *
17 ***************************************************************************/
18
19#include <speex/speex.h>
20#include <speex/speex_resampler.h>
21#include <stdio.h>
22#include <stdlib.h>
23#include <string.h>
24#include <stdbool.h>
25
26#include "rbspeex.h"
27
28/* Read an unaligned 32-bit little endian long from buffer. */
29unsigned int get_long_le(unsigned char *p)
30{
31 return p[0] | (p[1] << 8) | (p[2] << 16) | (p[3] << 24);
32}
33
34void put_ushort_le(unsigned short x, unsigned char *out)
35{
36 out[0] = x & 0xff;
37 out[1] = x >> 8;
38}
39
40void put_uint_le(unsigned int x, unsigned char *out)
41{
42 out[0] = x & 0xff;
43 out[1] = (x >> 8) & 0xff;
44 out[2] = (x >> 16) & 0xff;
45 out[3] = x >> 24;
46}
47
48
49
50bool get_wave_metadata(FILE *fd, int *numchan, int *bps, int *sr, int *numsamples)
51{
52 unsigned char buf[1024];
53 unsigned long totalsamples = 0;
54 unsigned long channels = 0;
55 unsigned long bitspersample = 0;
56 unsigned long numbytes = 0;
57 size_t read_bytes;
58 int i;
59
60 if ((read_bytes = fread(buf, 1, 12, fd)) < 12)
61 return false;
62
63 if ((memcmp(buf, "RIFF",4) != 0) || (memcmp(&buf[8], "WAVE", 4) != 0))
64 return false;
65
66 /* iterate over WAVE chunks until 'data' chunk */
67 while (1) {
68 /* get chunk header */
69 if ((read_bytes = fread(buf, 1, 8, fd)) < 8)
70 return false;
71
72 /* chunkSize */
73 i = get_long_le(&buf[4]);
74
75 if (memcmp(buf, "fmt ", 4) == 0) {
76 /* get rest of chunk */
77 if ((read_bytes = fread(buf, 1, 16, fd)) < 16)
78 return false;
79
80 i -= 16;
81
82 channels = *numchan = buf[2] | (buf[3] << 8);
83 *sr = get_long_le(&buf[4]);
84 /* wBitsPerSample */
85 bitspersample = *bps = buf[14] | (buf[15] << 8);
86 } else if (memcmp(buf, "data", 4) == 0) {
87 numbytes = i;
88 break;
89 } else if (memcmp(buf, "fact", 4) == 0) {
90 /* dwSampleLength */
91 if (i >= 4) {
92 /* get rest of chunk */
93 if ((read_bytes = fread(buf, 1, 4, fd)) < 4)
94 return false;
95
96 i -= 4;
97 totalsamples = get_long_le(buf);
98 }
99 }
100
101 /* seek to next chunk (even chunk sizes must be padded) */
102 if (i & 0x01)
103 i++;
104
105 if (fseek(fd, i, SEEK_CUR) < 0)
106 return false;
107 }
108
109 if ((numbytes == 0) || (channels == 0))
110 return false;
111
112 if (totalsamples == 0) {
113 /* for PCM only */
114 totalsamples = numbytes/((((bitspersample - 1) / 8) + 1)*channels);
115 }
116 *numsamples = totalsamples;
117 return true;
118}
119
120/* We'll eat an entire WAV file here, and encode it with Speex, packing the
121 * bits as tightly as we can. Output is completely raw, with absolutely
122 * nothing to identify the contents. Files are left open, so remember to close
123 * them.
124 */
125bool encode_file(FILE *fin, FILE *fout, float quality, int complexity,
126 bool narrowband, float volume, char *errstr, size_t errlen)
127{
128 spx_int16_t *in = NULL, *inpos;
129 spx_int16_t enc_buf[640]; /* Max frame size */
130 char cbits[200];
131 void *st = NULL;
132 SpeexResamplerState *resampler = NULL;
133 SpeexBits bits;
134 int i, tmp, target_sr, numchan, bps, sr, numsamples, frame_size, lookahead;
135 int nbytes;
136 bool ret = true;
137
138 if (!get_wave_metadata(fin, &numchan, &bps, &sr, &numsamples)) {
139 snprintf(errstr, errlen, "invalid WAV file");
140 return false;
141 }
142 if (numchan != 1) {
143 snprintf(errstr, errlen, "input file must be mono");
144 return false;
145 }
146 if (bps != 16) {
147 snprintf(errstr, errlen, "samples must be 16 bit");
148 return false;
149 }
150
151 /* Allocate an encoder of specified type, defaults to wideband */
152 st = speex_encoder_init(narrowband ? &speex_nb_mode : &speex_wb_mode);
153 if (narrowband)
154 target_sr = 8000;
155 else
156 target_sr = 16000;
157 speex_bits_init(&bits);
158
159 /* VBR */
160 tmp = 1;
161 speex_encoder_ctl(st, SPEEX_SET_VBR, &tmp);
162 /* Quality, 0-10 */
163 speex_encoder_ctl(st, SPEEX_SET_VBR_QUALITY, &quality);
164 /* Complexity, 0-10 */
165 speex_encoder_ctl(st, SPEEX_SET_COMPLEXITY, &complexity);
166 speex_encoder_ctl(st, SPEEX_GET_FRAME_SIZE, &frame_size);
167 speex_encoder_ctl(st, SPEEX_GET_LOOKAHEAD, &lookahead);
168
169 /* Read input samples into a buffer */
170 in = calloc(numsamples + lookahead, sizeof(spx_int16_t));
171 if (in == NULL) {
172 snprintf(errstr, errlen, "could not allocate clip memory");
173 ret = false;
174 goto finish;
175 }
176 if (fread(in, 2, numsamples, fin) != numsamples) {
177 snprintf(errstr, errlen, "could not read input file data");
178 ret = false;
179 goto finish;
180 }
181
182 if (volume != 1.0f) {
183 for (i = 0; i < numsamples; ++i)
184 in[i] *= volume;
185 }
186
187 if (sr != target_sr) {
188 resampler = speex_resampler_init(1, sr, target_sr, 10, NULL);
189 speex_resampler_skip_zeros(resampler);
190 }
191
192 /* There will be 'lookahead' samples of zero at the end of the array, to
193 * make sure the Speex encoder is allowed to spit out all its data at clip
194 * end */
195 numsamples += lookahead;
196
197 inpos = in;
198 while (numsamples > 0) {
199 int samples = frame_size;
200
201 /* Check if we need to resample */
202 if (sr != target_sr) {
203 spx_uint32_t in_len = numsamples, out_len = frame_size;
204 double resample_factor = (double)sr/(double)target_sr;
205 /* Calculate how many input samples are needed for one full frame
206 * out, and add some, just in case. */
207 spx_uint32_t samples_in = frame_size*resample_factor + 50;
208
209 /* Limit this or resampler will try to allocate it all on stack */
210 if (in_len > samples_in)
211 in_len = samples_in;
212 speex_resampler_process_int(resampler, 0, inpos, &in_len,
213 enc_buf, &out_len);
214 inpos += in_len;
215 samples = out_len;
216 numsamples -= in_len;
217 } else {
218 if (samples > numsamples)
219 samples = numsamples;
220 memcpy(enc_buf, inpos, samples*2);
221 inpos += frame_size;
222 numsamples -= frame_size;
223 }
224 /* Pad out with zeros if we didn't fill all input */
225 memset(enc_buf + samples, 0, (frame_size - samples)*2);
226
227 if (speex_encode_int(st, enc_buf, &bits) < 0) {
228 snprintf(errstr, errlen, "encoder error");
229 ret = false;
230 goto finish;
231 }
232
233 /* Copy the bits to an array of char that can be written */
234 nbytes = speex_bits_write_whole_bytes(&bits, cbits, 200);
235
236 /* Write the compressed data */
237 if (fwrite(cbits, 1, nbytes, fout) != nbytes) {
238 snprintf(errstr, errlen, "could not write output data");
239 ret = false;
240 goto finish;
241 }
242 }
243 /* Squeeze out the last bits */
244 nbytes = speex_bits_write(&bits, cbits, 200);
245 if (fwrite(cbits, 1, nbytes, fout) != nbytes) {
246 snprintf(errstr, errlen, "could not write output data");
247 ret = false;
248 }
249
250finish:
251 if (st != NULL)
252 speex_encoder_destroy(st);
253 speex_bits_destroy(&bits);
254 if (resampler != NULL)
255 speex_resampler_destroy(resampler);
256 if (in != NULL)
257 free(in);
258 return ret;
259}
260
261
diff --git a/tools/rbspeex/rbspeex.h b/tools/rbspeex/rbspeex.h
new file mode 100644
index 0000000000..00d045c74a
--- /dev/null
+++ b/tools/rbspeex/rbspeex.h
@@ -0,0 +1,34 @@
1/**************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 *
9 * Copyright (C) 2007 Thom Johansen
10 *
11 * All files in this archive are subject to the GNU General Public License.
12 * See the file COPYING in the source tree root for full license agreement.
13 *
14 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
15 * KIND, either express or implied.
16 *
17 ***************************************************************************/
18
19#ifndef RBSPEEX_H
20#define RBSPEEX_H
21
22#include <stdbool.h>
23
24unsigned int get_long_le(unsigned char *p);
25bool get_wave_metadata(FILE *fd, int *numchan, int *bps, int *sr, int *numsamples);
26bool encode_file(FILE *fin, FILE *fout, float quality, int complexity,
27 bool narrowband, float volume, char *errstr, size_t errlen);
28
29void put_ushort_le(unsigned short x, unsigned char *out);
30void put_uint_le(unsigned int x, unsigned char *out);
31
32
33#endif
34
diff --git a/tools/rbspeex/rbspeexdec.c b/tools/rbspeex/rbspeexdec.c
index 90562f7309..a29361da3a 100644
--- a/tools/rbspeex/rbspeexdec.c
+++ b/tools/rbspeex/rbspeexdec.c
@@ -20,25 +20,13 @@
20#include <stdio.h> 20#include <stdio.h>
21#include <stdlib.h> 21#include <stdlib.h>
22#include "string.h" 22#include "string.h"
23#include "rbspeex.h"
23 24
24 #define USAGE_TEXT \ 25 #define USAGE_TEXT \
25"Usage: rbspeexdec infile outfile\n"\ 26"Usage: rbspeexdec infile outfile\n"\
26"rbspeexdec outputs mono 16 bit 16 kHz WAV files.\n"\ 27"rbspeexdec outputs mono 16 bit 16 kHz WAV files.\n"\
27"WARNING: This tool will only decode files made with rbspeexenc!\n" 28"WARNING: This tool will only decode files made with rbspeexenc!\n"
28 29
29void put_ushort_le(unsigned short x, unsigned char *out)
30{
31 out[0] = x & 0xff;
32 out[1] = x >> 8;
33}
34
35void put_uint_le(unsigned int x, unsigned char *out)
36{
37 out[0] = x & 0xff;
38 out[1] = (x >> 8) & 0xff;
39 out[2] = (x >> 16) & 0xff;
40 out[3] = x >> 24;
41}
42 30
43int main(int argc, char **argv) 31int main(int argc, char **argv)
44{ 32{
diff --git a/tools/rbspeex/rbspeexenc.c b/tools/rbspeex/rbspeexenc.c
index e919bc8990..c7ea6e429a 100644
--- a/tools/rbspeex/rbspeexenc.c
+++ b/tools/rbspeex/rbspeexenc.c
@@ -16,13 +16,13 @@
16 * 16 *
17 ***************************************************************************/ 17 ***************************************************************************/
18 18
19#include <speex/speex.h>
20#include <speex/speex_resampler.h>
21#include <stdio.h> 19#include <stdio.h>
22#include <stdlib.h> 20#include <stdlib.h>
23#include <string.h> 21#include <string.h>
24#include <stdbool.h> 22#include <stdbool.h>
25 23
24#include "rbspeex.h"
25
26#define USAGE_TEXT \ 26#define USAGE_TEXT \
27"Usage: rbspeexenc [options] infile outfile\n"\ 27"Usage: rbspeexenc [options] infile outfile\n"\
28"Options:\n"\ 28"Options:\n"\
@@ -35,222 +35,6 @@
35"to either 16 kHz by default, or 8 kHz if narrowband mode is enabled.\n"\ 35"to either 16 kHz by default, or 8 kHz if narrowband mode is enabled.\n"\
36"WARNING: This tool will create files that are only usable by Rockbox!\n" 36"WARNING: This tool will create files that are only usable by Rockbox!\n"
37 37
38/* Read an unaligned 32-bit little endian long from buffer. */
39unsigned int get_long_le(unsigned char *p)
40{
41 return p[0] | (p[1] << 8) | (p[2] << 16) | (p[3] << 24);
42}
43
44bool get_wave_metadata(FILE *fd, int *numchan, int *bps, int *sr, int *numsamples)
45{
46 unsigned char buf[1024];
47 unsigned long totalsamples = 0;
48 unsigned long channels = 0;
49 unsigned long bitspersample = 0;
50 unsigned long numbytes = 0;
51 size_t read_bytes;
52 int i;
53
54 if ((read_bytes = fread(buf, 1, 12, fd)) < 12)
55 return false;
56
57 if ((memcmp(buf, "RIFF",4) != 0) || (memcmp(&buf[8], "WAVE", 4) != 0))
58 return false;
59
60 /* iterate over WAVE chunks until 'data' chunk */
61 while (1) {
62 /* get chunk header */
63 if ((read_bytes = fread(buf, 1, 8, fd)) < 8)
64 return false;
65
66 /* chunkSize */
67 i = get_long_le(&buf[4]);
68
69 if (memcmp(buf, "fmt ", 4) == 0) {
70 /* get rest of chunk */
71 if ((read_bytes = fread(buf, 1, 16, fd)) < 16)
72 return false;
73
74 i -= 16;
75
76 channels = *numchan = buf[2] | (buf[3] << 8);
77 *sr = get_long_le(&buf[4]);
78 /* wBitsPerSample */
79 bitspersample = *bps = buf[14] | (buf[15] << 8);
80 } else if (memcmp(buf, "data", 4) == 0) {
81 numbytes = i;
82 break;
83 } else if (memcmp(buf, "fact", 4) == 0) {
84 /* dwSampleLength */
85 if (i >= 4) {
86 /* get rest of chunk */
87 if ((read_bytes = fread(buf, 1, 4, fd)) < 4)
88 return false;
89
90 i -= 4;
91 totalsamples = get_long_le(buf);
92 }
93 }
94
95 /* seek to next chunk (even chunk sizes must be padded) */
96 if (i & 0x01)
97 i++;
98
99 if (fseek(fd, i, SEEK_CUR) < 0)
100 return false;
101 }
102
103 if ((numbytes == 0) || (channels == 0))
104 return false;
105
106 if (totalsamples == 0) {
107 /* for PCM only */
108 totalsamples = numbytes/((((bitspersample - 1) / 8) + 1)*channels);
109 }
110 *numsamples = totalsamples;
111 return true;
112}
113
114/* We'll eat an entire WAV file here, and encode it with Speex, packing the
115 * bits as tightly as we can. Output is completely raw, with absolutely
116 * nothing to identify the contents. Files are left open, so remember to close
117 * them.
118 */
119bool encode_file(FILE *fin, FILE *fout, float quality, int complexity,
120 bool narrowband, float volume, char *errstr, size_t errlen)
121{
122 spx_int16_t *in = NULL, *inpos;
123 spx_int16_t enc_buf[640]; /* Max frame size */
124 char cbits[200];
125 void *st = NULL;
126 SpeexResamplerState *resampler = NULL;
127 SpeexBits bits;
128 int i, tmp, target_sr, numchan, bps, sr, numsamples, frame_size, lookahead;
129 int nbytes;
130 bool ret = true;
131
132 if (!get_wave_metadata(fin, &numchan, &bps, &sr, &numsamples)) {
133 snprintf(errstr, errlen, "invalid WAV file");
134 return false;
135 }
136 if (numchan != 1) {
137 snprintf(errstr, errlen, "input file must be mono");
138 return false;
139 }
140 if (bps != 16) {
141 snprintf(errstr, errlen, "samples must be 16 bit");
142 return false;
143 }
144
145 /* Allocate an encoder of specified type, defaults to wideband */
146 st = speex_encoder_init(narrowband ? &speex_nb_mode : &speex_wb_mode);
147 if (narrowband)
148 target_sr = 8000;
149 else
150 target_sr = 16000;
151 speex_bits_init(&bits);
152
153 /* VBR */
154 tmp = 1;
155 speex_encoder_ctl(st, SPEEX_SET_VBR, &tmp);
156 /* Quality, 0-10 */
157 speex_encoder_ctl(st, SPEEX_SET_VBR_QUALITY, &quality);
158 /* Complexity, 0-10 */
159 speex_encoder_ctl(st, SPEEX_SET_COMPLEXITY, &complexity);
160 speex_encoder_ctl(st, SPEEX_GET_FRAME_SIZE, &frame_size);
161 speex_encoder_ctl(st, SPEEX_GET_LOOKAHEAD, &lookahead);
162
163 /* Read input samples into a buffer */
164 in = calloc(numsamples + lookahead, sizeof(spx_int16_t));
165 if (in == NULL) {
166 snprintf(errstr, errlen, "could not allocate clip memory");
167 ret = false;
168 goto finish;
169 }
170 if (fread(in, 2, numsamples, fin) != numsamples) {
171 snprintf(errstr, errlen, "could not read input file data");
172 ret = false;
173 goto finish;
174 }
175
176 if (volume != 1.0f) {
177 for (i = 0; i < numsamples; ++i)
178 in[i] *= volume;
179 }
180
181 if (sr != target_sr) {
182 resampler = speex_resampler_init(1, sr, target_sr, 10, NULL);
183 speex_resampler_skip_zeros(resampler);
184 }
185
186 /* There will be 'lookahead' samples of zero at the end of the array, to
187 * make sure the Speex encoder is allowed to spit out all its data at clip
188 * end */
189 numsamples += lookahead;
190
191 inpos = in;
192 while (numsamples > 0) {
193 int samples = frame_size;
194
195 /* Check if we need to resample */
196 if (sr != target_sr) {
197 spx_uint32_t in_len = numsamples, out_len = frame_size;
198 double resample_factor = (double)sr/(double)target_sr;
199 /* Calculate how many input samples are needed for one full frame
200 * out, and add some, just in case. */
201 spx_uint32_t samples_in = frame_size*resample_factor + 50;
202
203 /* Limit this or resampler will try to allocate it all on stack */
204 if (in_len > samples_in)
205 in_len = samples_in;
206 speex_resampler_process_int(resampler, 0, inpos, &in_len,
207 enc_buf, &out_len);
208 inpos += in_len;
209 samples = out_len;
210 numsamples -= in_len;
211 } else {
212 if (samples > numsamples)
213 samples = numsamples;
214 memcpy(enc_buf, inpos, samples*2);
215 inpos += frame_size;
216 numsamples -= frame_size;
217 }
218 /* Pad out with zeros if we didn't fill all input */
219 memset(enc_buf + samples, 0, (frame_size - samples)*2);
220
221 if (speex_encode_int(st, enc_buf, &bits) < 0) {
222 snprintf(errstr, errlen, "encoder error");
223 ret = false;
224 goto finish;
225 }
226
227 /* Copy the bits to an array of char that can be written */
228 nbytes = speex_bits_write_whole_bytes(&bits, cbits, 200);
229
230 /* Write the compressed data */
231 if (fwrite(cbits, 1, nbytes, fout) != nbytes) {
232 snprintf(errstr, errlen, "could not write output data");
233 ret = false;
234 goto finish;
235 }
236 }
237 /* Squeeze out the last bits */
238 nbytes = speex_bits_write(&bits, cbits, 200);
239 if (fwrite(cbits, 1, nbytes, fout) != nbytes) {
240 snprintf(errstr, errlen, "could not write output data");
241 ret = false;
242 }
243
244finish:
245 if (st != NULL)
246 speex_encoder_destroy(st);
247 speex_bits_destroy(&bits);
248 if (resampler != NULL)
249 speex_resampler_destroy(resampler);
250 if (in != NULL)
251 free(in);
252 return ret;
253}
254 38
255int main(int argc, char **argv) 39int main(int argc, char **argv)
256{ 40{
@@ -308,3 +92,4 @@ int main(int argc, char **argv)
308 } 92 }
309 return 0; 93 return 0;
310} 94}
95