From 20a2a2d9a25ba8495ef3166caa4efd3da3837fe6 Mon Sep 17 00:00:00 2001 From: Fred Gleason Date: Thu, 30 Oct 2014 17:30:16 -0400 Subject: [PATCH] 2014-10-30 Fred Gleason * Added a 'DSP Utilization' readout for rdhpiinfo(8) in 'utils/rdhpiinfo/rdhpiinfo.cpp' and 'utils/rdhpiinfo/rdhpiinfo.h'. * Added a 'Profile Details' dialog for rdhpiinfo(8) in 'utils/rdhpiinfo/virtdetails.cpp' and 'utils/rdhpiinfo/virtdetails.h'. --- ChangeLog | 5 + utils/rdhpiinfo/Makefile.am | 6 +- utils/rdhpiinfo/rdhpiinfo.cpp | 126 +++++++++++++++----- utils/rdhpiinfo/rdhpiinfo.h | 14 ++- utils/rdhpiinfo/virtdetails.cpp | 200 ++++++++++++++++++++++++++++++++ utils/rdhpiinfo/virtdetails.h | 66 +++++++++++ 6 files changed, 381 insertions(+), 36 deletions(-) create mode 100644 utils/rdhpiinfo/virtdetails.cpp create mode 100644 utils/rdhpiinfo/virtdetails.h diff --git a/ChangeLog b/ChangeLog index fe892590..da9f8fa9 100644 --- a/ChangeLog +++ b/ChangeLog @@ -14616,3 +14616,8 @@ 2014-10-30 Fred Gleason * Fixed a regression in 'lib/rdsimpleplayer.cpp' that cause play start position to be set incorrectly. +2014-10-30 Fred Gleason + * Added a 'DSP Utilization' readout for rdhpiinfo(8) in + 'utils/rdhpiinfo/rdhpiinfo.cpp' and 'utils/rdhpiinfo/rdhpiinfo.h'. + * Added a 'Profile Details' dialog for rdhpiinfo(8) in + 'utils/rdhpiinfo/virtdetails.cpp' and 'utils/rdhpiinfo/virtdetails.h'. diff --git a/utils/rdhpiinfo/Makefile.am b/utils/rdhpiinfo/Makefile.am index 3925d9f4..e2139870 100644 --- a/utils/rdhpiinfo/Makefile.am +++ b/utils/rdhpiinfo/Makefile.am @@ -33,10 +33,12 @@ moc_%.cpp: %.h bin_PROGRAMS = rdhpiinfo dist_rdhpiinfo_SOURCES = change_mode.cpp change_mode.h\ - rdhpiinfo.cpp rdhpiinfo.h + rdhpiinfo.cpp rdhpiinfo.h\ + virtdetails.cpp virtdetails.h nodist_rdhpiinfo_SOURCES = moc_change_mode.cpp\ - moc_rdhpiinfo.cpp + moc_rdhpiinfo.cpp\ + moc_virtdetails.cpp rdhpiinfo_LDADD = @LIB_RDLIBS@ @LIBVORBIS@ @LIBHPI@ diff --git a/utils/rdhpiinfo/rdhpiinfo.cpp b/utils/rdhpiinfo/rdhpiinfo.cpp index c47f8db2..cf4b92ed 100644 --- a/utils/rdhpiinfo/rdhpiinfo.cpp +++ b/utils/rdhpiinfo/rdhpiinfo.cpp @@ -30,8 +30,9 @@ #include -#include -#include +#include "rdhpiinfo.h" +#include "change_mode.h" +#include "virtdetails.h" MainWidget::MainWidget(QWidget *parent,const char *name) :QWidget(parent,name) @@ -170,25 +171,42 @@ MainWidget::MainWidget(QWidget *parent,const char *name) info_adapter_label->setFont(font); info_adapter_label->setAlignment(AlignLeft|AlignVCenter); + // + // DSP Utilization + // + info_utilization_label=new QLabel(tr("DSP Utilization")+":",this); + info_utilization_label->setGeometry(10,183,105,20); + info_utilization_label->setFont(label_font); + info_utilization_label->setAlignment(Qt::AlignRight|Qt::AlignVCenter); + info_utilization_label->setDisabled(true); + info_utilization_edit=new QLineEdit(this); + info_utilization_edit->setGeometry(120,183,60,20); + info_utilization_edit->setFont(font); + info_utilization_edit->setReadOnly(true); + info_utilization_edit->setDisabled(true); + info_utilization_button=new QPushButton(tr("Details"),this); + info_utilization_button->setGeometry(190,180,70,26); + info_utilization_button->setFont(font); + info_utilization_button->setDisabled(true); + connect(info_utilization_button,SIGNAL(clicked()), + this,SLOT(utilizationData())); + // // Adapter Mode // label=new QLabel(tr("Adapter Mode:"),this); - label->setGeometry(10,178,105,20); + label->setGeometry(10,213,105,20); label->setFont(label_font); label->setAlignment(AlignRight|AlignVCenter); - info_mode_label=new QLabel(this); - info_mode_label->setGeometry(120,178,sizeHint().width()-130,20); - info_mode_label->setFont(font); - info_mode_label->setAlignment(AlignLeft|AlignVCenter); - - // - // Change Mode Button - // + info_mode_edit=new QLineEdit(this); + info_mode_edit->setGeometry(120,213,sizeHint().width()-210,20); + info_mode_edit->setReadOnly(true); + info_mode_edit->setFont(font); + info_mode_edit->setAlignment(AlignLeft|AlignVCenter); info_changemode_button= - new QPushButton(tr("Change Card Mode"),this); - info_changemode_button->setGeometry(130,200,170,30); - info_changemode_button->setFont(label_font); + new QPushButton(tr("Change"),this); + info_changemode_button->setGeometry(sizeHint().width()-80,210,70,26); + info_changemode_button->setFont(font); connect(info_changemode_button,SIGNAL(clicked()), this,SLOT(changeModeData())); @@ -201,8 +219,14 @@ MainWidget::MainWidget(QWidget *parent,const char *name) connect(button,SIGNAL(clicked()),qApp,SLOT(quit())); LoadAdapters(); + + hpi_profile_timer=new QTimer(this); + connect(hpi_profile_timer,SIGNAL(timeout()), + this,SLOT(updateDspUtilization())); + if(info_name_box->count()>0) { nameActivatedData(0); + hpi_profile_timer->start(1000); } } @@ -215,7 +239,7 @@ MainWidget::~MainWidget() QSize MainWidget::sizeHint() const { - return QSize(400,250); + return QSize(400,290); } @@ -246,77 +270,77 @@ void MainWidget::nameActivatedData(int id) hpi_card_version[card]&7)); switch(hpi_mode[card]) { case 0: // No mode support - info_mode_label->setText(tr("Standard")); + info_mode_edit->setText(tr("Standard")); info_changemode_button->setDisabled(true); break; case HPI_ADAPTER_MODE_4OSTREAM: - info_mode_label->setText(tr("Four Output Streams")); + info_mode_edit->setText(tr("Four Output Streams")); info_changemode_button->setEnabled(true); break; case HPI_ADAPTER_MODE_6OSTREAM: - info_mode_label->setText(tr("Six Output Streams")); + info_mode_edit->setText(tr("Six Output Streams")); info_changemode_button->setEnabled(true); break; case HPI_ADAPTER_MODE_8OSTREAM: - info_mode_label->setText(tr("Eight Output Streams")); + info_mode_edit->setText(tr("Eight Output Streams")); info_changemode_button->setEnabled(true); break; case HPI_ADAPTER_MODE_12OSTREAM: - info_mode_label->setText(tr("Twelve Output Streams")); + info_mode_edit->setText(tr("Twelve Output Streams")); info_changemode_button->setEnabled(true); break; case HPI_ADAPTER_MODE_16OSTREAM: - info_mode_label->setText(tr("Sixteen Output Streams")); + info_mode_edit->setText(tr("Sixteen Output Streams")); info_changemode_button->setEnabled(true); break; case HPI_ADAPTER_MODE_1OSTREAM: - info_mode_label->setText(tr("One Output Stream")); + info_mode_edit->setText(tr("One Output Stream")); info_changemode_button->setEnabled(true); break; case HPI_ADAPTER_MODE_1: - info_mode_label->setText(tr("Mode 1")); + info_mode_edit->setText(tr("Mode 1")); info_changemode_button->setEnabled(true); break; case HPI_ADAPTER_MODE_2: - info_mode_label->setText(tr("Mode 2")); + info_mode_edit->setText(tr("Mode 2")); info_changemode_button->setEnabled(true); break; case HPI_ADAPTER_MODE_3: - info_mode_label->setText(tr("Mode 3")); + info_mode_edit->setText(tr("Mode 3")); info_changemode_button->setEnabled(true); break; case HPI_ADAPTER_MODE_MULTICHANNEL: - info_mode_label->setText(tr("Surround Sound [SSX]")); + info_mode_edit->setText(tr("Surround Sound [SSX]")); info_changemode_button->setEnabled(true); break; case HPI_ADAPTER_MODE_9OSTREAM: - info_mode_label->setText(tr("Nine Output Stream")); + info_mode_edit->setText(tr("Nine Output Stream")); info_changemode_button->setEnabled(true); break; case HPI_ADAPTER_MODE_MONO: - info_mode_label->setText(tr("Mono Mode")); + info_mode_edit->setText(tr("Mono Mode")); info_changemode_button->setEnabled(true); break; case HPI_ADAPTER_MODE_LOW_LATENCY: - info_mode_label->setText(tr("Low Latency Mode")); + info_mode_edit->setText(tr("Low Latency Mode")); info_changemode_button->setEnabled(true); break; default: - info_mode_label->setText(tr("N/A")); + info_mode_edit->setText(tr("N/A")); info_changemode_button->setDisabled(true); if(hpi_mode[card]!=hpi_serial[card]) { str=QString(tr("rdhpiinfo: unknown adapter mode")); @@ -357,6 +381,41 @@ void MainWidget::changeModeData() } +void MainWidget::utilizationData() +{ + VirtDetails *d=new VirtDetails(hpi_indexes[info_name_box->currentItem()], + hpi_profile[info_name_box->currentItem()], + hpi_profile_quan[info_name_box->currentItem()], + this); + hpi_profile_timer->stop(); + d->exec(); + hpi_profile_timer->start(1000); + delete d; +} + + +void MainWidget::updateDspUtilization() +{ + uint32_t util=0; + + if(HpiErr(HPI_ProfileGetUtilization(NULL, + hpi_profile[info_name_box->currentItem()], + &util))==0) { + info_utilization_edit->setText(QString().sprintf("%5.1lf%%", + (double)util/100.0)); + info_utilization_label->setEnabled(true); + info_utilization_edit->setEnabled(true); + info_utilization_button->setEnabled(true); + } + else { + info_utilization_edit->setText("xx.x"); + info_utilization_label->setDisabled(true); + info_utilization_edit->setDisabled(true); + info_utilization_button->setDisabled(true); + } +} + + void MainWidget::LoadAdapters() { int num_adapters; @@ -382,17 +441,19 @@ void MainWidget::LoadAdapters() HpiErr(HPI_AdapterGetMode(NULL,hpi_indexes[i],&hpi_mode[i]), "HPI_AdapterGetMode"); HpiErr(HPI_AdapterClose(NULL,hpi_indexes[i]),"HPI_AdapterClose"); + HpiErr(HPI_ProfileOpenAll(NULL,hpi_indexes[i],0,&hpi_profile[i], + &hpi_profile_quan[i])); } } } -void MainWidget::HpiErr(hpi_err_t err,const char *func_name) const +hpi_err_t MainWidget::HpiErr(hpi_err_t err,const char *func_name) const { char hpi_str[200]; if(err==HPI_ERROR_INVALID_FUNC) { - return; + return err; } if(err!=0) { HPI_GetErrorText(err,hpi_str); @@ -403,6 +464,7 @@ void MainWidget::HpiErr(hpi_err_t err,const char *func_name) const fprintf(stderr,"rdhpiinfo[%s]: %s\n",func_name,hpi_str); } } + return err; } diff --git a/utils/rdhpiinfo/rdhpiinfo.h b/utils/rdhpiinfo/rdhpiinfo.h index a0509e95..cb63baaf 100644 --- a/utils/rdhpiinfo/rdhpiinfo.h +++ b/utils/rdhpiinfo/rdhpiinfo.h @@ -27,7 +27,9 @@ #include #include #include +#include #include +#include #include #if HPI_VER < 0x040600 @@ -49,19 +51,24 @@ class MainWidget : public QWidget private slots: void nameActivatedData(int id); void changeModeData(); + void utilizationData(); + void updateDspUtilization(); private: void LoadAdapters(); - void HpiErr(hpi_err_t err,const char *func_name=0) const; + hpi_err_t HpiErr(hpi_err_t err,const char *func_name=0) const; QLabel *info_name_label; QComboBox *info_name_box; + QLabel *info_utilization_label; + QLineEdit *info_utilization_edit; + QPushButton *info_utilization_button; QLabel *info_index_label; QLabel *info_serial_label; QLabel *info_istreams_label; QLabel *info_ostreams_label; QLabel *info_dsp_label; QLabel *info_adapter_label; - QLabel *info_mode_label; + QLineEdit *info_mode_edit; QPushButton *info_changemode_button; uint32_t hpi_version; QString hpi_name[HPI_MAX_ADAPTERS]; @@ -73,6 +80,9 @@ class MainWidget : public QWidget uint32_t hpi_serial[HPI_MAX_ADAPTERS]; uint16_t hpi_type[HPI_MAX_ADAPTERS]; uint32_t hpi_mode[HPI_MAX_ADAPTERS]; + hpi_handle_t hpi_profile[HPI_MAX_ADAPTERS]; + uint16_t hpi_profile_quan[HPI_MAX_ADAPTERS]; + QTimer *hpi_profile_timer; }; diff --git a/utils/rdhpiinfo/virtdetails.cpp b/utils/rdhpiinfo/virtdetails.cpp new file mode 100644 index 00000000..665f0054 --- /dev/null +++ b/utils/rdhpiinfo/virtdetails.cpp @@ -0,0 +1,200 @@ +// virtdetails.cpp +// +// Show profile details for an AudioScience adapter. +// +// (C) Copyright 2014 Fred Gleason +// +// This program is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License version 2 as +// published by the Free Software Foundation. +// +// 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. +// + +#include +#include +#include + +#include "virtdetails.h" + +VirtDetails::VirtDetails(uint16_t card,hpi_handle_t profile, + uint16_t profile_quan,QWidget *parent) + : QDialog(parent,"",true) +{ + char name[200]; + + virt_card=card; + virt_profile=profile; + + // + // Fix the Window Size + // + setMinimumWidth(sizeHint().width()); + setMaximumWidth(sizeHint().width()); + setMinimumHeight(sizeHint().height()); + setMaximumHeight(sizeHint().height()); + + setCaption(tr("RdHPIInfo - Profile Details")); + + // + // Create Fonts + // + QFont font=QFont("Helvetica",12,QFont::Normal); + font.setPixelSize(12); + QFont label_font=QFont("Helvetica",12,QFont::Bold); + label_font.setPixelSize(12); + + // + // Adapter Mode + // + virt_profile_box=new QComboBox(this); + virt_profile_box->setGeometry(75,10,sizeHint().width()-85,20); + virt_profile_box->setFont(font); + virt_profile_label=new QLabel(virt_profile_box,tr("Profile")+":",this); + virt_profile_label->setGeometry(10,10,60,20); + virt_profile_label->setFont(label_font); + virt_profile_label->setAlignment(Qt::AlignRight|Qt::AlignVCenter); + for(uint16_t i=0;iinsertItem(name); + } + } + } + + // + // Utilization Counter + // + virt_utilization_label=new QLabel(tr("Overall DSP Utilization")+":",this); + virt_utilization_label->setGeometry(10,35,160,20); + virt_utilization_label->setFont(label_font); + virt_utilization_label->setAlignment(Qt::AlignRight|Qt::AlignVCenter); + virt_utilization_edit=new QLineEdit(this); + virt_utilization_edit->setGeometry(175,35,90,20); + virt_utilization_edit->setFont(font); + virt_utilization_edit->setReadOnly(true); + + // + // Profile Interval Counter + // + virt_interval_label=new QLabel(tr("Profile Interval")+":",this); + virt_interval_label->setGeometry(10,57,160,20); + virt_interval_label->setFont(label_font); + virt_interval_label->setAlignment(Qt::AlignRight|Qt::AlignVCenter); + virt_interval_edit=new QLineEdit(this); + virt_interval_edit->setGeometry(175,57,90,20); + virt_interval_edit->setFont(font); + virt_interval_edit->setReadOnly(true); + + // + // Total Tick Count Counter + // + virt_total_ticks_label=new QLabel(tr("Total Tick Count")+":",this); + virt_total_ticks_label->setGeometry(10,79,160,20); + virt_total_ticks_label->setFont(label_font); + virt_total_ticks_label->setAlignment(Qt::AlignRight|Qt::AlignVCenter); + virt_total_ticks_edit=new QLineEdit(this); + virt_total_ticks_edit->setGeometry(175,79,90,20); + virt_total_ticks_edit->setFont(font); + virt_total_ticks_edit->setReadOnly(true); + + // + // Call Count Counter + // + virt_call_count_label=new QLabel(tr("Call Count")+":",this); + virt_call_count_label->setGeometry(10,101,160,20); + virt_call_count_label->setFont(label_font); + virt_call_count_label->setAlignment(Qt::AlignRight|Qt::AlignVCenter); + virt_call_count_edit=new QLineEdit(this); + virt_call_count_edit->setGeometry(175,101,90,20); + virt_call_count_edit->setFont(font); + virt_call_count_edit->setReadOnly(true); + + // + // Maximum Ticks Counter + // + virt_max_ticks_label=new QLabel(tr("Maximum Ticks / Pass")+":",this); + virt_max_ticks_label->setGeometry(10,123,160,20); + virt_max_ticks_label->setFont(label_font); + virt_max_ticks_label->setAlignment(Qt::AlignRight|Qt::AlignVCenter); + virt_max_ticks_edit=new QLineEdit(this); + virt_max_ticks_edit->setGeometry(175,123,90,20); + virt_max_ticks_edit->setFont(font); + virt_max_ticks_edit->setReadOnly(true); + + // + // Ticks per Millisecond Counter + // + virt_ticks_per_ms_label=new QLabel(tr("Ticks / mS")+":",this); + virt_ticks_per_ms_label->setGeometry(10,145,160,20); + virt_ticks_per_ms_label->setFont(label_font); + virt_ticks_per_ms_label->setAlignment(Qt::AlignRight|Qt::AlignVCenter); + virt_ticks_per_ms_edit=new QLineEdit(this); + virt_ticks_per_ms_edit->setGeometry(175,145,90,20); + virt_ticks_per_ms_edit->setFont(font); + virt_ticks_per_ms_edit->setReadOnly(true); + + // + // Close Button + // + QPushButton *close_button=new QPushButton(this); + close_button->setGeometry(sizeHint().width()-70,sizeHint().height()-40, + 60,30); + close_button->setFont(font); + close_button->setText(tr("&Close")); + connect(close_button,SIGNAL(clicked()),this,SLOT(closeData())); + + QTimer *timer=new QTimer(this); + connect(timer,SIGNAL(timeout()),this,SLOT(updateProfileData())); + timer->start(1000); +} + + +QSize VirtDetails::sizeHint() const +{ + return QSize(280,222); +} + + +QSizePolicy VirtDetails::sizePolicy() const +{ + return QSizePolicy(QSizePolicy::Fixed,QSizePolicy::Fixed); +} + + +void VirtDetails::updateProfileData() +{ + uint32_t utilization; + uint16_t interval; + uint32_t total_ticks; + uint32_t call_count; + uint32_t max_ticks; + uint32_t ticks_per_ms; + + if(HPI_ProfileGetUtilization(NULL,virt_profile,&utilization)==0) { + virt_utilization_edit-> + setText(QString().sprintf("%5.1lf%%",(double)utilization/100.0)); + } + if(HPI_ProfileGet(NULL,virt_profile,virt_profile_box->currentItem(), + &interval,&total_ticks,&call_count,&max_ticks, + &ticks_per_ms)==0) { + virt_interval_edit->setText(QString().sprintf("%u sec",interval)); + virt_total_ticks_edit->setText(QString().sprintf("%u",total_ticks)); + virt_call_count_edit->setText(QString().sprintf("%u",call_count)); + virt_max_ticks_edit->setText(QString().sprintf("%u",max_ticks)); + virt_ticks_per_ms_edit->setText(QString().sprintf("%u",ticks_per_ms)); + } +} + + +void VirtDetails::closeData() +{ + done(0); +} diff --git a/utils/rdhpiinfo/virtdetails.h b/utils/rdhpiinfo/virtdetails.h new file mode 100644 index 00000000..8082d419 --- /dev/null +++ b/utils/rdhpiinfo/virtdetails.h @@ -0,0 +1,66 @@ +// virtdetails.h +// +// Show profiling data for an AudioScience adapter +// +// (C) Copyright 2014 Fred Gleason +// +// This program is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License version 2 as +// published by the Free Software Foundation. +// +// 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 VIRTDETAILS_H +#define VIRTDETAILS_H + +#include + +#include +#include +#include +#include + +#include + +class VirtDetails : public QDialog +{ + Q_OBJECT + public: + VirtDetails(uint16_t card,hpi_handle_t profile,uint16_t profile_quan, + QWidget *parent=0); + QSize sizeHint() const; + QSizePolicy sizePolicy() const; + +private slots: + void updateProfileData(); + void closeData(); + + private: + uint16_t virt_card; + hpi_handle_t virt_profile; + QLabel *virt_utilization_label; + QLineEdit *virt_utilization_edit; + QLabel *virt_profile_label; + QComboBox *virt_profile_box; + QLabel *virt_interval_label; + QLineEdit *virt_interval_edit; + QLabel *virt_total_ticks_label; + QLineEdit *virt_total_ticks_edit; + QLabel *virt_call_count_label; + QLineEdit *virt_call_count_edit; + QLabel *virt_max_ticks_label; + QLineEdit *virt_max_ticks_edit; + QLabel *virt_ticks_per_ms_label; + QLineEdit *virt_ticks_per_ms_edit; +}; + + +#endif // VIRTDETAILS_H