From 0c518bbbb5018f249d4b30df8e4a5f308efad7a0 Mon Sep 17 00:00:00 2001 From: "Dipl.-Ing. Jonas Stienen" Date: Thu, 7 Dec 2017 16:10:28 +0100 Subject: [PATCH] Adding HP equailization for binaural session, and improving circluating source example --- src/RedstartRunCirculatingSourceDialog.cpp | 24 +- src/RedstartRunCirculatingSourceDialog.h | 2 +- ...edstartSessionBinauralHeadphonesDialog.cpp | 93 ++++- src/RedstartSessionBinauralHeadphonesDialog.h | 4 +- src/RedstartWindow.cpp | 2 +- ui/RedstartRunCirculatingSourceDialog.ui | 385 ++++++++++++------ ui/RedstartSessionBinauralHeadphonesDialog.ui | 64 +-- ui/RedstartWindow.ui | 2 +- 8 files changed, 414 insertions(+), 162 deletions(-) diff --git a/src/RedstartRunCirculatingSourceDialog.cpp b/src/RedstartRunCirculatingSourceDialog.cpp index e4a2412..f6bceb2 100644 --- a/src/RedstartRunCirculatingSourceDialog.cpp +++ b/src/RedstartRunCirculatingSourceDialog.cpp @@ -43,6 +43,7 @@ RedstartRunCirculatingSourceDialog::RedstartRunCirculatingSourceDialog( QWidget m_dElevationDEG = 0.0f; m_qVAUpdateTimer = new QTimer( this ); + m_qVAUpdateTimer->setTimerType( Qt::TimerType::PreciseTimer ); connect( m_qVAUpdateTimer, SIGNAL( timeout() ), this, SLOT( UpdateScene() ) ); } @@ -148,20 +149,35 @@ void RedstartRunCirculatingSourceDialog::UpdateScene() v3Pos.x = -std::sin( grad2rad( m_dAzimuthDEG ) ) * ui->doubleSpinBox_radius->value(); v3Pos.y = std::sin( grad2rad( m_dElevationDEG ) ) * ui->doubleSpinBox_radius->value(); v3Pos.z = -std::cos( grad2rad( m_dAzimuthDEG ) ) * ui->doubleSpinBox_radius->value(); + + VAVec3 v3NewPos; try { m_pVAInterface->SetSoundSourcePosition( m_iSourceID, v3Pos ); + v3NewPos = m_pVAInterface->GetSoundSourcePosition( m_iSourceID ); } catch( CVAException& e ) { Stop(); } + ui->doubleSpinBox_azimuth->setValue( m_dAzimuthDEG ); + ui->doubleSpinBox_elevation->setValue( m_dElevationDEG ); + + ui->doubleSpinBox_source_pos_x->setValue( v3NewPos.x ); + ui->doubleSpinBox_source_pos_y->setValue( v3NewPos.y ); + ui->doubleSpinBox_source_pos_z->setValue( v3NewPos.z ); + + ui->doubleSpinBox_runtime_tracker->setValue( m_dRuntimeSeconds ); + m_dAzimuthDEG += ui->doubleSpinBox_azi_inc->value(); + m_dAzimuthDEG = anglef_proj_0_360_DEG( m_dAzimuthDEG ); m_dElevationDEG += ui->doubleSpinBox_ele_inc->value(); - m_dRuntime += ui->doubleSpinBox_timeout->value(); + m_dElevationDEG = anglef_proj_N90_90_DEG( m_dElevationDEG ); + + m_dRuntimeSeconds += ui->doubleSpinBox_timeout->value(); - if( m_dRuntime > ui->doubleSpinBox_runtime->value() ) + if( m_dRuntimeSeconds > ui->doubleSpinBox_runtime->value() ) Stop(); } @@ -171,13 +187,13 @@ void RedstartRunCirculatingSourceDialog::StartUpdateTimer() const int iIntervalMS = ceil( dTimeout * 1000.0f ); m_qVAUpdateTimer->setInterval( iIntervalMS ); m_qVAUpdateTimer->start(); - m_dRuntime = 0.0f; + m_dRuntimeSeconds = 0.0f; } void RedstartRunCirculatingSourceDialog::StopUpdateTimer() { m_qVAUpdateTimer->stop(); - m_dRuntime = 0.0f; + m_dRuntimeSeconds = 0.0f; m_dAzimuthDEG = 0.0f; m_dElevationDEG = 0.0f; diff --git a/src/RedstartRunCirculatingSourceDialog.h b/src/RedstartRunCirculatingSourceDialog.h index 2382d64..9974ac4 100644 --- a/src/RedstartRunCirculatingSourceDialog.h +++ b/src/RedstartRunCirculatingSourceDialog.h @@ -62,7 +62,7 @@ private: QString m_sSignalID; double m_dAzimuthDEG, m_dElevationDEG; - double m_dRuntime; + double m_dRuntimeSeconds; void StartUpdateTimer(); void StopUpdateTimer(); diff --git a/src/RedstartSessionBinauralHeadphonesDialog.cpp b/src/RedstartSessionBinauralHeadphonesDialog.cpp index e93d429..9db36e0 100644 --- a/src/RedstartSessionBinauralHeadphonesDialog.cpp +++ b/src/RedstartSessionBinauralHeadphonesDialog.cpp @@ -26,13 +26,16 @@ RedstartSessionBinauralHeadphonesDialog::RedstartSessionBinauralHeadphonesDialog ui->setupUi( this ); QDialog::setWindowTitle( "Binaural headphones session" ); - + QSettings qSettings; QString sLastBrowseFolder = qSettings.value( "Redstart/last_browse_folder" ).toString(); std::string s = sLastBrowseFolder.toStdString(); if( QDir( sLastBrowseFolder ).exists() ) m_oLastBasePath.setCurrent( sLastBrowseFolder ); + + if( ui->checkBox_hpir_auto_filter_length->isChecked() ) + ui->spinBox_inverse_hpir_filter_length->setEnabled( false ); } RedstartSessionBinauralHeadphonesDialog::~RedstartSessionBinauralHeadphonesDialog() @@ -51,11 +54,13 @@ QVariantHash RedstartSessionBinauralHeadphonesDialog::GetCoreConfig() const oPaths[ "DemoSoundBasePath" ] = m_oDemoSoundBasePath.absolutePath(); if( m_oHRIRBasePath.exists() && m_oHRIRBasePath != m_oDemoSoundBasePath ) oPaths[ "DefaultHRIRBasePath" ] = m_oHRIRBasePath.absolutePath(); + if( m_oInverseHPIRBasePath.exists() && m_oInverseHPIRBasePath != m_oHRIRBasePath ) + oPaths[ "HPIRBaseFolder" ] = m_oInverseHPIRBasePath.absolutePath(); oFinalCoreConfig[ "Paths" ] = oPaths; - QString sHRIRMacro = ui->lineEdit_macro_DefaultHRIR->text(); + QString sHRIRMacro = ui->lineEdit_macro_DefaultHRIR->text(); if( ui->checkBox_folders_as_search_path->isChecked() ) { QFileInfo oHRIR( sHRIRMacro ); @@ -75,8 +80,6 @@ QVariantHash RedstartSessionBinauralHeadphonesDialog::GetCoreConfig() const oFinalCoreConfig[ "Macros" ] = oMacros; - - // @todo switch between talkthrough and headphone reproduction with equalization QVariantHash oDevice; oDevice[ "Type" ] = "HP"; @@ -90,17 +93,50 @@ QVariantHash RedstartSessionBinauralHeadphonesDialog::GetCoreConfig() const oFinalCoreConfig[ "Output:MyDesktopHP" ] = oOutput; - QVariantHash oReproduction; - oReproduction[ "Class" ] = "Talkthrough"; - oReproduction[ "Outputs" ] = "MyDesktopHP"; + if( ui->groupBox_headphone_equalization->isChecked() ) + { + QVariantHash oReproduction; + oReproduction[ "Class" ] = "Headphones"; + oReproduction[ "Outputs" ] = "MyDesktopHP"; + + if( ui->checkBox_inverse_hpir_calibration_gain_db->isChecked() ) + oReproduction[ "HpIRInvCalibrationGainDecibel" ] = ui->doubleSpinBox_InvHPIRCalibrationGain->value(); + else + oReproduction[ "HpIRInvCalibrationGain" ] = ui->doubleSpinBox_InvHPIRCalibrationGain->value(); // no decibel + + QString sHPIRFile = ui->lineEdit_inverse_hpir_file->text(); + if( ui->checkBox_folders_as_search_path->isChecked() ) + { + QFileInfo oHRIR( sHPIRFile ); + sHPIRFile = oHRIR.fileName(); + } + oReproduction[ "HpIRInvFile" ] = sHPIRFile; + + if( !ui->checkBox_hpir_auto_filter_length->isChecked() ) + oReproduction[ "HpIRInvFilterLength" ] = ui->spinBox_inverse_hpir_filter_length->value(); + + oFinalCoreConfig[ "Reproduction:MyEqualizedHeadphones" ] = oReproduction; + + QVariantHash oRenderer; + oRenderer[ "Class" ] = "BinauralFreeField"; + oRenderer[ "Reproductions" ] = "MyEqualizedHeadphones"; + + oFinalCoreConfig[ "Renderer:MyBinauralRenderer" ] = oRenderer; + } + else + { + QVariantHash oReproduction; + oReproduction[ "Class" ] = "Talkthrough"; + oReproduction[ "Outputs" ] = "MyDesktopHP"; - oFinalCoreConfig[ "Reproduction:MyTalkthroughHeadphones" ] = oReproduction; + oFinalCoreConfig[ "Reproduction:MyTalkthroughHeadphones" ] = oReproduction; - QVariantHash oRenderer; - oRenderer[ "Class" ] = "BinauralFreeField"; - oRenderer[ "Reproductions" ] = "MyTalkthroughHeadphones"; + QVariantHash oRenderer; + oRenderer[ "Class" ] = "BinauralFreeField"; + oRenderer[ "Reproductions" ] = "MyTalkthroughHeadphones"; - oFinalCoreConfig[ "Renderer:MyBinauralRenderer" ] = oRenderer; + oFinalCoreConfig[ "Renderer:MyBinauralRenderer" ] = oRenderer; + } return oFinalCoreConfig; } @@ -173,3 +209,36 @@ void RedstartSessionBinauralHeadphonesDialog::on_pushButton_BrowseHRIR_clicked() } } } + +void RedstartSessionBinauralHeadphonesDialog::on_pushButton_inverse_hpir_file_select_clicked() +{ + QFileDialog fd; + fd.setNameFilter( "WAV files (*.wav)" ); + fd.setViewMode( QFileDialog::Detail ); + + if( m_oLastBasePath.exists() ) + fd.setDirectory( m_oLastBasePath ); + else + fd.setDirectory( QDir( QApplication::applicationDirPath() ) ); + + if( fd.exec() ) + { + QStringList lFiles = fd.selectedFiles(); + if( lFiles.empty() == false ) + { + QString sFilePath = lFiles[ 0 ]; + QFile oFile( sFilePath ); + if( oFile.exists() ) + { + m_oHRIRBasePath = fd.directory(); + m_oLastBasePath = m_oHRIRBasePath; + } + ui->lineEdit_inverse_hpir_file->setText( oFile.fileName() ); + } + } +} + +void RedstartSessionBinauralHeadphonesDialog::on_checkBox_hpir_auto_filter_length_clicked( bool bEnabled ) +{ + ui->spinBox_inverse_hpir_filter_length->setEnabled( !bEnabled ); +} diff --git a/src/RedstartSessionBinauralHeadphonesDialog.h b/src/RedstartSessionBinauralHeadphonesDialog.h index 427be7f..cecf494 100644 --- a/src/RedstartSessionBinauralHeadphonesDialog.h +++ b/src/RedstartSessionBinauralHeadphonesDialog.h @@ -38,13 +38,15 @@ private slots: void on_pushButton_CreateSession_clicked(); void on_pushButton_BrowseDemoSound_clicked(); void on_pushButton_BrowseHRIR_clicked(); + void on_pushButton_inverse_hpir_file_select_clicked(); + void on_checkBox_hpir_auto_filter_length_clicked( bool ); private: Ui::RedstartDialogSessionBinauralHeadphones* ui; QDir m_oLastBasePath; QDir m_oHRIRBasePath; + QDir m_oInverseHPIRBasePath; QDir m_oDemoSoundBasePath; - QString m_sFileBaseName; QSettings m_qSettings; }; diff --git a/src/RedstartWindow.cpp b/src/RedstartWindow.cpp index a5e49c7..f61023a 100644 --- a/src/RedstartWindow.cpp +++ b/src/RedstartWindow.cpp @@ -719,7 +719,7 @@ void RedstartWindow::on_pushButton_start_stop_clicked() m_pVAInterface = NULL; } - ui->statusBar->showMessage( QString::fromStdString( ex.ToString() ) ); + ui->statusBar->showMessage( QString::fromStdString( ex.ToString() ) + ". Will deactivate auto-start checkbox." ); ui->checkBox_redstart_auto_start->setChecked( false ); } } diff --git a/ui/RedstartRunCirculatingSourceDialog.ui b/ui/RedstartRunCirculatingSourceDialog.ui index 66b725c..c74f225 100644 --- a/ui/RedstartRunCirculatingSourceDialog.ui +++ b/ui/RedstartRunCirculatingSourceDialog.ui @@ -6,8 +6,8 @@ 0 0 - 545 - 325 + 579 + 312 @@ -16,14 +16,7 @@ - - - - Select - - - - + @@ -36,92 +29,101 @@ - - - - Demo sound - - - lineEdit_macro_DemoSound - - - - - - - Select - - - - + $(DemoSound) - - + + - Default HRIR - - - lineEdit_macro_DefaultHRIR + Current azimuth - - + + - Add all folders as search paths (instead of using absolute paths) - - - true + Source position - - - - seconds - - + + + + + + false + + + 3 + + + -999.000000000000000 + + + 999.000000000000000 + + + + + + + false + + + 3 + + + -999.000000000000000 + + + 999.000000000000000 + + + + + + + false + + + 3 + + + -999.000000000000000 + + + 999.000000000000000 + + + + - - + + - Runtime - - - doubleSpinBox_runtime - - - - - - - 1 - - - 99999999.000000000000000 - - - 20.000000000000000 + Current elevation - - - - false + + + + <html><head/><body><p>The runtime depends on the timer quality, CPU load and processing duration of the timout slot function. It may be deviating significantly from the actual time. For proper timing in VA, it is recommended to use high precision timer (ideally synchronized to the audio clock). In VAMatlab, an implementation of high performance timer is available.</p></body></html> - Stop + seconds + + <html><head/><body><p>The runtime depends on the timer quality, CPU load and processing duration of the timout slot function. It may be deviating significantly from the actual time. For proper timing in VA, it is recommended to use high precision timer (ideally synchronized to the audio clock). In VAMatlab, an implementation of high performance timer is available.</p></body></html> + Update timeout @@ -132,6 +134,9 @@ + + <html><head/><body><p>The runtime depends on the timer quality, CPU load and processing duration of the timout slot function. It may be deviating significantly from the actual time. For proper timing in VA, it is recommended to use high precision timer (ideally synchronized to the audio clock). In VAMatlab, an implementation of high performance timer is available.</p></body></html> + 3 @@ -149,20 +154,6 @@ - - - - seconds - - - - - - - Start - - - @@ -173,18 +164,8 @@ - - - - Elevation increment - - - doubleSpinBox_ele_inc - - - - - + + 3 @@ -194,16 +175,17 @@ 999999.000000000000000 - - 1.000000000000000 - - - 0.360000000000000 + + + + + + degrees - - + + 3 @@ -213,6 +195,12 @@ 999999.000000000000000 + + 1.000000000000000 + + + 0.360000000000000 + @@ -222,20 +210,13 @@ - - - - degrees - - - - - + + - Radius + Elevation increment - doubleSpinBox_radius + doubleSpinBox_ele_inc @@ -259,6 +240,180 @@ + + + + Radius + + + doubleSpinBox_radius + + + + + + + false + + + true + + + 1 + + + -99999999.000000000000000 + + + 999999999.000000000000000 + + + + + + + false + + + true + + + + + + + + + 1 + + + -99999.000000000000000 + + + 999999.000000000000000 + + + + + + + Demo sound + + + lineEdit_macro_DemoSound + + + + + + + Select + + + + + + + Select + + + + + + + <html><head/><body><p>The runtime depends on the timer quality, CPU load and processing duration of the timout slot function. It may be deviating significantly from the actual time. For proper timing in VA, it is recommended to use high precision timer (ideally synchronized to the audio clock). In VAMatlab, an implementation of high performance timer is available.</p></body></html> + + + seconds + + + + + + + Add all folders as search paths (instead of using absolute paths) + + + true + + + + + + + Default HRIR + + + lineEdit_macro_DefaultHRIR + + + + + + + <html><head/><body><p>The runtime depends on the timer quality, CPU load and processing duration of the timout slot function. It may be deviating significantly from the actual time. For proper timing in VA, it is recommended to use high precision timer (ideally synchronized to the audio clock). In VAMatlab, an implementation of high performance timer is available.</p></body></html> + + + 1 + + + 99999999.000000000000000 + + + 20.000000000000000 + + + + + + + <html><head/><body><p>The runtime depends on the timer quality, CPU load and processing duration of the timout slot function. It may be deviating significantly from the actual time. For proper timing in VA, it is recommended to use high precision timer (ideally synchronized to the audio clock). In VAMatlab, an implementation of high performance timer is available.</p></body></html> + + + Runtime + + + doubleSpinBox_runtime + + + + + + + + + false + + + <html><head/><body><p>The runtime depends on the timer quality, CPU load and processing duration of the timout slot function. It may be deviating significantly from the actual time. For proper timing in VA, it is recommended to use high precision timer (ideally synchronized to the audio clock). In VAMatlab, an implementation of high performance timer is available.</p></body></html> + + + 999999.000000000000000 + + + + + + + <html><head/><body><p>The runtime depends on the timer quality, CPU load and processing duration of the timout slot function. It may be deviating significantly from the actual time. For proper timing in VA, it is recommended to use high precision timer (ideally synchronized to the audio clock). In VAMatlab, an implementation of high performance timer is available.</p></body></html> + + + Start + + + + + + + + + false + + + Stop + + + @@ -271,7 +426,6 @@ - pushButton_start pushButton_run pushButton_BrowseDemoSound pushButton_BrowseHRIR @@ -283,7 +437,6 @@ doubleSpinBox_radius doubleSpinBox_runtime doubleSpinBox_timeout - pushButton_stop diff --git a/ui/RedstartSessionBinauralHeadphonesDialog.ui b/ui/RedstartSessionBinauralHeadphonesDialog.ui index c6ebb45..5cf121d 100644 --- a/ui/RedstartSessionBinauralHeadphonesDialog.ui +++ b/ui/RedstartSessionBinauralHeadphonesDialog.ui @@ -49,7 +49,7 @@ - ITA-Kunstkopf_5x5_256_44kHz.v17.ir.daff + ITA_Artificial_Head_5x5_44kHz_128.v17.ir.daff @@ -157,9 +157,9 @@ - + - false + true Headphone equalization @@ -172,10 +172,20 @@ - + + + 3 + + + -999.000000000000000 + + + 0.000000000000000 + + - + Inverse HPIR calibration gain @@ -185,7 +195,7 @@ - + dB @@ -200,39 +210,29 @@ Inverse HPIR file - lineEdit + lineEdit_inverse_hpir_file - + - + Select - - - - false - - - HPIR filter length - - lineEdit_2 - - + auto @@ -241,6 +241,19 @@ + + + + 0 + + + 99999 + + + 128 + + + @@ -264,13 +277,12 @@ checkBox_folders_as_search_path spinBox_hrir_filter_length lineEdit_headphone_channels - groupBox - pushButton - lineEdit + groupBox_headphone_equalization + pushButton_inverse_hpir_file_select + lineEdit_inverse_hpir_file doubleSpinBox_InvHPIRCalibrationGain - checkBox - lineEdit_2 - checkBox_2 + checkBox_inverse_hpir_calibration_gain_db + checkBox_hpir_auto_filter_length pushButton_BrowseHRIR diff --git a/ui/RedstartWindow.ui b/ui/RedstartWindow.ui index 51e94ec..f0c10ee 100644 --- a/ui/RedstartWindow.ui +++ b/ui/RedstartWindow.ui @@ -1281,7 +1281,7 @@ background-color: rgb(208, 255, 188); Reset - R, R + R, Esc -- GitLab