~ubuntu-branches/debian/sid/sflphone/sid

« back to all changes in this revision

Viewing changes to daemon/libs/pjproject/tests/pjsua/tools/cmp_wav.c

  • Committer: Package Import Robot
  • Author(s): Mark Purcell
  • Date: 2013-06-02 18:04:11 UTC
  • mfrom: (1.1.9)
  • Revision ID: package-import@ubuntu.com-20130602180411-3rcpy8c1zdlo8y0s
Tags: 1.2.2-1
* New upstream release
* changeset_rb68857a4b485b7d43f92714cd5792595ff895f82.diff - fix QTest
* pjproject ./configure --disable-sound --disable-video

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/* $Id: cmp_wav.c 3553 2011-05-05 06:14:19Z nanang $ */
2
 
/* 
3
 
 * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)
4
 
 * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>
5
 
 *
6
 
 * This program is free software; you can redistribute it and/or modify
7
 
 * it under the terms of the GNU General Public License as published by
8
 
 * the Free Software Foundation; either version 2 of the License, or
9
 
 * (at your option) any later version.
10
 
 *
11
 
 * This program is distributed in the hope that it will be useful,
12
 
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13
 
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14
 
 * GNU General Public License for more details.
15
 
 *
16
 
 * You should have received a copy of the GNU General Public License
17
 
 * along with this program; if not, write to the Free Software
18
 
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA 
19
 
 */
20
 
#include <pjmedia.h>
21
 
#include <pjlib-util.h>
22
 
#include <pjlib.h>
23
 
#include <stdio.h>
24
 
#include <stdlib.h>
25
 
 
26
 
#define app_perror(a,b,c) printf("%s: %s (%d)", a, b, c)
27
 
 
28
 
 
29
 
/* For logging purpose. */
30
 
#define THIS_FILE   "cmp_wav.c"
31
 
#define BYTES_PER_FRAME     512
32
 
 
33
 
static const char *desc = 
34
 
" FILE                                                              \n"
35
 
"                                                                   \n"
36
 
"  cmp_wav.c                                                        \n"
37
 
"                                                                   \n"
38
 
" PURPOSE                                                           \n"
39
 
"                                                                   \n"
40
 
"  Compare two WAV files.                                           \n"
41
 
"                                                                   \n"
42
 
" USAGE                                                             \n"
43
 
"                                                                   \n"
44
 
"  cmp_wav ORIGINAL_WAV DEGRADED_WAV [TIME] [DETAIL]                \n"
45
 
"                                                                   \n"
46
 
"  ORIGINAL_WAV     The original WAV file as reference.             \n"
47
 
"  DEGRADED_WAV     The degraded WAV file.                          \n"
48
 
"  TIME             Compare only some part of the files             \n"
49
 
"                   (in ms, since the beginning).                   \n"
50
 
"                   Specify 0 (default) to compare the whole time.  \n"
51
 
"  DETAIL           Show detail result, 1 or 0 (default=0, means no)\n"
52
 
"                                                                   \n"
53
 
"  Both files must have same clock rate and must contain            \n"
54
 
"  uncompressed (i.e. 16bit) PCM.                                   \n";
55
 
 
56
 
 
57
 
/* Sum of multiplication of corresponding samples in buf1 & buf2 */
58
 
double sum_mult_sig(pj_int16_t *buf1, pj_int16_t *buf2, unsigned nsamples)
59
 
{
60
 
    double mag = 0;
61
 
 
62
 
    while (nsamples--)
63
 
        mag += (double)*buf1++ * (double)*buf2++;
64
 
 
65
 
    return mag;
66
 
}
67
 
 
68
 
 
69
 
/*
70
 
 * main()
71
 
 */
72
 
int main(int argc, char *argv[])
73
 
{
74
 
    pj_caching_pool cp;
75
 
    pjmedia_endpt *med_endpt;
76
 
    pj_pool_t *pool;
77
 
    pjmedia_port *file_ori_port;
78
 
    pjmedia_port *file_deg_port;
79
 
    pj_status_t status;
80
 
    unsigned first_nsamples = 0;
81
 
    unsigned samples_compared = 0;
82
 
 
83
 
    char buf1[BYTES_PER_FRAME];
84
 
    char buf2[BYTES_PER_FRAME];
85
 
 
86
 
    double ref_mag = 0;
87
 
    double deg_mag = 0;
88
 
    double mix_mag = 0;
89
 
 
90
 
    int detail = 0;
91
 
    int res_deg, res_mix, res_overall;
92
 
 
93
 
    if (argc < 3) {
94
 
        puts("Error: original & degraded filename required");
95
 
        puts(desc);
96
 
        return 1;
97
 
    }
98
 
 
99
 
    /* Set log level. */
100
 
    pj_log_set_level(3);
101
 
 
102
 
    /* Must init PJLIB first: */
103
 
    status = pj_init();
104
 
    PJ_ASSERT_RETURN(status == PJ_SUCCESS, 1);
105
 
 
106
 
    /* Must create a pool factory before we can allocate any memory. */
107
 
    pj_caching_pool_init(&cp, &pj_pool_factory_default_policy, 0);
108
 
 
109
 
    /* 
110
 
     * Initialize media endpoint.
111
 
     * This will implicitly initialize PJMEDIA too.
112
 
     */
113
 
    status = pjmedia_endpt_create(&cp.factory, NULL, 1, &med_endpt);
114
 
    PJ_ASSERT_RETURN(status == PJ_SUCCESS, 1);
115
 
 
116
 
    /* Create memory pool for our file player */
117
 
    pool = pj_pool_create( &cp.factory,     /* pool factory         */
118
 
                           "wav",           /* pool name.           */
119
 
                           4000,            /* init size            */
120
 
                           4000,            /* increment size       */
121
 
                           NULL             /* callback on error    */
122
 
                           );
123
 
 
124
 
    /* Create file media port from the original WAV file */
125
 
    status = pjmedia_wav_player_port_create(  pool,     /* memory pool      */
126
 
                                              argv[1],  /* file to play     */
127
 
                                              40,       /* ptime.           */
128
 
                                              PJMEDIA_FILE_NO_LOOP,     /* flags            */
129
 
                                              0,        /* default buffer   */
130
 
                                              &file_ori_port/* returned port    */
131
 
                                              );
132
 
    if (status != PJ_SUCCESS) {
133
 
        app_perror(THIS_FILE, "Unable to use WAV file", status);
134
 
        return 1;
135
 
    }
136
 
 
137
 
    /* Create file media port from the degraded WAV file */
138
 
    status = pjmedia_wav_player_port_create(  pool,     /* memory pool      */
139
 
                                              argv[2],  /* file to play     */
140
 
                                              40,       /* ptime.           */
141
 
                                              PJMEDIA_FILE_NO_LOOP,     /* flags            */
142
 
                                              0,        /* default buffer   */
143
 
                                              &file_deg_port/* returned port    */
144
 
                                              );
145
 
    if (status != PJ_SUCCESS) {
146
 
        app_perror(THIS_FILE, "Unable to use WAV file", status);
147
 
        return 1;
148
 
    }
149
 
 
150
 
    if (file_ori_port->info.clock_rate != file_deg_port->info.clock_rate) {
151
 
        app_perror(THIS_FILE, "Clock rates must be same.", PJ_EINVAL);
152
 
        return 1;
153
 
    }
154
 
 
155
 
    if (argc > 3)
156
 
        first_nsamples = atoi(argv[3]) * file_ori_port->info.clock_rate / 1000;
157
 
 
158
 
    if (argc > 4)
159
 
        detail = atoi(argv[4]);
160
 
 
161
 
    while (1) {
162
 
        pjmedia_frame f1, f2;
163
 
 
164
 
        f1.buf = buf1;
165
 
        f1.size = BYTES_PER_FRAME;
166
 
        f2.buf = buf2;
167
 
        f2.size = BYTES_PER_FRAME;
168
 
 
169
 
        status = pjmedia_port_get_frame(file_ori_port, &f1);
170
 
        if (status == PJ_EEOF) {
171
 
            break;
172
 
        } else if (status != PJ_SUCCESS) {
173
 
            app_perror(THIS_FILE, "Error occured while reading file", status);
174
 
            break;
175
 
        }
176
 
        status = pjmedia_port_get_frame(file_deg_port, &f2);
177
 
        if (status == PJ_EEOF) {
178
 
            break;
179
 
        } else if (status != PJ_SUCCESS) {
180
 
            app_perror(THIS_FILE, "Error occured while reading file", status);
181
 
            break;
182
 
        }
183
 
 
184
 
        /* Calculate magnitudes */
185
 
        ref_mag += sum_mult_sig(f1.buf, f1.buf, BYTES_PER_FRAME >> 1);
186
 
        deg_mag += sum_mult_sig(f2.buf, f2.buf, BYTES_PER_FRAME >> 1);
187
 
        mix_mag += sum_mult_sig(f1.buf, f2.buf, BYTES_PER_FRAME >> 1);
188
 
 
189
 
        samples_compared += BYTES_PER_FRAME >> 1;
190
 
        if (first_nsamples && samples_compared >= first_nsamples)
191
 
            break;
192
 
    }
193
 
 
194
 
    /* Degraded magnitude compared to reference magnitude 
195
 
     */
196
 
    res_deg = (int) (deg_mag / ref_mag * 100.0);
197
 
    if (res_deg < 0)
198
 
        res_deg = -1;
199
 
    else if (res_deg >= 81)
200
 
        res_deg = 9;
201
 
    else
202
 
        res_deg = pj_isqrt(res_deg);
203
 
 
204
 
    /* Mixed magnitude (don't know what this is actually :D) compared to 
205
 
     * reference magnitude 
206
 
     */
207
 
    res_mix = (int) (mix_mag / ref_mag * 100.0);
208
 
    if (res_mix < 0)
209
 
        res_mix = -1;
210
 
    else if (res_mix >= 81)
211
 
        res_mix = 9;
212
 
    else
213
 
        res_mix = pj_isqrt(res_mix);
214
 
 
215
 
    /* Overall score.
216
 
     * If mixed score is -1, then overall score should be -1 as well.
217
 
     * Apply no weighting (1:1) for now.
218
 
     */
219
 
    if (res_mix == -1)
220
 
        res_overall = -1;
221
 
    else
222
 
        res_overall = (res_mix*1 + res_deg*1) / 2;
223
 
 
224
 
    if (detail) {
225
 
        printf("Reference = %.0f\n", ref_mag);
226
 
        printf("Degraded  = %.0f\n", deg_mag);
227
 
        printf("Mixed     = %.0f\n", mix_mag);
228
 
 
229
 
        printf("\n");
230
 
 
231
 
        printf("Score 1   = %d\n", res_deg);
232
 
        printf("Score 2   = %d\n", res_mix);
233
 
 
234
 
        printf("\n");
235
 
    }
236
 
 
237
 
    printf("Overall   = %d\n", res_overall);
238
 
 
239
 
    /* Destroy file port */
240
 
    status = pjmedia_port_destroy( file_ori_port );
241
 
    PJ_ASSERT_RETURN(status == PJ_SUCCESS, 1);
242
 
 
243
 
    status = pjmedia_port_destroy( file_deg_port );
244
 
    PJ_ASSERT_RETURN(status == PJ_SUCCESS, 1);
245
 
 
246
 
    /* Release application pool */
247
 
    pj_pool_release( pool );
248
 
 
249
 
    /* Destroy media endpoint. */
250
 
    pjmedia_endpt_destroy( med_endpt );
251
 
 
252
 
    /* Destroy pool factory */
253
 
    pj_caching_pool_destroy( &cp );
254
 
 
255
 
    /* Shutdown PJLIB */
256
 
    pj_shutdown();
257
 
 
258
 
 
259
 
    /* Done. */
260
 
    return 0;
261
 
}
262