Select Git revision
RedstartWindow.cpp

Dipl.-Ing. Jonas Stienen authored
Code owners
Assign users and groups as approvers for specific file changes. Learn more.
RedstartWindow.cpp 32.49 KiB
/*
* --------------------------------------------------------------------------------------------
*
* VVV VVV A Virtual Acoustics (VA) | http://www.virtualacoustics.org
* VVV VVV AAA Licensed under the Apache License, Version 2.0
* VVV VVV AAA
* VVV VVV AAA Copyright 2015-2017
* VVVVVV AAA Institute of Technical Acoustics (ITA)
* VVVV AAA RWTH Aachen University
*
* --------------------------------------------------------------------------------------------
*/
#include <QErrorMessage>
#include <QUrl>
#include <QDesktopServices>
#include <QHash>
#include <QShortcut>
#include <QFileDialog>
#include "RedstartWindow.h"
#include <ui_RedstartWindow.h>
#include "RedstartRunSimpleExample.h"
#include "RedstartSessionBinauralHeadphonesDialog.h"
#include "RedstartSessionExperimentalTalkthroughDialog.h"
#include "RedstartSessionImportDialog.h"
#include "RedstartSessionWizardDialog.h"
#include "RedstartUtils.h"
#include "RedstartCoreOutputPlainTextEdit.h"
#include "RedstartRunCirculatingSourceDialog.h"
#include <VA.h>
#include <VACore.h>
#include <VANet.h>
#include <ITAAsioInterface.h>
#include <ITAPortaudioInterface.h>
#include <ITAException.h>
#include <ITANumericUtils.h>
RedstartWindow::RedstartWindow( bool bFailSafeMode, bool bAutoStart, bool bSkipConfig, QWidget* pParent )
: QMainWindow( pParent )
, ui( new Ui::RedstartWindow )
, m_pVAInterface( NULL )
{
ui->setupUi( this );
ui->statusBar->showMessage( "Welcome to VA." );
// Shortcuts
QShortcut* start_b = new QShortcut( this );
start_b->setKey( Qt::Key_F5 );
start_b->setContext( Qt::WindowShortcut );
QShortcut* start_c = new QShortcut( this );
start_c->setKey( QKeySequence( tr( "CTRL+R" ) ) );
start_c->setContext( Qt::WindowShortcut );
connect( start_b, SIGNAL( activated() ), this, SLOT( on_pushButton_start_stop_clicked() ) );
connect( start_c, SIGNAL( activated() ), this, SLOT( on_pushButton_start_stop_clicked() ) );
m_pVANetServer = IVANetServer::Create();
m_pVANetClient = IVANetClient::Create();
ui->comboBox_audio_driver->addItem( "ASIO" );
ui->comboBox_audio_driver->addItem( "Portaudio" );
ui->comboBox_audio_iface_sampling_rate->addItem( "44.1 kHz", AudioSamplingRate::FS_44kHz );
ui->comboBox_audio_iface_sampling_rate->addItem( "48 kHz", AudioSamplingRate::FS_48kHz );
//ui->comboBox_audio_iface_sampling_rate->addItem( "96 kHz", AudioSamplingRate::FS_96kHz );
ui->comboBox_audio_iface_buffer_size->addItem( "AUTO", AudioBufferSize::AUTO );
m_iPortaudioDefaultDevice = -1;
if( !bSkipConfig )
LoadConfiguration();
// Signals & slots
ConnectSignalsAndSlots();
ui->menuRun->setEnabled( false );
if( ui->checkBox_redstart_network_connect_as_client->isChecked() )
ui->groupBox_redstart_audio_iface->setEnabled( false );
if( ( ui->checkBox_redstart_auto_start->isChecked() || bAutoStart ) && !bFailSafeMode )
on_pushButton_start_stop_clicked();
m_pCirculatingSourceDialog = new RedstartRunCirculatingSourceDialog( this );
}
RedstartWindow::~RedstartWindow()
{
StoreConfiguration();
if( m_pVANetServer->IsClientConnected() )
{
m_pVANetServer->Finalize();
delete m_pVAInterface;
}
delete m_pVANetServer;
if( m_pVANetClient->IsConnected() )
m_pVANetClient->Disconnect();
delete m_pVANetClient;
}
void RedstartWindow::ConnectSignalsAndSlots()
{
// Input control
connect( ui->doubleSpinBox_input_gain, SIGNAL( valueChanged( double ) ), this, SLOT( CoreChangeInputSignalDecibel( double ) ) );
connect( this, SIGNAL( InputSignalChangedDecibel( double ) ), ui->doubleSpinBox_input_gain, SLOT( setValue( double ) ) );
connect( ui->dial_core_control_input_gain, SIGNAL( valueChanged( int ) ), this, SLOT( CoreChangeInputSignalDecibel( int ) ) );
connect( this, SIGNAL( InputSignalChangedDecibel( int ) ), ui->dial_core_control_input_gain, SLOT( setValue( int ) ) );
connect( this, SIGNAL( InputIsMutedChanged( bool ) ), ui->checkBox_core_control_input_mute, SLOT( setChecked( bool ) ) );
connect( ui->checkBox_core_control_input_mute, SIGNAL( stateChanged( int ) ), this, SLOT( CoreChangeInputIsMuted( int ) ) );
// Output control
connect( ui->doubleSpinBox_output_gain, SIGNAL( valueChanged( double ) ), this, SLOT( CoreChangeOutputSignalDecibel( double ) ) );
connect( this, SIGNAL( OutputSignalChangedDecibel( double ) ), ui->doubleSpinBox_output_gain, SLOT( setValue( double ) ) );
connect( ui->dial_core_control_output_gain, SIGNAL( valueChanged( int ) ), this, SLOT( CoreChangeOutputSignalDecibel( int ) ) );
connect( this, SIGNAL( OutputSignalChangedDecibel( int ) ), ui->dial_core_control_output_gain, SLOT( setValue( int ) ) );
connect( this, SIGNAL( OutputIsMutedChanged( bool ) ), ui->checkBox_core_control_output_mute, SLOT( setChecked( bool ) ) );
connect( ui->checkBox_core_control_output_mute, SIGNAL( stateChanged( int ) ), this, SLOT( CoreChangeOutputIsMuted( int ) ) );
//connect( &m_qRenderTimer, SIGNAL( timeout() ), this, SLOT( Render() ) );
}
void RedstartWindow::LoadConfiguration()
{
RestoreWindowSize();
bool bValOK;
int iAudioBackend = m_qSettings.value( "Redstart/audio/backend_idx" ).toInt( &bValOK );
if( !bValOK )
iAudioBackend = AudioBackend::ASIO;
ui->comboBox_audio_driver->setCurrentIndex( iAudioBackend );
const int iBufferSizeIndex = m_qSettings.value( "Redstart/audio/buffersize_idx" ).toInt( &bValOK );
if( bValOK && iBufferSizeIndex < ui->comboBox_audio_iface_buffer_size->count() )
ui->comboBox_audio_iface_buffer_size->setCurrentIndex( iBufferSizeIndex );
const int iSamplingRateIndex = m_qSettings.value( "Redstart/audio/fs_idx" ).toInt( &bValOK );
if( bValOK && iSamplingRateIndex < ui->comboBox_audio_iface_sampling_rate->count() )
ui->comboBox_audio_iface_sampling_rate->setCurrentIndex( iSamplingRateIndex );
if( m_qSettings.contains( "Redstart/network/address" ) )
ui->lineEdit_redstart_network_address->setText( m_qSettings.value( "Redstart/network/address" ).toString() );
if( m_qSettings.contains( "Redstart/network/port" ) )
ui->lineEdit_redstart_network_address->setText( m_qSettings.value( "Redstart/network/port" ).toString() );
ui->checkBox_redstart_network_connect_as_client->setChecked( m_qSettings.value( "Redstart/network/client_mode" ).toBool() );
if( m_qSettings.contains( "Redstart/autostart" ) )
{
bool bAutostart = m_qSettings.value( "Redstart/autostart" ).toBool();
ui->checkBox_redstart_auto_start->setChecked( bAutostart );
}
m_iPortaudioDefaultDevice = m_qSettings.value( "Redstart/audio/portaudio_default_device", -1 ).toInt();
ui->checkBox_portaudio_default_device->setChecked( m_qSettings.value( "Redstart/audio/portaudio_use_default_device", true ).toBool() );
QVariantList voAudioDevices;
voAudioDevices = m_qSettings.value( "Redstart/audio/devicelist" ).toList();
for( const QVariant oAudioDevice : voAudioDevices )
m_voAudioDevices.push_back( CAudioDeviceSpecs( oAudioDevice.toHash() ) );
PopulateAudioDevices();
int iLastDevice = m_qSettings.value( "Redstart/audio/current_device", 0 ).toInt( &bValOK );
if( bValOK && ui->comboBox_audio_iface_device->count() >= iLastDevice )
ui->comboBox_audio_iface_device->setCurrentIndex( iLastDevice );
// Core control
ui->comboBox_core_settings_log_level->addItem( QString::fromStdString( m_pVAInterface->GetLogLevelStr( IVAInterface::VA_LOG_LEVEL_QUIET ) ) );
ui->comboBox_core_settings_log_level->addItem( QString::fromStdString( m_pVAInterface->GetLogLevelStr( IVAInterface::VA_LOG_LEVEL_ERROR ) ) );
ui->comboBox_core_settings_log_level->addItem( QString::fromStdString( m_pVAInterface->GetLogLevelStr( IVAInterface::VA_LOG_LEVEL_WARNING ) ) );
ui->comboBox_core_settings_log_level->addItem( QString::fromStdString( m_pVAInterface->GetLogLevelStr( IVAInterface::VA_LOG_LEVEL_INFO ) ) );
ui->comboBox_core_settings_log_level->addItem( QString::fromStdString( m_pVAInterface->GetLogLevelStr( IVAInterface::VA_LOG_LEVEL_VERBOSE ) ) );
ui->comboBox_core_settings_log_level->addItem( QString::fromStdString( m_pVAInterface->GetLogLevelStr( IVAInterface::VA_LOG_LEVEL_TRACE ) ) );
if( ui->listView_redstart_session_list->GetCurrentSessionID().isEmpty() == false )
ui->treeView_session_details->SetStruct( ui->listView_redstart_session_list->GetCurrentConfig() );
}
void RedstartWindow::StoreConfiguration()
{
m_qSettings.setValue( "Redstart/gui/WindowGeometry", saveGeometry() );
m_qSettings.setValue( "Redstart/gui/WindowState", saveState() );
m_qSettings.setValue( "Redstart/audio/backend_idx", ui->comboBox_audio_driver->currentIndex() );
m_qSettings.setValue( "Redstart/audio/buffersize_idx", ui->comboBox_audio_iface_buffer_size->currentIndex() );
m_qSettings.setValue( "Redstart/audio/fs_idx", ui->comboBox_audio_iface_sampling_rate->currentIndex() );
m_qSettings.setValue( "Redstart/network/address", ui->lineEdit_redstart_network_address->text() );
bool bValOK;
int iPort = ui->lineEdit_redstart_network_address->text().toInt( &bValOK );
if( bValOK )
m_qSettings.setValue( "Redstart/network/port", iPort );
m_qSettings.setValue( "Redstart/network/client_mode", ui->checkBox_redstart_network_connect_as_client->isChecked() );
bool bAutostart = ui->checkBox_redstart_auto_start->isChecked();
m_qSettings.setValue( "Redstart/autostart", bAutostart );
m_qSettings.setValue( "Redstart/audio/portaudio_default_device", m_iPortaudioDefaultDevice );
int iLastDevice = ui->comboBox_audio_iface_device->currentIndex();
m_qSettings.setValue( "Redstart/audio/current_device", iLastDevice );
m_qSettings.setValue( "Redstart/audio/portaudio_use_default_device", ui->checkBox_portaudio_default_device->isChecked() );
QVariantList voAudioDevices;
for( const CAudioDeviceSpecs& oDevice : m_voAudioDevices )
voAudioDevices.push_back( oDevice.asHash() );
m_qSettings.setValue( "Redstart/audio/devicelist", voAudioDevices );
}
void RedstartWindow::on_actionQuit_triggered()
{
close();
}
void RedstartWindow::PostCoreStart()
{
ui->pushButton_start_stop->setText( "Stop" );
// Switch UI elements enabled
ui->groupBox_redstart_audio_iface->setEnabled( false );
ui->groupBox_redstart_network->setEnabled( false );
ui->groupBox_session_list->setEnabled( false );
ui->groupBox_session_details->setEnabled( false );
ui->groupBox_core->setEnabled( true );
ui->groupBox_paths->setEnabled( true );
ui->groupBox_macros->setEnabled( true );
ui->menuRun->setEnabled( true );
ui->groupBox_core_control->setEnabled( true );
ui->graphicsView_input_levels->setEnabled( true );
ui->graphicsView_output_levels->setEnabled( true );
ui->groupBox_global_am->setEnabled( true );
ui->groupBox_output->setEnabled( true );
CVAVersionInfo oVersion;
m_pVAInterface->GetVersionInfo( &oVersion );
ui->lineEdit_core_settings_version->setText( QString::fromStdString( oVersion.ToString() ) );
CVAStruct oArgs;
oArgs[ "getloglevel" ] = true;
const CVAStruct oReturn = m_pVAInterface->CallModule( "VACore", oArgs );
const int iCurrentLogLevel = oReturn[ "loglevel" ];
ui->comboBox_core_settings_log_level->setCurrentIndex( iCurrentLogLevel );
CVAStruct oSearchPaths = m_pVAInterface->GetSearchPaths();
QStringList sPathList;
CVAStruct::const_iterator cit = oSearchPaths.Begin();
while( cit != oSearchPaths.End() )
{
const CVAStructValue& oValue( cit++->second );
if( oValue.IsString() )
sPathList << std::string( oValue ).c_str();
}
ui->listView_paths; // @todo
}
void RedstartWindow::PostCoreStop()
{
ui->pushButton_start_stop->setText( "Start" );
// Switch UI elements enabled
ui->groupBox_redstart_audio_iface->setEnabled( true );
ui->groupBox_redstart_network->setEnabled( true );
ui->groupBox_session_list->setEnabled( true );
ui->groupBox_session_details->setEnabled( true );
ui->groupBox_core->setEnabled( false );
ui->groupBox_paths->setEnabled( false );
ui->groupBox_macros->setEnabled( false );
ui->menuRun->setEnabled( false );
ui->groupBox_core_control->setEnabled( false );
ui->graphicsView_input_levels->setEnabled( false );
ui->graphicsView_output_levels->setEnabled( false );
ui->groupBox_global_am->setEnabled( false );
ui->groupBox_output->setEnabled( false );
// Clear
ui->lineEdit_core_settings_version->clear();
ui->listView_paths->reset();
// Reset elements
bool bPreserveCoreControlValues = m_qSettings.value( "PreserveCoreControlValues", true ).toBool(); // @todo control this setting via preferences dialog
if( !bPreserveCoreControlValues )
{
emit InputSignalChangedDecibel( 0.0f );
emit OutputSignalChangedDecibel( 0.0f );
emit InputIsMutedChanged( false );
emit OutputIsMutedChanged( false );
}
}
void RedstartWindow::RestoreWindowSize()
{
restoreGeometry( m_qSettings.value( "Redstart/gui/WindowGeometry" ).toByteArray() );
restoreState( m_qSettings.value( "Redstart/gui/WindowState" ).toByteArray() );
}
void RedstartWindow::HandleVAEvent( const CVAEvent* pEvent )
{
// Handle pushable events
switch( pEvent->iEventType )
{
case CVAEvent::VA_EVENT_PROGRESS_UPDATE:
//ui->statusBar->showMessage( pEvent->sParam.c_str() );
break;
case CVAEvent::VA_EVENT_MEASURES_UPDATE:
UpdateMeasures( pEvent->vfInputRMSs, pEvent->vfInputPeaks, pEvent->vfOutputRMSs, pEvent->vfOutputPeaks );
break;
}
/* Don't handle events that have been triggered from this interface connection
if( pEvent->pSender == m_pVAInterface )
return;
*/
switch( pEvent->iEventType )
{
case CVAEvent::VA_EVENT_INPUT_GAIN_CHANGED:
emit InputSignalChangedDecibel( ratio_to_db20( pEvent->dVolume ) );
break;
case CVAEvent::VA_EVENT_OUTPUT_GAIN_CHANGED:
emit OutputSignalChangedDecibel( ratio_to_db20( pEvent->dVolume ) );
break;
case CVAEvent::VA_EVENT_INPUT_MUTING_CHANGED:
emit InputIsMutedChanged( pEvent->bMuted );
break;
case CVAEvent::VA_EVENT_OUTPUT_MUTING_CHANGED:
emit OutputIsMutedChanged( pEvent->bMuted );
break;
}
}
void RedstartWindow::UpdateMeasures( const std::vector< float >& vfInputRMSs, const std::vector< float >& vfInputPeaks, const std::vector< float >& vfOutputRMSs, const std::vector< float >& vfOutputPeaks )
{
// @todo feed level meters
}
void RedstartWindow::AcquireAsioDevices()
{
std::vector< CAudioDeviceSpecs > voAudioDevices = m_voAudioDevices;
try
{
ITAsioInitializeLibrary();
long lDrivers = ITAsioGetNumDrivers();
if( lDrivers <= 0 )
ITA_EXCEPT1( INVALID_PARAMETER, "No ASIO-compatibel drivers could be found on this system." );
m_voAudioDevices.clear();
for( long i = 0; i < lDrivers; i++ )
{
CAudioDeviceSpecs oDeviceSpecs;
oDeviceSpecs.iDriverNumber = i;
oDeviceSpecs.iBackend = AudioBackend::ASIO;
oDeviceSpecs.sName = ITAsioGetDriverName( i );
try
{
ITAsioInitializeDriver( i );
long in = 0;
long out = 0;
ITAsioGetChannels( &in, &out );
oDeviceSpecs.iNumInputChannels = int( in );
oDeviceSpecs.iNumOutputChannels = int( out );
ITAsioFinalizeDriver();
oDeviceSpecs.bInitializable = true;
}
catch( const ITAException& )
{
oDeviceSpecs.bInitializable = false;
continue;
}
if( oDeviceSpecs.bInitializable )
m_voAudioDevices.push_back( oDeviceSpecs );
}
ITAsioFinalizeLibrary();
}
catch( const ITAException& e )
{
QString sErrorMessage = QString( "Error during ASIO device acquisition: %1" ).arg( QString::fromStdString( e.ToString() ) );
QErrorMessage oErrMsg;
oErrMsg.showMessage( sErrorMessage );
oErrMsg.exec();
}
for( const CAudioDeviceSpecs oDevice : voAudioDevices )
if( oDevice.iBackend != AudioBackend::ASIO )
m_voAudioDevices.push_back( oDevice );
}
void RedstartWindow::PopulateAudioDevices()
{
ui->comboBox_audio_iface_device->clear();
int iCurrentBackend = ui->comboBox_audio_driver->currentIndex();
for( const CAudioDeviceSpecs& oDevice : m_voAudioDevices )
{
if( oDevice.iBackend == iCurrentBackend )
ui->comboBox_audio_iface_device->addItem( oDevice.sName, QVariant( oDevice.iDriverNumber ) );
}
if( ui->comboBox_audio_driver->currentIndex() == AudioBackend::PORTAUDIO )
{
ui->checkBox_portaudio_default_device->setEnabled( true );
if( ui->checkBox_portaudio_default_device->isChecked() )
ui->comboBox_audio_iface_device->setEnabled( false );
else
ui->comboBox_audio_iface_device->setEnabled( true );
}
else
{
ui->checkBox_portaudio_default_device->setEnabled( false );
ui->comboBox_audio_iface_device->setEnabled( true );
}
}
void RedstartWindow::AcquirePortaudioDevices()
{
std::vector< CAudioDeviceSpecs > voAudioDevices = m_voAudioDevices;
try
{
ITAPortaudioInterface oPortaudio( 44100, 1024 );
oPortaudio.Initialize();
int lDrivers = oPortaudio.GetNumDevices();
if( lDrivers <= 0 )
ITA_EXCEPT1( INVALID_PARAMETER, "No Portaudio output devices could be found on this system." );
m_iPortaudioDefaultDevice = oPortaudio.GetDefaultOutputDevice();
m_voAudioDevices.clear();
for( long i = 0; i < lDrivers; i++ )
{
CAudioDeviceSpecs oDeviceSpecs;
oDeviceSpecs.iDriverNumber = i;
oDeviceSpecs.iBackend = AudioBackend::PORTAUDIO;
oDeviceSpecs.sName = oPortaudio.GetDeviceName( i ).c_str();
try
{
oPortaudio.GetNumChannels( i, oDeviceSpecs.iNumInputChannels, oDeviceSpecs.iNumOutputChannels );
oDeviceSpecs.bInitializable = true; // only a guess
if( i == oPortaudio.GetDefaultOutputDevice() )
oDeviceSpecs.bDefaultDevice = true;
else
oDeviceSpecs.bDefaultDevice = false;
}
catch( const ITAException& )
{
oDeviceSpecs.bInitializable = false;
continue;
}
if( oDeviceSpecs.bInitializable )
m_voAudioDevices.push_back( oDeviceSpecs );
}
oPortaudio.Finalize();
}
catch( const ITAException& e )
{
QString sErrorMessage = QString( "Error during Portaudio device acquisition: %1" ).arg( QString::fromStdString( e.ToString() ) );
QErrorMessage oErrMsg;
oErrMsg.showMessage( sErrorMessage );
oErrMsg.exec();
}
for( const CAudioDeviceSpecs oDevice : voAudioDevices )
if( oDevice.iBackend != AudioBackend::ASIO )
m_voAudioDevices.push_back( oDevice );
}
void RedstartWindow::on_pushButton_start_stop_clicked()
{
try
{
if( !ui->checkBox_redstart_network_connect_as_client->isChecked() )
{
if( m_pVAInterface )
{
m_pVANetServer->Finalize();
if( m_pVAInterface->GetState() == IVAInterface::VA_CORESTATE_READY )
m_pVAInterface->Finalize();
delete m_pVAInterface;
m_pVAInterface = nullptr;
ui->statusBar->showMessage( "VA core has been stopped." );
PostCoreStop();
}
else
{
CVAStruct oVAConfigArgs = ui->listView_redstart_session_list->GetCurrentConfig();
// Override configs
std::string sBackend, sDevice;
switch( ui->comboBox_audio_driver->currentIndex() )
{
case AudioBackend::ASIO:
{
sBackend = "ASIO";
sDevice = ui->comboBox_audio_iface_device->currentText().toStdString();
break;
}
case AudioBackend::PORTAUDIO:
default:
{
sBackend = "Portaudio";
if( ui->checkBox_portaudio_default_device->isChecked() )
sDevice = "default";
else
sDevice = ui->comboBox_audio_iface_device->currentIndex();
}
}
oVAConfigArgs[ "Audio driver" ] = CVAStruct();
oVAConfigArgs[ "Audio driver" ][ "Driver" ] = sBackend;
oVAConfigArgs[ "Audio driver" ][ "Device" ] = sDevice;
if( !oVAConfigArgs.HasKey( "Paths" ) )
oVAConfigArgs[ "Paths" ] = CVAStruct();
oVAConfigArgs[ "Paths" ][ "redstart_data" ] = "data";
oVAConfigArgs[ "Paths" ][ "redstart_data_dev" ] = "../VACore/data";
m_pVAInterface = VACore::CreateCoreInstance( oVAConfigArgs );
m_pVAInterface->SetOutputStream( ui->plainTextEdit_core_output->GetOutputStream() );
m_pVAInterface->Initialize();
m_pVAInterface->AttachEventHandler( this );
m_pVANetServer->SetCoreInstance( m_pVAInterface );
bool bOK;
int iPort = ui->lineEdit_redstart_network_port->text().toInt( &bOK );
int iStatus = -1;
if( bOK )
iStatus = m_pVANetServer->Initialize( ui->lineEdit_redstart_network_address->text().toStdString(), iPort );
else
iStatus = m_pVANetServer->Initialize( ui->lineEdit_redstart_network_address->text().toStdString() );
if( m_pVAInterface->GetState() == IVAInterface::VA_CORESTATE_READY && iStatus == IVANetServer::VA_NO_ERROR )
{
ui->statusBar->showMessage( "VA core successfully initialized and network server started. Running session " + ui->listView_redstart_session_list->GetCurrentSessionID() + "." );
PostCoreStart();
}
else
{
ui->statusBar->showMessage( "VA core initialization failed." );
m_pVANetServer->Finalize();
delete m_pVAInterface;
m_pVAInterface = NULL;
}
}
}
else
{
// Client mode
if( m_pVANetClient->IsConnected() )
m_pVANetClient->Disconnect();
bool bOK;
int iPort = ui->lineEdit_redstart_network_port->text().toInt( &bOK );
int iStatus = -1;
if( bOK )
iStatus = m_pVANetClient->Initialize( ui->lineEdit_redstart_network_address->text().toStdString(), iPort );
else
iStatus = m_pVANetClient->Initialize( ui->lineEdit_redstart_network_address->text().toStdString() );
if( iStatus != IVANetClient::VA_NO_ERROR )
{
VA_EXCEPT2( INVALID_PARAMETER, "Could not initialize client, connection failed." );
}
m_pVAInterface = m_pVANetClient->GetCoreInstance();
// @todo attach network event handler to detect server connection loss or abortion
//m_pVANetClient->AttachEventHandler( this );
}
}
catch( const CVAException& ex )
{
if( m_pVAInterface )
{
delete m_pVAInterface;
m_pVAInterface = NULL;
}
ui->statusBar->showMessage( QString::fromStdString( ex.ToString() ) );
ui->checkBox_redstart_auto_start->setChecked( false );
}
}
void RedstartWindow::on_pushButton_refresh_clicked()
{
const int iAudioBackend = ui->comboBox_audio_driver->currentIndex();
if( iAudioBackend == AudioBackend::PORTAUDIO )
{
AcquirePortaudioDevices();
}
else
{
AcquireAsioDevices();
}
PopulateAudioDevices();
}
void RedstartWindow::on_comboBox_audio_driver_currentIndexChanged( int )
{
PopulateAudioDevices();
}
void RedstartWindow::on_comboBox_audio_iface_device_currentIndexChanged( int )
{
}
void RedstartWindow::on_actionWebsite_triggered()
{
QUrl urlVAWebsite( "http://www.virtualacoustics.org/work" );
QDesktopServices::openUrl( urlVAWebsite );
}
void RedstartWindow::on_actionGet_started_triggered()
{
QUrl urlVAWebsiteGetStarted( "http://www.virtualacoustics.org/work/start.html" );
QDesktopServices::openUrl( urlVAWebsiteGetStarted );
}
void RedstartWindow::on_actionDocumentation_triggered()
{
QUrl urlVAWebsiteDocumentation( "http://www.virtualacoustics.org/work/documentation.html" );
QDesktopServices::openUrl( urlVAWebsiteDocumentation );
}
void RedstartWindow::on_actionGet_help_triggered()
{
QUrl urlVAWebsiteGetHelp( "http://www.virtualacoustics.org/work/help.html" );
QDesktopServices::openUrl( urlVAWebsiteGetHelp );
}
void RedstartWindow::on_checkBox_redstart_network_connect_as_client_clicked()
{
if( ui->checkBox_redstart_network_connect_as_client->isChecked() )
ui->groupBox_redstart_audio_iface->setEnabled( false );
else
ui->groupBox_redstart_audio_iface->setEnabled( true );
}
void RedstartWindow::on_checkBox_portaudio_default_device_clicked()
{
if( ui->checkBox_portaudio_default_device->isChecked() )
{
ui->comboBox_audio_iface_device->setEnabled( false );
if( ui->comboBox_audio_iface_device->count() >= m_iPortaudioDefaultDevice )
ui->comboBox_audio_iface_device->setCurrentIndex( m_iPortaudioDefaultDevice );
}
else
ui->comboBox_audio_iface_device->setEnabled( true );
}
void RedstartWindow::on_listView_redstart_session_list_clicked( const QModelIndex &index )
{
if( ui->listView_redstart_session_list->model()->data( index ).isValid() )
{
std::string sSessionName = ui->listView_redstart_session_list->model()->data( index ).toString().toStdString();
CVAStruct oStruct = ui->listView_redstart_session_list->GetCurrentConfig();
ui->treeView_session_details->SetStruct( oStruct );
}
}
void RedstartWindow::on_actionBinauralHeadphones_triggered()
{
RedstartSessionBinauralHeadphonesDialog d( this );
if( d.exec() )
{
// Enforce unique session id if id is already existing
QString sNewID = d.GetSessionName();
while( ui->listView_redstart_session_list->SessionNameExists( sNewID ) )
sNewID += "_new";
ui->listView_redstart_session_list->AddSession( sNewID, d.GetCoreConfig() ); // In any case save the session so no data is lost
CVAStruct oStruct = ui->listView_redstart_session_list->GetCurrentConfig();
ui->treeView_session_details->SetStruct( oStruct );
}
}
void RedstartWindow::on_actionImport_session_triggered()
{
RedstartSessionImportDialog d( this );
if( d.exec() )
{
try
{
// Enforce unique session id if id is already existing
QString sNewID = d.GetSessionName();
while( ui->listView_redstart_session_list->SessionNameExists( sNewID ) )
sNewID += "_new";
ui->listView_redstart_session_list->AddSession( sNewID, d.GetCoreConfig() ); // In any case save the session so no data is lost
CVAStruct oStruct = ui->listView_redstart_session_list->GetCurrentConfig();
ui->treeView_session_details->SetStruct( oStruct );
}
catch( CVAException& e )
{
QString sErrorMessage = QString( "Could not run simple example scene: %1" ).arg( QString::fromStdString( e.ToString() ) );
QErrorMessage oErrMsg;
oErrMsg.showMessage( sErrorMessage );
oErrMsg.exec();
}
}
}
void RedstartWindow::on_actionDefault_experimental_session_triggered()
{
RedstartSessionExperimentalTalkthroughDialog d( this );
if( d.exec() )
{
// Enforce unique session id if id is already existing
QString sNewID = d.GetSessionName();
while( ui->listView_redstart_session_list->SessionNameExists( sNewID ) )
sNewID += "_new";
ui->listView_redstart_session_list->AddSession( sNewID, d.GetCoreConfig() ); // In any case save the session so no data is lost
CVAStruct oStruct = ui->listView_redstart_session_list->GetCurrentConfig();
ui->treeView_session_details->SetStruct( oStruct );
}
}
void RedstartWindow::on_actionCirculating_source_triggered()
{
if( !m_pVAInterface )
return;
m_pCirculatingSourceDialog->SetVAInterface( m_pVAInterface );
m_pCirculatingSourceDialog->exec();
m_pCirculatingSourceDialog->hide();
}
void RedstartWindow::on_actionAmbisonics_triggered()
{
}
void RedstartWindow::on_actionExport_to_file_triggered()
{
QFileDialog fd;
fd.setNameFilters( QStringList() << "INI files (*.ini)" << "Any file (*.*)" );
fd.setViewMode( QFileDialog::Detail );
fd.setAcceptMode( QFileDialog::AcceptSave );
QDir oLastDir( m_qSettings.value( "Redstart/last_browse_folder" ).toString() );
if( oLastDir.exists() )
fd.setDirectory( oLastDir );
else
fd.setDirectory( QDir( QApplication::applicationDirPath() ) );
QString sFileName = ui->listView_redstart_session_list->GetCurrentSessionID();
if( sFileName.isEmpty() == false )
fd.selectFile( sFileName + ".ini" );
if( fd.exec() )
{
QStringList lFiles = fd.selectedFiles();
if( lFiles.empty() == false )
{
QString sFilePath = lFiles[ 0 ];
QFileInfo oFile( sFilePath );
if( fd.directory().exists() )
m_qSettings.setValue( "Redstart/last_browse_folder", oFile.absolutePath() );
try
{
CVAStruct oConfig = ui->listView_redstart_session_list->GetCurrentConfig();
VACore::StoreCoreConfigToFile( oConfig, sFilePath.toStdString() );
}
catch( CVAException& e )
{
QString sErrorMessage = QString( "Could not export session configuration: %1" ).arg( QString::fromStdString( e.ToString() ) );
QErrorMessage oErrMsg;
oErrMsg.showMessage( sErrorMessage );
oErrMsg.exec();
}
}
}
}
void RedstartWindow::on_actionRemove_triggered()
{
ui->listView_redstart_session_list->RemoveCurrentSession();
CVAStruct oStruct;
if( !ui->listView_redstart_session_list->GetCurrentSessionID().isEmpty() )
oStruct = ui->listView_redstart_session_list->GetCurrentConfig();
ui->treeView_session_details->SetStruct( oStruct );
}
void RedstartWindow::on_actionEdit_session_triggered()
{
RedstartSessionWizardDialog d( this );
QString sCurrentSessionID = ui->listView_redstart_session_list->GetCurrentSessionID();
CVAStruct oCurrentConfig;
if( sCurrentSessionID.isEmpty() )
return;
oCurrentConfig = ui->listView_redstart_session_list->GetCurrentConfig();
d.SetSession( sCurrentSessionID, ConvertVAStructToQHash( oCurrentConfig ) );
if( d.exec() )
{
bool bEnforceDuplicate = true;
if( sCurrentSessionID != d.GetSessionName() && !ui->listView_redstart_session_list->SessionNameExists( d.GetSessionName() ) )
{
ui->listView_redstart_session_list->RenameSession( sCurrentSessionID, d.GetSessionName() );
bEnforceDuplicate = false;
}
QVariantHash oNewConfig = d.GetCoreConfig();
if( d.GetDuplicationRequested() || bEnforceDuplicate )
{
// Enforce unique session id if duplicate requested or session should be renamed to an already existing session
QString sNewID = d.GetSessionName();
while( ui->listView_redstart_session_list->SessionNameExists( sNewID ) )
sNewID += "_copy";
ui->listView_redstart_session_list->AddSession( sNewID, oNewConfig );
}
else
{
ui->listView_redstart_session_list->UpdateSession( d.GetSessionName(), oNewConfig );
}
ui->treeView_session_details->SetStruct( ConvertQHashToVAStruct( oNewConfig ) );
}
}
void RedstartWindow::on_actionSession_wizard_triggered()
{
RedstartSessionWizardDialog d( this );
d.SetDuplicationOptionDeactivated();
if( d.exec() )
{
QVariantHash oNewConfig = d.GetCoreConfig();
if( ui->listView_redstart_session_list->SessionNameExists( d.GetSessionName() ) )
{
// Enforce unique session id if id is already existing
QString sNewID = d.GetSessionName();
while( ui->listView_redstart_session_list->SessionNameExists( sNewID ) )
sNewID += "_new";
ui->listView_redstart_session_list->AddSession( sNewID, oNewConfig ); // In any case save the session so no data is lost
}
else
{
ui->listView_redstart_session_list->AddSession( d.GetSessionName(), oNewConfig );
}
ui->treeView_session_details->SetStruct( ConvertQHashToVAStruct( oNewConfig ) );
}
}
void RedstartWindow::on_actionDuplicate_current_session_triggered()
{
RedstartSessionWizardDialog d( this );
QString sCurrentSessionID = ui->listView_redstart_session_list->GetCurrentSessionID();
CVAStruct oCurrentConfig;
if( sCurrentSessionID.isEmpty() )
return;
oCurrentConfig = ui->listView_redstart_session_list->GetCurrentConfig();
d.SetSession( sCurrentSessionID, ConvertVAStructToQHash( oCurrentConfig ) );
d.SetDuplicationOptionActivated();
if( d.exec() )
{
QVariantHash oNewConfig = d.GetCoreConfig();
if( ui->listView_redstart_session_list->SessionNameExists( d.GetSessionName() ) )
{
// Enforce unique session id if id is already existing
QString sNewID = d.GetSessionName();
while( ui->listView_redstart_session_list->SessionNameExists( sNewID ) )
sNewID += "_copy";
ui->listView_redstart_session_list->AddSession( sNewID, oNewConfig ); // In any case save the session so no data is lost
}
else
{
ui->listView_redstart_session_list->AddSession( d.GetSessionName(), oNewConfig );
}
ui->treeView_session_details->SetStruct( ConvertQHashToVAStruct( oNewConfig ) );
}
}
void RedstartWindow::CoreChangeInputSignalDecibel( int iLevelDB )
{
emit InputSignalChangedDecibel( iLevelDB );
emit InputSignalChangedDecibel( ( double ) iLevelDB );
}
void RedstartWindow::CoreChangeInputSignalDecibel( double dLevelDB )
{
emit InputSignalChangedDecibel( dLevelDB );
emit InputSignalChangedDecibel( ( int ) dLevelDB );
if( m_pVAInterface )
{
const double dGain = db20_to_ratio( dLevelDB );
m_pVAInterface->SetInputGain( dGain );
}
}
void RedstartWindow::CoreChangeInputIsMuted( int iMuted )
{
emit InputIsMutedChanged( ( bool ) iMuted );
if( m_pVAInterface )
m_pVAInterface->SetInputMuted( ( bool ) iMuted );
}
void RedstartWindow::CoreChangeOutputSignalDecibel( int iLevelDB )
{
emit OutputSignalChangedDecibel( iLevelDB );
emit OutputSignalChangedDecibel( ( double ) iLevelDB );
}
void RedstartWindow::CoreChangeOutputSignalDecibel( double dLevelDB )
{
emit OutputSignalChangedDecibel( dLevelDB );
emit OutputSignalChangedDecibel( ( int ) dLevelDB );
if( m_pVAInterface )
{
const double dGain = db20_to_ratio( dLevelDB );
m_pVAInterface->SetOutputGain( dGain );
}
}
void RedstartWindow::CoreChangeOutputIsMuted( int iMuted )
{
emit OutputIsMutedChanged( ( bool ) iMuted );
if( m_pVAInterface )
m_pVAInterface->SetOutputMuted( ( bool ) iMuted );
}
void RedstartWindow::on_actionRunSimpleExample_triggered()
{
try
{
if( !m_pVAInterface )
VA_EXCEPT2( INVALID_PARAMETER, "No VA interface available. Please start a session, first." );
RunSimpleExample( m_pVAInterface );
}
catch( CVAException& e )
{
QString sErrorMessage = QString( "Could not run simple example scene: %1" ).arg( QString::fromStdString( e.ToString() ) );
QErrorMessage oErrMsg;
oErrMsg.showMessage( sErrorMessage );
oErrMsg.exec();
}
}
void RedstartWindow::on_pushButton_core_control_reset_clicked()
{
if( m_pVAInterface )
m_pVAInterface->Reset();
}