/* FxSound Copyright (C) 2023 FxSound LLC 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 3 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, see . */ #include "u_DfxDsp.h" #include "codedefs.h" #include "DfxSdk.h" #include "dfxp.h" #include "prelst.h" #include "file.h" #include "qnt.h" #include #include "BinauralSyn.h" #include "ptutil\dfxp\u_dfxp.h" #include "com.h" #include "dfxSharedUtil.h" #include "GraphicEq.h" #include "spectrum.h" #include "SurroundSyn.h" #define DFXG_REGISTRY_DFX_PRODUCT_NAME_WIDE L"DFX" #define DFXG_DISPLAYED_DFX_PRODUCT_NAME_WIDE L"FxSound" #define DFXP_VENDOR_CODE_UNIVERSAL 23 #define DFXG_MIN_USER_PRESET_INDEX 99 /* 0 based number of min user preset (preset number 100) */ #define DFXG_MAX_PRESET_NAME_LENGTH 128 #define DFXG_NO_PROCESSING_PRESET 0 #define DFXG_DEFAULT_PRESET_INDEX 0 /* 0 based, i.e. index of 2 corresponds to preset number 3 */ #define DFXG_FREE_PRESET_MIN_INDEX 0 #define DFXG_FREE_PRESET_MAX_INDEX 0 #define MIDI_MIN_VALUE 0 #define MIDI_MAX_VALUE 127 DfxDspPrivate::DfxDspPrivate() { midi_to_rval_qnt_handle_ = NULL; rval_to_midi_qnt_handle_ = NULL; swprintf(product_specific_.wcp_registry_product_name, PT_MAX_GENERIC_STRLEN, L"%s", DFXG_REGISTRY_DFX_PRODUCT_NAME_WIDE); swprintf(product_specific_.wcp_displayed_product_name, PT_MAX_GENERIC_STRLEN, L"%s", DFXG_DISPLAYED_DFX_PRODUCT_NAME_WIDE); product_specific_.full_version = static_cast(13.028); product_specific_.major_version = static_cast(13.028); vendor_specific_.vendor_code = DFXP_VENDOR_CODE_UNIVERSAL; // Initialize the processing mode if (dfxpInit(&dfxp_handle_, L"DFX", 23, 14, 1, IS_FALSE, IS_FALSE, 0, IS_FALSE, IS_FALSE, IS_FALSE, slout1_) != OKAY) { //return(NOT_OKAY); MessageBox(NULL, L"TTEST", L"TEST", MB_OK); } // Make sure the vocal reduction is turned off if (dfxpSetButtonValue(dfxp_handle_, DFX_UI_BUTTON_VOCAL_REDUCTION_ON, IS_FALSE) != OKAY) { //return(NOT_OKAY); } // From dfxg_InitStaticQnts() in dfxgQnt.cpp /* * Initalize the qnt handle for calculating the real value based * on a MIDI value. */ if (qntIToRInit(&(midi_to_rval_qnt_handle_), slout1_, MIDI_MIN_VALUE, MIDI_MAX_VALUE, DFX_UI_MIN_VALUE, DFX_UI_MAX_VALUE, IS_FALSE, 0, IS_FALSE, (realtype)0.0, IS_FALSE, QNT_RESPONSE_LINEAR) != OKAY) { } /* * Initialize the qnt handle for calculating the midi value * based on the real value. */ if (qntRToIInit(&(rval_to_midi_qnt_handle_), slout1_, DFX_UI_MIN_VALUE, DFX_UI_MAX_VALUE, MIDI_MIN_VALUE, MIDI_MAX_VALUE, IS_FALSE, 0, IS_FALSE) != OKAY) { } //return(OKAY); } DfxDspPrivate::~DfxDspPrivate() { // So the thread/timer will not attempt to use this object while it's being destroyed. being_destroyed_ = true; // Free the prelst if (preset_list_handle_ != NULL) { if (prelstFreeUp(&(preset_list_handle_)) != OKAY) { } } // Free the midi to rval and visa versa qnt handles if (midi_to_rval_qnt_handle_ != NULL) { if (qntFreeUp(&(midi_to_rval_qnt_handle_)) != OKAY) { } } if (rval_to_midi_qnt_handle_ != NULL) { if (qntFreeUp(&(rval_to_midi_qnt_handle_)) != OKAY) { } } // Free dfxp handle dfxpFreeAll(); free(dfxp_handle_); //*dfxp_handle_ = NULL; // Free the slout handle if (slout1_ != NULL) delete slout1_; } /** dfxg_UpdateFromRegistryAllSettings() **/ void DfxDspPrivate::processTimer() { bool anything_changed = false; int i_eq_changed = IS_FALSE; if (update_from_registry_) { eqUpdateFromRegistry(&i_eq_changed); } if (i_eq_changed) { anything_changed = true; } /* If any settings have been changed, communicate all the changes to the DSP module */ // NOTE: I find that without this if condition and call dfxpCOmmunicateAll() repeatedly will mess up the audio. if (anything_changed) { dfxpCommunicateAll(dfxp_handle_); } } int DfxDspPrivate::processAudio(short int *si_input_samples, short int *si_output_samples, int i_num_sample_sets, int i_check_for_duplicate_buffers) { processTimer(); // Apply DFX processing here using data and format vars above. Format will always be 32 bit floating point. if (dfxpUniversalModifySamples(dfxp_handle_, si_input_samples, si_output_samples, i_num_sample_sets, i_check_for_duplicate_buffers) != OKAY) return(NOT_OKAY); return OKAY; } int DfxDspPrivate::setSignalFormat(int i_bps, int i_nch, int i_srate, int i_valid_bits) { if (dfxpUniversalSetSignalFormat(dfxp_handle_, i_bps, i_nch, i_srate, i_valid_bits) != OKAY) return(NOT_OKAY); return OKAY; } void DfxDspPrivate::powerOn(bool on) { if (on) { if (dfxpSetButtonValue(dfxp_handle_, DFX_UI_BUTTON_BYPASS, 0) != OKAY) { } } else { if (dfxpSetButtonValue(dfxp_handle_, DFX_UI_BUTTON_BYPASS, 1) != OKAY) { } } } bool DfxDspPrivate::isPowerOn() { int value; dfxpGetButtonValue(dfxp_handle_, DFX_UI_BUTTON_BYPASS, &value); if (value != 0) { return true; } else { return false; } } float DfxDspPrivate::getEffectValue(DfxDsp::Effect effect) { switch (effect) { case DfxDsp::Effect::Fidelity: return fidelity_.value; case DfxDsp::Effect::Ambience: return ambience_.value; case DfxDsp::Effect::Surround: return surround_.value; case DfxDsp::Effect::DynamicBoost: return dynamic_boost_.value; case DfxDsp::Effect::Bass: return bass_boost_.value; } return -1.0f; } void DfxDspPrivate::setEffectValue(DfxDsp::Effect effect, float value) { int button; int knob; switch (effect) { case DfxDsp::Effect::Fidelity: button = DFX_UI_BUTTON_FIDELITY; knob = DFX_UI_KNOB_FIDELITY; fidelity_.value = (realtype)value / (realtype)10.0; break; case DfxDsp::Effect::Ambience: button = DFX_UI_BUTTON_AMBIENCE; knob = DFX_UI_KNOB_AMBIENCE; ambience_.value = (realtype)value / (realtype)10.0; break; case DfxDsp::Effect::Surround: button = DFX_UI_BUTTON_SURROUND; knob = DFX_UI_KNOB_SURROUND; surround_.value = (realtype)value / (realtype)10.0; break; case DfxDsp::Effect::DynamicBoost: button = DFX_UI_BUTTON_DYNAMIC_BOOST; knob = DFX_UI_KNOB_DYNAMIC_BOOST; dynamic_boost_.value = (realtype)value / (realtype)10.0; break; case DfxDsp::Effect::Bass: button = DFX_UI_BUTTON_BASS_BOOST; knob = DFX_UI_KNOB_BASS_BOOST; bass_boost_.value = (realtype)value / (realtype)10.0; break; default: return; } if (value != 0.0) { dfxpSetButtonValue(dfxp_handle_, button, 1); } else { dfxpSetButtonValue(dfxp_handle_, button, 0); } dfxpSetKnobValue(dfxp_handle_, knob, (realtype)value / (realtype)10.0, false); } unsigned long DfxDspPrivate::getTotalAudioProcessedTime() { unsigned long value; dfxpGetTotalAudioProcessedTime(dfxp_handle_, &value); return value; } void DfxDspPrivate::resetTotalAudioProcessedTime() { dfxpSetTotalAudioProcessedTime(dfxp_handle_, 0); } /* * */ int DfxDspPrivate::dfxpFreeAll() { struct dfxpHdlType *cast_handle; cast_handle = (struct dfxpHdlType *)(dfxp_handle_); if (cast_handle == NULL) return(OKAY); /* Free all the midi_to_dsp qnt handles */ if (cast_handle->midi_to_dsp.fidelity_qnt_hdl != NULL) { if (qntFreeUp(&(cast_handle->midi_to_dsp.fidelity_qnt_hdl)) != OKAY) return(NOT_OKAY); } if (cast_handle->midi_to_dsp.spaciousness_qnt_hdl != NULL) { if (qntFreeUp(&(cast_handle->midi_to_dsp.spaciousness_qnt_hdl)) != OKAY) return(NOT_OKAY); } if (cast_handle->midi_to_dsp.ambience_qnt_hdl != NULL) { if (qntFreeUp(&(cast_handle->midi_to_dsp.ambience_qnt_hdl)) != OKAY) return(NOT_OKAY); } if (cast_handle->midi_to_dsp.dynamic_boost_qnt_hdl != NULL) { if (qntFreeUp(&(cast_handle->midi_to_dsp.dynamic_boost_qnt_hdl)) != OKAY) return(NOT_OKAY); } if (cast_handle->midi_to_dsp.bass_boost_qnt_hdl != NULL) { if (qntFreeUp(&(cast_handle->midi_to_dsp.bass_boost_qnt_hdl)) != OKAY) return(NOT_OKAY); } /* Fixed Aural Activation Specific */ if (cast_handle->midi_to_dsp.aural_filter_gain_qnt_hdl != NULL) { if (qntFreeUp(&(cast_handle->midi_to_dsp.aural_filter_gain_qnt_hdl)) != OKAY) return(NOT_OKAY); } if (cast_handle->midi_to_dsp.aural_filter_a1_qnt_hdl != NULL) { if (qntFreeUp(&(cast_handle->midi_to_dsp.aural_filter_a1_qnt_hdl)) != OKAY) return(NOT_OKAY); } if (cast_handle->midi_to_dsp.aural_filter_a0_qnt_hdl != NULL) { if (qntFreeUp(&(cast_handle->midi_to_dsp.aural_filter_a0_qnt_hdl)) != OKAY) return(NOT_OKAY); } /* Fixed Reverb Specific */ if (cast_handle->midi_to_dsp.room_size_qnt_hdl != NULL) { if (qntFreeUp(&(cast_handle->midi_to_dsp.room_size_qnt_hdl)) != OKAY) return(NOT_OKAY); } if (cast_handle->midi_to_dsp.damping_bandwidth_qnt_hdl != NULL) { if (qntFreeUp(&(cast_handle->midi_to_dsp.damping_bandwidth_qnt_hdl)) != OKAY) return(NOT_OKAY); } if (cast_handle->midi_to_dsp.rolloff_bandwidth_qnt_hdl != NULL) { if (qntFreeUp(&(cast_handle->midi_to_dsp.rolloff_bandwidth_qnt_hdl)) != OKAY) return(NOT_OKAY); } if (cast_handle->midi_to_dsp.motion_rate_qnt_hdl != NULL) { if (qntFreeUp(&(cast_handle->midi_to_dsp.motion_rate_qnt_hdl)) != OKAY) return(NOT_OKAY); } if (cast_handle->midi_to_dsp.motion_depth_qnt_hdl != NULL) { if (qntFreeUp(&(cast_handle->midi_to_dsp.motion_depth_qnt_hdl)) != OKAY) return(NOT_OKAY); } if (cast_handle->midi_to_dsp.screen_lex_main_knob3_qnt_hdl != NULL) { if (qntFreeUp(&(cast_handle->midi_to_dsp.screen_lex_main_knob3_qnt_hdl)) != OKAY) return(NOT_OKAY); } if (cast_handle->midi_to_dsp.screen_lex_main_knob4_qnt_hdl != NULL) { if (qntFreeUp(&(cast_handle->midi_to_dsp.screen_lex_main_knob4_qnt_hdl)) != OKAY) return(NOT_OKAY); } /* Fixed Optimizer Specific */ if (cast_handle->midi_to_dsp.release_time_beta_qnt_hdl != NULL) { if (qntFreeUp(&(cast_handle->midi_to_dsp.release_time_beta_qnt_hdl)) != OKAY) return(NOT_OKAY); } if (cast_handle->midi_to_dsp.screen_opt_main_knob3_qnt_hdl != NULL) { if (qntFreeUp(&(cast_handle->midi_to_dsp.screen_opt_main_knob3_qnt_hdl)) != OKAY) return(NOT_OKAY); } /* Fixed Widener Specific */ if (cast_handle->midi_to_dsp.dispersion_delay_qnt_hdl != NULL) { if (qntFreeUp(&(cast_handle->midi_to_dsp.dispersion_delay_qnt_hdl)) != OKAY) return(NOT_OKAY); } if (cast_handle->midi_to_dsp.wid_filter_gain_qnt_hdl != NULL) { if (qntFreeUp(&(cast_handle->midi_to_dsp.wid_filter_gain_qnt_hdl)) != OKAY) return(NOT_OKAY); } if (cast_handle->midi_to_dsp.wid_filter_a1_qnt_hdl != NULL) { if (qntFreeUp(&(cast_handle->midi_to_dsp.wid_filter_a1_qnt_hdl)) != OKAY) return(NOT_OKAY); } if (cast_handle->midi_to_dsp.wid_filter_a0_qnt_hdl != NULL) { if (qntFreeUp(&(cast_handle->midi_to_dsp.wid_filter_a0_qnt_hdl)) != OKAY) return(NOT_OKAY); } /* Delay specific */ if (cast_handle->midi_to_dsp.dly_qnt_hdl != NULL) { if (qntFreeUp(&(cast_handle->midi_to_dsp.dly_qnt_hdl)) != OKAY) return(NOT_OKAY); } /* Free all the other qnt handles */ if (cast_handle->real_to_midi_qnt_hdl != NULL) { if (qntFreeUp(&(cast_handle->real_to_midi_qnt_hdl)) != OKAY) return(NOT_OKAY); } if (cast_handle->midi_to_real_qnt_hdl != NULL) { if (qntFreeUp(&(cast_handle->midi_to_real_qnt_hdl)) != OKAY) return(NOT_OKAY); } /* Free the com handles */ if (cast_handle->com_hdl_front != NULL) { if (comFreeUp(&(cast_handle->com_hdl_front)) != OKAY) return(NOT_OKAY); } if (cast_handle->com_hdl_rear != NULL) { if (comFreeUp(&(cast_handle->com_hdl_rear)) != OKAY) return(NOT_OKAY); } if (cast_handle->com_hdl_side != NULL) { if (comFreeUp(&(cast_handle->com_hdl_side)) != OKAY) return(NOT_OKAY); } if (cast_handle->com_hdl_center != NULL) { if (comFreeUp(&(cast_handle->com_hdl_center)) != OKAY) return(NOT_OKAY); } if (cast_handle->com_hdl_subwoofer != NULL) { if (comFreeUp(&(cast_handle->com_hdl_subwoofer)) != OKAY) return(NOT_OKAY); } // Free EQ handle if (cast_handle->eq.graphicEq_hdl != NULL) { if (GraphicEqFreeUp(&(cast_handle->eq.graphicEq_hdl)) != OKAY) return(NOT_OKAY); } // Free SurroundSyn handle if (cast_handle->SurroundSyn_hdl != NULL) { if (SurroundSynFreeUp(&(cast_handle->SurroundSyn_hdl)) != OKAY) return(NOT_OKAY); } /* Free the spectrum handle */ if (cast_handle->spectrum.spectrum_hdl != NULL) { if (spectrumFreeUp(&(cast_handle->spectrum.spectrum_hdl)) != OKAY) return(NOT_OKAY); } /* Free the binauralSyn handle */ if (cast_handle->BinauralSyn_hdl != NULL) { if (BinauralSynFreeUp(&(cast_handle->BinauralSyn_hdl)) != OKAY) return(NOT_OKAY); } /* Free shared memory library */ if (cast_handle->hp_sharedUtil != NULL) { if (dfxSharedUtilFreeUp(&(cast_handle->hp_sharedUtil)) != OKAY) return(NOT_OKAY); } return(OKAY); } void DfxDspPrivate::getSpectrumBandValues(float* rp_band_values, int i_array_size) { dfxpSpectrumGetBandValues(dfxp_handle_, rp_band_values, i_array_size); }