13
0

Add a DSPLoadCalculator class to the PortAudioBackend for DSP load calculation

The class uses the same algorithm as in the coreaudio and alsa backends and
should probably go into libardour at some point
This commit is contained in:
Tim Mayberry 2015-08-27 17:09:04 +10:00
parent cb7bac5599
commit a65b1ddedc
3 changed files with 102 additions and 11 deletions

View File

@ -0,0 +1,88 @@
/*
* Copyright (C) 2015 Tim Mayberry <mojofunk@gmail.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#ifndef DSP_LOAD_CALCULATOR_H
#define DSP_LOAD_CALCULATOR_H
#include <stdint.h>
class DSPLoadCalculator {
public:
DSPLoadCalculator()
: m_max_time_us(0)
, m_start_timestamp_us(0)
, m_stop_timestamp_us(0)
, m_dsp_load(0.0f)
{
}
void set_max_time_us(uint64_t max_time_us) { m_max_time_us = max_time_us; }
uint64_t get_max_time_us() { return m_max_time_us; }
void set_start_timestamp_us(uint64_t start_timestamp_us)
{
m_start_timestamp_us = start_timestamp_us;
}
void set_stop_timestamp_us(uint64_t stop_timestamp_us)
{
m_stop_timestamp_us = stop_timestamp_us;
if (elapsed_time_us() > m_max_time_us) {
m_dsp_load = 1.0f;
} else {
const float load = elapsed_time_us() / (float)m_max_time_us;
if (load > m_dsp_load) {
m_dsp_load = load;
} else {
const float alpha = 0.2f * (m_max_time_us * 1e-6f);
m_dsp_load = m_dsp_load + alpha * (load - m_dsp_load) + 1e-12;
}
}
}
uint64_t elapsed_time_us()
{
return m_stop_timestamp_us - m_start_timestamp_us;
}
/**
* @return a decimal value between 0.0 and 1.0 representing the percentage
* of time spent between start and stop in proportion to the max expected time
* in microseconds(us).
*/
float get_dsp_load()
{
if (m_dsp_load > m_max_time_us) {
return 1.0f;
}
if (m_dsp_load < 0.0f) {
return 0.0f;
}
return m_dsp_load;
}
private:
uint64_t m_max_time_us;
uint64_t m_start_timestamp_us;
uint64_t m_stop_timestamp_us;
float m_dsp_load;
};
#endif // DSP_LOAD_CALCULATOR_H

View File

@ -516,6 +516,8 @@ PortAudioBackend::_start (bool for_latency_measurement)
m_cycle_timer.set_samplerate(_samplerate);
m_cycle_timer.set_samples_per_cycle(_samples_per_period);
m_dsp_calc.set_max_time_us (m_cycle_timer.get_length_us());
DEBUG_MIDI ("Registering MIDI ports\n");
if (register_system_midi_ports () != 0) {
@ -1477,13 +1479,10 @@ bool
PortAudioBackend::blocking_process_main ()
{
uint32_t i = 0;
uint64_t clock1, clock2;
int64_t min_elapsed_us = 1000000;
int64_t max_elapsed_us = 0;
const int64_t nomial_time = 1e6 * _samples_per_period / _samplerate;
// const int64_t nomial_time = m_cycle_timer.get_length_us();
uint64_t min_elapsed_us = 1000000;
uint64_t max_elapsed_us = 0;
clock1 = utils::get_microseconds();
m_dsp_calc.set_start_timestamp_us (utils::get_microseconds());
/* get audio */
i = 0;
@ -1605,12 +1604,13 @@ PortAudioBackend::blocking_process_main ()
_processed_samples += _samples_per_period;
/* calculate DSP load */
clock2 = utils::get_microseconds();
const int64_t elapsed_time = clock2 - clock1;
_dsp_load = elapsed_time / (float)nomial_time;
m_dsp_calc.set_stop_timestamp_us (utils::get_microseconds());
_dsp_load = m_dsp_calc.get_dsp_load();
max_elapsed_us = std::max(elapsed_time, max_elapsed_us);
min_elapsed_us = std::min(elapsed_time, min_elapsed_us);
DEBUG_TIMING(string_compose("DSP Load: %1\n", _dsp_load));
max_elapsed_us = std::max(m_dsp_calc.elapsed_time_us(), max_elapsed_us);
min_elapsed_us = std::min(m_dsp_calc.elapsed_time_us(), min_elapsed_us);
if ((m_cycle_count % 1000) == 0) {
DEBUG_TIMING(string_compose("Elapsed process time(usecs) max: %1, min: %2\n",
max_elapsed_us,

View File

@ -35,6 +35,7 @@
#include "portaudio_io.h"
#include "winmmemidi_io.h"
#include "cycle_timer.h"
#include "dsp_load_calculator.h"
namespace ARDOUR {
@ -338,6 +339,8 @@ class PortAudioBackend : public AudioBackend {
bool _freewheeling;
bool _measure_latency;
DSPLoadCalculator m_dsp_calc;
uint64_t m_cycle_count;
uint64_t m_total_deviation_us;
uint64_t m_max_deviation_us;