File: test_codecs.c

package info (click to toggle)
rat 4.2.22-2.2
  • links: PTS
  • area: main
  • in suites: jessie, jessie-kfreebsd
  • size: 2,896 kB
  • ctags: 3,717
  • sloc: ansic: 36,542; tcl: 2,740; sh: 2,675; makefile: 295
file content (143 lines) | stat: -rw-r--r-- 4,566 bytes parent folder | download | duplicates (6)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
#include "config_unix.h"
#include "codec_types.h"
#include "codec.h"

#include "util.h" /* Block alloc */
#include "debug.h"

static void
buffer_fill(sample *s, int s_bytes, int channels, int freq)
{
        int i, j, samples = s_bytes / sizeof(sample);

        xmemchk();
        assert(channels == 1 || channels == 2);
        assert(samples > 30);
        for(i = 0; i < samples; i+=channels) {
                for(j = 0; j<channels; j++) {
                        s[i+j] = (sample)
                                (16384.0 * sin(2 * M_PI * (float)i/(float)freq));
                }
        }
        xmemchk();
}

static double
snr(sample *src, sample *replica, int s_bytes)
{
        int i, n_samples = s_bytes / sizeof(sample);
        double st = 0.0, nt = 0.0;
        
        for(i = 0; i < n_samples; i++) {
                st += fabs((double)src[i]);
                nt += fabs((double)src[i] - (double)replica[i]);
        }

        if (nt == 0) return -100000000.0;

        return -20 * (log10(st / nt));
}

/* This function encodes and decodes frames of audio
 * containing tones and produces SNR estimate.
 *
 * For codecs that are not pitch synchronous this does not
 * make a lot of sense with first finding max correlation score
 * between buffers and then realigning.
 */  

static void
test_codec(codec_id_t cid, const codec_format_t *cf)
{
        codec_state *enc, *dec;
        coded_unit  input, output, coded;
        int success, fill_freq;
        float sig_err;

        success = codec_encoder_create(cid, &enc);
        assert(success == 1);
        success = codec_decoder_create(cid, &dec);
        assert(success == 1);        

        /* First make buffer of raw audio */
        input.id    = codec_get_native_coding(cf->format.sample_rate,
                                               cf->format.channels);
        input.state     = NULL;
        input.state_len = 0;
        input.data      = (u_char*)block_alloc(cf->format.bytes_per_block);
        input.data_len  = cf->format.bytes_per_block;

        for(fill_freq = 1000; fill_freq < 3500; fill_freq += 500) {
                buffer_fill((sample*)input.data, 
                            input.data_len, 
                            cf->format.channels,
                            fill_freq);

                memset(&coded, 0, sizeof(coded_unit));
                codec_encode(enc, &input, &coded);

                assert(codec_peek_frame_size(coded.id,
                                             coded.data,
                                             1000) == coded.data_len);
                
                memset(&output, 0, sizeof(coded_unit));
                codec_decode(dec, &coded, &output);

                /* Make sure raw audio frame sizes match */
                assert(input.data_len == output.data_len);

                /* Do snr thing */
                printf("%d\t", 
                       fill_freq);
                sig_err = snr((sample*)input.data, (sample*)output.data, input.data_len);
                printf("%d\n", (int)(sig_err));

                /* Clear memory allocated by encoder */
                codec_clear_coded_unit(&coded);
                /* Clear memory allocated by decoder */
                codec_clear_coded_unit(&output);

        }
        codec_clear_coded_unit(&input);
        codec_encoder_destroy(&enc);
        codec_decoder_destroy(&dec);
}

int main()
{
        const codec_format_t *cf;
        u_int32               n_codecs, i;

        codec_id_t cid;
        codec_init();

        n_codecs = codec_get_number_of_codecs();
        for (i = 0; i < n_codecs; i++) {
                cid = codec_get_codec_number(i);
                assert(codec_id_is_valid(cid));
                cf = codec_get_format(cid);
                printf("Codec 0x%x: ",
                       (unsigned)cid);
                printf("%s (%s).\n", 
                       cf->long_name, 
                       cf->short_name);

                printf("%s\nDefault pt (%u)\n",
                       cf->description,
                       cf->default_pt
                       );
                if (codec_can_encode(cid) && codec_can_decode(cid)) {
                        test_codec(cid, cf);
                } else {
                        printf("*** Not tested encode(%d) decode(%d)\n",
                               codec_can_encode(cid),
                               codec_can_decode(cid));
                }

                xmemchk();
        }

        codec_exit();
        xmemdmp();
        return 1;
}