├── README.md ├── Tests ├── Install requirements.bat ├── Test.Cavern │ ├── Consts │ │ ├── Usings.cs │ │ ├── TestUtils.cs │ │ └── Generators.cs │ ├── TestData │ │ ├── ToEqualizerAPO.txt │ │ ├── ToXML.xml │ │ └── ToXML_ExtraParams.xml │ ├── ArrayExtensions_Tests.cs │ ├── Channels │ │ └── ChannelPrototype_Tests.cs │ ├── Test.Cavern.csproj │ ├── ComplexArray_Tests.cs │ ├── QMath_Tests.cs │ └── Filters │ │ └── QFactor_Tests.cs ├── Test.Cavern.Format │ ├── Consts │ │ ├── Usings.cs │ │ ├── Consts.cs │ │ └── AudioSamples.cs │ └── Test.Cavern.Format.csproj ├── Test.Cavern.QuickEQ │ ├── Consts │ │ ├── Usings.cs │ │ ├── Consts.cs │ │ └── TestUtils.cs │ ├── FilterSet │ │ ├── Exceptions │ │ │ ├── GainOutOfRangeException.cs │ │ │ ├── QImpreciseException.cs │ │ │ └── GainImpreciseException.cs │ │ ├── Rotel_Tests.cs │ │ └── StormAudio_Tests.cs │ ├── Crossover │ │ ├── BasicCrossover_Tests.cs │ │ ├── CavernCrossover_Tests.cs │ │ ├── SyntheticBiquadCrossover_Tests.cs │ │ └── CrossoverAnalyzer_Tests.cs │ ├── MovingAverage_Tests.cs │ ├── EQCurves │ │ ├── Depth_Tests.cs │ │ ├── EQCurve_Tests.cs │ │ └── RoomCurve_Tests.cs │ ├── Test.Cavern.QuickEQ.csproj │ ├── Equalization │ │ └── EQGenerator.Averaging_Tests.cs │ └── PeakingEqualizer_Tests.cs ├── Test.Cavern with coverage.bat └── Test.CavernUnity │ └── Test.CavernUnity.csproj ├── CavernSamples ├── Icon.ico ├── _Common │ └── CavernLogo.png ├── CavernizeGUI │ ├── Resources │ │ ├── Images │ │ │ ├── Help.png │ │ │ ├── Delete.png │ │ │ ├── Folder.png │ │ │ ├── Render.png │ │ │ ├── Language.png │ │ │ ├── Settings.png │ │ │ ├── AddToQueue.png │ │ │ └── RenderQueue.png │ │ ├── RenderTargetSelectorStrings.xaml │ │ ├── RenderTargetSelectorStrings.hu-HU.xaml │ │ └── UpmixingSettings.settings │ ├── MainWindow.Shutdown.cs │ ├── Windows │ │ └── CodecMetadata.xaml.cs │ ├── App.xaml.cs │ ├── UserControls │ │ ├── TextWithIcon.xaml │ │ └── TextWithIcon.xaml.cs │ └── CavernSettings │ │ └── DynamicSpecialRenderModeSettings.cs ├── EQAPOtoFIR │ ├── AssemblyInfo.cs │ ├── App.xaml │ ├── App.xaml.cs │ ├── Enums.cs │ ├── EQAPOtoFIR.csproj.user │ └── Dialogs │ │ ├── SegmentsDialog.xaml.cs │ │ └── SegmentsDialog.xaml ├── FilterStudio │ ├── AssemblyInfo.cs │ ├── App.xaml │ ├── Resources │ │ ├── RenameDialogStrings.xaml │ │ ├── RenameDialogStrings.hu-HU.xaml │ │ ├── ConvolutionLengthDialogStrings.xaml │ │ ├── ConvolutionLengthDialogStrings.hu-HU.xaml │ │ ├── CrossoverDialogStrings.xaml │ │ ├── CrossoverDialogStrings.hu-HU.xaml │ │ └── Settings.settings │ ├── App.xaml.cs │ ├── Consts │ │ └── _Exceptions.cs │ └── Windows │ │ └── ConvolutionLengthDialog.xaml.cs ├── EnhancedAC3Merger │ ├── AssemblyInfo.cs │ ├── App.xaml.cs │ ├── App.xaml │ ├── Settings.settings │ └── EnhancedAC3Merger.csproj.user ├── QuickEQResultMerger │ ├── AssemblyInfo.cs │ ├── App.xaml.cs │ ├── App.xaml │ └── QuickEQResultMerger.csproj ├── WAVChannelReorderer │ ├── AssemblyInfo.cs │ ├── App.xaml.cs │ ├── ChannelComboBox.cs │ ├── App.xaml │ └── WAVChannelReorderer.csproj.user ├── CavernPipeServer.Windows │ ├── AssemblyInfo.cs │ ├── App.xaml.cs │ ├── App.xaml │ ├── CavernPipeServer.Windows.csproj.user │ ├── MainWindow.xaml │ └── ThreadSafeChannelMeters.cs ├── Benchmark │ ├── App.xaml.cs │ ├── App.xaml │ ├── Benchmark.csproj.user │ └── Benchmarks │ │ └── Benchmark.cs ├── Deconvolver │ ├── App.xaml.cs │ ├── App.xaml │ └── Settings.settings ├── HRTFSetImporter │ ├── App.xaml.cs │ ├── App.xaml │ ├── Settings.settings │ └── StringBuilderExtensions.cs ├── ImpulseFlattener │ ├── App.xaml.cs │ ├── App.xaml │ └── Settings.settings ├── WavefrontSimulator │ ├── App.xaml.cs │ ├── App.xaml │ ├── WavefrontSimulator.csproj.user │ └── Settings.settings ├── Reusable │ ├── Cavernize.Logic │ │ ├── Consts │ │ │ └── _Exceptions.cs │ │ ├── CommandLine │ │ │ ├── BaseClasses │ │ │ │ ├── HiddenCommand.cs │ │ │ │ └── IntegerCommand.cs │ │ │ ├── CommandException.cs │ │ │ ├── OutputCommand.cs │ │ │ ├── SurroundSwapCommand.cs │ │ │ ├── EffectCommand.cs │ │ │ ├── HiddenCommands │ │ │ │ ├── UnsafeCommand.cs │ │ │ │ ├── RenderGainCommand.cs │ │ │ │ ├── OverrideBedReader.cs │ │ │ │ └── OverrideBedDecoder.cs │ │ │ ├── UpconvertCommand.cs │ │ │ ├── MuteBedCommand.cs │ │ │ ├── SmoothnessCommand.cs │ │ │ ├── MatrixCommand.cs │ │ │ ├── InputCommand.cs │ │ │ ├── MuteGroundCommand.cs │ │ │ ├── SpeakerVirtualizerCommand.cs │ │ │ ├── Force24BitCommand.cs │ │ │ └── HelpCommand.cs │ │ ├── External │ │ │ └── _Exceptions.cs │ │ ├── Models │ │ │ ├── InvalidTrack.cs │ │ │ └── RenderTargets │ │ │ │ ├── VirtualizerRenderTarget.cs │ │ │ │ └── DriverRenderTarget.cs │ │ └── CavernSettings │ │ │ └── SpecialRenderModeSettings.cs │ └── CavernPipeServer.Logic │ │ └── _Exceptions.cs ├── .editorconfig ├── VoidX.WPF │ ├── FFmpeg │ │ ├── FFmpegStream.cs │ │ └── FFmpegArgument.cs │ ├── FFTSize.cs │ └── NumericUpDown.xaml ├── CavernPipeServer.Multiplatform │ └── Program.cs ├── Coding style.txt └── CavernPipeClient │ └── CavernPipeClient.csproj ├── docs ├── NuGet Readme.md ├── img │ └── rnd_balance.png ├── Channel placement guide.md ├── Quality modes.md ├── NuGet Licence.md └── Format bitstream definitions │ └── Convolution Box Format.md ├── Cavern ├── Resources │ └── CavernLogo.png ├── Utilities │ ├── Interfaces │ │ ├── ILongProcess.cs │ │ ├── ILocalizableToString.cs │ │ └── ILicence.cs │ ├── QFile.cs │ ├── TupleUtils.cs │ ├── ChannelExtensions.cs │ ├── DictionaryExtensions.cs │ └── LinqExtensions.cs ├── Internals │ └── _Exceptions.cs ├── Filters │ ├── Interfaces │ │ ├── IConvolution.cs │ │ ├── IEqualizerAPOFilter.cs │ │ └── ISampleRateDependentFilter.cs │ └── _Exceptions.cs ├── Waveforms │ └── Exceptions │ │ └── DifferentSignalLengthsException.cs ├── Channels │ └── Exceptions │ │ └── ChannelCountMismatchException.cs ├── Remapping │ ├── Exceptions │ │ └── DifferentInputChannelCountsException.cs │ └── SpatialRemappingSource.cs ├── SpecialSources │ ├── StreamedSource.cs │ └── MuteSource.cs └── Virtualizer │ └── _Exceptions.cs ├── CavernAmp ├── waveformUtils.cpp ├── waveformUtils.h ├── export.h ├── complexArray.h ├── complex.h ├── filter.h ├── main.h ├── qmath.cpp ├── complexArray.cpp ├── graphUtils.h ├── peakingFilter.h ├── main.cpp ├── fftcache.h ├── measurements.h └── peakingEqualizer.h ├── Cavern.Format ├── Common │ ├── TrackExtra.cs │ ├── IMetadataSupplier.cs │ ├── _CavernFormatGlobal.cs │ ├── Container.cs │ ├── TrackExtensions.cs │ ├── IExportable.cs │ └── BasicEncodingRules.cs ├── Consts │ ├── FormatConsts.cs │ ├── CoreAudioFormatConsts.cs │ ├── MeridianLosslessPackingConsts.cs │ ├── LimitlessAudioFormatConsts.cs │ └── MXFConsts.cs ├── Container │ ├── MP4 │ │ ├── RawBox.cs │ │ ├── TimeToSampleBox.cs │ │ └── ChunkOffsetBox.cs │ └── Matroska │ │ ├── MatroskaTrackExtraVideo.cs │ │ └── MatroskaTrack.cs ├── Renderers │ ├── BaseClasses │ │ └── IMixedBedObjectRenderer.cs │ ├── DummyRenderer.cs │ ├── RendererConsts.cs │ └── MeridianLosslessPackingRenderer.cs ├── Utilities │ ├── ParserExtensions.cs │ └── IXDocumentSerializable.cs ├── Decoders │ └── EnhancedAC3 │ │ └── ObjectAudioMetadataEnums.cs └── Transcoders │ ├── EnhancedAC3Body │ └── AllocationHistory.cs │ └── EnhancedAC3Enums.cs ├── CavernUnity DLL ├── FilterInterfaces │ └── _Exceptions.cs └── QuickEQ │ └── NoisyChannel.cs ├── Libraries └── Cavern.WPF │ ├── Resources │ ├── CrossoverStrings.xaml │ ├── CrossoverStrings.hu-HU.xaml │ ├── EQEditorStrings.xaml │ ├── EQEditorStrings.hu-HU.xaml │ ├── ChannelSelectorStyle.xaml │ ├── CommonStrings.xaml │ ├── CommonStrings.hu-HU.xaml │ ├── ConvolutionEditorStrings.xaml │ ├── ConvolutionEditorStrings.hu-HU.xaml │ ├── BiquadEditorStrings.xaml │ ├── BiquadEditorStrings.hu-HU.xaml │ ├── UpmixingSetupStrings.xaml │ └── UpmixingSetupStrings.hu-HU.xaml │ ├── Controls │ └── GraphRendererControl.xaml │ ├── Utils │ ├── ChannelOnUI.cs │ ├── CrossoverTypeOnUI.cs │ └── ColorUtils.cs │ └── BaseClasses │ └── OkCancelDialog.cs ├── Cavern.QuickEQ ├── Common │ └── _Exceptions.cs ├── EQCurves │ ├── Depth.cs │ ├── RoomCurve.cs │ └── Smoother.cs ├── Graphing │ ├── Overlays │ │ ├── GraphOverlay.cs │ │ └── GridFront.cs │ └── DrawableMeasurementType.cs ├── PolarityCorrections │ ├── PolarityCorrectionType.cs │ └── ImpulsePeakBasedPolarityCorrection.cs ├── Equalization │ └── EqualizerExtensions.cs ├── Measurement │ └── PhaseDelayCompensationType.cs └── Crossover │ └── BasicCrossover.cs ├── Cavern.QuickEQ.Format ├── ConfigurationFile │ ├── Presets │ │ └── FilterSetPreset.cs │ ├── Exceptions │ │ ├── PlaceholderFilterException.cs │ │ ├── NotPreparedChannelException.cs │ │ ├── LastSplitPointException.cs │ │ ├── NotEqualizerAPOFilterException.cs │ │ ├── DuplicateLabelException.cs │ │ ├── NotCavernFilterStudioFilterException.cs │ │ └── UnsupportedFilterForExportException.cs │ ├── ConfigurationFileType.cs │ ├── Helpers │ │ └── ILazyLoadableFilter.cs │ ├── ConvolutionBoxFormat │ │ └── CBFEntry.cs │ └── ConfigurationFileTypeExtensions.cs ├── FilterSet │ ├── BaseClasses │ │ └── FilterProperty.cs │ ├── Enums │ │ └── DelayUnit.cs │ ├── Exceptions │ │ ├── FIRGainException.cs │ │ ├── InvalidSourceException.cs │ │ ├── UnsupportedFilterException.cs │ │ ├── DeltaSetException.cs │ │ └── ChannelDependentBandCountException.cs │ ├── MultEQXTargetFilterSet.cs │ ├── MiniDSPDDRC88AFilterSet.cs │ ├── MiniDSPFlexHTxFilterSet.cs │ ├── AcurusMuseFilterSet.cs │ ├── WiiMFilterSet.cs │ ├── AUNBandEQ.cs │ ├── Multiband10FilterSet.cs │ ├── YPAOLiteFilterSet.cs │ └── MultEQXRawFilterSet.cs └── JSON │ └── JsonFileExtensions.cs ├── UnityPlugins └── CavernWebGL │ └── microphone.jslib.meta └── LICENSE.md /README.md: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/VoidXH/Cavern/HEAD/README.md -------------------------------------------------------------------------------- /Tests/Install requirements.bat: -------------------------------------------------------------------------------- 1 | dotnet tool install -g dotnet-reportgenerator-globaltool -------------------------------------------------------------------------------- /CavernSamples/Icon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/VoidXH/Cavern/HEAD/CavernSamples/Icon.ico -------------------------------------------------------------------------------- /Tests/Test.Cavern/Consts/Usings.cs: -------------------------------------------------------------------------------- 1 | global using Microsoft.VisualStudio.TestTools.UnitTesting; -------------------------------------------------------------------------------- /docs/NuGet Readme.md: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/VoidXH/Cavern/HEAD/docs/NuGet Readme.md -------------------------------------------------------------------------------- /docs/img/rnd_balance.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/VoidXH/Cavern/HEAD/docs/img/rnd_balance.png -------------------------------------------------------------------------------- /Tests/Test.Cavern.Format/Consts/Usings.cs: -------------------------------------------------------------------------------- 1 | global using Microsoft.VisualStudio.TestTools.UnitTesting; -------------------------------------------------------------------------------- /Tests/Test.Cavern.QuickEQ/Consts/Usings.cs: -------------------------------------------------------------------------------- 1 | global using Microsoft.VisualStudio.TestTools.UnitTesting; -------------------------------------------------------------------------------- /Cavern/Resources/CavernLogo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/VoidXH/Cavern/HEAD/Cavern/Resources/CavernLogo.png -------------------------------------------------------------------------------- /docs/Channel placement guide.md: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/VoidXH/Cavern/HEAD/docs/Channel placement guide.md -------------------------------------------------------------------------------- /CavernSamples/_Common/CavernLogo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/VoidXH/Cavern/HEAD/CavernSamples/_Common/CavernLogo.png -------------------------------------------------------------------------------- /Tests/Test.Cavern/TestData/ToEqualizerAPO.txt: -------------------------------------------------------------------------------- 1 | Copy: L=L R=R C=C SUB=SUB RL=0.92387956*RL+0.3826834*RR+SL RR=0.38268337*RL+0.92387956*RR+SR SL=0 SR=0 -------------------------------------------------------------------------------- /CavernSamples/CavernizeGUI/Resources/Images/Help.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/VoidXH/Cavern/HEAD/CavernSamples/CavernizeGUI/Resources/Images/Help.png -------------------------------------------------------------------------------- /CavernSamples/CavernizeGUI/Resources/Images/Delete.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/VoidXH/Cavern/HEAD/CavernSamples/CavernizeGUI/Resources/Images/Delete.png -------------------------------------------------------------------------------- /CavernSamples/CavernizeGUI/Resources/Images/Folder.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/VoidXH/Cavern/HEAD/CavernSamples/CavernizeGUI/Resources/Images/Folder.png -------------------------------------------------------------------------------- /CavernSamples/CavernizeGUI/Resources/Images/Render.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/VoidXH/Cavern/HEAD/CavernSamples/CavernizeGUI/Resources/Images/Render.png -------------------------------------------------------------------------------- /CavernSamples/CavernizeGUI/Resources/Images/Language.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/VoidXH/Cavern/HEAD/CavernSamples/CavernizeGUI/Resources/Images/Language.png -------------------------------------------------------------------------------- /CavernSamples/CavernizeGUI/Resources/Images/Settings.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/VoidXH/Cavern/HEAD/CavernSamples/CavernizeGUI/Resources/Images/Settings.png -------------------------------------------------------------------------------- /CavernSamples/CavernizeGUI/Resources/Images/AddToQueue.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/VoidXH/Cavern/HEAD/CavernSamples/CavernizeGUI/Resources/Images/AddToQueue.png -------------------------------------------------------------------------------- /CavernSamples/CavernizeGUI/Resources/Images/RenderQueue.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/VoidXH/Cavern/HEAD/CavernSamples/CavernizeGUI/Resources/Images/RenderQueue.png -------------------------------------------------------------------------------- /CavernSamples/EQAPOtoFIR/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Windows; 2 | 3 | [assembly: ThemeInfo(ResourceDictionaryLocation.None, ResourceDictionaryLocation.SourceAssembly)] -------------------------------------------------------------------------------- /CavernSamples/FilterStudio/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Windows; 2 | 3 | [assembly: ThemeInfo(ResourceDictionaryLocation.None, ResourceDictionaryLocation.SourceAssembly)] -------------------------------------------------------------------------------- /CavernSamples/EnhancedAC3Merger/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Windows; 2 | 3 | [assembly: ThemeInfo(ResourceDictionaryLocation.None, ResourceDictionaryLocation.SourceAssembly)] -------------------------------------------------------------------------------- /CavernSamples/QuickEQResultMerger/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Windows; 2 | 3 | [assembly: ThemeInfo(ResourceDictionaryLocation.None, ResourceDictionaryLocation.SourceAssembly)] -------------------------------------------------------------------------------- /CavernSamples/WAVChannelReorderer/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Windows; 2 | 3 | [assembly: ThemeInfo(ResourceDictionaryLocation.None, ResourceDictionaryLocation.SourceAssembly)] -------------------------------------------------------------------------------- /CavernSamples/CavernPipeServer.Windows/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Windows; 2 | 3 | [assembly: ThemeInfo(ResourceDictionaryLocation.None, ResourceDictionaryLocation.SourceAssembly)] -------------------------------------------------------------------------------- /CavernAmp/waveformUtils.cpp: -------------------------------------------------------------------------------- 1 | #include "waveformUtils.h" 2 | 3 | void Mix(float* from, float* to, int length) { 4 | for (int i = 0; i < length; ++i) 5 | to[i] += from[i]; 6 | } 7 | -------------------------------------------------------------------------------- /Cavern.Format/Common/TrackExtra.cs: -------------------------------------------------------------------------------- 1 | namespace Cavern.Format.Common { 2 | /// 3 | /// Extra metadata of a track. 4 | /// 5 | public abstract class TrackExtra { } 6 | } -------------------------------------------------------------------------------- /CavernAmp/waveformUtils.h: -------------------------------------------------------------------------------- 1 | #ifndef WAVEFORMUTILS_H 2 | #define WAVEFORMUTILS_H 3 | 4 | // Mix a track to a stream. 5 | void Mix(float* from, float* to, int length); 6 | 7 | #endif // WAVEFORMUTILS_H 8 | -------------------------------------------------------------------------------- /CavernSamples/Benchmark/App.xaml.cs: -------------------------------------------------------------------------------- 1 | using System.Windows; 2 | 3 | namespace Benchmark { 4 | /// 5 | /// Interaction logic for App.xaml 6 | /// 7 | public partial class App : Application { 8 | } 9 | } -------------------------------------------------------------------------------- /CavernAmp/export.h: -------------------------------------------------------------------------------- 1 | #ifndef EXPORT_H 2 | #define EXPORT_H 3 | 4 | #ifdef BUILD_DLL 5 | #define DLL_EXPORT __declspec(dllexport) 6 | #else 7 | #define DLL_EXPORT __declspec(dllimport) 8 | #endif 9 | 10 | #endif // EXPORT_H 11 | -------------------------------------------------------------------------------- /CavernSamples/Deconvolver/App.xaml.cs: -------------------------------------------------------------------------------- 1 | using System.Windows; 2 | 3 | namespace Deconvolver { 4 | /// 5 | /// Interaction logic for App.xaml 6 | /// 7 | public partial class App : Application { 8 | } 9 | } -------------------------------------------------------------------------------- /CavernSamples/HRTFSetImporter/App.xaml.cs: -------------------------------------------------------------------------------- 1 | using System.Windows; 2 | 3 | namespace HRTFSetImporter { 4 | /// 5 | /// Interaction logic for App.xaml 6 | /// 7 | public partial class App : Application { 8 | } 9 | } -------------------------------------------------------------------------------- /CavernSamples/QuickEQResultMerger/App.xaml.cs: -------------------------------------------------------------------------------- 1 | using System.Windows; 2 | 3 | namespace QuickEQResultMerger { 4 | /// 5 | /// Interaction logic for App.xaml 6 | /// 7 | public partial class App : Application { } 8 | } -------------------------------------------------------------------------------- /CavernSamples/EnhancedAC3Merger/App.xaml.cs: -------------------------------------------------------------------------------- 1 | using System.Windows; 2 | 3 | namespace EnhancedAC3Merger { 4 | /// 5 | /// Interaction logic for App.xaml 6 | /// 7 | public partial class App : Application { 8 | } 9 | } -------------------------------------------------------------------------------- /CavernSamples/ImpulseFlattener/App.xaml.cs: -------------------------------------------------------------------------------- 1 | using System.Windows; 2 | 3 | namespace ImpulseFlattener { 4 | /// 5 | /// Interaction logic for App.xaml 6 | /// 7 | public partial class App : Application { 8 | } 9 | } -------------------------------------------------------------------------------- /CavernSamples/WavefrontSimulator/App.xaml.cs: -------------------------------------------------------------------------------- 1 | using System.Windows; 2 | 3 | namespace WavefrontSimulator { 4 | /// 5 | /// Interaction logic for App.xaml 6 | /// 7 | public partial class App : Application { 8 | } 9 | } -------------------------------------------------------------------------------- /CavernSamples/CavernPipeServer.Windows/App.xaml.cs: -------------------------------------------------------------------------------- 1 | using System.Windows; 2 | 3 | namespace CavernPipeServer.Windows; 4 | 5 | /// 6 | /// Interaction logic for App.xaml 7 | /// 8 | public partial class App : Application { 9 | } 10 | -------------------------------------------------------------------------------- /CavernSamples/WAVChannelReorderer/App.xaml.cs: -------------------------------------------------------------------------------- 1 | using System.Windows; 2 | 3 | namespace WAVChannelReorderer { 4 | /// 5 | /// Interaction logic for App.xaml 6 | /// 7 | public partial class App : Application { 8 | } 9 | } -------------------------------------------------------------------------------- /CavernAmp/complexArray.h: -------------------------------------------------------------------------------- 1 | #ifndef COMPLEXARRAY_H 2 | #define COMPLEXARRAY_H 3 | 4 | #include "complex.h" 5 | 6 | // Replace the source with its convolution with an other array. 7 | void Convolve(Complex* source, Complex* other, int len); 8 | 9 | #endif 10 | -------------------------------------------------------------------------------- /CavernSamples/Reusable/Cavernize.Logic/Consts/_Exceptions.cs: -------------------------------------------------------------------------------- 1 | namespace Cavernize.Logic; 2 | 3 | /// 4 | /// Tells that a network operation has failed. 5 | /// 6 | public class NetworkException(string message) : Exception(message) { 7 | } 8 | -------------------------------------------------------------------------------- /CavernUnity DLL/FilterInterfaces/_Exceptions.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace Cavern.FilterInterfaces { 4 | /// 5 | /// Represents that a filter does not exists. 6 | /// 7 | public class FilterNotExistsException : Exception { } 8 | } -------------------------------------------------------------------------------- /CavernSamples/EnhancedAC3Merger/App.xaml: -------------------------------------------------------------------------------- 1 | 5 | -------------------------------------------------------------------------------- /Tests/Test.Cavern/TestData/ToXML.xml: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /Tests/Test.Cavern with coverage.bat: -------------------------------------------------------------------------------- 1 | cd Test.Cavern 2 | dotnet test /p:CollectCoverage=true /p:CoverletOutputFormat=cobertura /p:CoverletOutput=../TestResults/coverage 3 | reportgenerator -reports:../TestResults/coverage.cobertura.xml -targetdir:../TestResults/HtmlReport 4 | start ../TestResults/HtmlReport/index.html -------------------------------------------------------------------------------- /CavernAmp/complex.h: -------------------------------------------------------------------------------- 1 | #ifndef COMPLEX_H 2 | #define COMPLEX_H 3 | 4 | #include 5 | 6 | struct Complex { 7 | float real; 8 | float imaginary; 9 | 10 | float getMagnitude() { 11 | return sqrtf(real * real + imaginary * imaginary); 12 | } 13 | }; 14 | 15 | #endif // COMPLEX_H 16 | -------------------------------------------------------------------------------- /CavernAmp/filter.h: -------------------------------------------------------------------------------- 1 | #ifndef FILTER_H 2 | #define FILTER_H 3 | 4 | // Abstract base class for filters. 5 | class Filter { 6 | public: 7 | virtual void Process(float* samples, int len) = 0; 8 | virtual void Process(float* samples, int len, int channel, int channels) = 0; 9 | }; 10 | 11 | #endif // FILTER_H 12 | -------------------------------------------------------------------------------- /CavernSamples/WAVChannelReorderer/ChannelComboBox.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Windows.Controls; 3 | 4 | using Cavern.Channels; 5 | 6 | namespace WAVChannelReorderer { 7 | internal class ChannelComboBox : ComboBox { 8 | public ChannelComboBox() => ItemsSource = Enum.GetValues(typeof(ReferenceChannel)); 9 | } 10 | } -------------------------------------------------------------------------------- /Tests/Test.Cavern/TestData/ToXML_ExtraParams.xml: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /CavernAmp/main.h: -------------------------------------------------------------------------------- 1 | #ifndef __MAIN_H__ 2 | #define __MAIN_H__ 3 | 4 | #include 5 | 6 | #include "export.h" 7 | #include "fftcache.h" 8 | 9 | #ifdef __cplusplus 10 | extern "C" { 11 | #endif 12 | 13 | // Main 14 | bool DLL_EXPORT IsAvailable(); 15 | 16 | #ifdef __cplusplus 17 | } 18 | #endif 19 | 20 | #endif // __MAIN_H__ 21 | -------------------------------------------------------------------------------- /CavernSamples/FilterStudio/App.xaml: -------------------------------------------------------------------------------- 1 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /CavernSamples/CavernPipeServer.Windows/App.xaml: -------------------------------------------------------------------------------- 1 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /CavernSamples/.editorconfig: -------------------------------------------------------------------------------- 1 | [*.cs] 2 | dotnet_diagnostic.CA1806.severity = none 3 | dotnet_diagnostic.CS8600.severity = none 4 | dotnet_diagnostic.CS8602.severity = none 5 | dotnet_diagnostic.CS8603.severity = none 6 | dotnet_diagnostic.CS8604.severity = none 7 | dotnet_diagnostic.CS8618.severity = none 8 | dotnet_diagnostic.CS8625.severity = none 9 | dotnet_diagnostic.CS8629.severity = none -------------------------------------------------------------------------------- /CavernSamples/Benchmark/App.xaml: -------------------------------------------------------------------------------- 1 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /CavernSamples/EQAPOtoFIR/App.xaml: -------------------------------------------------------------------------------- 1 | 6 | 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /CavernSamples/EQAPOtoFIR/App.xaml.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Configuration; 4 | using System.Data; 5 | using System.Linq; 6 | using System.Threading.Tasks; 7 | using System.Windows; 8 | 9 | namespace EQAPOtoFIR { 10 | /// 11 | /// Interaction logic for App.xaml 12 | /// 13 | public partial class App : Application { 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /Cavern.Format/Consts/FormatConsts.cs: -------------------------------------------------------------------------------- 1 | namespace Cavern.Format.Consts { 2 | /// 3 | /// Constants needed across the entire library. 4 | /// 5 | internal static class FormatConsts { 6 | /// 7 | /// Only read 10 MB blocks at max to optimize I/O performance. 8 | /// 9 | public const int blockSize = 10 * 1024 * 1024; 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /Cavern/Utilities/Interfaces/ILongProcess.cs: -------------------------------------------------------------------------------- 1 | namespace Cavern.Utilities { 2 | /// 3 | /// An operation that takes a long time and should run in the background. Its interface provides progress polling. 4 | /// 5 | public interface ILongProcess { 6 | /// 7 | /// The ratio of doneness [0;1]. 8 | /// 9 | float Progress { get; } 10 | } 11 | } -------------------------------------------------------------------------------- /CavernSamples/QuickEQResultMerger/App.xaml: -------------------------------------------------------------------------------- 1 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /Cavern.Format/Common/IMetadataSupplier.cs: -------------------------------------------------------------------------------- 1 | namespace Cavern.Format.Common { 2 | /// 3 | /// A codec that can supply its metadata in human-readable format. 4 | /// 5 | public interface IMetadataSupplier { 6 | /// 7 | /// Gets the metadata for this codec in a human-readable format. 8 | /// 9 | public ReadableMetadata GetMetadata(); 10 | } 11 | } -------------------------------------------------------------------------------- /CavernSamples/Deconvolver/App.xaml: -------------------------------------------------------------------------------- 1 | 6 | 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /CavernSamples/HRTFSetImporter/App.xaml: -------------------------------------------------------------------------------- 1 | 6 | 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /CavernAmp/qmath.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #include "qmath.h" 4 | 5 | double Clamp(double value, double min, double max) { 6 | if (value < min) 7 | return min; 8 | if (value > max) 9 | return max; 10 | return value; 11 | } 12 | 13 | float SumAbs(float* array, int arrayLength) { 14 | float sum = 0; 15 | for (int i = 0; i < arrayLength; ++i) 16 | sum += fabsf(array[i]); 17 | return sum; 18 | } 19 | -------------------------------------------------------------------------------- /CavernSamples/FilterStudio/Resources/RenameDialogStrings.xaml: -------------------------------------------------------------------------------- 1 | 4 | Rename 5 | New name of {0}: 6 | -------------------------------------------------------------------------------- /CavernSamples/ImpulseFlattener/App.xaml: -------------------------------------------------------------------------------- 1 | 6 | 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /CavernSamples/Reusable/Cavernize.Logic/CommandLine/BaseClasses/HiddenCommand.cs: -------------------------------------------------------------------------------- 1 | namespace Cavernize.Logic.CommandLine.BaseClasses; 2 | 3 | /// 4 | /// Marks a command that won't show up under -help. 5 | /// 6 | public abstract class HiddenCommand : Command { 7 | /// 8 | /// Hidden commands don't have shorthands. 9 | /// 10 | public sealed override string Alias => string.Empty; 11 | } 12 | -------------------------------------------------------------------------------- /Libraries/Cavern.WPF/Resources/CrossoverStrings.xaml: -------------------------------------------------------------------------------- 1 | 4 | Biquadratic 5 | Synthetic biquadratic 6 | -------------------------------------------------------------------------------- /CavernSamples/FilterStudio/Resources/RenameDialogStrings.hu-HU.xaml: -------------------------------------------------------------------------------- 1 | 4 | Átnevezés 5 | {0} új neve: 6 | -------------------------------------------------------------------------------- /CavernSamples/Reusable/Cavernize.Logic/CommandLine/CommandException.cs: -------------------------------------------------------------------------------- 1 | namespace Cavernize.Logic.CommandLine; 2 | 3 | /// 4 | /// A command's execution has failed. 5 | /// 6 | public sealed class CommandException(string message) : Exception(message) { } 7 | 8 | /// 9 | /// Stop further command processing with no message. 10 | /// 11 | public sealed class CommandProcessingCanceledException : Exception { } 12 | -------------------------------------------------------------------------------- /CavernSamples/WAVChannelReorderer/App.xaml: -------------------------------------------------------------------------------- 1 | 6 | 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /CavernSamples/WavefrontSimulator/App.xaml: -------------------------------------------------------------------------------- 1 | 6 | 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /Libraries/Cavern.WPF/Resources/CrossoverStrings.hu-HU.xaml: -------------------------------------------------------------------------------- 1 | 4 | Bikvadratikus 5 | Szintetikus bikvadratikus 6 | -------------------------------------------------------------------------------- /CavernSamples/FilterStudio/App.xaml.cs: -------------------------------------------------------------------------------- 1 | using System.Windows; 2 | 3 | namespace FilterStudio { 4 | /// 5 | /// Interaction logic for App.xaml 6 | /// 7 | public partial class App : Application { 8 | /// 9 | /// Set the language strings with the app launch. 10 | /// 11 | public App() => Resources.MergedDictionaries.Add(Consts.Language.GetMainWindowStrings()); 12 | } 13 | } -------------------------------------------------------------------------------- /CavernSamples/CavernizeGUI/MainWindow.Shutdown.cs: -------------------------------------------------------------------------------- 1 | using System.Windows; 2 | 3 | namespace CavernizeGUI { 4 | // Shutdown process and related debug features 5 | partial class MainWindow { 6 | static void CheckBlocks() { 7 | #if DEBUG 8 | foreach (Window window in Application.Current.Windows) { 9 | Error("This window is still open: " + window.GetType().FullName); 10 | } 11 | #endif 12 | } 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /CavernSamples/EQAPOtoFIR/Enums.cs: -------------------------------------------------------------------------------- 1 | namespace EQAPOtoFIR { 2 | /// 3 | /// Time direction by the target filter. 4 | /// 5 | public enum ExportFormat { 6 | /// 7 | /// Forward time impulse export for convolution filters. 8 | /// 9 | Impulse, 10 | /// 11 | /// Inverse time impulse export for FIR filters. 12 | /// 13 | FIR 14 | } 15 | } -------------------------------------------------------------------------------- /Cavern.Format/Common/_CavernFormatGlobal.cs: -------------------------------------------------------------------------------- 1 | namespace Cavern.Format.Common { 2 | /// 3 | /// Settings related to the entirety of the Cavern.Format library. 4 | /// 5 | public static class CavernFormatGlobal { 6 | /// 7 | /// Disables checks for conditions that don't inherently break operation, but are mandated by standards. 8 | /// 9 | public static bool Unsafe { get; set; } 10 | } 11 | } -------------------------------------------------------------------------------- /CavernAmp/complexArray.cpp: -------------------------------------------------------------------------------- 1 | #include "complexArray.h" 2 | 3 | void Convolve(Complex* source, Complex* other, int len) { 4 | Complex* end = source + len; 5 | while (source != end) { 6 | float oldReal = source->real; 7 | source->real = source->real * other->real - source->imaginary * other->imaginary; 8 | source->imaginary = oldReal * other->imaginary + source->imaginary * other->real; 9 | source++; 10 | other++; 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /Tests/Test.Cavern.QuickEQ/FilterSet/Exceptions/GainOutOfRangeException.cs: -------------------------------------------------------------------------------- 1 | namespace Test.Cavern.QuickEQ.FilterSet.Exceptions { 2 | /// 3 | /// Tells if a filter gain is out of the device range. 4 | /// 5 | public class GainOutOfRangeException(double gain, double minGain, double maxGain) : Exception(string.Format(message, gain, minGain, maxGain)) { 6 | const string message = "Filter gain ({0} dB) is out of the device range ({1}-{2} dB)"; 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /CavernSamples/FilterStudio/Resources/ConvolutionLengthDialogStrings.xaml: -------------------------------------------------------------------------------- 1 | 4 | Convolution length 5 | Number of convolution samples for each filter: 6 | -------------------------------------------------------------------------------- /Libraries/Cavern.WPF/Resources/EQEditorStrings.xaml: -------------------------------------------------------------------------------- 1 | 4 | Graphic EQ Editor 5 | Frequency 6 | Gain 7 | -------------------------------------------------------------------------------- /Cavern/Utilities/Interfaces/ILocalizableToString.cs: -------------------------------------------------------------------------------- 1 | using System.Globalization; 2 | 3 | namespace Cavern.Utilities { 4 | /// 5 | /// Adds a version of that can be translated. 6 | /// 7 | public interface ILocalizableToString { 8 | /// 9 | /// Returns a string that represents the current objects in the passed language. 10 | /// 11 | string ToString(CultureInfo culture); 12 | } 13 | } -------------------------------------------------------------------------------- /CavernSamples/FilterStudio/Resources/ConvolutionLengthDialogStrings.hu-HU.xaml: -------------------------------------------------------------------------------- 1 | 4 | Konvolúció hossza 5 | Konvolúciós minták száma minden szűrő esetén: 6 | -------------------------------------------------------------------------------- /Cavern/Utilities/QFile.cs: -------------------------------------------------------------------------------- 1 | using System.IO; 2 | 3 | namespace Cavern.Utilities { 4 | /// 5 | /// Shorthand for common file operations. 6 | /// 7 | public static class QFile { 8 | /// 9 | /// Delete a file only if it exists. 10 | /// 11 | public static void DeleteIfExists(string path) { 12 | if (File.Exists(path)) { 13 | File.Delete(path); 14 | } 15 | } 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /Libraries/Cavern.WPF/Resources/EQEditorStrings.hu-HU.xaml: -------------------------------------------------------------------------------- 1 | 4 | Grafikus EQ szerkesztő 5 | Frekvencia 6 | Erősítés 7 | -------------------------------------------------------------------------------- /Tests/Test.Cavern.QuickEQ/FilterSet/Exceptions/QImpreciseException.cs: -------------------------------------------------------------------------------- 1 | namespace Test.Cavern.QuickEQ.FilterSet.Exceptions { 2 | /// 3 | /// Tells if a filter's Q factor is not within tolerance to the required precision. 4 | /// 5 | public class QImpreciseException(double q, double expectedPrecision) : Exception(string.Format(message, q, expectedPrecision)) { 6 | const string message = "The filter's Q factor ({0}) is not aligned to the allowed precision ({1})"; 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /Tests/Test.Cavern.QuickEQ/FilterSet/Exceptions/GainImpreciseException.cs: -------------------------------------------------------------------------------- 1 | namespace Test.Cavern.QuickEQ.FilterSet.Exceptions { 2 | /// 3 | /// Tells if a filter gain is not within tolerance to the required precision. 4 | /// 5 | public class GainImpreciseException(double gain, double expectedPrecision) : Exception(string.Format(message, gain, expectedPrecision)) { 6 | const string message = "Filter gain ({0} dB) is not aligned to the allowed precision ({1} dB)"; 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /CavernSamples/CavernizeGUI/Windows/CodecMetadata.xaml.cs: -------------------------------------------------------------------------------- 1 | using System.Windows; 2 | 3 | using Cavern.Format.Common; 4 | 5 | namespace CavernizeGUI.Windows { 6 | /// 7 | /// Displays field-level debug information about the selected source track. 8 | /// 9 | public partial class CodecMetadata : Window { 10 | public CodecMetadata(ReadableMetadata source) { 11 | InitializeComponent(); 12 | data.ItemsSource = source.Headers; 13 | } 14 | } 15 | } -------------------------------------------------------------------------------- /CavernSamples/Reusable/Cavernize.Logic/External/_Exceptions.cs: -------------------------------------------------------------------------------- 1 | namespace Cavernize.Logic.External; 2 | 3 | /// 4 | /// Tells if no valid release was found while searching. 5 | /// 6 | public class NoValidReleaseException : Exception { 7 | const string message = "No valid release was found while searching."; 8 | 9 | /// 10 | /// Tells if no valid release was found while searching. 11 | /// 12 | public NoValidReleaseException() : base(message) { } 13 | } 14 | -------------------------------------------------------------------------------- /CavernSamples/VoidX.WPF/FFmpeg/FFmpegStream.cs: -------------------------------------------------------------------------------- 1 | namespace VoidX.WPF.FFmpeg; 2 | 3 | /// 4 | /// Stream types in FFmpeg used for mapping. 5 | /// 6 | public enum FFmpegStream { 7 | /// 8 | /// Video stream selection. 9 | /// 10 | Video = 'v', 11 | /// 12 | /// Audio stream selection. 13 | /// 14 | Audio = 'a', 15 | /// 16 | /// Subtitle stream selection. 17 | /// 18 | Subtitle = 's', 19 | } 20 | -------------------------------------------------------------------------------- /Cavern.Format/Container/MP4/RawBox.cs: -------------------------------------------------------------------------------- 1 | using System.IO; 2 | 3 | using static Cavern.Format.Consts.MP4Consts; 4 | 5 | namespace Cavern.Format.Container.MP4 { 6 | /// 7 | /// Raw data of the tracks in an MP4 container. 8 | /// 9 | internal class RawBox : Box { 10 | /// 11 | /// Raw data of the tracks in an MP4 container. 12 | /// 13 | public RawBox(uint length, Stream reader) : base(length, rawBox, reader) { 14 | } 15 | } 16 | } -------------------------------------------------------------------------------- /CavernSamples/EQAPOtoFIR/EQAPOtoFIR.csproj.user: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | Designer 7 | 8 | 9 | 10 | 11 | Designer 12 | 13 | 14 | -------------------------------------------------------------------------------- /CavernSamples/WavefrontSimulator/WavefrontSimulator.csproj.user: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | Designer 7 | 8 | 9 | 10 | 11 | Designer 12 | 13 | 14 | -------------------------------------------------------------------------------- /Cavern.Format/Renderers/BaseClasses/IMixedBedObjectRenderer.cs: -------------------------------------------------------------------------------- 1 | using Cavern.Channels; 2 | 3 | namespace Cavern.Format.Renderers.BaseClasses { 4 | /// 5 | /// A that has static beds and dynamic objects in the same stream. 6 | /// 7 | public interface IMixedBedObjectRenderer { 8 | /// 9 | /// Get the "objects" that are just static channels. 10 | /// 11 | ReferenceChannel[] GetStaticChannels(); 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /CavernSamples/WAVChannelReorderer/WAVChannelReorderer.csproj.user: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | Designer 7 | 8 | 9 | 10 | 11 | 12 | Designer 13 | 14 | 15 | -------------------------------------------------------------------------------- /Libraries/Cavern.WPF/Controls/GraphRendererControl.xaml: -------------------------------------------------------------------------------- 1 | 8 | 9 | -------------------------------------------------------------------------------- /Cavern.QuickEQ/Common/_Exceptions.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace Cavern.QuickEQ { 4 | /// 5 | /// Tells that an EQ Curve can't be created by a generic switch. 6 | /// 7 | public class NonGeneralizedCurveException : Exception { 8 | const string message = "This EQ should be created with its constructor."; 9 | 10 | /// 11 | /// Tells that an EQ Curve can't be created by a generic switch. 12 | /// 13 | public NonGeneralizedCurveException() : base(message) { } 14 | } 15 | } -------------------------------------------------------------------------------- /Libraries/Cavern.WPF/Resources/ChannelSelectorStyle.xaml: -------------------------------------------------------------------------------- 1 | 3 | 11 | -------------------------------------------------------------------------------- /Cavern.QuickEQ.Format/ConfigurationFile/Presets/FilterSetPreset.cs: -------------------------------------------------------------------------------- 1 | namespace Cavern.Format.ConfigurationFile.Presets { 2 | /// 3 | /// An added preconfigured step to a filter graph. 4 | /// 5 | public abstract class FilterSetPreset { 6 | /// 7 | /// Add this preset to a work in progress configuration at the given split point . 8 | /// 9 | public abstract void Add(ConfigurationFile file, int index); 10 | } 11 | } -------------------------------------------------------------------------------- /Cavern/Internals/_Exceptions.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace Cavern.Internals { 4 | /// 5 | /// Tells if the developer used something without properly understanding what it does. 6 | /// 7 | public class DevHasNoIdeaException : Exception { 8 | const string message = "The developer is very irresponsible."; 9 | 10 | /// 11 | /// Tells if the developer used something without properly understanding what it does. 12 | /// 13 | public DevHasNoIdeaException() : base(message) { } 14 | } 15 | } -------------------------------------------------------------------------------- /CavernSamples/EnhancedAC3Merger/Settings.settings: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /Cavern.Format/Consts/CoreAudioFormatConsts.cs: -------------------------------------------------------------------------------- 1 | namespace Cavern.Format.Consts { 2 | /// 3 | /// Constants for reading/writing Core Audio Format files. 4 | /// 5 | internal static class CoreAudioFormatConsts { 6 | /// 7 | /// caff sync word, stream marker. 8 | /// 9 | public const int syncWord = 0x66666163; 10 | 11 | /// 12 | /// desc sync word, audio description chunk marker. 13 | /// 14 | public const int audioDescriptionChunk = 0x63736564; 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /Cavern.Format/Utilities/ParserExtensions.cs: -------------------------------------------------------------------------------- 1 | namespace Cavern.Format.Utilities { 2 | /// 3 | /// Common parsing utilities. 4 | /// 5 | public static class ParserExtensions { 6 | /// 7 | /// Convert a big-endian integer four-character code to characters. 8 | /// 9 | public static string ToFourCC(this uint tag) => new string(new[] { 10 | (char)(tag >> 24), 11 | (char)((tag >> 16) & 0xFF), 12 | (char)((tag >> 8) & 0xFF), 13 | (char)((tag) & 0xFF) 14 | }); 15 | } 16 | } -------------------------------------------------------------------------------- /Cavern.QuickEQ.Format/FilterSet/BaseClasses/FilterProperty.cs: -------------------------------------------------------------------------------- 1 | namespace Cavern.Format.FilterSet { 2 | /// 3 | /// Possible values to export for each filter. 4 | /// 5 | public enum FilterProperty { 6 | /// 7 | /// Center frequency of the filter. 8 | /// 9 | Frequency, 10 | /// 11 | /// Gain of the filter, in dB. 12 | /// 13 | Gain, 14 | /// 15 | /// Q factor of the filter. 16 | /// 17 | QFactor, 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /CavernSamples/CavernizeGUI/Resources/RenderTargetSelectorStrings.xaml: -------------------------------------------------------------------------------- 1 | 4 | Layouts compatible with all systems 5 | Specially wired (matrixed) compatible layouts 6 | 8+ channel layouts requiring special systems 7 | -------------------------------------------------------------------------------- /CavernSamples/Deconvolver/Settings.settings: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | False 7 | 8 | 9 | True 10 | 11 | 12 | -------------------------------------------------------------------------------- /Tests/Test.Cavern.QuickEQ/FilterSet/Rotel_Tests.cs: -------------------------------------------------------------------------------- 1 | using Cavern.Format.FilterSet; 2 | 3 | using Test.Cavern.QuickEQ.FilterSet.TestEnvironment; 4 | 5 | namespace Test.Cavern.QuickEQ.FilterSet { 6 | /// 7 | /// Tests if s are handled properly. 8 | /// 9 | [TestClass] 10 | public class Rotel_Tests : IIRFilterSetJig { 11 | /// 12 | /// Tests if s are handled properly. 13 | /// 14 | public Rotel_Tests() : base(FilterSetTarget.Rotel) { } 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /Cavern/Filters/Interfaces/IConvolution.cs: -------------------------------------------------------------------------------- 1 | namespace Cavern.Filters.Interfaces { 2 | /// 3 | /// A filter that's implementing a convolution with a single impulse response using any algorithm. 4 | /// 5 | public interface IConvolution : ISampleRateDependentFilter { 6 | /// 7 | /// Impulse response to convolve with. 8 | /// 9 | float[] Impulse { get; set; } 10 | 11 | /// 12 | /// Added delay to the filter's , in samples. 13 | /// 14 | int Delay { get; set; } 15 | } 16 | } -------------------------------------------------------------------------------- /Tests/Test.Cavern.QuickEQ/Crossover/BasicCrossover_Tests.cs: -------------------------------------------------------------------------------- 1 | using Cavern.QuickEQ.Crossover; 2 | 3 | namespace Test.Cavern.QuickEQ.Crossover { 4 | /// 5 | /// Tests the class. 6 | /// 7 | [TestClass] 8 | public class BasicCrossover_Tests { 9 | /// 10 | /// Tests if generates correct impulse responses. 11 | /// 12 | [TestMethod, Timeout(1000)] 13 | public void ImpulseResponse() => Utils.ImpulseResponse(new BasicCrossover(null, null), 0.49152157f, 0.50847834f); 14 | } 15 | } -------------------------------------------------------------------------------- /Tests/Test.Cavern.QuickEQ/Crossover/CavernCrossover_Tests.cs: -------------------------------------------------------------------------------- 1 | using Cavern.QuickEQ.Crossover; 2 | 3 | namespace Test.Cavern.QuickEQ.Crossover { 4 | /// 5 | /// Tests the class. 6 | /// 7 | [TestClass] 8 | public class CavernCrossover_Tests { 9 | /// 10 | /// Tests if generates correct impulse responses. 11 | /// 12 | [TestMethod, Timeout(1000)] 13 | public void ImpulseResponse() => Utils.ImpulseResponse(new CavernCrossover(null, null), 0.3567448f, 0.7216354f); 14 | } 15 | } -------------------------------------------------------------------------------- /Tests/Test.Cavern.QuickEQ/FilterSet/StormAudio_Tests.cs: -------------------------------------------------------------------------------- 1 | using Cavern.Format.FilterSet; 2 | 3 | using Test.Cavern.QuickEQ.FilterSet.TestEnvironment; 4 | 5 | namespace Test.Cavern.QuickEQ.FilterSet { 6 | /// 7 | /// Tests if s are handled properly. 8 | /// 9 | [TestClass] 10 | public class StormAudio_Tests : IIRFilterSetJig { 11 | /// 12 | /// Tests if s are handled properly. 13 | /// 14 | public StormAudio_Tests() : base(FilterSetTarget.StormAudio) { } 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /Cavern/Utilities/TupleUtils.cs: -------------------------------------------------------------------------------- 1 | namespace Cavern.Utilities { 2 | /// 3 | /// Advanced functions for handling tuples. 4 | /// 5 | public static class TupleUtils { 6 | /// 7 | /// From an array of tuples, get only the second "column". 8 | /// 9 | public static T2[] GetItem2s(this (T1, T2)[] items) { 10 | T2[] result = new T2[items.Length]; 11 | for (int i = 0; i < items.Length; i++) { 12 | result[i] = items[i].Item2; 13 | } 14 | return result; 15 | } 16 | } 17 | } -------------------------------------------------------------------------------- /CavernSamples/Benchmark/Benchmark.csproj.user: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | Designer 7 | 8 | 9 | 10 | 11 | 12 | Designer 13 | 14 | 15 | Designer 16 | 17 | 18 | -------------------------------------------------------------------------------- /Libraries/Cavern.WPF/Utils/ChannelOnUI.cs: -------------------------------------------------------------------------------- 1 | using Cavern.Channels; 2 | using Cavern.WPF.Consts; 3 | 4 | namespace Cavern.WPF.Utils { 5 | /// 6 | /// Used to display a channel's name on a UI in the user's language and contain which it is. 7 | /// 8 | public class ChannelOnUI(ReferenceChannel channel) { 9 | /// 10 | /// The displayed channel. 11 | /// 12 | public ReferenceChannel Channel => channel; 13 | 14 | /// 15 | public override string ToString() => Channel.Translate(); 16 | } 17 | } -------------------------------------------------------------------------------- /Cavern.Format/Utilities/IXDocumentSerializable.cs: -------------------------------------------------------------------------------- 1 | using System.Xml; 2 | using System.Xml.Linq; 3 | 4 | namespace Cavern.Format.Utilities { 5 | /// 6 | /// An object that can be serialized into an XDocument. 7 | /// 8 | public interface IXDocumentSerializable { 9 | /// 10 | /// Create an XML element about this object. 11 | /// 12 | void Serialize(XmlWriter writer); 13 | 14 | /// 15 | /// Read the values of an XML element into this object. 16 | /// 17 | void Deserialize(XElement source); 18 | } 19 | } -------------------------------------------------------------------------------- /Cavern.QuickEQ.Format/ConfigurationFile/Exceptions/PlaceholderFilterException.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace Cavern.Format.ConfigurationFile { 4 | /// 5 | /// Thrown when a placeholder filter is used for signal processing. 6 | /// 7 | public class PlaceholderFilterException : Exception { 8 | const string message = "A placeholder filter is used for signal processing."; 9 | 10 | /// 11 | /// Thrown when a placeholder filter is used for signal processing. 12 | /// 13 | public PlaceholderFilterException() : base(message) { } 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /Cavern/Waveforms/Exceptions/DifferentSignalLengthsException.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace Cavern.Waveforms { 4 | /// 5 | /// Tells if a multichannel waveform's channels wouldn't have a matching length. 6 | /// 7 | public class DifferentSignalLengthsException : Exception { 8 | const string message = "The sample count of the channels doesn't match."; 9 | 10 | /// 11 | /// Tells if a multichannel waveform's channels wouldn't have a matching length. 12 | /// 13 | public DifferentSignalLengthsException() : base(message) { } 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /Libraries/Cavern.WPF/Utils/CrossoverTypeOnUI.cs: -------------------------------------------------------------------------------- 1 | using Cavern.QuickEQ.Crossover; 2 | using Cavern.WPF.Consts; 3 | 4 | namespace Cavern.WPF.Utils { 5 | /// 6 | /// Used to display a crossover type's name on a UI in the user's language and contain which it is. 7 | /// 8 | public class CrossoverTypeOnUI(CrossoverType type) { 9 | /// 10 | /// The displayed channel. 11 | /// 12 | public CrossoverType Type => type; 13 | 14 | /// 15 | public override string ToString() => Type.Translate(); 16 | } 17 | } -------------------------------------------------------------------------------- /Cavern/Filters/_Exceptions.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace Cavern.Filters { 4 | /// 5 | /// Tells if a property can only be used when the filter was created with a set sample rate. 6 | /// 7 | public class SampleRateNotSetException : Exception { 8 | const string message = "This property can only be used when the filter was created with a set sample rate."; 9 | 10 | /// 11 | /// Tells if a property can only be used when the filter was created with a set sample rate. 12 | /// 13 | public SampleRateNotSetException() : base(message) { } 14 | } 15 | } -------------------------------------------------------------------------------- /CavernSamples/Benchmark/Benchmarks/Benchmark.cs: -------------------------------------------------------------------------------- 1 | namespace Benchmark.Benchmarks { 2 | /// 3 | /// Benchmark base class. 4 | /// 5 | abstract class Benchmark { 6 | /// 7 | /// Performs one round of the benchmark. 8 | /// 9 | public abstract void Step(); 10 | 11 | /// 12 | /// Displays the result of the benchmark in a relevant metric. 13 | /// 14 | public virtual string ToString(int steps, int seconds) { 15 | return $"{steps / (float)seconds:0.0} operations/second"; 16 | } 17 | } 18 | } -------------------------------------------------------------------------------- /docs/Quality modes.md: -------------------------------------------------------------------------------- 1 | # Cavern quality modes 2 | | Quality | Doppler/pitch | Resampling | Object downmix | Angle precision | Asymmetric mixing | 3 | |----------|---------------|--------------|----------------|-----------------|-------------------| 4 | | Perfect | High | Catmull-Rom | All channels | Arcsine | As-is | 5 | | High | High | Linear | All channels | Arcsine | Triangulated | 6 | | Medium | Low | Nearest | First channel | Linear | Triangulated | 7 | | Low | Disabled | Nearest | First channel | Linear | Triangulated | 8 | -------------------------------------------------------------------------------- /CavernSamples/CavernizeGUI/Resources/RenderTargetSelectorStrings.hu-HU.xaml: -------------------------------------------------------------------------------- 1 | 4 | Minden rendszerrel kompatibilis elrendezések 5 | Különlegesen kábelezett (mátrixolt) kompatibilis elrendezések 6 | 8+ csatornás elrendezések, amikhez különleges rendszer kell 7 | -------------------------------------------------------------------------------- /Cavern.QuickEQ.Format/ConfigurationFile/Exceptions/NotPreparedChannelException.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace Cavern.Format.ConfigurationFile { 4 | /// 5 | /// Thrown when a channel was used before it was created. 6 | /// 7 | public class NotPreparedChannelException : Exception { 8 | const string message = "A channel was used before it was created: {0}."; 9 | 10 | /// 11 | /// Thrown when a channel was used before it was created. 12 | /// 13 | public NotPreparedChannelException(string chName) : base(string.Format(message, chName)) { } 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /Cavern.QuickEQ.Format/FilterSet/Enums/DelayUnit.cs: -------------------------------------------------------------------------------- 1 | namespace Cavern.Format.FilterSet.Enums { 2 | /// 3 | /// In what to measure delays when exporting a filter set. 4 | /// 5 | public enum DelayUnit { 6 | /// 7 | /// Measure in audio samples on the filter's sample rate. 8 | /// 9 | Samples, 10 | /// 11 | /// Measure in time: milliseconds. 12 | /// 13 | Milliseconds, 14 | /// 15 | /// Measure in distance: centimeters. 16 | /// 17 | Centimeters, 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /Cavern.QuickEQ/EQCurves/Depth.cs: -------------------------------------------------------------------------------- 1 | namespace Cavern.QuickEQ.EQCurves { 2 | /// 3 | /// EQ curve with a sub-bass slope for depth emphasis. Linearly rises by 12 dB down from 60 Hz to 20 Hz, 4 | /// and optionally linearly decreases from 1 kHz to 20 kHz by 3 dB. 5 | /// 6 | public class Depth : RoomCurveLikeCurve { 7 | /// 8 | /// EQ curve with a sub-bass slope for depth emphasis. Linearly rises by 12 dB down from 60 Hz to 20 Hz, 9 | /// and optionally linearly decreases from 1 kHz to 20 kHz by 3 dB. 10 | /// 11 | public Depth() : base(60, 12) { } 12 | } 13 | } -------------------------------------------------------------------------------- /Cavern.Format/Renderers/DummyRenderer.cs: -------------------------------------------------------------------------------- 1 | using Cavern.Format.Decoders; 2 | 3 | namespace Cavern.Format.Renderers { 4 | /// 5 | /// Renders silence. 6 | /// 7 | public class DummyRenderer : Renderer { 8 | /// 9 | /// Renders silence. 10 | /// 11 | public DummyRenderer(Decoder stream) : base(stream) => SetupChannels(); 12 | 13 | /// 14 | /// Renders silence. 15 | /// 16 | public override void Update(int samples) { 17 | // Override the update code with nothing to save on performance 18 | } 19 | } 20 | } -------------------------------------------------------------------------------- /Cavern/Channels/Exceptions/ChannelCountMismatchException.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace Cavern.Channels { 4 | /// 5 | /// Tells that this operation requires a different channel count than what's given. 6 | /// 7 | public class ChannelCountMismatchException : Exception { 8 | const string message = "This operation requires a different channel count than what's given."; 9 | 10 | /// 11 | /// Tells that this operation requires a different channel count than what's given. 12 | /// 13 | public ChannelCountMismatchException() : base(message) { } 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /CavernAmp/graphUtils.h: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | #include "complex.h" 5 | 6 | #ifndef GRAPHUTILS_H 7 | #define GRAPHUTILS_H 8 | 9 | // Convert a response to logarithmically scaled cut frequency range. 10 | float* ConvertToGraph(float* response, int responseLength, double startFreq, double endFreq, int sampleRate, int resultSize); 11 | void ConvertToGraph(float* response, int responseLength, double startFreq, double endFreq, int sampleRate, float* result, int resultSize); 12 | // Convert a response curve to decibel scale. 13 | void ConvertToDecibels(float* curve, int curveLength, float minimum = -100); 14 | 15 | #endif // GRAPHUTILS_H 16 | -------------------------------------------------------------------------------- /Tests/Test.Cavern.QuickEQ/Consts/Consts.cs: -------------------------------------------------------------------------------- 1 | namespace Test.Cavern.QuickEQ { 2 | /// 3 | /// Constant test values. 4 | /// 5 | static class Consts { 6 | /// 7 | /// Test sample rate. 8 | /// 9 | internal const int sampleRate = 48000; 10 | 11 | /// 12 | /// Convolution length used for tests. 13 | /// 14 | internal const int convolutionLength = 4096; 15 | 16 | /// 17 | /// Allowed floating point margin of error. 18 | /// 19 | internal const float delta = .000001f; 20 | } 21 | } -------------------------------------------------------------------------------- /Cavern.QuickEQ.Format/ConfigurationFile/Exceptions/LastSplitPointException.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace Cavern.Format.ConfigurationFile { 4 | /// 5 | /// Thrown when a channel was used before it was created. 6 | /// 7 | public class LastSplitPointException : Exception { 8 | const string message = "The last split point can't be removed, configuration files are made of at least one working unit (split point)."; 9 | 10 | /// 11 | /// Thrown when a channel was used before it was created. 12 | /// 13 | public LastSplitPointException() : base(message) { } 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /CavernSamples/EQAPOtoFIR/Dialogs/SegmentsDialog.xaml.cs: -------------------------------------------------------------------------------- 1 | using System.Windows; 2 | 3 | namespace EQAPOtoFIR.Dialogs { 4 | /// 5 | /// Segment count selector dialog. 6 | /// 7 | public partial class SegmentsDialog : Window { 8 | /// 9 | /// Resulting segment count. 10 | /// 11 | public int Segments => segments.Value; 12 | 13 | /// 14 | /// Segment count selector dialog. 15 | /// 16 | public SegmentsDialog() => InitializeComponent(); 17 | 18 | void OK(object sender, RoutedEventArgs e) => DialogResult = true; 19 | } 20 | } -------------------------------------------------------------------------------- /CavernSamples/FilterStudio/Resources/CrossoverDialogStrings.xaml: -------------------------------------------------------------------------------- 1 | 4 | Crossover 5 | Channels 6 | Enable crossover 7 | Crossover type: 8 | Crossover low frequencies to this channel: 9 | -------------------------------------------------------------------------------- /Cavern.QuickEQ.Format/ConfigurationFile/ConfigurationFileType.cs: -------------------------------------------------------------------------------- 1 | namespace Cavern.Format.ConfigurationFile { 2 | /// 3 | /// Supported configuration file formats. 4 | /// 5 | public enum ConfigurationFileType { 6 | /// 7 | /// Cavern Filter Studio configuration file. 8 | /// 9 | CavernFilterStudio, 10 | /// 11 | /// Convolution Box Format configuration file. 12 | /// 13 | ConvolutionBoxFormat, 14 | /// 15 | /// Equalizer APO configuration file. 16 | /// 17 | EqualizerAPO, 18 | } 19 | } -------------------------------------------------------------------------------- /Cavern.QuickEQ/EQCurves/RoomCurve.cs: -------------------------------------------------------------------------------- 1 | namespace Cavern.QuickEQ.EQCurves { 2 | /// 3 | /// Frequently used target curve for very small rooms. Linearly rises by 3 dB down from 200 Hz to 20 Hz, 4 | /// and optionally linearly decreases from 1 kHz to 20 kHz by 3 dB. 5 | /// 6 | public class RoomCurve : RoomCurveLikeCurve { 7 | /// 8 | /// Frequently used target curve for very small rooms. Linearly rises by 3 dB down from 200 Hz to 20 Hz, 9 | /// and optionally linearly decreases from 1 kHz to 20 kHz by 3 dB. 10 | /// 11 | public RoomCurve() : base(defaultKnee, 3) { } 12 | } 13 | } -------------------------------------------------------------------------------- /Cavern.QuickEQ/Graphing/Overlays/GraphOverlay.cs: -------------------------------------------------------------------------------- 1 | namespace Cavern.QuickEQ.Graphing.Overlays { 2 | /// 3 | /// Something to draw over the graph, like a or . 4 | /// 5 | public abstract class GraphOverlay { 6 | /// 7 | /// Adds the overlay's foreground to a measurement. 8 | /// 9 | public virtual void DrawOn(DrawableMeasurement target) { } 10 | 11 | /// 12 | /// Adds the overlay's background to a measurement. 13 | /// 14 | public virtual void DrawBehind(DrawableMeasurement target) { } 15 | } 16 | } -------------------------------------------------------------------------------- /Cavern/Filters/Interfaces/IEqualizerAPOFilter.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | 3 | namespace Cavern.Filters.Interfaces { 4 | /// 5 | /// This filter can be exported to Equalizer APO. 6 | /// 7 | public interface IEqualizerAPOFilter { 8 | /// 9 | /// Attach this filter to an Equalizer APO configuration file in the making. 10 | /// 11 | /// New lines that are needed in the configuration file to perform this filter 12 | /// will be added to this list 13 | public abstract void ExportToEqualizerAPO(List wipConfig); 14 | } 15 | } -------------------------------------------------------------------------------- /Cavern/Remapping/Exceptions/DifferentInputChannelCountsException.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace Cavern.Remapping { 4 | /// 5 | /// Tells if a mixing matrix has different input channel counts for two outputs. 6 | /// 7 | public class DifferentInputChannelCountsException : Exception { 8 | const string message = "The mixing matrix has different input channel counts for two outputs."; 9 | 10 | /// 11 | /// Tells if a mixing matrix has different input channel counts for two outputs. 12 | /// 13 | public DifferentInputChannelCountsException() : base(message) { } 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /Tests/Test.Cavern.QuickEQ/Crossover/SyntheticBiquadCrossover_Tests.cs: -------------------------------------------------------------------------------- 1 | using Cavern.QuickEQ.Crossover; 2 | 3 | namespace Test.Cavern.QuickEQ.Crossover { 4 | /// 5 | /// Tests the class. 6 | /// 7 | [TestClass] 8 | public class SyntheticBiquadCrossover_Tests { 9 | /// 10 | /// Tests if generates correct impulse responses. 11 | /// 12 | [TestMethod, Timeout(1000)] 13 | public void ImpulseResponse() => Utils.ImpulseResponse(new SyntheticBiquadCrossover(null, null), .474857f, .52310514f); 14 | } 15 | } -------------------------------------------------------------------------------- /Libraries/Cavern.WPF/Resources/CommonStrings.xaml: -------------------------------------------------------------------------------- 1 | 4 | OK 5 | Accept 6 | Cancel 7 | Error 8 | Warning 9 | All supported formats|{0} 10 | -------------------------------------------------------------------------------- /CavernSamples/FilterStudio/Consts/_Exceptions.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace FilterStudio { 4 | /// 5 | /// Tells if value can't be edited for a filter, because the type is not currently supported for parsing. 6 | /// 7 | public class UneditableTypeException : Exception { 8 | const string message = "This value can't be edited, because the type is not currently supported for parsing."; 9 | 10 | /// 11 | /// Tells if value can't be edited for a filter, because the type is not currently supported for parsing. 12 | /// 13 | public UneditableTypeException() : base(message) { } 14 | } 15 | } -------------------------------------------------------------------------------- /Cavern.Format/Common/Container.cs: -------------------------------------------------------------------------------- 1 | namespace Cavern.Format.Common { 2 | /// 3 | /// Container formats supported by Cavern. 4 | /// 5 | public enum Container { 6 | /// 7 | /// The format is not a container, but a simple audio file. 8 | /// 9 | NotContainer, 10 | /// 11 | /// Matroska and WebM. 12 | /// 13 | Matroska, 14 | /// 15 | /// MP4 and QuickTime. 16 | /// 17 | MP4, 18 | /// 19 | /// Material eXchange Format. 20 | /// 21 | MXF, 22 | } 23 | } -------------------------------------------------------------------------------- /CavernSamples/FilterStudio/Resources/CrossoverDialogStrings.hu-HU.xaml: -------------------------------------------------------------------------------- 1 | 4 | Keresztváltó 5 | Csatornák 6 | Vágás engedélyezése 7 | Keresztváltó típusa: 8 | Mélyfrekvenciák keverése erre a csatornára: 9 | -------------------------------------------------------------------------------- /Tests/Test.Cavern/ArrayExtensions_Tests.cs: -------------------------------------------------------------------------------- 1 | using Cavern.Utilities; 2 | 3 | namespace Test.Cavern { 4 | /// 5 | /// Tests the class. 6 | /// 7 | [TestClass] 8 | public class ArrayExtensions_Tests { 9 | /// 10 | /// Tests the method. 11 | /// 12 | [TestMethod, Timeout(1000)] 13 | public void Nearest() { 14 | float[] testArray = { 1, 2, 3, 4 }; 15 | Assert.AreEqual(2, testArray.Nearest(1.99f)); 16 | Assert.AreEqual(3, testArray.Nearest(3.01f)); 17 | } 18 | } 19 | } -------------------------------------------------------------------------------- /Cavern.Format/Common/TrackExtensions.cs: -------------------------------------------------------------------------------- 1 | namespace Cavern.Format.Common { 2 | /// 3 | /// Extension methods for s. 4 | /// 5 | public static class TrackExtensions { 6 | /// 7 | /// Find the first track with the given ID in the tracklist. If found, the index is returned, -1 otherwise. 8 | /// 9 | public static int GetIndexByID(this Track[] tracks, long id) { 10 | for (int i = 0; i < tracks.Length; i++) { 11 | if (tracks[i].ID == id) { 12 | return i; 13 | } 14 | } 15 | return -1; 16 | } 17 | } 18 | } -------------------------------------------------------------------------------- /Libraries/Cavern.WPF/Resources/CommonStrings.hu-HU.xaml: -------------------------------------------------------------------------------- 1 | 4 | OK 5 | Elfogad 6 | Mégse 7 | Hiba 8 | Figyelmeztetés 9 | Minden támogatott formátum|{0} 10 | -------------------------------------------------------------------------------- /Cavern/Utilities/ChannelExtensions.cs: -------------------------------------------------------------------------------- 1 | namespace Cavern.Utilities { 2 | /// 3 | /// Extension functions for s. 4 | /// 5 | public static class ChannelExtensions { 6 | /// 7 | /// Get the number of channels above the horizon for a given channel layout. 8 | /// 9 | public static int GetOverheadChannelCount(this Channel[] channels) { 10 | int count = 0; 11 | for (int i = 0; i < channels.Length; i++) { 12 | if (channels[i].X < 0) { 13 | count++; 14 | } 15 | } 16 | return count; 17 | } 18 | } 19 | } -------------------------------------------------------------------------------- /CavernAmp/peakingFilter.h: -------------------------------------------------------------------------------- 1 | #include "filter.h" 2 | 3 | #ifndef PEAKINGFILTER_H 4 | #define PEAKINGFILTER_H 5 | 6 | #define Q_REF 0.7071067811865475 7 | 8 | // Simple first-order biquad filter. 9 | class PeakingFilter /*: public Filter*/ { 10 | private: 11 | double centerFreq, q, gain; 12 | int sampleRate; 13 | float x1, x2, y1, y2, a1, a2, b0, b1, b2; 14 | 15 | public: 16 | PeakingFilter(int sampleRate, double centerFreq, double q = Q_REF, double gain = 0); 17 | void Reset(double centerFreq, double q = Q_REF, double gain = 0); 18 | void Process(float* samples, int len); 19 | void Process(float* samples, int len, int channel, int channels); 20 | }; 21 | 22 | #endif // PEAKINGFILTER_H 23 | -------------------------------------------------------------------------------- /Cavern.QuickEQ/PolarityCorrections/PolarityCorrectionType.cs: -------------------------------------------------------------------------------- 1 | namespace Cavern.QuickEQ.PolarityCorrections { 2 | /// 3 | /// Supported methods to detect and correct swapped polarities. 4 | /// 5 | public enum PolarityCorrectionType { 6 | /// 7 | /// Polarity correction is disabled. 8 | /// 9 | None, 10 | /// 11 | /// Checks if pairs of channels add together constructively or destructively. 12 | /// 13 | ConstructivityBased, 14 | /// 15 | /// Aligns impulse peaks to the same direction. 16 | /// 17 | ImpulsePeakBased, 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /Libraries/Cavern.WPF/BaseClasses/OkCancelDialog.cs: -------------------------------------------------------------------------------- 1 | using System.Windows; 2 | 3 | namespace Cavern.WPF.BaseClasses { 4 | /// 5 | /// A dialog with OK and Cancel buttons. 6 | /// 7 | public class OkCancelDialog : Window { 8 | /// 9 | /// Closes the dialog with the settings applied. 10 | /// 11 | protected virtual void OK(object _, RoutedEventArgs e) { 12 | DialogResult = true; 13 | Close(); 14 | } 15 | 16 | /// 17 | /// Closes the dialog with no change applied. 18 | /// 19 | protected virtual void Cancel(object _, RoutedEventArgs e) => Close(); 20 | } 21 | } -------------------------------------------------------------------------------- /Cavern.QuickEQ.Format/ConfigurationFile/Exceptions/NotEqualizerAPOFilterException.cs: -------------------------------------------------------------------------------- 1 | using Cavern.Filters; 2 | 3 | namespace Cavern.Format.ConfigurationFile { 4 | /// 5 | /// Thrown when an unsupported filter would be exported for Equalizer APO. 6 | /// 7 | public class NotEqualizerAPOFilterException : UnsupportedFilterForExportException { 8 | const string message = "Equalizer APO does not support the following filter: "; 9 | 10 | /// 11 | /// Thrown when an unsupported filter would be exported for Equalizer APO. 12 | /// 13 | public NotEqualizerAPOFilterException(Filter filter) : base(message + filter, filter) { } 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /Cavern.QuickEQ.Format/FilterSet/Exceptions/FIRGainException.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace Cavern.Format.FilterSet { 4 | /// 5 | /// Thrown when a FIR channel's gain was tried to be accessed. There is no such thing, it's included in the filter coefficients. 6 | /// 7 | public class FIRGainException : Exception { 8 | const string message = "FIR filters have no gain values, it's included in the filter coefficients."; 9 | 10 | /// 11 | /// Thrown when a FIR channel's gain was tried to be accessed. There is no such thing, it's included in the filter coefficients. 12 | /// 13 | public FIRGainException() : base(message) { } 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /Cavern.QuickEQ/Equalization/EqualizerExtensions.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace Cavern.QuickEQ.Equalization { 4 | /// 5 | /// Helper functions for s. 6 | /// 7 | public static class EqualizerExtensions { 8 | /// 9 | /// Check if a is likeliy a measurement, based on its channel and spectra. 10 | /// 11 | public static bool IsLFE(this Equalizer measurement, int channel, int channels) => channels == Listener.Channels.Length ? 12 | Listener.Channels[channel].LFE : 13 | ((channel == 3 && channels >= 6) || Math.Abs(measurement[80] - measurement[8000]) > 50); 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /CavernSamples/Reusable/Cavernize.Logic/Models/InvalidTrack.cs: -------------------------------------------------------------------------------- 1 | using Cavern.Format.Common; 2 | 3 | using Cavernize.Logic.Language; 4 | 5 | namespace Cavernize.Logic.Models; 6 | 7 | /// 8 | /// An audio track's replacement when it failed to load. 9 | /// 10 | public sealed class InvalidTrack : CavernizeTrack { 11 | /// 12 | /// An audio track's replacement when it failed to load. 13 | /// 14 | public InvalidTrack(string error, Codec codec, string language, TrackStrings strings) : base(strings) { 15 | FormatHeader = $"{strings.InvalidTrack}\n{error} {strings.Later}"; 16 | Details = []; 17 | Codec = codec; 18 | Language = language; 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /Libraries/Cavern.WPF/Utils/ColorUtils.cs: -------------------------------------------------------------------------------- 1 | using System.Runtime.CompilerServices; 2 | using System.Windows.Media; 3 | 4 | namespace Cavern.WPF.Utils { 5 | /// 6 | /// Extension functions for interoperability between Cavern's raw ARGB pixel arrays and WPF's . 7 | /// 8 | public static class ColorUtils { 9 | /// 10 | /// Convert a 32-bit ARGB value to WPF's used in, for example, es. 11 | /// 12 | [MethodImpl(MethodImplOptions.AggressiveInlining)] 13 | public static Color ToColor(uint argb) => Color.FromArgb((byte)(argb >> 24), (byte)(argb >> 16), (byte)(argb >> 8), (byte)argb); 14 | } 15 | } -------------------------------------------------------------------------------- /Cavern.QuickEQ.Format/FilterSet/MultEQXTargetFilterSet.cs: -------------------------------------------------------------------------------- 1 | using Cavern.Channels; 2 | 3 | namespace Cavern.Format.FilterSet { 4 | /// 5 | /// Filter curve collection for MultEQ-X. 6 | /// 7 | public class MultEQXTargetFilterSet : EqualizerFilterSet { 8 | /// 9 | /// Filter curve collection for MultEQ-X. 10 | /// 11 | public MultEQXTargetFilterSet(int channels, int sampleRate) : base(channels, sampleRate) { } 12 | 13 | /// 14 | /// Filter curve collection for MultEQ-X. 15 | /// 16 | public MultEQXTargetFilterSet(ReferenceChannel[] channels, int sampleRate) : base(channels, sampleRate) { } 17 | } 18 | } -------------------------------------------------------------------------------- /Cavern/Filters/Interfaces/ISampleRateDependentFilter.cs: -------------------------------------------------------------------------------- 1 | using System.Runtime.Serialization; 2 | 3 | namespace Cavern.Filters.Interfaces { 4 | /// 5 | /// A filter that requires its sample rate to match with the output sample rate. 6 | /// 7 | public interface ISampleRateDependentFilter { 8 | /// 9 | /// Sample rate of the filter. 10 | /// 11 | /// All implementations shall be attributed with and per-filter changes should 12 | /// not be allowed for the user. This is the job of the filter handling subsystems. 13 | [IgnoreDataMember] 14 | int SampleRate { get; set; } 15 | } 16 | } -------------------------------------------------------------------------------- /Cavern.QuickEQ.Format/JSON/JsonFileExtensions.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using System.Runtime.CompilerServices; 3 | 4 | namespace Cavern.Format.JSON { 5 | /// 6 | /// Extensions making it easy to work with and generate JSON data. 7 | /// 8 | public static class JsonFileExtensions { 9 | /// 10 | /// A shorthand as .Stores() to create a used in Cavern's JSON parser. 11 | /// 12 | [MethodImpl(MethodImplOptions.AggressiveInlining)] 13 | public static KeyValuePair Stores(this string key, object value) => new KeyValuePair(key, value); 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /Cavern.QuickEQ.Format/ConfigurationFile/Exceptions/DuplicateLabelException.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace Cavern.Format.ConfigurationFile { 4 | /// 5 | /// Thrown when a format that doesn't allow duplicate labels would be used to export duplicate labels. 6 | /// 7 | public class DuplicateLabelException : Exception { 8 | const string message = "This format expects all labels to differ. \"{0}\" was present more than once."; 9 | 10 | /// 11 | /// Thrown when a format that doesn't allow duplicate labels would be used to export duplicate labels. 12 | /// 13 | public DuplicateLabelException(string label) : base(string.Format(message, label)) { } 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /CavernSamples/EnhancedAC3Merger/EnhancedAC3Merger.csproj.user: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | Designer 7 | 8 | 9 | 10 | 11 | Code 12 | 13 | 14 | 15 | 16 | Designer 17 | 18 | 19 | Designer 20 | 21 | 22 | -------------------------------------------------------------------------------- /Tests/Test.Cavern/Channels/ChannelPrototype_Tests.cs: -------------------------------------------------------------------------------- 1 | using Cavern.Channels; 2 | 3 | namespace Test.Cavern.Channels { 4 | /// 5 | /// Tests the struct. 6 | /// 7 | [TestClass] 8 | public class ChannelPrototype_Tests { 9 | /// 10 | /// Tests if the standard layouts have correct channel counts. 11 | /// 12 | [TestMethod, Timeout(1000)] 13 | public void LayoutSizes() { 14 | for (int i = 1; i <= 16; i++) { 15 | Assert.AreEqual(i, ChannelPrototype.GetStandardMatrix(i).Length); 16 | Assert.AreEqual(i, ChannelPrototype.GetIndustryStandardMatrix(i).Length); 17 | } 18 | } 19 | } 20 | } -------------------------------------------------------------------------------- /Cavern.QuickEQ/Measurement/PhaseDelayCompensationType.cs: -------------------------------------------------------------------------------- 1 | namespace Cavern.QuickEQ.Measurement { 2 | /// 3 | /// What technique to use for removing the effect of delay when working with phase curves. 4 | /// 5 | public enum PhaseDelayCompensationType { 6 | /// 7 | /// Do not try to remove delay. 8 | /// 9 | None, 10 | /// 11 | /// The delay is the slope of a phase curve, detect the slope and remove it. 12 | /// 13 | Slope, 14 | /// 15 | /// Remove as many samples of delay as far the impulse peak is away from the beginning of the signal. 16 | /// 17 | ImpulsePeak, 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /Cavern.QuickEQ.Format/ConfigurationFile/Exceptions/NotCavernFilterStudioFilterException.cs: -------------------------------------------------------------------------------- 1 | using Cavern.Filters; 2 | 3 | namespace Cavern.Format.ConfigurationFile { 4 | /// 5 | /// Thrown when an unsupported filter would be exported for Cavern Filter Studio. 6 | /// 7 | public class NotCavernFilterStudioFilterException : UnsupportedFilterForExportException { 8 | const string message = "Cavern Filter Studio's format does not support the following filter: "; 9 | 10 | /// 11 | /// Thrown when an unsupported filter would be exported for Cavern Filter Studio. 12 | /// 13 | public NotCavernFilterStudioFilterException(Filter filter) : base(message + filter, filter) { } 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /Libraries/Cavern.WPF/Resources/ConvolutionEditorStrings.xaml: -------------------------------------------------------------------------------- 1 | 4 | Convolution Editor 5 | Import from file... 6 | Polarity: {0} 7 | Phase: {0}° 8 | Delay: {0} samples 9 | 10 | Only mono files are supported for convolution import. 11 | -------------------------------------------------------------------------------- /CavernSamples/CavernizeGUI/App.xaml.cs: -------------------------------------------------------------------------------- 1 | using System.Windows; 2 | 3 | using Cavernize.Logic.CommandLine; 4 | 5 | namespace CavernizeGUI { 6 | /// 7 | /// Windows application handler. 8 | /// 9 | public partial class App : Application { 10 | /// 11 | /// Windows application entry point that also handles console commands. 12 | /// 13 | void Main(object _, StartupEventArgs e) { 14 | MainWindow app = new MainWindow(); 15 | string[] args = e.Args; 16 | if (args.Length == 0 || CommandLineProcessor.Initialize(args, app)) { 17 | app.Show(); 18 | } else { 19 | app.Close(); 20 | } 21 | } 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /UnityPlugins/CavernWebGL/microphone.jslib.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 5a289ff8df269764aab26fa9a0b14cf2 3 | PluginImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | iconMap: {} 7 | executionOrder: {} 8 | defineConstraints: [] 9 | isPreloaded: 0 10 | isOverridable: 0 11 | isExplicitlyReferenced: 0 12 | validateReferences: 1 13 | platformData: 14 | - first: 15 | Any: 16 | second: 17 | enabled: 0 18 | settings: {} 19 | - first: 20 | Editor: Editor 21 | second: 22 | enabled: 0 23 | settings: 24 | DefaultValueInitialized: true 25 | - first: 26 | WebGL: WebGL 27 | second: 28 | enabled: 1 29 | settings: {} 30 | userData: 31 | assetBundleName: 32 | assetBundleVariant: 33 | -------------------------------------------------------------------------------- /CavernAmp/main.cpp: -------------------------------------------------------------------------------- 1 | #include "main.h" 2 | 3 | // a sample exported function 4 | bool DLL_EXPORT IsAvailable() { 5 | return true; 6 | } 7 | 8 | extern "C" DLL_EXPORT BOOL APIENTRY DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved) { 9 | switch (fdwReason) { 10 | case DLL_PROCESS_ATTACH: 11 | // attach to process 12 | // return FALSE to fail DLL load 13 | break; 14 | 15 | case DLL_PROCESS_DETACH: 16 | // detach from process 17 | break; 18 | 19 | case DLL_THREAD_ATTACH: 20 | // attach to thread 21 | break; 22 | 23 | case DLL_THREAD_DETACH: 24 | // detach from thread 25 | break; 26 | } 27 | return TRUE; // succesful 28 | } 29 | -------------------------------------------------------------------------------- /Libraries/Cavern.WPF/Resources/ConvolutionEditorStrings.hu-HU.xaml: -------------------------------------------------------------------------------- 1 | 4 | Konvolúció szerkesztő 5 | Betöltés fájlból... 6 | Polaritás: {0} 7 | Fázis: {0}° 8 | Késleltetés: {0} minta 9 | 10 | Csak monó fájlok támogatottak konvolúció importálásához. 11 | -------------------------------------------------------------------------------- /Cavern.Format/Decoders/EnhancedAC3/ObjectAudioMetadataEnums.cs: -------------------------------------------------------------------------------- 1 | namespace Cavern.Format.Decoders.EnhancedAC3 { 2 | enum NonStandardBedChannel { 3 | FrontLeft = 0, 4 | FrontRight = 1, 5 | Center = 2, 6 | LowFrequencyEffects = 3, 7 | SurroundLeft = 4, 8 | SurroundRight = 5, 9 | RearLeft = 6, 10 | RearRight = 7, 11 | TopFrontLeft = 8, 12 | TopFrontRight = 9, 13 | TopSurroundLeft = 10, 14 | TopSurroundRight = 11, 15 | TopRearLeft = 12, 16 | TopRearRight = 13, 17 | WideLeft = 14, 18 | WideRight = 15, 19 | LowFrequencyEffects2 = 16, 20 | Max = 17 21 | } 22 | 23 | enum ObjectAnchor { 24 | Room, 25 | Screen, 26 | Speaker 27 | } 28 | } -------------------------------------------------------------------------------- /Cavern.QuickEQ.Format/FilterSet/Exceptions/InvalidSourceException.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace Cavern.Format.FilterSet { 4 | /// 5 | /// Represents that this filter set was incorrectly initialized as a nonexistent or invalid file was read. 6 | /// 7 | public class InvalidSourceException : Exception { 8 | const string message = "This filter set was incorrectly initialized as a nonexistent or invalid file was read."; 9 | 10 | /// 11 | /// The target filter set couldn't be used for configuration without before/after measurements (target curve hacking), 12 | /// so regular filter set exports are not supported. 13 | /// 14 | public InvalidSourceException() : base(message) { } 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /Cavern.QuickEQ/Graphing/DrawableMeasurementType.cs: -------------------------------------------------------------------------------- 1 | namespace Cavern.QuickEQ.Graphing { 2 | /// 3 | /// Possible drawings to produce from various measurements. 4 | /// 5 | public enum DrawableMeasurementType { 6 | /// 7 | /// Any kind of curve: spectrum, phase, etc., using the . 8 | /// 9 | Graph, 10 | /// 11 | /// Frequency intensity by time using the . 12 | /// 13 | Spectogram, 14 | /// 15 | /// A special case of , handling phase response calculation in parsing using the . 16 | /// 17 | Phase, 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /CavernSamples/CavernizeGUI/UserControls/TextWithIcon.xaml: -------------------------------------------------------------------------------- 1 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /CavernSamples/QuickEQResultMerger/QuickEQResultMerger.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | WinExe 4 | net8.0-windows 5 | disable 6 | true 7 | QuickEQ Result Merger 8 | VoidX 9 | Copyright © Bence Sgánetz 2016-2025 10 | Combines the result of multiple Cavern QuickEQ measurements to aid in EQing an unlimited number of channels on select systems. 11 | 12 | 13 | 14 | false 15 | none 16 | true 17 | 18 | -------------------------------------------------------------------------------- /Cavern/SpecialSources/StreamedSource.cs: -------------------------------------------------------------------------------- 1 | namespace Cavern.SpecialSources { 2 | /// 3 | /// An always rendered source where only or should be overridden. 4 | /// 5 | public class StreamedSource : Source { 6 | /// 7 | /// Force the source to be played. 8 | /// 9 | protected internal override bool Precollect() { 10 | ForcePrecollect(); 11 | return base.Precollect(); 12 | } 13 | 14 | /// 15 | /// Indicates that the source meets rendering requirements, and won't fail. 16 | /// 17 | protected internal override bool Renderable => IsPlaying; 18 | } 19 | } -------------------------------------------------------------------------------- /Cavern/Utilities/DictionaryExtensions.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | 3 | namespace Cavern.Utilities { 4 | /// 5 | /// Extension methods for . 6 | /// 7 | public static class DictionaryExtensions { 8 | /// 9 | /// Get the key for a value that's found in the source . 10 | /// 11 | public static TKey GetKey(this Dictionary dictionary, TValue value) { 12 | foreach (KeyValuePair pair in dictionary) { 13 | if (pair.Value.Equals(value)) { 14 | return pair.Key; 15 | } 16 | } 17 | return default; 18 | } 19 | } 20 | } -------------------------------------------------------------------------------- /CavernSamples/Reusable/Cavernize.Logic/CommandLine/OutputCommand.cs: -------------------------------------------------------------------------------- 1 | using Cavernize.Logic.CommandLine.BaseClasses; 2 | using Cavernize.Logic.Models; 3 | 4 | namespace Cavernize.Logic.CommandLine; 5 | 6 | /// 7 | /// Starts a render to this file. 8 | /// 9 | sealed class OutputCommand : Command { 10 | /// 11 | public override string Name => "-output"; 12 | 13 | /// 14 | public override string Alias => "-o"; 15 | 16 | /// 17 | public override int Parameters => 1; 18 | 19 | /// 20 | public override string Help => "Starts a render to this file."; 21 | 22 | /// 23 | public override void Execute(string[] args, int offset, ICavernizeApp app) => app.RenderContent(args[offset]); 24 | } 25 | -------------------------------------------------------------------------------- /Cavern.Format/Common/IExportable.cs: -------------------------------------------------------------------------------- 1 | namespace Cavern.Format.Common { 2 | /// 3 | /// Interface for a format that can be exported to a file. 4 | /// 5 | public interface IExportable { 6 | /// 7 | /// Extension of the main file created with . If multiple files are created, this is the extension of 8 | /// the root file. This should be displayed on export dialogs. This value shall not include the dot before the extension. 9 | /// 10 | public string FileExtension { get; } 11 | 12 | /// 13 | /// Export this object to a target file. 14 | /// 15 | /// Location of the target file 16 | public void Export(string path); 17 | } 18 | } -------------------------------------------------------------------------------- /Cavern.QuickEQ.Format/ConfigurationFile/Helpers/ILazyLoadableFilter.cs: -------------------------------------------------------------------------------- 1 | using Cavern.Filters; 2 | using Cavern.Utilities; 3 | 4 | namespace Cavern.Format.ConfigurationFile.Helpers { 5 | /// 6 | /// The would be mildly computationally heavy to construct, increasing loading times. Hold on to the raw data, 7 | /// and recreate the filter in parallel when a configuration file was completely parsed. 8 | /// 9 | public interface ILazyLoadableFilter { 10 | /// 11 | /// Create the actual filter that should replace this placeholder. 12 | /// 13 | /// If the filter performs FFT, parallel creation can use s 14 | Filter CreateFilter(FFTCachePool cachePool); 15 | } 16 | } -------------------------------------------------------------------------------- /CavernSamples/VoidX.WPF/FFTSize.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Windows; 3 | 4 | namespace VoidX.WPF { 5 | /// 6 | /// FFT size (numbers that are a power of 2) selector control with limits. 7 | /// 8 | public partial class FFTSize : NumericUpDown { 9 | /// 10 | protected override void CheckValue() { 11 | value = (int)Math.Pow(2, Math.Round(Math.Log(value, 2))); 12 | base.CheckValue(); 13 | } 14 | 15 | /// 16 | protected override void Increase(object sender, RoutedEventArgs e) => Value = (int)Math.Pow(2, Math.Log(Value, 2) + 1); 17 | 18 | /// 19 | protected override void Decrease(object sender, RoutedEventArgs e) => Value = (int)Math.Pow(2, Math.Log(Value, 2) - 1); 20 | } 21 | } -------------------------------------------------------------------------------- /Libraries/Cavern.WPF/Resources/BiquadEditorStrings.xaml: -------------------------------------------------------------------------------- 1 | 4 | Biquad Filter Editor 5 | Filter type: 6 | Center frequency: 7 | Q factor: 8 | Gain (dB): 9 | Swap phase 10 | Spectrum 11 | Phase 12 | -------------------------------------------------------------------------------- /Cavern/Utilities/LinqExtensions.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | 3 | namespace Cavern.Utilities { 4 | /// 5 | /// Operations that LINQ should have had. 6 | /// 7 | public static class LinqExtensions { 8 | /// 9 | /// Get the index of a given in a enumerable or -1 if it's not in the collection. 10 | /// 11 | public static int IndexOf(this IEnumerable source, T item) { 12 | int index = 0; 13 | foreach (T element in source) { 14 | if (EqualityComparer.Default.Equals(element, item)) { 15 | return index; 16 | } 17 | index++; 18 | } 19 | return -1; 20 | } 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /CavernSamples/Reusable/Cavernize.Logic/Models/RenderTargets/VirtualizerRenderTarget.cs: -------------------------------------------------------------------------------- 1 | using Cavern; 2 | using Cavern.Channels; 3 | 4 | namespace Cavernize.Logic.Models.RenderTargets; 5 | 6 | /// 7 | /// Applies a layout for headphone virtualization. 8 | /// 9 | public class VirtualizerRenderTarget : RenderTarget { 10 | /// 11 | /// Applies a layout for headphone virtualization. 12 | /// 13 | public VirtualizerRenderTarget() : base(targetName, [ReferenceChannel.SideLeft, ReferenceChannel.SideRight]) => OutputChannels = 2; 14 | 15 | /// 16 | public override void Apply(bool _) => Listener.HeadphoneVirtualizer = true; 17 | 18 | /// 19 | /// Name of this render target. 20 | /// 21 | const string targetName = "Headphone Virtualizer"; 22 | } 23 | -------------------------------------------------------------------------------- /Libraries/Cavern.WPF/Resources/BiquadEditorStrings.hu-HU.xaml: -------------------------------------------------------------------------------- 1 | 4 | Biquad szűrő szerkesztő 5 | Szűrő típusa: 6 | Középfrekvencia: 7 | Jósági tényező: 8 | Erősítés (dB): 9 | Fázis felcserélése 10 | Spektrum 11 | Fázis 12 | -------------------------------------------------------------------------------- /Cavern/Utilities/Interfaces/ILicence.cs: -------------------------------------------------------------------------------- 1 | namespace Cavern.Utilities { 2 | /// 3 | /// Provides a way to accept a licence before using a feature that requires it. 4 | /// 5 | public interface ILicence { 6 | /// 7 | /// Display a text before the licence text, explaining why this software is needed. 8 | /// 9 | public void SetDescription(string description); 10 | 11 | /// 12 | /// Provide the agreement text the user must accept. 13 | /// 14 | public void SetLicenceText(string licence); 15 | 16 | /// 17 | /// Show the licence and prompt the user to accept it. 18 | /// 19 | /// If the licence was accepted. 20 | public bool Prompt(); 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /CavernSamples/CavernPipeServer.Windows/CavernPipeServer.Windows.csproj.user: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | Designer 7 | 8 | 9 | 10 | 11 | Designer 12 | 13 | 14 | Designer 15 | 16 | 17 | Designer 18 | 19 | 20 | Designer 21 | 22 | 23 | -------------------------------------------------------------------------------- /Tests/Test.Cavern.QuickEQ/MovingAverage_Tests.cs: -------------------------------------------------------------------------------- 1 | using Cavern.Utilities; 2 | 3 | namespace Test.Cavern.QuickEQ { 4 | /// 5 | /// Tests the class. 6 | /// 7 | [TestClass] 8 | public class MovingAverage_Tests { 9 | /// 10 | /// Tests if works as intended. 11 | /// 12 | [TestMethod, Timeout(1000)] 13 | public void MovingAverage() { 14 | MovingAverage average = new MovingAverage(3); 15 | float[] first = { 1, 0, 4 }; 16 | average.AddFrame(first); 17 | Equals(average.Average, first); 18 | average.AddFrame([2, 0, 4]); 19 | average.AddFrame([3, 3, 4]); 20 | Equals(average.Average, new float[] { 2, 1, 4 }); 21 | } 22 | } 23 | } -------------------------------------------------------------------------------- /Cavern.QuickEQ.Format/FilterSet/Exceptions/UnsupportedFilterException.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | using Cavern.Filters; 4 | 5 | namespace Cavern.Format.FilterSet { 6 | /// 7 | /// The target system does not support the applied filter. 8 | /// 9 | public class UnsupportedFilterException : Exception { 10 | const string message = "The target system does not support the applied filter"; 11 | 12 | /// 13 | /// The target system does not support the applied filter. 14 | /// 15 | public UnsupportedFilterException() : base(message + '.') { } 16 | 17 | /// 18 | /// The target system does not support the applied filter. 19 | /// 20 | public UnsupportedFilterException(Filter filter) : base($"{message}: {filter}") { } 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /CavernSamples/CavernizeGUI/CavernSettings/DynamicSpecialRenderModeSettings.cs: -------------------------------------------------------------------------------- 1 | using Cavernize.Logic.CavernSettings; 2 | 3 | namespace CavernizeGUI.CavernSettings; 4 | 5 | /// 6 | /// Use the settings stored in Cavernize for special rendering modes. 7 | /// 8 | sealed class DynamicSpecialRenderModeSettings : SpecialRenderModeSettings { 9 | /// 10 | /// Said settings file. 11 | /// 12 | readonly Resources.Settings source = Resources.Settings.Default; 13 | 14 | /// 15 | public override bool SpeakerVirtualizer { 16 | get => source.speakerVirtualizer; 17 | set => source.speakerVirtualizer = value; 18 | } 19 | 20 | /// 21 | public override bool Force24Bit { 22 | get => source.force24Bit; 23 | set => source.force24Bit = value; 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /Cavern.Format/Consts/MeridianLosslessPackingConsts.cs: -------------------------------------------------------------------------------- 1 | using Cavern.Format.Decoders; 2 | 3 | namespace Cavern.Format.Consts { 4 | /// 5 | /// Used for both . 6 | /// 7 | internal static class MeridianLosslessPackingConsts { 8 | /// 9 | /// Magic number marking a major sync block in an MLP stream. 10 | /// 11 | public const int syncWord = unchecked((int)0xF8726FBA); 12 | 13 | /// 14 | /// Bytes that must be read before determining the frame size. 15 | /// 16 | public const int mustDecode = 8; 17 | 18 | /// 19 | /// Additional integrity check for major sync blocks. 20 | /// 21 | public const ushort majorSyncSignature = 0xB752; 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /Tests/Test.Cavern.QuickEQ/EQCurves/Depth_Tests.cs: -------------------------------------------------------------------------------- 1 | using Cavern.QuickEQ.EQCurves; 2 | 3 | namespace Test.Cavern.QuickEQ.EQCurves { 4 | /// 5 | /// Tests the class. 6 | /// 7 | [TestClass] 8 | public class Depth_Tests { 9 | /// 10 | /// Tests if 's this operator works as intended. 11 | /// 12 | [TestMethod, Timeout(1000)] 13 | public void This() => EQCurveTestUtils.RoomCurveLikeThis(new Depth(), 60, 12, 3); 14 | 15 | /// 16 | /// Tests if works as intended. 17 | /// 18 | [TestMethod, Timeout(1000)] 19 | public void GenerateLinearCurve() => EQCurveTestUtils.RoomCurveLikeGenerateLinearCurve(new Depth(), 60, 12, 3); 20 | } 21 | } -------------------------------------------------------------------------------- /CavernSamples/WavefrontSimulator/Settings.settings: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | False 7 | 8 | 9 | False 10 | 11 | 12 | 3 13 | 14 | 15 | 5 16 | 17 | 18 | -------------------------------------------------------------------------------- /Tests/Test.Cavern.Format/Test.Cavern.Format.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | net8.0 5 | enable 6 | disable 7 | 8 | false 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | -------------------------------------------------------------------------------- /Cavern.QuickEQ.Format/ConfigurationFile/Exceptions/UnsupportedFilterForExportException.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | using Cavern.Filters; 4 | 5 | namespace Cavern.Format.ConfigurationFile { 6 | /// 7 | /// Thrown when an unsupported filter would be exported to a . 8 | /// 9 | public abstract class UnsupportedFilterForExportException : Exception { 10 | /// 11 | /// The filter not supported by the . 12 | /// 13 | public Filter Filter { get; } 14 | 15 | /// 16 | /// Thrown when an unsupported filter would be exported to a . 17 | /// 18 | protected UnsupportedFilterForExportException(string message, Filter filter) : base(message) => Filter = filter; 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /Cavern.QuickEQ/PolarityCorrections/ImpulsePeakBasedPolarityCorrection.cs: -------------------------------------------------------------------------------- 1 | using Cavern.Utilities; 2 | 3 | namespace Cavern.QuickEQ.PolarityCorrections { 4 | /// 5 | /// Generates a polarity correction by aligning impulse peaks to the same direction. 6 | /// 7 | /// This is a naive approach and should only be used when performance is more important than precision. 8 | public sealed class ImpulsePeakBasedPolarityCorrection : PolarityCorrection { 9 | /// 10 | public override bool[] GetInvertedChannels(MultichannelWaveform simulations) { 11 | bool[] result = new bool[simulations.Channels]; 12 | for (int i = 0; i < result.Length; i++) { 13 | result[i] = WaveformUtils.GetPeakSigned(simulations[i]) < 0; 14 | } 15 | return result; 16 | } 17 | } 18 | } -------------------------------------------------------------------------------- /CavernSamples/CavernPipeServer.Multiplatform/Program.cs: -------------------------------------------------------------------------------- 1 | using CavernPipeServer.Logic; 2 | 3 | Console.WriteLine("Launching CavernPipe Server..."); 4 | 5 | bool running = true; 6 | while (running) { 7 | using PipeHandler handler = new(); 8 | handler.OnException += e => { 9 | if (!e.StackTrace.Contains("QueueStream")) { // That would be a normal disconnection 10 | Console.Error.WriteLine(e.Message); 11 | } 12 | running = false; 13 | }; 14 | 15 | Console.WriteLine("CavernPipe Server is waiting for client connection."); 16 | bool canShutDown = false; 17 | handler.StatusChanged += () => { 18 | if (handler.IsConnected) { 19 | Console.WriteLine("Client connected."); 20 | } 21 | canShutDown = !handler.Running; 22 | }; 23 | 24 | while (!canShutDown) { 25 | Thread.Sleep(1000); 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /Tests/Test.Cavern.QuickEQ/EQCurves/EQCurve_Tests.cs: -------------------------------------------------------------------------------- 1 | using Cavern.QuickEQ.EQCurves; 2 | 3 | namespace Test.Cavern.QuickEQ.EQCurves { 4 | /// 5 | /// Tests the class. 6 | /// 7 | [TestClass] 8 | public class EQCurve_Tests { 9 | /// 10 | /// Tests if works as intended. 11 | /// 12 | [TestMethod, Timeout(1000)] 13 | public void GetAverageLevel() { 14 | EQCurve curve = new Punch(3); 15 | Assert.AreEqual(1.8299298951978702, curve.GetAverageLevel(20, 120, 10), Consts.delta); 16 | Assert.AreEqual(0, curve.GetAverageLevel(200, 1000, 100), Consts.delta); 17 | Assert.AreEqual(-0.34931992656327837, curve.GetAverageLevel(1000, 2000, 100), Consts.delta); 18 | } 19 | } 20 | } -------------------------------------------------------------------------------- /Tests/Test.Cavern/Consts/TestUtils.cs: -------------------------------------------------------------------------------- 1 | namespace Test.Cavern { 2 | /// 3 | /// Common utilities used in testing like assertions. 4 | /// 5 | internal static class TestUtils { 6 | /// 7 | /// Test if the number of zeros in an array match an expected . 8 | /// 9 | public static void AssertNumberOfZeros(IList list, int count) { 10 | int zeros = 0; 11 | for (int i = 0, c = list.Count; i < c; i++) { 12 | float[] subarray = list[i]; 13 | for (int j = 0; j < subarray.Length; j++) { 14 | if (subarray[j] == 0) { 15 | zeros++; 16 | } 17 | } 18 | } 19 | Assert.AreEqual(count, zeros); 20 | } 21 | } 22 | } -------------------------------------------------------------------------------- /Cavern.Format/Container/Matroska/MatroskaTrackExtraVideo.cs: -------------------------------------------------------------------------------- 1 | using System.IO; 2 | 3 | using Cavern.Format.Common; 4 | 5 | namespace Cavern.Format.Container.Matroska { 6 | /// 7 | /// Video track metadata with fields that are only contained in Matroska files. 8 | /// 9 | public class MatroskaTrackExtraVideo : TrackExtraVideo { 10 | /// 11 | /// Elements that extend the track format, other than . 12 | /// This is not decoded, just transfered. 13 | /// 14 | public byte[] BlockAdditionMapping { get; set; } 15 | 16 | /// 17 | /// Parse video metadata from a Matroska track's video metadata node. 18 | /// 19 | internal MatroskaTrackExtraVideo(Stream reader, MatroskaTree videoMeta) : base(reader, videoMeta) { } 20 | } 21 | } -------------------------------------------------------------------------------- /CavernSamples/Coding style.txt: -------------------------------------------------------------------------------- 1 | 0. Performance before readability. 2 | 1. Functions and properties are PascalCase. 3 | 2. Variables are camelCase. 4 | 3. Braces always present, starting braces are never in new line. 5 | 4. Summaries are mandatory. 6 | 7 | Ordering: 8 | * Classes, structs 9 | * Enums 10 | * Delegates 11 | * Events 12 | * Public static properties 13 | * Public static variables 14 | * Protected static properties 15 | * Protected static variables 16 | * Private static properties 17 | * Private static variables 18 | * Public properties 19 | * Public variables 20 | * Protected properties 21 | * Protected variables 22 | * Private properties 23 | * Private readonly variables 24 | * Private variables 25 | * Constructors 26 | * Public static functions 27 | * Internal static functions 28 | * Private static functions 29 | * Public functions 30 | * Internal functions 31 | * Private functions 32 | * Constants -------------------------------------------------------------------------------- /Tests/Test.Cavern.QuickEQ/EQCurves/RoomCurve_Tests.cs: -------------------------------------------------------------------------------- 1 | using Cavern.QuickEQ.EQCurves; 2 | 3 | namespace Test.Cavern.QuickEQ.EQCurves { 4 | /// 5 | /// Tests the class. 6 | /// 7 | [TestClass] 8 | public class RoomCurve_Tests { 9 | /// 10 | /// Tests if 's this operator works as intended. 11 | /// 12 | [TestMethod, Timeout(1000)] 13 | public void This() => EQCurveTestUtils.RoomCurveLikeThis(new RoomCurve(), 200, 3, 3); 14 | 15 | /// 16 | /// Tests if works as intended. 17 | /// 18 | [TestMethod, Timeout(1000)] 19 | public void GenerateLinearCurve() => EQCurveTestUtils.RoomCurveLikeGenerateLinearCurve(new RoomCurve(), 200, 3, 3); 20 | } 21 | } -------------------------------------------------------------------------------- /Tests/Test.Cavern.QuickEQ/Test.Cavern.QuickEQ.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | net8.0 5 | enable 6 | disable 7 | 8 | false 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | -------------------------------------------------------------------------------- /CavernSamples/FilterStudio/Resources/Settings.settings: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | True 7 | 8 | 9 | 0 10 | 11 | 12 | 255 13 | 14 | 15 | 48000 16 | 17 | 18 | -------------------------------------------------------------------------------- /Tests/Test.Cavern.Format/Consts/Consts.cs: -------------------------------------------------------------------------------- 1 | using Cavern; 2 | 3 | namespace Test.Cavern.Format { 4 | /// 5 | /// Constant test values. 6 | /// 7 | static class Consts { 8 | /// 9 | /// Test sample rate. 10 | /// 11 | internal const int sampleRate = 48000; 12 | 13 | /// 14 | /// Allowed floating point margin of error. 15 | /// 16 | internal const float epsilon = .000001f; 17 | 18 | /// 19 | /// Mono channel layout. 20 | /// 21 | internal static readonly Channel[] mono = new[] { new Channel(0, 0) }; 22 | 23 | /// 24 | /// Stereo channel layout. 25 | /// 26 | internal static readonly Channel[] stereo = new[] { new Channel(0, -45), new Channel(0, 45) }; 27 | } 28 | } -------------------------------------------------------------------------------- /CavernSamples/CavernizeGUI/Resources/UpmixingSettings.settings: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | False 7 | 8 | 9 | False 10 | 11 | 12 | 0.75 13 | 14 | 15 | 0.8 16 | 17 | 18 | -------------------------------------------------------------------------------- /Cavern.Format/Renderers/RendererConsts.cs: -------------------------------------------------------------------------------- 1 | using System.Numerics; 2 | 3 | using Cavern.Channels; 4 | 5 | namespace Cavern.Format.Renderers { 6 | /// 7 | /// Constants required for rendering. 8 | /// 9 | public abstract partial class Renderer { 10 | /// 11 | /// Get which standard renderer position corresponds to which channel. 12 | /// 13 | /// Internal Cavern channel positions are not the same. 14 | public static ReferenceChannel ChannelFromPosition(Vector3 position) { 15 | for (int i = 0; i < ChannelPrototype.AlternativePositions.Length; i++) { 16 | if (position == ChannelPrototype.AlternativePositions[i]) { 17 | return (ReferenceChannel)i; 18 | } 19 | } 20 | return ReferenceChannel.Unknown; 21 | } 22 | } 23 | } -------------------------------------------------------------------------------- /CavernSamples/Reusable/Cavernize.Logic/CommandLine/SurroundSwapCommand.cs: -------------------------------------------------------------------------------- 1 | using Cavernize.Logic.CommandLine.BaseClasses; 2 | using Cavernize.Logic.Models; 3 | 4 | namespace Cavernize.Logic.CommandLine; 5 | 6 | /// 7 | /// Swaps the side and rear surround outputs with each other. 8 | /// 9 | sealed class SurroundSwapCommand : BooleanCommand { 10 | /// 11 | public override string Name => "-surround_swap"; 12 | 13 | /// 14 | public override string Alias => "-ss"; 15 | 16 | /// 17 | public override string Help => "Swaps the side and rear surround outputs with each other."; 18 | 19 | /// 20 | public override void Execute(bool value, ICavernizeApp app) { 21 | if (app.Rendering) { 22 | InProgressError(app, "surround swap"); 23 | } 24 | 25 | app.SurroundSwap = value; 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /CavernSamples/Reusable/Cavernize.Logic/CommandLine/EffectCommand.cs: -------------------------------------------------------------------------------- 1 | using Cavernize.Logic.CommandLine.BaseClasses; 2 | using Cavernize.Logic.Models; 3 | 4 | namespace Cavernize.Logic.CommandLine; 5 | 6 | /// 7 | /// Sets height generation effect strength for the upconverter. 8 | /// 9 | sealed class EffectCommand : IntegerCommand { 10 | /// 11 | public override string Name => "-effect"; 12 | 13 | /// 14 | public override string Alias => "-e"; 15 | 16 | /// 17 | public override string Help => "Sets height generation effect strength for the upconverter in percent."; 18 | 19 | /// 20 | public override void Execute(int value, ICavernizeApp app) { 21 | if (app.Rendering) { 22 | InProgressError(app, "effect"); 23 | } 24 | 25 | app.UpmixingSettings.Effect = value * .01f; 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /Cavern/Remapping/SpatialRemappingSource.cs: -------------------------------------------------------------------------------- 1 | namespace Cavern.Remapping { 2 | /// 3 | /// Content layouts supported for the feature. 4 | /// 5 | public enum SpatialRemappingSource { 6 | /// 7 | /// Spatial Remapping is disabled. 8 | /// 9 | Off, 10 | /// 11 | /// 7.1 with ITU angles (legacy content). 12 | /// 13 | ITU_7_1, 14 | /// 15 | /// 5.1.2 with ITU angles (legacy content). 16 | /// 17 | ITU_5_1_2, 18 | /// 19 | /// 7.1 with cinema standard room wall positions. 20 | /// 21 | Allocentric_7_1, 22 | /// 23 | /// 5.1.2 with cinema standard room wall positions. 24 | /// 25 | Allocentric_5_1_2 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /CavernSamples/Reusable/Cavernize.Logic/CommandLine/HiddenCommands/UnsafeCommand.cs: -------------------------------------------------------------------------------- 1 | using Cavern.Format.Common; 2 | 3 | using Cavernize.Logic.CommandLine.BaseClasses; 4 | using Cavernize.Logic.Models; 5 | 6 | namespace Cavernize.Logic.CommandLine.HiddenCommands; 7 | 8 | /// 9 | /// Disables checks for conditions that don't inherently break operation, but are mandated by standards. 10 | /// 11 | class UnsafeCommand : HiddenCommand { 12 | /// 13 | public override string Name => "--unsafe"; 14 | 15 | /// 16 | public override int Parameters => 0; 17 | 18 | /// 19 | public override string Help => "Disables checks for conditions that are mandated by standards but might don't break decoding."; 20 | 21 | /// 22 | public override void Execute(string[] args, int offset, ICavernizeApp app) => CavernFormatGlobal.Unsafe = true; 23 | } 24 | -------------------------------------------------------------------------------- /CavernSamples/HRTFSetImporter/Settings.settings: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | DirectionalImpulse_{Y}_{X}.wav 10 | 11 | 12 | AngleImpulse_{A}_D{D}.wav 13 | 14 | 15 | True 16 | 17 | 18 | -------------------------------------------------------------------------------- /CavernSamples/Reusable/Cavernize.Logic/CommandLine/UpconvertCommand.cs: -------------------------------------------------------------------------------- 1 | using Cavernize.Logic.CommandLine.BaseClasses; 2 | using Cavernize.Logic.Models; 3 | 4 | namespace Cavernize.Logic.CommandLine; 5 | 6 | /// 7 | /// Turns height generation from regular content on or off, up to 7.1. 8 | /// 9 | sealed class UpconvertCommand : BooleanCommand { 10 | /// 11 | public override string Name => "-upconvert"; 12 | 13 | /// 14 | public override string Alias => "-u"; 15 | 16 | /// 17 | public override string Help => "Turns height generation from regular content up to 7.1 on or off."; 18 | 19 | /// 20 | public override void Execute(bool value, ICavernizeApp app) { 21 | if (app.Rendering) { 22 | InProgressError(app, "upconversion"); 23 | } 24 | 25 | app.UpmixingSettings.Cavernize = value; 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /Tests/Test.Cavern/Test.Cavern.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | net8.0 5 | enable 6 | disable 7 | 8 | false 9 | 10 | 11 | 12 | 13 | runtime; build; native; contentfiles; analyzers; buildtransitive 14 | all 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | -------------------------------------------------------------------------------- /Cavern.QuickEQ.Format/ConfigurationFile/ConvolutionBoxFormat/CBFEntry.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.IO; 3 | 4 | namespace Cavern.Format.ConfigurationFile.ConvolutionBoxFormat { 5 | /// 6 | /// A single filter to be written into a . 7 | /// 8 | abstract class CBFEntry { 9 | /// 10 | /// Export this filter. 11 | /// 12 | public abstract void Write(Stream target); 13 | 14 | /// 15 | /// Get the next entry from a . 16 | /// 17 | public static CBFEntry Read(Stream stream) => stream.ReadByte() switch { 18 | 0 => new MatrixEntry(stream), 19 | 1 => new ConvolutionEntry(stream), 20 | _ => throw new NotImplementedException(), 21 | }; 22 | } 23 | } -------------------------------------------------------------------------------- /Cavern.QuickEQ.Format/FilterSet/Exceptions/DeltaSetException.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace Cavern.Format.FilterSet { 4 | /// 5 | /// The target filter set couldn't be used for configuration without before/after measurements (target curve hacking), 6 | /// so regular filter set exports are not supported. 7 | /// 8 | public class DeltaSetException : Exception { 9 | const string message = "The target filter set couldn't be used for configuration without before/after measurements " + 10 | "(target curve hacking), so regular filter set exports are not supported."; 11 | 12 | /// 13 | /// The target filter set couldn't be used for configuration without before/after measurements (target curve hacking), 14 | /// so regular filter set exports are not supported. 15 | /// 16 | public DeltaSetException() : base(message) { } 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /Cavern.QuickEQ/Graphing/Overlays/GridFront.cs: -------------------------------------------------------------------------------- 1 | namespace Cavern.QuickEQ.Graphing.Overlays { 2 | /// 3 | /// A that draws the grid over the image instead of behind it. 4 | /// 5 | public class GridFront : Grid { 6 | /// 7 | /// A that draws the grid over the image instead of behind it. 8 | /// 9 | public GridFront(int borderWidth, int gridWidth, uint color, int xSteps, int ySteps) : base(borderWidth, gridWidth, color, xSteps, ySteps) { } 10 | 11 | /// 12 | public override void DrawBehind(DrawableMeasurement target) { 13 | // Cancel Grid behavior, move it to DrawOn 14 | } 15 | 16 | /// 17 | public override void DrawOn(DrawableMeasurement target) { 18 | base.DrawBehind(target); 19 | base.DrawOn(target); 20 | } 21 | } 22 | } -------------------------------------------------------------------------------- /CavernSamples/Reusable/Cavernize.Logic/CommandLine/MuteBedCommand.cs: -------------------------------------------------------------------------------- 1 | using Cavernize.Logic.CommandLine.BaseClasses; 2 | using Cavernize.Logic.Models; 3 | 4 | namespace Cavernize.Logic.CommandLine; 5 | 6 | /// 7 | /// Mutes the fixed bed channels. 8 | /// 9 | sealed class MuteBedCommand : Command { 10 | /// 11 | public override string Name => "-mute_bed"; 12 | 13 | /// 14 | public override string Alias => "-mb"; 15 | 16 | /// 17 | public override int Parameters => 0; 18 | 19 | /// 20 | public override string Help => "Mutes the fixed bed channels."; 21 | 22 | /// 23 | public override void Execute(string[] args, int offset, ICavernizeApp app) { 24 | if (app.Rendering) { 25 | InProgressError(app, "muting"); 26 | } 27 | 28 | app.SpecialRenderModeSettings.MuteBed = true; 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /CavernSamples/Reusable/Cavernize.Logic/CommandLine/SmoothnessCommand.cs: -------------------------------------------------------------------------------- 1 | using Cavernize.Logic.CommandLine.BaseClasses; 2 | using Cavernize.Logic.Models; 3 | 4 | namespace Cavernize.Logic.CommandLine; 5 | 6 | /// 7 | /// Sets generated object movement smoothness for the upconverter. 8 | /// 9 | sealed class SmoothnessCommand : IntegerCommand { 10 | /// 11 | public override string Name => "-smooth"; 12 | 13 | /// 14 | public override string Alias => "-s"; 15 | 16 | /// 17 | public override string Help => "Sets generated object movement smoothness for the upconverter in percent."; 18 | 19 | /// 20 | public override void Execute(int value, ICavernizeApp app) { 21 | if (app.Rendering) { 22 | InProgressError(app, "smoothness"); 23 | } 24 | 25 | app.UpmixingSettings.Smoothness = value * .01f; 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /Cavern/Virtualizer/_Exceptions.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace Cavern.Virtualizer { 4 | /// 5 | /// Tells if a ground channel is present, preventing an opteration. 6 | /// 7 | public class NonGroundChannelPresentException : Exception { 8 | const string message = "The active layout does not support height virtualization on speakers. " + 9 | "Either disable the option or choose a layout with ground channels only."; 10 | 11 | /// 12 | /// Tells if a ground channel is present and preventing an opteration. 13 | /// 14 | public NonGroundChannelPresentException() : base(message) { } 15 | 16 | /// 17 | /// Tells if a ground channel is present and preventing an opteration, with a custom message. 18 | /// 19 | public NonGroundChannelPresentException(string message) : base(message) { } 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /CavernSamples/Reusable/Cavernize.Logic/CommandLine/MatrixCommand.cs: -------------------------------------------------------------------------------- 1 | using Cavernize.Logic.CommandLine.BaseClasses; 2 | using Cavernize.Logic.Models; 3 | 4 | namespace Cavernize.Logic.CommandLine; 5 | 6 | /// 7 | /// Turns 7.1-creation from channel-based sources with less channels on or off. 8 | /// 9 | sealed class MatrixCommand : BooleanCommand { 10 | /// 11 | public override string Name => "-matrix"; 12 | 13 | /// 14 | public override string Alias => "-mx"; 15 | 16 | /// 17 | public override string Help => "Turns 7.1-creation from channel-based sources with less channels on or off."; 18 | 19 | /// 20 | public override void Execute(bool value, ICavernizeApp app) { 21 | if (app.Rendering) { 22 | InProgressError(app, "matrixing"); 23 | } 24 | 25 | app.UpmixingSettings.MatrixUpmixing = value; 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /CavernSamples/Reusable/Cavernize.Logic/CommandLine/InputCommand.cs: -------------------------------------------------------------------------------- 1 | using Cavernize.Logic.CommandLine.BaseClasses; 2 | using Cavernize.Logic.Models; 3 | 4 | namespace Cavernize.Logic.CommandLine; 5 | 6 | /// 7 | /// Opens a content file. 8 | /// 9 | sealed class InputCommand : Command { 10 | /// 11 | public override string Name => "-input"; 12 | 13 | /// 14 | public override string Alias => "-i"; 15 | 16 | /// 17 | public override int Parameters => 1; 18 | 19 | /// 20 | public override string Help => "Opens a content file."; 21 | 22 | /// 23 | public override void Execute(string[] args, int offset, ICavernizeApp app) { 24 | if (!File.Exists(args[offset])) { 25 | throw new CommandException($"The file \"{args[offset]}\" does not exist."); 26 | } 27 | app.OpenContent(args[offset]); 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /Tests/Test.CavernUnity/Test.CavernUnity.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | net8.0 5 | enable 6 | disable 7 | 8 | false 9 | true 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | -------------------------------------------------------------------------------- /CavernSamples/Reusable/Cavernize.Logic/CommandLine/MuteGroundCommand.cs: -------------------------------------------------------------------------------- 1 | using Cavernize.Logic.CommandLine.BaseClasses; 2 | using Cavernize.Logic.Models; 3 | 4 | namespace Cavernize.Logic.CommandLine; 5 | 6 | /// 7 | /// Mutes objects that are not elevated. 8 | /// 9 | sealed class MuteGroundCommand : Command { 10 | /// 11 | public override string Name => "-mute_gnd"; 12 | 13 | /// 14 | public override string Alias => "-mg"; 15 | 16 | /// 17 | public override int Parameters => 0; 18 | 19 | /// 20 | public override string Help => "Mutes objects that are not elevated."; 21 | 22 | /// 23 | public override void Execute(string[] args, int offset, ICavernizeApp app) { 24 | if (app.Rendering) { 25 | InProgressError(app, "muting"); 26 | } 27 | 28 | app.SpecialRenderModeSettings.MuteGround = true; 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /Libraries/Cavern.WPF/Resources/UpmixingSetupStrings.xaml: -------------------------------------------------------------------------------- 1 | 4 | Upmixing Setup 5 | Fill 7.1 6 | Use a matrix upmixer to create the full 7.1 bed for legacy channel-based content. 7 | Upconvert non-spatial content 8 | Tries to recreate height information for regular content up to 7.1. 9 | Upmixing effect: 10 | Upmixing smoothness: 11 | Reset 12 | -------------------------------------------------------------------------------- /Cavern.Format/Common/BasicEncodingRules.cs: -------------------------------------------------------------------------------- 1 | using System.IO; 2 | 3 | using Cavern.Format.Utilities; 4 | 5 | namespace Cavern.Format.Common { 6 | /// 7 | /// Handles values encoded in Basic Encoding Rules (BER) format. 8 | /// 9 | public static class BasicEncodingRules { 10 | /// 11 | /// Read a BER value from a stream. 12 | /// 13 | public static long Read(Stream reader) { 14 | int bytes = reader.ReadByte(); 15 | if ((bytes & 0x80) == 0) { 16 | return bytes; 17 | } 18 | return bytes switch { 19 | 0x81 => reader.ReadByte(), 20 | 0x82 => reader.ReadUInt16BE(), 21 | 0x83 => (reader.ReadUInt16BE() << 8) | reader.ReadByte(), 22 | 0x84 => reader.ReadUInt32BE(), 23 | _ => throw new UnsupportedFeatureException("long BER") 24 | }; 25 | } 26 | } 27 | } -------------------------------------------------------------------------------- /CavernSamples/Reusable/Cavernize.Logic/CommandLine/SpeakerVirtualizerCommand.cs: -------------------------------------------------------------------------------- 1 | using Cavernize.Logic.CommandLine.BaseClasses; 2 | using Cavernize.Logic.Models; 3 | 4 | namespace Cavernize.Logic.CommandLine; 5 | 6 | /// 7 | /// Virtualizes and downmixes elevated objects to ground-only layouts. 8 | /// 9 | sealed class SpeakerVirtualizerCommand : BooleanCommand { 10 | /// 11 | public override string Name => "-speaker_virt"; 12 | 13 | /// 14 | public override string Alias => "-sv"; 15 | 16 | /// 17 | public override string Help => "Virtualizes and downmixes elevated objects to ground-only layouts."; 18 | 19 | /// 20 | public override void Execute(bool value, ICavernizeApp app) { 21 | if (app.Rendering) { 22 | InProgressError(app, "speaker virtualization"); 23 | } 24 | 25 | app.SpecialRenderModeSettings.SpeakerVirtualizer = value; 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /Cavern.QuickEQ.Format/ConfigurationFile/ConfigurationFileTypeExtensions.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace Cavern.Format.ConfigurationFile { 4 | /// 5 | /// Extension functions for . 6 | /// 7 | public static class ConfigurationFileTypeExtensions { 8 | /// 9 | /// Convert the device to its name, and return null when the device is not available for single-measurement 10 | /// export, allowing for easier filtering of targets. 11 | /// 12 | public static string GetName(this ConfigurationFileType type) => type switch { 13 | ConfigurationFileType.CavernFilterStudio => "Cavern Filter Studio", 14 | ConfigurationFileType.ConvolutionBoxFormat => "Convolution Box Format", 15 | ConfigurationFileType.EqualizerAPO => "Equalizer APO", 16 | _ => throw new NotSupportedException() 17 | }; 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /CavernAmp/fftcache.h: -------------------------------------------------------------------------------- 1 | #ifndef FFTCACHE_H 2 | #define FFTCACHE_H 3 | 4 | #include "complex.h" 5 | #include "export.h" 6 | 7 | /// Class 8 | // Precalculated constants and preallocated recursion arrays for a given FFT size. 9 | class FFTCache { 10 | int depth; 11 | 12 | public: 13 | float *sin, *cos; 14 | Complex **even, **odd; 15 | 16 | // FFT cache constructor. 17 | FFTCache(const int fftSize); 18 | // Get the creation size of the FFT cache. 19 | int size() const; 20 | // FFT cache destructor. 21 | ~FFTCache(); 22 | }; 23 | 24 | #ifdef __cplusplus 25 | extern "C" { 26 | #endif 27 | 28 | /// Exports 29 | // FFT cache constructor. 30 | FFTCache* DLL_EXPORT FFTCache_Create(const int fftSize); 31 | // Get the creation size of the FFT cache. 32 | int DLL_EXPORT FFTCache_Size(const FFTCache *cache); 33 | // Dispose an FFT cache. 34 | void DLL_EXPORT FFTCache_Dispose(FFTCache *cache); 35 | 36 | #ifdef __cplusplus 37 | } 38 | #endif 39 | 40 | #endif // FFTCACHE_H 41 | -------------------------------------------------------------------------------- /CavernSamples/HRTFSetImporter/StringBuilderExtensions.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Globalization; 3 | using System.Text; 4 | 5 | namespace HRTFSetImporter { 6 | static class StringBuilderExtensions { 7 | public static StringBuilder AppendArray(this StringBuilder builder, float[] array) { 8 | builder.Append("new float[").Append(array.Length).Append("] { "); 9 | for (int i = 0; i < array.Length; ++i) { 10 | string str = array[i].ToString(CultureInfo.InvariantCulture); 11 | if (str.StartsWith("0.")) { 12 | builder.Append(str.AsSpan(1)).Append("f, "); 13 | } else if (str.Equals("0")) { 14 | builder.Append("0, "); 15 | } else { 16 | builder.Append(str).Append("f, "); 17 | } 18 | } 19 | builder.Remove(builder.Length - 2, 2).AppendLine(" },"); 20 | return builder; 21 | } 22 | } 23 | } -------------------------------------------------------------------------------- /Tests/Test.Cavern.Format/Consts/AudioSamples.cs: -------------------------------------------------------------------------------- 1 | using Cavern.QuickEQ.SignalGeneration; 2 | 3 | namespace Test.Cavern.Format { 4 | /// 5 | /// Pre-rendered audio samples for reuse in tests. 6 | /// 7 | static class AudioSamples { 8 | /// 9 | /// 4 seconds of linear sweep from 20 Hz to 20 kHz at a 48 kHz sampling rate. 10 | /// 11 | public static float[] Sweep4Sec => sweep4Sec ??= SweepGenerator.Linear(20, 20000, 4 * Consts.sampleRate, Consts.sampleRate); 12 | static float[] sweep4Sec; 13 | 14 | /// 15 | /// 4 seconds of a linear and an exponential sweep from 20 Hz to 20 kHz at a 48 kHz sampling rate. 16 | /// 17 | public static float[][] Sweep4SecStereo => sweep4SecStereo ??= new[] 18 | { Sweep4Sec, SweepGenerator.Exponential(20, 20000, 4 * Consts.sampleRate, Consts.sampleRate) }; 19 | static float[][] sweep4SecStereo; 20 | } 21 | } -------------------------------------------------------------------------------- /Tests/Test.Cavern.QuickEQ/Equalization/EQGenerator.Averaging_Tests.cs: -------------------------------------------------------------------------------- 1 | using Cavern.QuickEQ.Equalization; 2 | 3 | namespace Test.Cavern.QuickEQ.Equalization { 4 | /// 5 | /// Tests the class's averaging functions. 6 | /// 7 | [TestClass] 8 | public class EQGeneratorAveraging_Tests { 9 | /// 10 | /// Tests if works as intended. 11 | /// 12 | [TestMethod, Timeout(1000)] 13 | public void AverageRMS() { 14 | Equalizer a = new Equalizer([new Band(20, 1)], true), 15 | b = new Equalizer([new Band(20, 10)], true), 16 | avg = EQGenerator.AverageRMS(a, b), 17 | avg_nodiv = EQGenerator.AverageRMS(a, a); 18 | Assert.AreEqual(7.50466946361249, avg.PeakGain); 19 | Assert.AreEqual(a.PeakGain, avg_nodiv.PeakGain, Consts.delta); 20 | } 21 | } 22 | } -------------------------------------------------------------------------------- /Cavern.QuickEQ.Format/FilterSet/MiniDSPDDRC88AFilterSet.cs: -------------------------------------------------------------------------------- 1 | using Cavern.Channels; 2 | 3 | namespace Cavern.Format.FilterSet { 4 | /// 5 | /// IIR filter set for MiniDSP DDRC-88A. 6 | /// 7 | /// MiniDSP DDRC-88A only works on 48 kHz sampling rate. Using anything else breaks the filter set. 8 | public class MiniDSPDDRC88AFilterSet : MiniDSP2x4HDFilterSetLite { 9 | /// 10 | /// IIR filter set for MiniDSP DDRC-88A. 11 | /// 12 | public MiniDSPDDRC88AFilterSet(int channels) : base(channels, sampleRate) { } 13 | 14 | /// 15 | /// IIR filter set for MiniDSP 2x4 with a given set of channels. 16 | /// 17 | public MiniDSPDDRC88AFilterSet(ReferenceChannel[] channels) : base(channels, sampleRate) { } 18 | 19 | /// 20 | /// Fixed sample rate of the DDRC-88A. 21 | /// 22 | const int sampleRate = 48000; 23 | } 24 | } -------------------------------------------------------------------------------- /Cavern.QuickEQ.Format/FilterSet/MiniDSPFlexHTxFilterSet.cs: -------------------------------------------------------------------------------- 1 | using Cavern.Channels; 2 | 3 | namespace Cavern.Format.FilterSet { 4 | /// 5 | /// IIR filter set for MiniDSP Flex HTx. 6 | /// 7 | /// MiniDSP Flex HTx only works on 48 kHz sampling rate. Using anything else breaks the filter set. 8 | public class MiniDSPFlexHTxFilterSet : MiniDSP2x4HDFilterSet { 9 | /// 10 | /// IIR filter set for MiniDSP Flex HTx. 11 | /// 12 | public MiniDSPFlexHTxFilterSet(int channels) : base(channels, sampleRate) { } 13 | 14 | /// 15 | /// IIR filter set for MiniDSP 2x4 with a given set of channels. 16 | /// 17 | public MiniDSPFlexHTxFilterSet(ReferenceChannel[] channels) : base(channels, sampleRate) { } 18 | 19 | /// 20 | /// Fixed sample rate of the Flex HTx. 21 | /// 22 | const int sampleRate = 48000; 23 | } 24 | } -------------------------------------------------------------------------------- /Cavern.QuickEQ/EQCurves/Smoother.cs: -------------------------------------------------------------------------------- 1 | using Cavern.QuickEQ.Equalization; 2 | 3 | namespace Cavern.QuickEQ.EQCurves { 4 | /// 5 | /// An EQ curve that smooths out inter-channel differences while keeping the system's sound character. 6 | /// 7 | public class Smoother : Custom { 8 | /// 9 | /// Create a custom EQ curve from a source stored as an Equalier. 10 | /// 11 | public Smoother(Equalizer[] sourceFrequencyResponses) : base(MakeCurve(sourceFrequencyResponses)) {} 12 | 13 | /// 14 | /// Create a target EQ from raw frequency responses, by averaging and smoothing the channels. 15 | /// 16 | static Equalizer MakeCurve(Equalizer[] sourceFrequencyResponses) { 17 | Equalizer target = EQGenerator.AverageRMS(sourceFrequencyResponses); 18 | target.Smooth(.75); 19 | target.Normalize(500, 10000); 20 | return target; 21 | } 22 | } 23 | } -------------------------------------------------------------------------------- /Cavern.QuickEQ.Format/FilterSet/Exceptions/ChannelDependentBandCountException.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace Cavern.Format.FilterSet { 4 | /// 5 | /// Thrown when can't be used, because the band count is dependent on channels more than 6 | /// just having a different main/LFE band count. In this case, use . 7 | /// 8 | public class ChannelDependentBandCountException : Exception { 9 | const string message = "The band count is dependent on the channel."; 10 | 11 | /// 12 | /// Thrown when can't be used, because the band count is dependent on channels more than 13 | /// just having a different main/LFE band count. In this case, use . 14 | /// 15 | public ChannelDependentBandCountException() : base(message) { } 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /CavernSamples/Reusable/Cavernize.Logic/CommandLine/HiddenCommands/RenderGainCommand.cs: -------------------------------------------------------------------------------- 1 | using Cavern.Utilities; 2 | 3 | using Cavernize.Logic.Models; 4 | 5 | namespace Cavernize.Logic.CommandLine.HiddenCommands; 6 | 7 | /// 8 | /// Adds additional gain to renders. 9 | /// 10 | sealed class RenderGainCommand : UnsafeCommand { 11 | /// 12 | public override string Name => "--render-gain"; 13 | 14 | /// 15 | public override int Parameters => 1; 16 | 17 | /// 18 | public override string Help => "Applies additional gain to the content volume in decibels."; 19 | 20 | /// 21 | public override void Execute(string[] args, int offset, ICavernizeApp app) { 22 | if (!QMath.TryParseFloat(args[offset], out float attenuation)) { 23 | throw new CommandException($"The provided render gain ({args[offset]}) is not a number."); 24 | } 25 | app.RenderGain = QMath.DbToGain(attenuation); 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /CavernSamples/Reusable/Cavernize.Logic/CommandLine/HiddenCommands/OverrideBedReader.cs: -------------------------------------------------------------------------------- 1 | using Cavern.Format; 2 | using Cavern.Format.Utilities; 3 | 4 | namespace Cavernize.Logic.CommandLine.HiddenCommands; 5 | 6 | /// 7 | /// Enhanced AC-3 file reader that reads the PCM data from another file. 8 | /// 9 | /// Path of the original E-AC-3 file 10 | /// Stream to override the PCM data with - only applies to the source PCM data, 11 | /// not the JOC-decoded objects 12 | sealed class OverrideBedReader(string path, AudioReader overrider) : EnhancedAC3Reader(path) { 13 | /// 14 | /// Read the file header. 15 | /// 16 | public override void ReadHeader() { 17 | decoder = new OverrideBedDecoder(BlockBuffer.Create(reader, 10 * 1024 * 1024), fileSize, overrider); 18 | ChannelCount = decoder.ChannelCount; 19 | Length = decoder.Length; 20 | SampleRate = decoder.SampleRate; 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /Tests/Test.Cavern/Consts/Generators.cs: -------------------------------------------------------------------------------- 1 | using Cavern.Utilities; 2 | 3 | namespace Test.Cavern { 4 | /// 5 | /// Functions that generate test data. 6 | /// 7 | public static class Generators { 8 | /// 9 | /// Generates a one period sine wave. 10 | /// 11 | public static float[] Sine(int length) { 12 | float[] result = new float[length]; 13 | for (int i = 0; i < length; i++) { 14 | result[i] = MathF.Cos(2 * MathF.PI * i / length); 15 | } 16 | return result; 17 | } 18 | 19 | /// 20 | /// Generates a Dirac-delta in Fourier-space (constant 1). 21 | /// 22 | public static Complex[] DiracFourier(int length) { 23 | Complex[] result = new Complex[length]; 24 | for (int i = 0; i < length; i++) { 25 | result[i].Real = 1; 26 | } 27 | return result; 28 | } 29 | } 30 | } -------------------------------------------------------------------------------- /CavernSamples/CavernizeGUI/UserControls/TextWithIcon.xaml.cs: -------------------------------------------------------------------------------- 1 | using System.Windows.Controls; 2 | using System.Windows.Media; 3 | 4 | namespace CavernizeGUI.UserControls { 5 | /// 6 | /// An icon and a text in a single control. 7 | /// 8 | public partial class TextWithIcon : UserControl { 9 | /// 10 | /// The displayed text of the item that needs both a text and an icon. 11 | /// 12 | public string Text { 13 | get => text.Text; 14 | set => text.Text = value; 15 | } 16 | 17 | /// 18 | /// Icon displayed on the left of the . 19 | /// 20 | public ImageSource Icon { 21 | get => icon.Source; 22 | set => icon.Source = value; 23 | } 24 | 25 | /// 26 | /// An icon and a text in a single control. 27 | /// 28 | public TextWithIcon() => InitializeComponent(); 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /CavernSamples/Reusable/Cavernize.Logic/CommandLine/HiddenCommands/OverrideBedDecoder.cs: -------------------------------------------------------------------------------- 1 | using Cavern.Format; 2 | using Cavern.Format.Decoders; 3 | using Cavern.Format.Utilities; 4 | 5 | namespace Cavernize.Logic.CommandLine.HiddenCommands; 6 | 7 | /// 8 | /// Converts an Enhanced AC-3 bitstream to raw samples, replaces the PCM data with external. 9 | /// 10 | /// Accesses the linear E-AC-3 bitstream 11 | /// Length of the E-AC-3 bitstream 12 | /// Stream to override the PCM data with - only applies to the source PCM data, 13 | /// not the JOC-decoded objects 14 | sealed class OverrideBedDecoder(BlockBuffer reader, long fileSize, AudioReader overrider) : EnhancedAC3Decoder(reader, fileSize) { 15 | /// 16 | protected override float[] DecodeFrame() { 17 | float[] result = base.DecodeFrame(); 18 | overrider?.ReadBlock(result, 0, result.Length); 19 | return result; 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /CavernSamples/Reusable/Cavernize.Logic/CommandLine/Force24BitCommand.cs: -------------------------------------------------------------------------------- 1 | using Cavernize.Logic.CommandLine.BaseClasses; 2 | using Cavernize.Logic.Models; 3 | 4 | namespace Cavernize.Logic.CommandLine; 5 | 6 | /// 7 | /// Forces 24-bit export for formats that support it, like WAV or LAF. 8 | /// 9 | sealed class Force24BitCommand : Command { 10 | /// 11 | public override string Name => "-force_24_bit"; 12 | 13 | /// 14 | public override string Alias => "-f24"; 15 | 16 | /// 17 | public override int Parameters => 0; 18 | 19 | /// 20 | public override string Help => "Forces 24-bit export for formats that support it, like WAV or LAF."; 21 | 22 | /// 23 | public override void Execute(string[] args, int offset, ICavernizeApp app) { 24 | if (app.Rendering) { 25 | InProgressError(app, "forcing 24-bit"); 26 | } 27 | 28 | app.SpecialRenderModeSettings.MuteBed = true; 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /Libraries/Cavern.WPF/Resources/UpmixingSetupStrings.hu-HU.xaml: -------------------------------------------------------------------------------- 1 | 4 | Felkeverési beállítások 5 | 7.1 kitöltése 6 | Mátrixfelkeveréssel kihasználja a teljes 7.1 alapot hagyományos csatornaalapú tartalmaknál. 7 | Nem térbeli tartalom felkonvertálása 8 | Megpróbálja kitalálni a magassági információt hagyományos tartalmakhoz, maximum 7.1-ig. 9 | Felkeverés ereje: 10 | Felkeverés folytonossága: 11 | Alaphelyzet 12 | -------------------------------------------------------------------------------- /CavernSamples/ImpulseFlattener/Settings.settings: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | False 7 | 8 | 9 | True 10 | 11 | 12 | False 13 | 14 | 15 | False 16 | 17 | 18 | True 19 | 20 | 21 | -------------------------------------------------------------------------------- /Cavern.Format/Container/MP4/TimeToSampleBox.cs: -------------------------------------------------------------------------------- 1 | using System.IO; 2 | 3 | using Cavern.Format.Utilities; 4 | 5 | using static Cavern.Format.Consts.MP4Consts; 6 | 7 | namespace Cavern.Format.Container.MP4 { 8 | /// 9 | /// Contains how many consecutive samples have a given duration. This is used for seeking. 10 | /// 11 | internal class TimeToSampleBox : Box { 12 | /// 13 | /// Contains how many consecutive samples have a given duration. This is used for seeking. 14 | /// 15 | public readonly (uint sampleCount, uint duration)[] durations; 16 | 17 | public TimeToSampleBox(uint length, Stream reader) : base(length, timeToSampleBox, reader) { 18 | reader.Position += 4; // Version byte and zero flags 19 | durations = new (uint, uint)[reader.ReadUInt32BE()]; 20 | for (int i = 0; i < durations.Length; i++) { 21 | durations[i] = (reader.ReadUInt32BE(), reader.ReadUInt32BE()); 22 | } 23 | } 24 | } 25 | } -------------------------------------------------------------------------------- /CavernSamples/Reusable/Cavernize.Logic/CavernSettings/SpecialRenderModeSettings.cs: -------------------------------------------------------------------------------- 1 | using Cavern; 2 | 3 | namespace Cavernize.Logic.CavernSettings; 4 | 5 | /// 6 | /// Holds settings for rendering modifiers regarding a conversion. 7 | /// 8 | public class SpecialRenderModeSettings { 9 | /// 10 | /// Virtualize and downmix elevated objects to ground-only layouts by practically applying HRTFs on height channels. 11 | /// 12 | public virtual bool SpeakerVirtualizer { get; set; } 13 | 14 | /// 15 | /// Mute s at reference channel positions. 16 | /// 17 | public virtual bool MuteBed { get; set; } 18 | 19 | /// 20 | /// Mute s which have no elevation. 21 | /// 22 | public virtual bool MuteGround { get; set; } 23 | 24 | /// 25 | /// Forces 24-bit export for formats that support it, like WAV or LAF. 26 | /// 27 | public virtual bool Force24Bit { get; set; } 28 | } 29 | -------------------------------------------------------------------------------- /Tests/Test.Cavern/ComplexArray_Tests.cs: -------------------------------------------------------------------------------- 1 | using Cavern.Utilities; 2 | 3 | using Test.Cavern.Filters; 4 | 5 | namespace Test.Cavern { 6 | /// 7 | /// Tests the class. 8 | /// 9 | [TestClass] 10 | public class ComplexArray_Tests { 11 | /// 12 | /// Tests the method. 13 | /// 14 | /// Further convolution tests are under . 15 | [TestMethod, Timeout(1000)] 16 | public void Convolve() { 17 | const int length = 32; 18 | Complex[] lhs = Generators.DiracFourier(length), 19 | rhs = Generators.Sine(length).ParseForFFT(); 20 | lhs.Convolve(rhs); 21 | CollectionAssert.AreEqual(lhs, rhs); 22 | 23 | lhs.SetToDiracDelta(); 24 | rhs.SwapDimensions(); 25 | lhs.Convolve(rhs); 26 | CollectionAssert.AreEqual(lhs, rhs); 27 | } 28 | } 29 | } -------------------------------------------------------------------------------- /Cavern.QuickEQ.Format/FilterSet/AcurusMuseFilterSet.cs: -------------------------------------------------------------------------------- 1 | using Cavern.Channels; 2 | 3 | namespace Cavern.Format.FilterSet { 4 | /// 5 | /// IIR filter set for Acurus Muse processors. 6 | /// 7 | public class AcurusMuseFilterSet : IIRFilterSet { 8 | /// 9 | public override int Bands => 5; 10 | 11 | /// 12 | public override double MinGain => -12; 13 | 14 | /// 15 | public override double MaxGain => 6; 16 | 17 | /// 18 | public override double GainPrecision => .5; 19 | 20 | /// 21 | /// IIR filter set for Acurus Muse processors. 22 | /// 23 | public AcurusMuseFilterSet(int channels, int sampleRate) : base(channels, sampleRate) { } 24 | 25 | /// 26 | /// IIR filter set for Acurus Muse processors. 27 | /// 28 | public AcurusMuseFilterSet(ReferenceChannel[] channels, int sampleRate) : base(channels, sampleRate) { } 29 | } 30 | } -------------------------------------------------------------------------------- /CavernSamples/EQAPOtoFIR/Dialogs/SegmentsDialog.xaml: -------------------------------------------------------------------------------- 1 | 10 | 11 |