Exemple #1
0
/* Feed the meter. Scan a single frame of audio. */
int meter_feed(struct dr_meter *self, void *buf, size_t buf_size) {
	size_t samples = buf_size / (self->sample_size * self->channels);
	int err;

	while (samples) {
		if (!self->fragment_started) {
			err = meter_fragment_start(self);
			if (err) return err;
		}

		size_t fragment_left = self->fragment_size - self->fragment_read;
		size_t to_scan = min(fragment_left, samples);
		#define CASE(fmt) case fmt: meter_scan_internal(self, buf, to_scan, fmt); break
		switch (self->sample_fmt) {
		CASE(AV_SAMPLE_FMT_U8);
		CASE(AV_SAMPLE_FMT_S16);
		CASE(AV_SAMPLE_FMT_S32);
		CASE(AV_SAMPLE_FMT_FLT);
		CASE(AV_SAMPLE_FMT_DBL);
		default:
			meter_scan_internal(self, buf, to_scan, self->sample_fmt);
		}
		#undef CASE
		buf = (char *)buf + self->sample_size * self->channels * to_scan;
		self->fragment_read += to_scan;

		if (self->fragment_size <= self->fragment_read) {
			meter_fragment_finish(self);
		}

		samples -= to_scan;
	}

	return 0;
}
Exemple #2
0
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;
}
Exemple #3
0
/* Feed the meter. Scan a single frame of audio. */
int meter_feed(struct dr_meter *self, void **buf, size_t samples) {
	size_t start = 0, end = samples;
	int err;

	if (debug && 0) {
		fprintf(stdout, "%zd\n", samples);
	}

	while (start < samples) {
		if (!self->fragment_started) {
			err = meter_fragment_start(self);
			if (err) return err;
		}

		size_t fragment_left = self->fragment_size - self->fragment_read;
		end = min(fragment_left, samples);
		#define CASE(fmt) case fmt: meter_scan_internal(self, buf, start, end, samples, fmt); break
		switch (self->sample_fmt) {
		CASE(AV_SAMPLE_FMT_U8);
		CASE(AV_SAMPLE_FMT_U8P);
		CASE(AV_SAMPLE_FMT_S16);
		CASE(AV_SAMPLE_FMT_S16P);
		CASE(AV_SAMPLE_FMT_S32);
		CASE(AV_SAMPLE_FMT_S32P);
		CASE(AV_SAMPLE_FMT_FLT);
		CASE(AV_SAMPLE_FMT_FLTP);
		CASE(AV_SAMPLE_FMT_DBL);
		CASE(AV_SAMPLE_FMT_DBLP);
		default:
			meter_scan_internal(self, buf, start, end, samples, self->sample_fmt);
		}
		#undef CASE
		self->fragment_read += end - start;
		start = end;

		if (self->fragment_size <= self->fragment_read) {
			meter_fragment_finish(self);
		}
	}

	//printf("%lld += %zu\n", self->total_samples, samples);
	self->total_samples += samples;

	return 0;
}
Exemple #4
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;
}