2 * Copyright (c) 2013 The WebRTC project authors. All Rights Reserved.
4 * Use of this source code is governed by a BSD-style license
5 * that can be found in the LICENSE file in the root of the source
6 * tree. An additional intellectual property rights grant can be found
7 * in the file PATENTS. All contributing project authors may
8 * be found in the AUTHORS file in the root of the source tree.
11 #include "webrtc/modules/audio_coding/neteq/statistics_calculator.h"
14 #include <string.h> // memset
16 #include "webrtc/modules/audio_coding/neteq/decision_logic.h"
17 #include "webrtc/modules/audio_coding/neteq/delay_manager.h"
21 StatisticsCalculator::StatisticsCalculator()
22 : preemptive_samples_(0),
23 accelerate_samples_(0),
24 added_zero_samples_(0),
25 expanded_voice_samples_(0),
26 expanded_noise_samples_(0),
27 discarded_packets_(0),
29 last_report_timestamp_(0),
30 len_waiting_times_(0),
31 next_waiting_time_index_(0) {
32 memset(waiting_times_, 0, kLenWaitingTimes * sizeof(waiting_times_[0]));
35 void StatisticsCalculator::Reset() {
36 preemptive_samples_ = 0;
37 accelerate_samples_ = 0;
38 added_zero_samples_ = 0;
39 expanded_voice_samples_ = 0;
40 expanded_noise_samples_ = 0;
43 void StatisticsCalculator::ResetMcu() {
44 discarded_packets_ = 0;
46 last_report_timestamp_ = 0;
49 void StatisticsCalculator::ResetWaitingTimeStatistics() {
50 memset(waiting_times_, 0, kLenWaitingTimes * sizeof(waiting_times_[0]));
51 len_waiting_times_ = 0;
52 next_waiting_time_index_ = 0;
55 void StatisticsCalculator::ExpandedVoiceSamples(int num_samples) {
56 expanded_voice_samples_ += num_samples;
59 void StatisticsCalculator::ExpandedNoiseSamples(int num_samples) {
60 expanded_noise_samples_ += num_samples;
63 void StatisticsCalculator::PreemptiveExpandedSamples(int num_samples) {
64 preemptive_samples_ += num_samples;
67 void StatisticsCalculator::AcceleratedSamples(int num_samples) {
68 accelerate_samples_ += num_samples;
71 void StatisticsCalculator::AddZeros(int num_samples) {
72 added_zero_samples_ += num_samples;
75 void StatisticsCalculator::PacketsDiscarded(int num_packets) {
76 discarded_packets_ += num_packets;
79 void StatisticsCalculator::LostSamples(int num_samples) {
80 lost_timestamps_ += num_samples;
83 void StatisticsCalculator::IncreaseCounter(int num_samples, int fs_hz) {
84 last_report_timestamp_ += num_samples;
85 if (last_report_timestamp_ >
86 static_cast<uint32_t>(fs_hz * kMaxReportPeriod)) {
88 last_report_timestamp_ = 0;
89 discarded_packets_ = 0;
93 void StatisticsCalculator::StoreWaitingTime(int waiting_time_ms) {
94 assert(next_waiting_time_index_ < kLenWaitingTimes);
95 waiting_times_[next_waiting_time_index_] = waiting_time_ms;
96 next_waiting_time_index_++;
97 if (next_waiting_time_index_ >= kLenWaitingTimes) {
98 next_waiting_time_index_ = 0;
100 if (len_waiting_times_ < kLenWaitingTimes) {
101 len_waiting_times_++;
105 void StatisticsCalculator::GetNetworkStatistics(
107 int num_samples_in_buffers,
108 int samples_per_packet,
109 const DelayManager& delay_manager,
110 const DecisionLogic& decision_logic,
111 NetEqNetworkStatistics *stats) {
112 if (fs_hz <= 0 || !stats) {
117 stats->added_zero_samples = added_zero_samples_;
118 stats->current_buffer_size_ms = num_samples_in_buffers * 1000 / fs_hz;
119 const int ms_per_packet = decision_logic.packet_length_samples() /
121 stats->preferred_buffer_size_ms = (delay_manager.TargetLevel() >> 8) *
123 stats->jitter_peaks_found = delay_manager.PeakFound();
124 stats->clockdrift_ppm = delay_manager.AverageIAT();
126 stats->packet_loss_rate = CalculateQ14Ratio(lost_timestamps_,
127 last_report_timestamp_);
129 const unsigned discarded_samples = discarded_packets_ * samples_per_packet;
130 stats->packet_discard_rate = CalculateQ14Ratio(discarded_samples,
131 last_report_timestamp_);
133 stats->accelerate_rate = CalculateQ14Ratio(accelerate_samples_,
134 last_report_timestamp_);
136 stats->preemptive_rate = CalculateQ14Ratio(preemptive_samples_,
137 last_report_timestamp_);
139 stats->expand_rate = CalculateQ14Ratio(expanded_voice_samples_ +
140 expanded_noise_samples_,
141 last_report_timestamp_);
148 void StatisticsCalculator::WaitingTimes(std::vector<int>* waiting_times) {
149 if (!waiting_times) {
152 waiting_times->assign(waiting_times_, waiting_times_ + len_waiting_times_);
153 ResetWaitingTimeStatistics();
156 int StatisticsCalculator::CalculateQ14Ratio(uint32_t numerator,
157 uint32_t denominator) {
158 if (numerator == 0) {
160 } else if (numerator < denominator) {
161 // Ratio must be smaller than 1 in Q14.
162 assert((numerator << 14) / denominator < (1 << 14));
163 return (numerator << 14) / denominator;
165 // Will not produce a ratio larger than 1, since this is probably an error.
170 } // namespace webrtc