1/* 2** Copyright (C) 1999-2017 Erik de Castro Lopo <erikd@mega-nerd.com> 3** 4** This program is free software; you can redistribute it and/or modify 5** it under the terms of the GNU General Public License as published by 6** the Free Software Foundation; either version 2 of the License, or 7** (at your option) any later version. 8** 9** This program 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 12** GNU General Public License for more details. 13** 14** You should have received a copy of the GNU General Public License 15** along with this program; if not, write to the Free Software 16** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 17*/ 18 19#include "sfconfig.h" 20 21#include <stdio.h> 22#if HAVE_UNISTD_H 23#include <unistd.h> 24#else 25#include "sf_unistd.h" 26#endif 27#include <stdlib.h> 28#include <string.h> 29#include <math.h> 30 31#include "g72x.h" 32#include "g72x_priv.h" 33 34#ifndef M_PI 35#define M_PI 3.14159265358979323846264338 36#endif 37 38#define BUFFER_SIZE (1 << 14) 39#define SAMPLE_RATE 11025 40 41 42static void g721_test (void) ; 43static void g723_test (double margin) ; 44 45static void gen_signal_double (double *data, double scale, int datalen) ; 46static int error_function (double data, double orig, double margin) ; 47 48static int oct_save_short (short *a, short *b, int len) ; 49 50int 51main (int argc, char *argv []) 52{ int bDoAll = 0 ; 53 int nTests = 0 ; 54 55 if (argc != 2) 56 { printf ("Usage : %s <test>\n", argv [0]) ; 57 printf (" Where <test> is one of the following:\n") ; 58 printf (" g721 - test G721 encoder and decoder\n") ; 59 printf (" g723 - test G721 encoder and decoder\n") ; 60 printf (" all - perform all tests\n") ; 61 exit (1) ; 62 } ; 63 64 bDoAll = !strcmp (argv [1], "all") ; 65 66 if (bDoAll || ! strcmp (argv [1], "g721")) 67 { g721_test () ; 68 nTests++ ; 69 } ; 70 71 if (bDoAll || ! strcmp (argv [1], "g723")) 72 { g723_test (0.53) ; 73 nTests++ ; 74 } ; 75 76 if (nTests == 0) 77 { printf ("Mono : ************************************\n") ; 78 printf ("Mono : * No '%s' test defined.\n", argv [1]) ; 79 printf ("Mono : ************************************\n") ; 80 return 1 ; 81 } ; 82 83 return 0 ; 84} /* main */ 85 86static void 87g721_test (void) 88{ 89 return ; 90} /* g721_test */ 91 92static void 93g723_test (double margin) 94{ static double orig_buffer [BUFFER_SIZE] ; 95 static short orig [BUFFER_SIZE] ; 96 static short data [BUFFER_SIZE] ; 97 98 G72x_STATE encoder_state, decoder_state ; 99 100 long k ; 101 int code, position, max_err ; 102 103 private_init_state (&encoder_state) ; 104 encoder_state.encoder = g723_24_encoder ; 105 encoder_state.codec_bits = 3 ; 106 107 private_init_state (&decoder_state) ; 108 decoder_state.decoder = g723_24_decoder ; 109 decoder_state.codec_bits = 3 ; 110 111 memset (data, 0, BUFFER_SIZE * sizeof (short)) ; 112 memset (orig, 0, BUFFER_SIZE * sizeof (short)) ; 113 114 printf (" g723_test : ") ; 115 fflush (stdout) ; 116 117 gen_signal_double (orig_buffer, 32000.0, BUFFER_SIZE) ; 118 for (k = 0 ; k < BUFFER_SIZE ; k++) 119 orig [k] = (short) orig_buffer [k] ; 120 121 /* Write and read data here. */ 122 position = 0 ; 123 max_err = 0 ; 124 for (k = 0 ; k < BUFFER_SIZE ; k++) 125 { code = encoder_state.encoder (orig [k], &encoder_state) ; 126 data [k] = decoder_state.decoder (code, &decoder_state) ; 127 if (abs (orig [k] - data [k]) > max_err) 128 { position = k ; 129 max_err = abs (orig [k] - data [k]) ; 130 } ; 131 } ; 132 133 printf ("\n\nMax error of %d at postion %d.\n", max_err, position) ; 134 135 for (k = 0 ; k < BUFFER_SIZE ; k++) 136 { if (error_function (data [k], orig [k], margin)) 137 { printf ("Line %d: Incorrect sample A (#%ld : %d should be %d).\n", __LINE__, k, data [k], orig [k]) ; 138 oct_save_short (orig, data, BUFFER_SIZE) ; 139 exit (1) ; 140 } ; 141 } ; 142 143 144 printf ("ok\n") ; 145 146 return ; 147} /* g723_test */ 148 149 150#define SIGNAL_MAXVAL 30000.0 151#define DECAY_COUNT 1000 152 153static void 154gen_signal_double (double *gendata, double scale, int gendatalen) 155{ int k, ramplen ; 156 double amp = 0.0 ; 157 158 ramplen = DECAY_COUNT ; 159 160 for (k = 0 ; k < gendatalen ; k++) 161 { if (k <= ramplen) 162 amp = scale * k / ((double) ramplen) ; 163 else if (k > gendatalen - ramplen) 164 amp = scale * (gendatalen - k) / ((double) ramplen) ; 165 166 gendata [k] = amp * (0.4 * sin (33.3 * 2.0 * M_PI * ((double) (k+1)) / ((double) SAMPLE_RATE)) 167 + 0.3 * cos (201.1 * 2.0 * M_PI * ((double) (k+1)) / ((double) SAMPLE_RATE))) ; 168 } ; 169 170 return ; 171} /* gen_signal_double */ 172 173static int 174error_function (double data, double orig, double margin) 175{ double error ; 176 177 if (fabs (orig) <= 500.0) 178 error = fabs (fabs (data) - fabs (orig)) / 2000.0 ; 179 else if (fabs (orig) <= 1000.0) 180 error = fabs (data - orig) / 3000.0 ; 181 else 182 error = fabs (data - orig) / fabs (orig) ; 183 184 if (error > margin) 185 { printf ("\n\n*******************\nError : %f\n", error) ; 186 return 1 ; 187 } ; 188 return 0 ; 189} /* error_function */ 190 191static int 192oct_save_short (short *a, short *b, int len) 193{ FILE *file ; 194 int k ; 195 196 if (! (file = fopen ("error.dat", "w"))) 197 return 1 ; 198 199 fprintf (file, "# Not created by Octave\n") ; 200 201 fprintf (file, "# name: a\n") ; 202 fprintf (file, "# type: matrix\n") ; 203 fprintf (file, "# rows: %d\n", len) ; 204 fprintf (file, "# columns: 1\n") ; 205 206 for (k = 0 ; k < len ; k++) 207 fprintf (file, "% d\n", a [k]) ; 208 209 fprintf (file, "# name: b\n") ; 210 fprintf (file, "# type: matrix\n") ; 211 fprintf (file, "# rows: %d\n", len) ; 212 fprintf (file, "# columns: 1\n") ; 213 214 for (k = 0 ; k < len ; k++) 215 fprintf (file, "% d\n", b [k]) ; 216 217 fclose (file) ; 218 return 0 ; 219} /* oct_save_short */ 220 221