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;
}
|