diff options
Diffstat (limited to 'lib/rbcodec/codecs/libopus/celt/opus_custom_demo.c')
-rw-r--r-- | lib/rbcodec/codecs/libopus/celt/opus_custom_demo.c | 210 |
1 files changed, 210 insertions, 0 deletions
diff --git a/lib/rbcodec/codecs/libopus/celt/opus_custom_demo.c b/lib/rbcodec/codecs/libopus/celt/opus_custom_demo.c new file mode 100644 index 0000000000..ae41c0de5a --- /dev/null +++ b/lib/rbcodec/codecs/libopus/celt/opus_custom_demo.c | |||
@@ -0,0 +1,210 @@ | |||
1 | /* Copyright (c) 2007-2008 CSIRO | ||
2 | Copyright (c) 2007-2009 Xiph.Org Foundation | ||
3 | Written by Jean-Marc Valin */ | ||
4 | /* | ||
5 | Redistribution and use in source and binary forms, with or without | ||
6 | modification, are permitted provided that the following conditions | ||
7 | are met: | ||
8 | |||
9 | - Redistributions of source code must retain the above copyright | ||
10 | notice, this list of conditions and the following disclaimer. | ||
11 | |||
12 | - Redistributions in binary form must reproduce the above copyright | ||
13 | notice, this list of conditions and the following disclaimer in the | ||
14 | documentation and/or other materials provided with the distribution. | ||
15 | |||
16 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | ||
17 | ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | ||
18 | LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR | ||
19 | A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER | ||
20 | OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, | ||
21 | EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, | ||
22 | PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR | ||
23 | PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF | ||
24 | LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING | ||
25 | NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS | ||
26 | SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||
27 | */ | ||
28 | |||
29 | #ifdef HAVE_CONFIG_H | ||
30 | #include "config.h" | ||
31 | #endif | ||
32 | |||
33 | #include "opus_custom.h" | ||
34 | #include "arch.h" | ||
35 | #include <stdio.h> | ||
36 | #include <stdlib.h> | ||
37 | #include <math.h> | ||
38 | #include <string.h> | ||
39 | |||
40 | #define MAX_PACKET 1275 | ||
41 | |||
42 | int main(int argc, char *argv[]) | ||
43 | { | ||
44 | int err; | ||
45 | char *inFile, *outFile; | ||
46 | FILE *fin, *fout; | ||
47 | OpusCustomMode *mode=NULL; | ||
48 | OpusCustomEncoder *enc; | ||
49 | OpusCustomDecoder *dec; | ||
50 | int len; | ||
51 | opus_int32 frame_size, channels, rate; | ||
52 | int bytes_per_packet; | ||
53 | unsigned char data[MAX_PACKET]; | ||
54 | int complexity; | ||
55 | #if !(defined (FIXED_POINT) && !defined(CUSTOM_MODES)) && defined(RESYNTH) | ||
56 | int i; | ||
57 | double rmsd = 0; | ||
58 | #endif | ||
59 | int count = 0; | ||
60 | opus_int32 skip; | ||
61 | opus_int16 *in, *out; | ||
62 | if (argc != 9 && argc != 8 && argc != 7) | ||
63 | { | ||
64 | fprintf (stderr, "Usage: test_opus_custom <rate> <channels> <frame size> " | ||
65 | " <bytes per packet> [<complexity> [packet loss rate]] " | ||
66 | "<input> <output>\n"); | ||
67 | return 1; | ||
68 | } | ||
69 | |||
70 | rate = (opus_int32)atol(argv[1]); | ||
71 | channels = atoi(argv[2]); | ||
72 | frame_size = atoi(argv[3]); | ||
73 | mode = opus_custom_mode_create(rate, frame_size, NULL); | ||
74 | if (mode == NULL) | ||
75 | { | ||
76 | fprintf(stderr, "failed to create a mode\n"); | ||
77 | return 1; | ||
78 | } | ||
79 | |||
80 | bytes_per_packet = atoi(argv[4]); | ||
81 | if (bytes_per_packet < 0 || bytes_per_packet > MAX_PACKET) | ||
82 | { | ||
83 | fprintf (stderr, "bytes per packet must be between 0 and %d\n", | ||
84 | MAX_PACKET); | ||
85 | return 1; | ||
86 | } | ||
87 | |||
88 | inFile = argv[argc-2]; | ||
89 | fin = fopen(inFile, "rb"); | ||
90 | if (!fin) | ||
91 | { | ||
92 | fprintf (stderr, "Could not open input file %s\n", argv[argc-2]); | ||
93 | return 1; | ||
94 | } | ||
95 | outFile = argv[argc-1]; | ||
96 | fout = fopen(outFile, "wb+"); | ||
97 | if (!fout) | ||
98 | { | ||
99 | fprintf (stderr, "Could not open output file %s\n", argv[argc-1]); | ||
100 | fclose(fin); | ||
101 | return 1; | ||
102 | } | ||
103 | |||
104 | enc = opus_custom_encoder_create(mode, channels, &err); | ||
105 | if (err != 0) | ||
106 | { | ||
107 | fprintf(stderr, "Failed to create the encoder: %s\n", opus_strerror(err)); | ||
108 | fclose(fin); | ||
109 | fclose(fout); | ||
110 | return 1; | ||
111 | } | ||
112 | dec = opus_custom_decoder_create(mode, channels, &err); | ||
113 | if (err != 0) | ||
114 | { | ||
115 | fprintf(stderr, "Failed to create the decoder: %s\n", opus_strerror(err)); | ||
116 | fclose(fin); | ||
117 | fclose(fout); | ||
118 | return 1; | ||
119 | } | ||
120 | opus_custom_decoder_ctl(dec, OPUS_GET_LOOKAHEAD(&skip)); | ||
121 | |||
122 | if (argc>7) | ||
123 | { | ||
124 | complexity=atoi(argv[5]); | ||
125 | opus_custom_encoder_ctl(enc,OPUS_SET_COMPLEXITY(complexity)); | ||
126 | } | ||
127 | |||
128 | in = (opus_int16*)malloc(frame_size*channels*sizeof(opus_int16)); | ||
129 | out = (opus_int16*)malloc(frame_size*channels*sizeof(opus_int16)); | ||
130 | |||
131 | while (!feof(fin)) | ||
132 | { | ||
133 | int ret; | ||
134 | err = fread(in, sizeof(short), frame_size*channels, fin); | ||
135 | if (feof(fin)) | ||
136 | break; | ||
137 | len = opus_custom_encode(enc, in, frame_size, data, bytes_per_packet); | ||
138 | if (len <= 0) | ||
139 | fprintf (stderr, "opus_custom_encode() failed: %s\n", opus_strerror(len)); | ||
140 | |||
141 | /* This is for simulating bit errors */ | ||
142 | #if 0 | ||
143 | int errors = 0; | ||
144 | int eid = 0; | ||
145 | /* This simulates random bit error */ | ||
146 | for (i=0;i<len*8;i++) | ||
147 | { | ||
148 | if (rand()%atoi(argv[8])==0) | ||
149 | { | ||
150 | if (i<64) | ||
151 | { | ||
152 | errors++; | ||
153 | eid = i; | ||
154 | } | ||
155 | data[i/8] ^= 1<<(7-(i%8)); | ||
156 | } | ||
157 | } | ||
158 | if (errors == 1) | ||
159 | data[eid/8] ^= 1<<(7-(eid%8)); | ||
160 | else if (errors%2 == 1) | ||
161 | data[rand()%8] ^= 1<<rand()%8; | ||
162 | #endif | ||
163 | |||
164 | #if 1 /* Set to zero to use the encoder's output instead */ | ||
165 | /* This is to simulate packet loss */ | ||
166 | if (argc==9 && rand()%1000<atoi(argv[argc-3])) | ||
167 | /*if (errors && (errors%2==0))*/ | ||
168 | ret = opus_custom_decode(dec, NULL, len, out, frame_size); | ||
169 | else | ||
170 | ret = opus_custom_decode(dec, data, len, out, frame_size); | ||
171 | if (ret < 0) | ||
172 | fprintf(stderr, "opus_custom_decode() failed: %s\n", opus_strerror(ret)); | ||
173 | #else | ||
174 | for (i=0;i<ret*channels;i++) | ||
175 | out[i] = in[i]; | ||
176 | #endif | ||
177 | #if !(defined (FIXED_POINT) && !defined(CUSTOM_MODES)) && defined(RESYNTH) | ||
178 | for (i=0;i<ret*channels;i++) | ||
179 | { | ||
180 | rmsd += (in[i]-out[i])*1.0*(in[i]-out[i]); | ||
181 | /*out[i] -= in[i];*/ | ||
182 | } | ||
183 | #endif | ||
184 | count++; | ||
185 | fwrite(out+skip*channels, sizeof(short), (ret-skip)*channels, fout); | ||
186 | skip = 0; | ||
187 | } | ||
188 | PRINT_MIPS(stderr); | ||
189 | |||
190 | opus_custom_encoder_destroy(enc); | ||
191 | opus_custom_decoder_destroy(dec); | ||
192 | fclose(fin); | ||
193 | fclose(fout); | ||
194 | opus_custom_mode_destroy(mode); | ||
195 | free(in); | ||
196 | free(out); | ||
197 | #if !(defined (FIXED_POINT) && !defined(CUSTOM_MODES)) && defined(RESYNTH) | ||
198 | if (rmsd > 0) | ||
199 | { | ||
200 | rmsd = sqrt(rmsd/(1.0*frame_size*channels*count)); | ||
201 | fprintf (stderr, "Error: encoder doesn't match decoder\n"); | ||
202 | fprintf (stderr, "RMS mismatch is %f\n", rmsd); | ||
203 | return 1; | ||
204 | } else { | ||
205 | fprintf (stderr, "Encoder matches decoder!!\n"); | ||
206 | } | ||
207 | #endif | ||
208 | return 0; | ||
209 | } | ||
210 | |||