Remove redundant mid-only flag when side VAD flag is set.
[opus.git] / celt / test_opus_custom.c
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 FOUNDATION OR
20    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       return 1;
101    }
102    
103    enc = opus_custom_encoder_create(mode, channels, &err);
104    if (err != 0)
105    {
106       fprintf(stderr, "Failed to create the encoder: %s\n", opus_strerror(err));
107       return 1;
108    }
109    dec = opus_custom_decoder_create(mode, channels, &err);
110    if (err != 0)
111    {
112       fprintf(stderr, "Failed to create the decoder: %s\n", opus_strerror(err));
113       return 1;
114    }
115    opus_custom_decoder_ctl(dec, OPUS_GET_LOOKAHEAD(&skip));
116
117    if (argc>7)
118    {
119       complexity=atoi(argv[5]);
120       opus_custom_encoder_ctl(enc,OPUS_SET_COMPLEXITY(complexity));
121    }
122    
123    in = (opus_int16*)malloc(frame_size*channels*sizeof(opus_int16));
124    out = (opus_int16*)malloc(frame_size*channels*sizeof(opus_int16));
125
126    while (!feof(fin))
127    {
128       int ret;
129       err = fread(in, sizeof(short), frame_size*channels, fin);
130       if (feof(fin))
131          break;
132       len = opus_custom_encode(enc, in, frame_size, data, bytes_per_packet);
133       if (len <= 0)
134          fprintf (stderr, "opus_custom_encode() failed: %s\n", opus_strerror(len));
135
136       /* This is for simulating bit errors */
137 #if 0
138       int errors = 0;
139       int eid = 0;
140       /* This simulates random bit error */
141       for (i=0;i<len*8;i++)
142       {
143          if (rand()%atoi(argv[8])==0)
144          {
145             if (i<64)
146             {
147                errors++;
148                eid = i;
149             }
150             data[i/8] ^= 1<<(7-(i%8));
151          }
152       }
153       if (errors == 1)
154          data[eid/8] ^= 1<<(7-(eid%8));
155       else if (errors%2 == 1)
156          data[rand()%8] ^= 1<<rand()%8;
157 #endif
158
159 #if 1 /* Set to zero to use the encoder's output instead */
160       /* This is to simulate packet loss */
161       if (argc==9 && rand()%1000<atoi(argv[argc-3]))
162       /*if (errors && (errors%2==0))*/
163          ret = opus_custom_decode(dec, NULL, len, out, frame_size);
164       else
165          ret = opus_custom_decode(dec, data, len, out, frame_size);
166       if (ret < 0)
167          fprintf(stderr, "opus_custom_decode() failed: %s\n", opus_strerror(ret));
168 #else
169       for (i=0;i<ret*channels;i++)
170          out[i] = in[i];
171 #endif
172 #if !(defined (FIXED_POINT) && !defined(CUSTOM_MODES)) && defined(RESYNTH)
173       for (i=0;i<ret*channels;i++)
174       {
175          rmsd += (in[i]-out[i])*1.0*(in[i]-out[i]);
176          /*out[i] -= in[i];*/
177       }
178 #endif
179       count++;
180       fwrite(out+skip*channels, sizeof(short), (ret-skip)*channels, fout);
181       skip = 0;
182    }
183    PRINT_MIPS(stderr);
184    
185    opus_custom_encoder_destroy(enc);
186    opus_custom_decoder_destroy(dec);
187    fclose(fin);
188    fclose(fout);
189    opus_custom_mode_destroy(mode);
190    free(in);
191    free(out);
192 #if !(defined (FIXED_POINT) && !defined(CUSTOM_MODES)) && defined(RESYNTH)
193    if (rmsd > 0)
194    {
195       rmsd = sqrt(rmsd/(1.0*frame_size*channels*count));
196       fprintf (stderr, "Error: encoder doesn't match decoder\n");
197       fprintf (stderr, "RMS mismatch is %f\n", rmsd);
198       return 1;
199    } else {
200       fprintf (stderr, "Encoder matches decoder!!\n");
201    }
202 #endif
203    return 0;
204 }
205