00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024 #ifdef HAVE_CONFIG_H
00025 #include <config.h>
00026 #endif
00027
00028 #ifdef BRHIST
00029
00030
00031
00032 #ifndef BRHIST_WIDTH
00033 # define BRHIST_WIDTH 14
00034 #endif
00035 #ifndef BRHIST_RES
00036 # define BRHIST_RES 14
00037 #endif
00038
00039
00040
00041
00042 #ifdef STDC_HEADERS
00043 # include <stdlib.h>
00044 # include <string.h>
00045 #endif
00046
00047 #include "brhist.h"
00048 #include "console.h"
00049
00050 #ifdef WITH_DMALLOC
00051 #include <dmalloc.h>
00052 #endif
00053
00054
00055
00056
00057
00058
00059
00060
00061 extern Console_IO_t Console_IO;
00062
00063 static struct {
00064 int vbr_bitrate_min_index;
00065 int vbr_bitrate_max_index;
00066 int kbps[BRHIST_WIDTH];
00067 int hist_printed_lines;
00068 char bar_asterisk[512 + 1];
00069 char bar_percent[512 + 1];
00070 char bar_coded[512 + 1];
00071 char bar_space[512 + 1];
00072 } brhist;
00073
00074 static int
00075 calculate_index(const int *const array, const int len, const int value)
00076 {
00077 int i;
00078
00079 for (i = 0; i < len; i++)
00080 if (array[i] == value)
00081 return i;
00082 return -1;
00083 }
00084
00085 int
00086 brhist_init(const lame_global_flags * gf, const int bitrate_kbps_min, const int bitrate_kbps_max)
00087 {
00088 brhist.hist_printed_lines = 0;
00089
00090 #ifndef RH_HIST
00091
00092 if (bitrate_kbps_min > bitrate_kbps_max) {
00093 error_printf("lame internal error: VBR min %d kbps > VBR max %d kbps.\n",
00094 bitrate_kbps_min, bitrate_kbps_max);
00095 return -1;
00096 }
00097 if (bitrate_kbps_min < 8 || bitrate_kbps_max > 320) {
00098 error_printf("lame internal error: VBR min %d kbps or VBR max %d kbps out of range.\n",
00099 bitrate_kbps_min, bitrate_kbps_max);
00100 return -1;
00101 }
00102 #endif
00103
00104
00105 lame_bitrate_kbps(gf, brhist.kbps);
00106 brhist.vbr_bitrate_min_index = calculate_index(brhist.kbps, BRHIST_WIDTH, bitrate_kbps_min);
00107 brhist.vbr_bitrate_max_index = calculate_index(brhist.kbps, BRHIST_WIDTH, bitrate_kbps_max);
00108
00109 if (brhist.vbr_bitrate_min_index >= BRHIST_WIDTH ||
00110 brhist.vbr_bitrate_max_index >= BRHIST_WIDTH) {
00111 error_printf("lame internal error: VBR min %d kbps or VBR max %d kbps not allowed.\n",
00112 bitrate_kbps_min, bitrate_kbps_max);
00113 return -1;
00114 }
00115
00116 memset(brhist.bar_asterisk, '*', sizeof(brhist.bar_asterisk) - 1);
00117 memset(brhist.bar_percent, '%', sizeof(brhist.bar_percent) - 1);
00118 memset(brhist.bar_space, '-', sizeof(brhist.bar_space) - 1);
00119 memset(brhist.bar_coded, '-', sizeof(brhist.bar_space) - 1);
00120
00121 return 0;
00122 }
00123
00124 static int
00125 digits(unsigned number)
00126 {
00127 int ret = 1;
00128
00129 if (number >= 100000000) {
00130 ret += 8;
00131 number /= 100000000;
00132 }
00133 if (number >= 10000) {
00134 ret += 4;
00135 number /= 10000;
00136 }
00137 if (number >= 100) {
00138 ret += 2;
00139 number /= 100;
00140 }
00141 if (number >= 10) {
00142 ret += 1;
00143 }
00144
00145 return ret;
00146 }
00147
00148
00149 static void
00150 brhist_disp_line(int i, int br_hist_TOT, int br_hist_LR, int full, int frames)
00151 {
00152 char brppt[14];
00153 int barlen_TOT;
00154 int barlen_LR;
00155 int ppt = 0;
00156 int res = digits(frames) + 3 + 4 + 1;
00157
00158 if (full != 0) {
00159
00160 barlen_TOT = (br_hist_TOT * (Console_IO.disp_width - res) + full - 1) / full;
00161 barlen_LR = (br_hist_LR * (Console_IO.disp_width - res) + full - 1) / full;
00162 }
00163 else {
00164 barlen_TOT = barlen_LR = 0;
00165 }
00166
00167 if (frames > 0)
00168 ppt = (1000 * br_hist_TOT + frames / 2) / frames;
00169
00170 sprintf(brppt, " [%*i]", digits(frames), br_hist_TOT);
00171
00172 if (Console_IO.str_clreoln[0])
00173 console_printf("\n%3d%s %.*s%.*s%s",
00174 brhist.kbps[i], brppt,
00175 barlen_LR, brhist.bar_percent,
00176 barlen_TOT - barlen_LR, brhist.bar_asterisk, Console_IO.str_clreoln);
00177 else
00178 console_printf("\n%3d%s %.*s%.*s%*s",
00179 brhist.kbps[i], brppt,
00180 barlen_LR, brhist.bar_percent,
00181 barlen_TOT - barlen_LR, brhist.bar_asterisk,
00182 Console_IO.disp_width - res - barlen_TOT, "");
00183
00184 brhist.hist_printed_lines++;
00185 }
00186
00187
00188 #ifdef RH_HIST
00189 static void
00190 progress_line(const lame_global_flags * gf, int full, int frames)
00191 {
00192 char rst[20] = "\0";
00193 int barlen_TOT = 0, barlen_COD = 0, barlen_RST = 0;
00194 int res = 1;
00195 float time_in_sec = 0;
00196 unsigned int hour, min, sec;
00197 int fsize = lame_get_framesize(gf);
00198 int srate = lame_get_out_samplerate(gf);
00199
00200 if (full < frames) {
00201 full = frames;
00202 }
00203 if (srate > 0) {
00204 time_in_sec = (float)(full - frames);
00205 time_in_sec *= fsize;
00206 time_in_sec /= srate;
00207 }
00208 hour = (unsigned int)(time_in_sec / 3600);
00209 time_in_sec -= hour * 3600;
00210 min = (unsigned int)(time_in_sec / 60);
00211 time_in_sec -= min * 60;
00212 sec = (unsigned int)time_in_sec;
00213 if (full != 0) {
00214 if (hour > 0) {
00215 sprintf(rst, "%*d:%02u:%02u", digits(hour), hour, min, sec);
00216 res += digits(hour) + 1 + 5;
00217 }
00218 else {
00219 sprintf(rst, "%02u:%02u", min, sec);
00220 res += 5;
00221 }
00222
00223 barlen_TOT = (full * (Console_IO.disp_width - res) + full - 1) / full;
00224 barlen_COD = (frames * (Console_IO.disp_width - res) + full - 1) / full;
00225 barlen_RST = barlen_TOT - barlen_COD;
00226 if (barlen_RST == 0) {
00227 sprintf(rst, "%.*s", res - 1, brhist.bar_coded);
00228 }
00229 }
00230 else {
00231 barlen_TOT = barlen_COD = barlen_RST = 0;
00232 }
00233 if (Console_IO.str_clreoln[0]) {
00234 console_printf("\n%.*s%s%.*s%s",
00235 barlen_COD, brhist.bar_coded,
00236 rst, barlen_RST, brhist.bar_space, Console_IO.str_clreoln);
00237 }
00238 else {
00239 console_printf("\n%.*s%s%.*s%*s",
00240 barlen_COD, brhist.bar_coded,
00241 rst, barlen_RST, brhist.bar_space, Console_IO.disp_width - res - barlen_TOT,
00242 "");
00243 }
00244 brhist.hist_printed_lines++;
00245 }
00246
00247
00248 static int
00249 stats_value(double x)
00250 {
00251 if (x > 0.0) {
00252 console_printf(" %5.1f", x);
00253 return 6;
00254 }
00255 return 0;
00256 }
00257
00258 static int
00259 stats_head(double x, const char *txt)
00260 {
00261 if (x > 0.0) {
00262 console_printf(txt);
00263 return 6;
00264 }
00265 return 0;
00266 }
00267
00268
00269 static void
00270 stats_line(double *stat)
00271 {
00272 int n = 1;
00273 console_printf("\n kbps ");
00274 n += 12;
00275 n += stats_head(stat[1], " mono");
00276 n += stats_head(stat[2], " IS ");
00277 n += stats_head(stat[3], " LR ");
00278 n += stats_head(stat[4], " MS ");
00279 console_printf(" %% ");
00280 n += 6;
00281 n += stats_head(stat[5], " long ");
00282 n += stats_head(stat[6], "switch");
00283 n += stats_head(stat[7], " short");
00284 n += stats_head(stat[8], " mixed");
00285 n += console_printf(" %%");
00286 if (Console_IO.str_clreoln[0]) {
00287 console_printf("%s", Console_IO.str_clreoln);
00288 }
00289 else {
00290 console_printf("%*s", Console_IO.disp_width - n, "");
00291 }
00292 brhist.hist_printed_lines++;
00293
00294 n = 1;
00295 console_printf("\n %5.1f ", stat[0]);
00296 n += 12;
00297 n += stats_value(stat[1]);
00298 n += stats_value(stat[2]);
00299 n += stats_value(stat[3]);
00300 n += stats_value(stat[4]);
00301 console_printf(" ");
00302 n += 6;
00303 n += stats_value(stat[5]);
00304 n += stats_value(stat[6]);
00305 n += stats_value(stat[7]);
00306 n += stats_value(stat[8]);
00307 if (Console_IO.str_clreoln[0]) {
00308 console_printf("%s", Console_IO.str_clreoln);
00309 }
00310 else {
00311 console_printf("%*s", Console_IO.disp_width - n, "");
00312 }
00313 brhist.hist_printed_lines++;
00314 }
00315 #endif
00316
00317
00318 #define LR 0
00319 #define MS 2
00320
00321 void
00322 brhist_disp(const lame_global_flags * gf)
00323 {
00324 int i, lines = 0;
00325 int br_hist[BRHIST_WIDTH];
00326 int br_sm_hist[BRHIST_WIDTH][4];
00327 int st_mode[4];
00328 int bl_type[6];
00329 int frames;
00330 int most_often;
00331 double sum = 0.;
00332 #ifdef RH_HIST
00333 double stat[9] = { 0 };
00334 int st_frames = 0;
00335 #endif
00336
00337 brhist.hist_printed_lines = 0;
00338
00339 lame_bitrate_stereo_mode_hist(gf, br_sm_hist);
00340 lame_bitrate_hist(gf, br_hist);
00341 lame_stereo_mode_hist(gf, st_mode);
00342 lame_block_type_hist(gf, bl_type);
00343
00344 frames = most_often = 0;
00345 for (i = 0; i < BRHIST_WIDTH; i++) {
00346 frames += br_hist[i];
00347 sum += br_hist[i] * brhist.kbps[i];
00348 if (most_often < br_hist[i])
00349 most_often = br_hist[i];
00350 if (br_hist[i])
00351 ++lines;
00352 }
00353
00354 for (i = 0; i < BRHIST_WIDTH; i++) {
00355 int show = br_hist[i];
00356 #ifdef RH_HIST
00357 show = show && (lines > 1);
00358 #endif
00359 if (show || (i >= brhist.vbr_bitrate_min_index && i <= brhist.vbr_bitrate_max_index))
00360 brhist_disp_line(i, br_hist[i], br_sm_hist[i][LR], most_often, frames);
00361 }
00362 #ifdef RH_HIST
00363 for (i = 0; i < 4; i++) {
00364 st_frames += st_mode[i];
00365 }
00366 if (frames > 0) {
00367 stat[0] = sum / frames;
00368 stat[1] = 100. * (frames - st_frames) / frames;
00369 }
00370 if (st_frames > 0) {
00371 stat[2] = 0.0;
00372 stat[3] = 100. * st_mode[LR] / st_frames;
00373 stat[4] = 100. * st_mode[MS] / st_frames;
00374 }
00375 if (bl_type[5] > 0) {
00376 stat[5] = 100. * bl_type[0] / bl_type[5];
00377 stat[6] = 100. * (bl_type[1] + bl_type[3]) / bl_type[5];
00378 stat[7] = 100. * bl_type[2] / bl_type[5];
00379 stat[8] = 100. * bl_type[4] / bl_type[5];
00380 }
00381 progress_line(gf, lame_get_totalframes(gf), frames);
00382 stats_line(stat);
00383 #endif
00384 }
00385
00386 void
00387 brhist_jump_back(void)
00388 {
00389 console_up(brhist.hist_printed_lines);
00390 brhist.hist_printed_lines = 0;
00391 }
00392
00393
00394 void
00395 brhist_disp_total(const lame_global_flags * gf)
00396 {
00397 #ifndef RH_HIST
00398
00399 int i;
00400 int br_hist[BRHIST_WIDTH];
00401 int st_mode[4];
00402 int bl_type[6];
00403 int st_frames = 0;
00404 int br_frames = 0;
00405 double sum = 0.;
00406
00407 lame_stereo_mode_hist(gf, st_mode);
00408 lame_bitrate_hist(gf, br_hist);
00409 lame_block_type_hist(gf, bl_type);
00410
00411 for (i = 0; i < BRHIST_WIDTH; i++) {
00412 br_frames += br_hist[i];
00413 sum += br_hist[i] * brhist.kbps[i];
00414 }
00415
00416 for (i = 0; i < 4; i++) {
00417 st_frames += st_mode[i];
00418 }
00419
00420 if (0 == br_frames)
00421 return;
00422
00423 console_printf("\naverage: %5.1f kbps", sum / br_frames);
00424
00425
00426
00427 if (st_frames > 0) {
00428 if (st_mode[LR] > 0)
00429 console_printf(" LR: %d (%#5.4g%%)", st_mode[LR], 100. * st_mode[LR] / st_frames);
00430 else
00431 console_printf(" ");
00432 if (st_mode[MS] > 0)
00433 console_printf(" MS: %d (%#5.4g%%)", st_mode[MS], 100. * st_mode[MS] / st_frames);
00434 }
00435 console_printf("\n");
00436
00437 if (bl_type[5] > 0) {
00438 extern int silent;
00439 if (silent <= -5 && silent > -10) {
00440 console_printf("block type");
00441 console_printf(" long: %#4.3f", 100. * bl_type[0] / bl_type[5]);
00442 console_printf(" start: %#4.3f", 100. * bl_type[1] / bl_type[5]);
00443 console_printf(" short: %#4.3f", 100. * bl_type[2] / bl_type[5]);
00444 console_printf(" stop: %#4.3f", 100. * bl_type[3] / bl_type[5]);
00445 console_printf(" mixed: %#4.3f", 100. * bl_type[4] / bl_type[5]);
00446 console_printf(" (%%)\n");
00447 }
00448 else if (silent <= -10) {
00449 console_printf("block types granules percent\n");
00450 console_printf(" long: % 10d % 8.3f%%\n",
00451 bl_type[0], 100. * bl_type[0] / bl_type[5]);
00452 console_printf(" start: % 10d % 8.3f%%\n",
00453 bl_type[1], 100. * bl_type[1] / bl_type[5]);
00454 console_printf(" short: % 10d % 8.3f%%\n",
00455 bl_type[2], 100. * bl_type[2] / bl_type[5]);
00456 console_printf(" stop: % 10d % 8.3f%%\n",
00457 bl_type[3], 100. * bl_type[3] / bl_type[5]);
00458 console_printf(" mixed: % 10d % 8.3f%%\n",
00459 bl_type[4], 100. * bl_type[4] / bl_type[5]);
00460 }
00461 }
00462 #else
00463 (void) gf;
00464 #endif
00465 }
00466
00467
00468
00469
00470
00471
00472
00473
00474
00475
00476
00477
00478
00479 #endif