|
| 1 | +/** |
| 2 | +* \class AnechoicControls |
| 3 | +* |
| 4 | +* \brief Declaration of AnechoicControls interface. |
| 5 | +* \date June 2019 |
| 6 | +* |
| 7 | +* \authors Reactify Music LLP: R. Hrafnkelsson || |
| 8 | +* Coordinated by , A. Reyes-Lecuona (University of Malaga) and L.Picinali (Imperial College London) || |
| 9 | +* \b Contact: areyes@uma.es and l.picinali@imperial.ac.uk |
| 10 | +* |
| 11 | +* \b Project: 3DTI (3D-games for TUNing and lEarnINg about hearing aids) || |
| 12 | +* \b Website: http://3d-tune-in.eu/ |
| 13 | +* |
| 14 | +* \b Copyright: University of Malaga and Imperial College London - 2019 |
| 15 | +* |
| 16 | +* \b Licence: This copy of the 3D Tune-In Toolkit Plugin is licensed to you under the terms described in the LICENSE.md file included in this distribution. |
| 17 | +* |
| 18 | +* \b Acknowledgement: This project has received funding from the European Union's Horizon 2020 research and innovation programme under grant agreements No 644051 and 726765. |
| 19 | +*/ |
| 20 | + |
| 21 | +#include "AnechoicControls.h" |
| 22 | + |
| 23 | +AnechoicControls::AnechoicControls(Toolkit3dtiPluginAudioProcessor& processor) |
| 24 | + : mProcessor(processor), |
| 25 | + mCore(processor.getCore()), |
| 26 | + distanceAttenuationLabel("Distance Label", "dB attenuation per double distance") |
| 27 | +{ |
| 28 | + for ( int i = 0; i < BundledHRTFs.size(); i++ ) { |
| 29 | + hrtfMenu.addItem( BundledHRTFs[i], i+1 ); // IDs must be non-zero |
| 30 | + } |
| 31 | + hrtfMenu.onChange = [this] { hrtfMenuChanged(); }; |
| 32 | + hrtfMenu.setSelectedItemIndex(0, dontSendNotification); |
| 33 | + addAndMakeVisible( hrtfMenu ); |
| 34 | + |
| 35 | + headCircumferenceToggle.setButtonText( "Custom Head Circumference" ); |
| 36 | + headCircumferenceToggle.onClick = [this] { updateHeadCircumference(); }; |
| 37 | + addAndMakeVisible(headCircumferenceToggle); |
| 38 | + |
| 39 | + mapParameterToSlider( headCircumferenceSlider, mCore.headCircumference ); |
| 40 | + headCircumferenceSlider.setTextValueSuffix(" mm"); |
| 41 | + headCircumferenceSlider.setTextBoxStyle( Slider::TextBoxRight, false, 65, 24 ); |
| 42 | + headCircumferenceSlider.addListener( this ); |
| 43 | + headCircumferenceSlider.setValue( mCore.headCircumference, dontSendNotification ); |
| 44 | + addAndMakeVisible( headCircumferenceSlider ); |
| 45 | + |
| 46 | + headCircumferenceSlider.setEnabled( headCircumferenceToggle.getToggleState() ); |
| 47 | + |
| 48 | + bypassToggle.setButtonText("On/Off"); |
| 49 | + bypassToggle.setToggleState(true, dontSendNotification); |
| 50 | + bypassToggle.onClick = [this] { updateBypass(); }; |
| 51 | + addAndMakeVisible( bypassToggle ); |
| 52 | + |
| 53 | + nearFieldToggle.setButtonText( "Near field correction (IIR)" ); |
| 54 | + nearFieldToggle.onClick = [this] { updateNearFieldCorrection(); }; |
| 55 | + addAndMakeVisible( nearFieldToggle ); |
| 56 | + |
| 57 | + farFieldToggle.setButtonText( "Far field correction (IIR)" ); |
| 58 | + farFieldToggle.onClick = [this] { updateFarFieldCorrection(); }; |
| 59 | + addAndMakeVisible( farFieldToggle ); |
| 60 | + |
| 61 | + distanceAttenuationToggle.setButtonText("On/Off"); |
| 62 | + distanceAttenuationToggle.setToggleState(true, dontSendNotification); |
| 63 | + distanceAttenuationToggle.onClick = [this] { updateDistanceAttenuation(); }; |
| 64 | + addAndMakeVisible( distanceAttenuationToggle ); |
| 65 | + |
| 66 | + qualityToggle.setButtonText( "High Quality" ); |
| 67 | + qualityToggle.onClick = [this] { updateQualitySetting(); }; |
| 68 | + // addAndMakeVisible( qualityToggle ); |
| 69 | + |
| 70 | + setLabelStyle( distanceAttenuationLabel ); |
| 71 | + distanceAttenuationLabel.setJustificationType( Justification::left ); |
| 72 | + addAndMakeVisible( distanceAttenuationLabel ); |
| 73 | + |
| 74 | + mapParameterToSlider( distanceAttenuationSlider, mCore.sourceDistanceAttenuation ); |
| 75 | + distanceAttenuationSlider.setTextValueSuffix(" dB"); |
| 76 | + distanceAttenuationSlider.setTextBoxStyle( Slider::TextBoxRight, false, 65, 24 ); |
| 77 | + distanceAttenuationSlider.addListener( this ); |
| 78 | + addAndMakeVisible( distanceAttenuationSlider ); |
| 79 | + |
| 80 | + updateGui(); |
| 81 | +} |
| 82 | + |
| 83 | +void AnechoicControls::updateGui() { |
| 84 | + headCircumferenceToggle.setToggleState( mCore.enableCustomizedITD, dontSendNotification ); |
| 85 | + headCircumferenceSlider.setValue( mCore.headCircumference, dontSendNotification ); |
| 86 | + headCircumferenceSlider.setEnabled( headCircumferenceToggle.getToggleState() ); |
| 87 | + |
| 88 | + if ( !mCore.getSources().empty() ) { |
| 89 | + auto source = mCore.getSources().front(); |
| 90 | + bypassToggle.setToggleState(source->IsAnechoicProcessEnabled(), dontSendNotification); |
| 91 | + |
| 92 | + bool distanceAttenuationEnabled = source->IsDistanceAttenuationEnabledAnechoic(); |
| 93 | + distanceAttenuationToggle.setToggleState(distanceAttenuationEnabled, dontSendNotification); |
| 94 | + distanceAttenuationSlider.setValue(mCore.sourceDistanceAttenuation, dontSendNotification); |
| 95 | + distanceAttenuationLabel.setEnabled(distanceAttenuationEnabled); |
| 96 | + distanceAttenuationSlider.setEnabled(distanceAttenuationEnabled); |
| 97 | + } |
| 98 | + |
| 99 | + nearFieldToggle.setToggleState( mCore.enableNearDistanceEffect, dontSendNotification); |
| 100 | + farFieldToggle.setToggleState( mCore.enableFarDistanceEffect, dontSendNotification); |
| 101 | + qualityToggle.setToggleState( mCore.spatializationMode, dontSendNotification); |
| 102 | + |
| 103 | + auto hrtfIndex = mCore.getHrtfIndex(); |
| 104 | + if ( hrtfIndex != hrtfMenu.getSelectedItemIndex() && hrtfIndex < BundledHRTFs.size()-2 ) { // Show filename if custom file is selected |
| 105 | + hrtfMenu.setSelectedItemIndex(hrtfIndex, dontSendNotification); |
| 106 | + } |
| 107 | +} |
| 108 | + |
| 109 | +void AnechoicControls::resized() { |
| 110 | + auto area = getLocalBounds(); |
| 111 | + bypassToggle.setBounds( 10, 4, 80, 24 ); |
| 112 | + hrtfMenu.setBounds( 12, 40, area.getWidth()-24, 22 ); |
| 113 | + headCircumferenceToggle.setBounds( 10, hrtfMenu.getBottom() + 8, area.getWidth()-20, 26); |
| 114 | + headCircumferenceSlider.setBounds( 6, headCircumferenceToggle.getBottom(), area.getWidth()-18, 24); |
| 115 | + nearFieldToggle.setBounds(10, headCircumferenceSlider.getBottom(), area.getWidth()-20, 32); |
| 116 | + farFieldToggle.setBounds(10, nearFieldToggle.getBottom(), area.getWidth()-20, 32); |
| 117 | + // qualityToggle.setBounds(10, farFieldToggle.getBottom(), area.getWidth()-20, 30); |
| 118 | + distanceAttenuationToggle.setBounds( 10, farFieldToggle.getBottom() + 4, 80, 24); |
| 119 | + distanceAttenuationLabel.setBounds( 94, distanceAttenuationToggle.getY(), area.getWidth()-100, 24); |
| 120 | + distanceAttenuationSlider.setBounds( 6, distanceAttenuationToggle.getBottom() + 4, area.getWidth()-20, 24); |
| 121 | +} |
| 122 | + |
| 123 | +void AnechoicControls::updateBypass() { |
| 124 | + bool enabled = bypassToggle.getToggleState(); |
| 125 | + if ( enabled ) { |
| 126 | + mCore.getSources().front()->EnableAnechoicProcess(); |
| 127 | + } else { |
| 128 | + mCore.getSources().front()->DisableAnechoicProcess(); |
| 129 | + } |
| 130 | + setAlpha( enabled + 0.4f ); |
| 131 | +} |
| 132 | + |
| 133 | +void AnechoicControls::hrtfMenuChanged() { |
| 134 | + auto text = hrtfMenu.getText(); |
| 135 | + // Note(Ragnar): Windows FileChooser will only accept |
| 136 | + // one filetype at at time se we provide separate options |
| 137 | + if ( text == "Load 3DTI" ) { |
| 138 | + loadCustomHrtf("*.3dti-hrtf"); |
| 139 | + } else if ( text == "Load SOFA" ) { |
| 140 | + loadCustomHrtf("*.sofa"); |
| 141 | + } else { |
| 142 | + mCore.loadHRTF(hrtfMenu.getSelectedItemIndex()); |
| 143 | + } |
| 144 | +} |
| 145 | + |
| 146 | +void AnechoicControls::loadCustomHrtf(String fileTypes) { |
| 147 | + fc.reset (new FileChooser ("Choose a file to open...", |
| 148 | + HRTFDirectory(), |
| 149 | + fileTypes, |
| 150 | + true)); |
| 151 | + |
| 152 | + fc->launchAsync(FileBrowserComponent::openMode | FileBrowserComponent::canSelectFiles, |
| 153 | + [this] (const FileChooser& chooser) |
| 154 | + { |
| 155 | + String chosen; |
| 156 | + auto results = chooser.getURLResults(); |
| 157 | + |
| 158 | + auto result = results.getFirst(); |
| 159 | + |
| 160 | + chosen << (result.isLocalFile() ? result.getLocalFile().getFullPathName() |
| 161 | + : result.toString (false)); |
| 162 | + |
| 163 | + if ( mCore.loadHRTF(File(chosen.removeCharacters("\n"))) ) { |
| 164 | + updateHrtfLabelText(); |
| 165 | + }; |
| 166 | + }); |
| 167 | +} |
| 168 | + |
| 169 | +void AnechoicControls::updateHeadCircumference() { |
| 170 | + bool enabled = headCircumferenceToggle.getToggleState(); |
| 171 | + mCore.enableCustomizedITD = enabled; |
| 172 | + mCore.headCircumference = headCircumferenceSlider.getValue(); |
| 173 | + |
| 174 | + // TODO: Show circumference in mm |
| 175 | + // IM.slHeadCircumference.footer = "mm (r: " + Utils.FloatToString(r_cm, 1) + " cm)"; |
| 176 | + headCircumferenceSlider.setEnabled(enabled); |
| 177 | +} |
| 178 | + |
| 179 | +void AnechoicControls::updateHrtfLabelText() { |
| 180 | + auto hrtf = mCore.getHrtfPath().getFileNameWithoutExtension().upToLastOccurrenceOf("_", false, false);; |
| 181 | + hrtfMenu.setText(hrtf, dontSendNotification); |
| 182 | +} |
| 183 | + |
| 184 | +void AnechoicControls::updateNearFieldCorrection() { |
| 185 | + mCore.enableNearDistanceEffect = nearFieldToggle.getToggleState(); |
| 186 | +} |
| 187 | + |
| 188 | +void AnechoicControls::updateFarFieldCorrection() { |
| 189 | + mCore.enableFarDistanceEffect = farFieldToggle.getToggleState(); |
| 190 | +} |
| 191 | + |
| 192 | +void AnechoicControls::updateQualitySetting() { |
| 193 | + auto mode = qualityToggle.getToggleState() ? Binaural::HighQuality : Binaural::HighPerformance; |
| 194 | + mCore.spatializationMode = mode; |
| 195 | +} |
| 196 | + |
| 197 | +void AnechoicControls::updateDistanceAttenuation() { |
| 198 | + auto source = mCore.getSources().front(); |
| 199 | + if ( distanceAttenuationToggle.getToggleState() ) { |
| 200 | + source->EnableDistanceAttenuationAnechoic(); |
| 201 | + } else { |
| 202 | + source->DisableDistanceAttenuationAnechoic(); |
| 203 | + } |
| 204 | +} |
0 commit comments