Mercurial > mplayer.hg
comparison libaf/af_stats.c @ 28661:20787bd5c506
Add statistics audio filter that prints information about the audio stream.
patch by Nicolas George, nicolas.george normalesup org
author | diego |
---|---|
date | Sat, 21 Feb 2009 21:27:27 +0000 |
parents | |
children | 8e9f6dfd7580 |
comparison
equal
deleted
inserted
replaced
28660:0812215421d7 | 28661:20787bd5c506 |
---|---|
1 /* | |
2 * Copyright (C) 2009 Nicolas George <nicolas.george@normalesup.org> | |
3 * | |
4 * This file is part of MPlayer. | |
5 * | |
6 * MPlayer 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 * MPlayer 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 along | |
17 * with MPlayer; if not, write to the Free Software Foundation, Inc., | |
18 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. | |
19 */ | |
20 | |
21 #include <stdio.h> | |
22 #include <stdlib.h> | |
23 #include <inttypes.h> | |
24 #include <math.h> | |
25 | |
26 #include "af.h" | |
27 | |
28 #define MAX_DB 80 | |
29 #define MIN_VAL 1E-8 | |
30 | |
31 struct af_stats | |
32 { | |
33 long long n_samples; | |
34 double tsquare; | |
35 int max; | |
36 long long histogram[65536]; | |
37 }; | |
38 | |
39 static inline int logdb(double v) | |
40 { | |
41 return v > 1 ? 0 : v <= MIN_VAL ? MAX_DB - 1 : | |
42 log(v) / -0.23025850929940456840179914546843642076; | |
43 } | |
44 | |
45 static int stats_init(af_instance_t *af, struct af_stats *s, af_data_t *data) | |
46 { | |
47 int i; | |
48 | |
49 if (!data) | |
50 return AF_ERROR; | |
51 *(af->data) = *data; | |
52 af->data->format = AF_FORMAT_S16_NE; | |
53 af->data->bps = 2; | |
54 s->n_samples = 0; | |
55 s->tsquare = 0; | |
56 s->max = 0; | |
57 for (i = 0; i < 65536; i++) | |
58 s->histogram[i] = 0; | |
59 return af_test_output(af, data); | |
60 } | |
61 | |
62 static void stats_print(struct af_stats *s) | |
63 { | |
64 int i; | |
65 long long sum; | |
66 float v; | |
67 long long h[MAX_DB]; | |
68 | |
69 s->tsquare /= 32768 * 32768; | |
70 mp_msg(MSGT_AFILTER, MSGL_INFO, "stats: n_samples: %lld\n", s->n_samples); | |
71 if (s->n_samples == 0) | |
72 return; | |
73 mp_msg(MSGT_AFILTER, MSGL_INFO, "stats: mean_volume: -%d dB\n", | |
74 logdb(s->tsquare / s->n_samples)); | |
75 mp_msg(MSGT_AFILTER, MSGL_INFO, "stats: max_volume: -%d dB\n", | |
76 logdb(s->max / 32768.0)); | |
77 for (i = 0; i < MAX_DB; i++) | |
78 h[i] = 0; | |
79 for (i = 0; i < 65536; i++) { | |
80 v = (i - 32768) / 32768.0; | |
81 h[logdb(v * v)] += s->histogram[i]; | |
82 } | |
83 for (i = 0; i < MAX_DB; i++) | |
84 if (h[i] != 0) | |
85 break; | |
86 sum = 0; | |
87 for (; i < MAX_DB; i++) { | |
88 sum += h[i]; | |
89 mp_msg(MSGT_AFILTER, MSGL_INFO, "stats:histogram_%ddb: %lld\n", | |
90 i, h[i]); | |
91 if (sum > s->n_samples / 1000) | |
92 break; | |
93 } | |
94 } | |
95 | |
96 static int control(struct af_instance_s *af, int cmd, void *arg) | |
97 { | |
98 struct af_stats *s = (struct af_stats *)af->setup; | |
99 | |
100 switch(cmd) { | |
101 case AF_CONTROL_REINIT: | |
102 return stats_init(af, s, arg); | |
103 | |
104 case AF_CONTROL_PRE_DESTROY: | |
105 stats_print(s); | |
106 return AF_OK; | |
107 } | |
108 return AF_UNKNOWN; | |
109 } | |
110 | |
111 static void uninit(struct af_instance_s *af) | |
112 { | |
113 if (af->data) | |
114 free(af->data); | |
115 if (af->setup) | |
116 free(af->setup); | |
117 } | |
118 | |
119 static af_data_t *play(struct af_instance_s *af, af_data_t *data) | |
120 { | |
121 struct af_stats *s = (struct af_stats *)af->setup; | |
122 int16_t *a, *aend; | |
123 int v, v2; | |
124 | |
125 a = data->audio; | |
126 aend = (int16_t *)((char *)data->audio + data->len); | |
127 s->n_samples += aend - a; | |
128 for (; a < aend; a++) { | |
129 v = *a; | |
130 v2 = v * v; | |
131 s->tsquare += v2; | |
132 s->histogram[v + 32768]++; | |
133 if (v2 > s->max) | |
134 s->max = v2; | |
135 } | |
136 return data; | |
137 } | |
138 | |
139 static int af_open(af_instance_t* af){ | |
140 af->control = control; | |
141 af->uninit = uninit; | |
142 af->play = play; | |
143 af->mul = 1; | |
144 af->data = malloc(sizeof(af_data_t)); | |
145 af->setup = malloc(sizeof(struct af_stats)); | |
146 if (af->data == NULL || af->setup == NULL) | |
147 return AF_ERROR; | |
148 return AF_OK; | |
149 } | |
150 | |
151 af_info_t af_info_stats = { | |
152 "Statistics audio filter", | |
153 "stats", | |
154 "Nicolas George", | |
155 "", | |
156 0, | |
157 af_open | |
158 }; |