void print_dr(struct track_info *info, int count) { int i; const char *artist = collapse(info, count, sizeof(struct track_info), offsetof(struct track_info, artist), "Unknown", "Unknown"); const char *album = collapse(info, count, sizeof(struct track_info), offsetof(struct track_info, album), "Unknown", "Various Artists"); sample dr_sum = 0; printf("dr_meter " VERSION "\n"); //printf("log date: \n"); printf("\n"); print_bar('-'); printf("Analyzed: %s / %s\n", artist, album); print_bar('-'); printf("\n"); printf("DR Peak RMS Duration Track\n"); print_bar('-'); for (i = 0; i < count; i++) { // XXX don't print tracks with errors struct track_info *t = &info[i]; if (t->err) continue; printf("DR%-4d %8.2f dB %8.2f dB %6d:%02d %s-%s\n", (int)round(t->dr), to_db(t->peak), to_db(t->rms), t->duration/60, t->duration%60, t->tracknumber, t->title); dr_sum += t->dr; } print_bar('-'); printf("\n"); printf("Number of tracks: %i\n", count); printf("Official DR value: DR%i\n", (int)round(dr_sum / count)); print_bar('='); printf("\n"); }
int meter_finish(struct dr_meter *self, struct track_info *info) { if (self->fragment_started) { // process any leftover audio meter_fragment_finish(self); } sample rms_score[MAX_CHANNELS]; sample rms[MAX_CHANNELS]; sample peak_score[MAX_CHANNELS]; sample dr_channel[MAX_CHANNELS]; sample dr_sum = 0; sample peak_max = 0; sample rms_sum = 0; size_t values_to_use = 0; values_to_use = max(self->fragment / 5, 1); if (!values_to_use) { info->peak = 0; info->rms = 0; info->dr = -INFINITY; info->duration = 0; return 0; } for (int ch = 0; ch < self->channels; ch++) { qsort(self->rms_values[ch], self->fragment, sizeof(*self->rms_values[ch]), compare_samples); sample rms_ch_sum = 0; for (size_t i = 0; i < values_to_use; i++) { sample value = self->rms_values[ch][i]; rms_ch_sum += value * value; } rms_score[ch] = sqrt(rms_ch_sum / values_to_use); for (size_t i = values_to_use; i < self->fragment; i++) { sample value = self->rms_values[ch][i]; rms_ch_sum += value * value; } rms[ch] = sqrt(rms_ch_sum / self->fragment); rms_sum += rms_ch_sum / self->fragment; qsort(self->peak_values[ch], self->fragment, sizeof(*self->peak_values[ch]), compare_samples); peak_score[ch] = self->peak_values[ch][min(1, self->fragment)]; peak_max = max(peak_max, self->peak_values[ch][0]); dr_channel[ch] = to_db(peak_score[ch] / rms_score[ch]); dr_sum += dr_channel[ch]; printf("Ch. %2i: Peak %8.2f (%8.2f) RMS %8.2f (%8.2f) DR = %6.2f\n", ch, to_db(self->peak_values[ch][0]), to_db(peak_score[ch]), to_db(rms[ch]), to_db(rms_score[ch]), dr_channel[ch]); } info->peak = peak_max; info->rms = sqrt(rms_sum / (sample)self->channels); info->dr = dr_sum / (sample)self->channels; info->duration = (self->total_samples + self->sample_rate/2) / self->sample_rate; //printf("%lld\n", self->total_samples); printf("DR%d\n", (int)round(info->dr)); return 0; }
int meter_finish(struct dr_meter *self) { if (self->fragment_started) { meter_fragment_finish(self); } fprintf(stderr, "\nDoing some statistics...\n"); sample rms_score[MAX_CHANNELS]; sample rms[MAX_CHANNELS]; sample peak_score[MAX_CHANNELS]; sample dr_channel[MAX_CHANNELS]; sample dr_sum = 0; for (int ch = 0; ch < self->channels; ch++) { qsort(self->rms_values[ch], self->fragment, sizeof(**self->rms_values), compare_samples); sample rms_sum = 0; size_t values_to_use = self->fragment / 5; for (size_t i = 0; i < values_to_use; i++) { sample value = self->rms_values[ch][i]; rms_sum += value * value; } rms_score[ch] = sqrt(rms_sum / values_to_use); rms_sum = 0; for (size_t i = 0; i < self->fragment; i++) { sample value = self->rms_values[ch][i]; rms_sum += value * value; } rms[ch] = sqrt(rms_sum / self->fragment); qsort(self->peak_values[ch], self->fragment, sizeof(*self->peak_values[ch]), compare_samples); peak_score[ch] = self->peak_values[ch][min(1, self->fragment)]; dr_channel[ch] = to_db(peak_score[ch] / rms_score[ch]); printf("Ch. %2i: Peak %8.2f (%8.2f) RMS %8.2f (%8.2f) DR = %6.2f\n", ch, to_db(self->peak_values[ch][0]), to_db(peak_score[ch]), to_db(rms[ch]), to_db(rms_score[ch]), dr_channel[ch]); dr_sum += dr_channel[ch]; } printf("Overall dynamic range: DR%i\n", (int)round(dr_sum / ((sample)self->channels))); return 0; }