├── 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 |
12 |
14 |
15 |
16 |
17 |
--------------------------------------------------------------------------------
/LICENSE.md:
--------------------------------------------------------------------------------
1 | # Cavern licence
2 | By downloading, using, copying, modifying, or compiling the source code or a
3 | build, you are accepting these terms. The source code, just like the compiled
4 | software, is given to you for free, but without any warranty. It is not
5 | guaranteed to work, and the developer is not responsible for any damages from
6 | the use of the software. You are allowed to make any modifications, and release
7 | them for free under this licence. If you release a modified version, you have to
8 | link this repository as its source. You are not allowed to sell any part of the
9 | original or the modified version. You are also not allowed to show
10 | advertisements in the modified software. The software must be named with a link
11 | to the creator (http://en.sbence.hu) when used in public (e.g. for screenings)
12 | or commercially (e.g. as an API in another software), also, the original
13 | creator's permission is required for public use (e.g. screening). If you include
14 | these code or any part of the original version in any other project, these terms
15 | still apply.
16 |
--------------------------------------------------------------------------------
/docs/NuGet Licence.md:
--------------------------------------------------------------------------------
1 | By downloading, using, copying, modifying, or compiling the source code or a
2 | build, you are accepting these terms. The source code, just like the compiled
3 | software, is given to you for free, but without any warranty. It is not
4 | guaranteed to work, and the developer is not responsible for any damages from
5 | the use of the software. You are allowed to make any modifications, and release
6 | them for free under this licence. If you release a modified version, you have to
7 | link the VoidXH/Cavern GitHub repository as its source. You are not allowed to
8 | sell any part of the original or the modified version. You are also not allowed
9 | to show advertisements in the modified software. The software must be named with
10 | a link to the creator (https://en.sbence.hu) when used in public (e.g. for
11 | screenings) or commercially (e.g. as an API in another software), also, the
12 | original creator's permission is required for public use (e.g. screening). If
13 | you include these code or any part of the original version in any other project,
14 | these terms still apply.
15 |
--------------------------------------------------------------------------------
/CavernSamples/Reusable/Cavernize.Logic/CommandLine/BaseClasses/IntegerCommand.cs:
--------------------------------------------------------------------------------
1 | using Cavernize.Logic.Models;
2 |
3 | namespace Cavernize.Logic.CommandLine.BaseClasses;
4 |
5 | ///
6 | /// A command with a single integer parameter.
7 | ///
8 | public abstract class IntegerCommand : Command {
9 | ///
10 | public sealed override int Parameters => 1;
11 |
12 | ///
13 | /// Execute the command.
14 | ///
15 | /// The value supplied
16 | /// Reference to the application to perform setting changes and operations
17 | public abstract void Execute(int value, ICavernizeApp app);
18 |
19 | ///
20 | public sealed override void Execute(string[] args, int offset, ICavernizeApp app) {
21 | if (int.TryParse(args[offset], out int value)) {
22 | Execute(value, app);
23 | return;
24 | }
25 |
26 | throw new CommandException($"Invalid parameter for {Name}, {args[offset]} is not an integer.");
27 | }
28 | }
29 |
--------------------------------------------------------------------------------
/Tests/Test.Cavern.QuickEQ/Crossover/CrossoverAnalyzer_Tests.cs:
--------------------------------------------------------------------------------
1 | using Cavern.QuickEQ.Crossover;
2 | using Cavern.Utilities;
3 |
4 | namespace Test.Cavern.QuickEQ.Crossover {
5 | ///
6 | /// Tests the class.
7 | ///
8 | [TestClass]
9 | public class CrossoverAnalyzer_Tests {
10 | ///
11 | /// Tests if works as intended.
12 | ///
13 | [TestMethod, Timeout(1000)]
14 | public void FindCrossoverFrequency() {
15 | BasicCrossover crossover = new(null, null);
16 | using FFTCache cache = new(512);
17 | const int sampleRate = 500;
18 | Complex[] high = crossover.GetHighpass(sampleRate, 80, cache.Size).FFT(cache),
19 | low = crossover.GetLowpass(sampleRate, 80, cache.Size).FFT(cache);
20 | float freq = CrossoverAnalyzer.FindCrossoverFrequency(crossover, low, high, sampleRate, 40, 120, 10);
21 | Assert.AreEqual(70, freq);
22 | }
23 | }
24 | }
--------------------------------------------------------------------------------
/CavernSamples/Reusable/Cavernize.Logic/CommandLine/HelpCommand.cs:
--------------------------------------------------------------------------------
1 | using Cavernize.Logic.CommandLine.BaseClasses;
2 | using Cavernize.Logic.Models;
3 |
4 | namespace Cavernize.Logic.CommandLine;
5 |
6 | ///
7 | /// Lists all available commands.
8 | ///
9 | sealed class HelpCommand : Command {
10 | ///
11 | public override string Name => "-help";
12 |
13 | ///
14 | public override string Alias => "-h";
15 |
16 | ///
17 | public override int Parameters => 0;
18 |
19 | ///
20 | public override string Help => "Lists all available commands.";
21 |
22 | ///
23 | public override void Execute(string[] args, int offset, ICavernizeApp app) {
24 | Command[] pool = CommandPool;
25 | for (int i = 0; i < pool.Length; i++) {
26 | if (pool[i] is not HiddenCommand) {
27 | Console.WriteLine($"{pool[i].Name} ({pool[i].Alias})\t: {pool[i].Help}");
28 | }
29 | }
30 | throw new CommandProcessingCanceledException();
31 | }
32 | }
33 |
--------------------------------------------------------------------------------
/Cavern/SpecialSources/MuteSource.cs:
--------------------------------------------------------------------------------
1 | namespace Cavern.SpecialSources {
2 | ///
3 | /// A source that plays silence.
4 | ///
5 | public class MuteSource : StreamedSource {
6 | ///
7 | /// Empty cache to return.
8 | ///
9 | MultichannelWaveform samples = new MultichannelWaveform(1, 0);
10 |
11 | ///
12 | /// A source that plays silence.
13 | ///
14 | /// Take the listener's sample rate to prevent redundant resampling calls
15 | public MuteSource(Listener listener) {
16 | Clip = new Clip(samples, listener.SampleRate);
17 | }
18 |
19 | ///
20 | /// Get the next samples in the audio stream.
21 | ///
22 | protected internal override MultichannelWaveform GetSamples() {
23 | if (samples[0].Length != PitchedUpdateRate) {
24 | samples = new MultichannelWaveform(1, PitchedUpdateRate);
25 | }
26 | return samples;
27 | }
28 | }
29 | }
--------------------------------------------------------------------------------
/CavernSamples/VoidX.WPF/FFmpeg/FFmpegArgument.cs:
--------------------------------------------------------------------------------
1 | using System.Text;
2 |
3 | namespace VoidX.WPF.FFmpeg;
4 |
5 | ///
6 | /// A single FFmpeg argument as a key-value pair.
7 | ///
8 | public readonly struct FFmpegArgument(string key, string value) {
9 | ///
10 | /// FFmpeg command line argument name.
11 | ///
12 | public readonly string key = key;
13 |
14 | ///
15 | /// Value to be passed for this argument.
16 | ///
17 | public readonly string value = value;
18 |
19 | ///
20 | /// Append this argument to a set of arguments under constructions.
21 | ///
22 | public void ToString(StringBuilder builder) {
23 | builder.Append(key);
24 | builder.Append(' ');
25 | if (string.IsNullOrEmpty(value)) {
26 | return;
27 | }
28 |
29 | if (value.Contains(' ')) {
30 | builder.Append('"').Append(value.Replace("\"", "\\\"")).Append('"');
31 | } else {
32 | builder.Append(value);
33 | }
34 | builder.Append(' ');
35 | }
36 | }
--------------------------------------------------------------------------------
/Cavern.Format/Container/Matroska/MatroskaTrack.cs:
--------------------------------------------------------------------------------
1 | using Cavern.Format.Common;
2 |
3 | namespace Cavern.Format.Container.Matroska {
4 | ///
5 | /// Track data for a , containing read positions.
6 | ///
7 | internal class MatroskaTrack : Track {
8 | ///
9 | /// Currently read cluster.
10 | ///
11 | internal int lastCluster;
12 |
13 | ///
14 | /// Last read block in the current cluster.
15 | ///
16 | internal int lastBlock;
17 |
18 | ///
19 | /// Create a track to be placed in the list of a container's tracks.
20 | ///
21 | /// The container containing this track.
22 | /// The position of the track in the container's list of tracks.
23 | /// The required for reading from the container.
24 | internal MatroskaTrack(ContainerReader source, int trackNumber) : base(source, trackNumber) { }
25 | }
26 | }
--------------------------------------------------------------------------------
/CavernUnity DLL/QuickEQ/NoisyChannel.cs:
--------------------------------------------------------------------------------
1 | using System.Diagnostics.CodeAnalysis;
2 | using UnityEngine;
3 |
4 | using Cavern.QuickEQ.SignalGeneration;
5 |
6 | namespace Cavern.QuickEQ {
7 | ///
8 | /// Generates noise on the selected output channel.
9 | ///
10 | [AddComponentMenu("Audio/QuickEQ/Noisy Channel")]
11 | public class NoisyChannel : AudioSource3D {
12 | ///
13 | /// Target output channel.
14 | ///
15 | [Header("Noisy channel")]
16 | [Tooltip("Target output channel.")]
17 | public int Channel;
18 |
19 | ///
20 | /// Generates noise on the selected output channel.
21 | ///
22 | [SuppressMessage("CodeQuality", "IDE0051:Remove unused private members", Justification = "Used by Unity lifecycle")]
23 | void Awake() => cavernSource = new NoiseGenerator();
24 |
25 | [SuppressMessage("CodeQuality", "IDE0051:Remove unused private members", Justification = "Used by Unity lifecycle")]
26 | void LateUpdate() => ((NoiseGenerator)cavernSource).channel = Channel;
27 | }
28 | }
--------------------------------------------------------------------------------
/Tests/Test.Cavern.QuickEQ/PeakingEqualizer_Tests.cs:
--------------------------------------------------------------------------------
1 | using Cavern.Filters;
2 | using Cavern.QuickEQ.Equalization;
3 |
4 | namespace Test.Cavern.QuickEQ {
5 | ///
6 | /// Tests the class.
7 | ///
8 | [TestClass]
9 | public class PeakingEqualizer_Tests {
10 | ///
11 | /// Tests if the private method brute forcing gains works as intended.
12 | ///
13 | [TestMethod, Timeout(10000)]
14 | public void BruteForceGains() {
15 | Equalizer slash = new Equalizer();
16 | slash.AddBand(new Band(20, 0));
17 | slash.AddBand(new Band(20000, 10));
18 | PeakingEqualizer peq = new PeakingEqualizer(slash) {
19 | MinGain = -6,
20 | MaxGain= 6,
21 | };
22 | PeakingEQ[] result = peq.GetPeakingEQ(48000, 31.25, 1, 10);
23 | for (int i = 1; i < result.Length; i++) {
24 | Assert.IsTrue(result[i - 1].Gain - .05f /* eps */ < result[i].Gain); // The gains in a slash EQ have to grow
25 | }
26 | }
27 | }
28 | }
--------------------------------------------------------------------------------
/Cavern.Format/Transcoders/EnhancedAC3Body/AllocationHistory.cs:
--------------------------------------------------------------------------------
1 | namespace Cavern.Format.Transcoders {
2 | // Contains the last read common data shared between all allocations.
3 | partial class EnhancedAC3Body {
4 | ///
5 | /// Index of the next mantissa in .
6 | ///
7 | public int bap1Pos;
8 |
9 | ///
10 | /// Index of the next mantissa in .
11 | ///
12 | public int bap2Pos;
13 |
14 | ///
15 | /// Index of the next mantissa in .
16 | ///
17 | public int bap4Pos;
18 |
19 | ///
20 | /// Next mantissa values in case the bap is 1.
21 | ///
22 | public int[] bap1Next;
23 |
24 | ///
25 | /// Next mantissa values in case the bap is 2.
26 | ///
27 | public int[] bap2Next;
28 |
29 | ///
30 | /// Next mantissa values in case the bap is 4.
31 | ///
32 | public int[] bap4Next;
33 | }
34 | }
--------------------------------------------------------------------------------
/CavernSamples/CavernPipeServer.Windows/MainWindow.xaml:
--------------------------------------------------------------------------------
1 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
--------------------------------------------------------------------------------
/Cavern.Format/Consts/LimitlessAudioFormatConsts.cs:
--------------------------------------------------------------------------------
1 | namespace Cavern.Format.Consts {
2 | ///
3 | /// Used for both and .
4 | ///
5 | internal static class LimitlessAudioFormatConsts {
6 | ///
7 | /// First half of the LIMITLESS word as a single int for quick format detection.
8 | ///
9 | public const int syncWord = 0x494D494C;
10 |
11 | ///
12 | /// Limitless Audio Format indicator starting bytes, first 4.
13 | ///
14 | public static readonly byte[] limitless1 = { (byte)'L', (byte)'I', (byte)'M', (byte)'I' };
15 |
16 | ///
17 | /// Limitless Audio Format indicator starting bytes, following 5.
18 | ///
19 | public static readonly byte[] limitless2 = { (byte)'T', (byte)'L', (byte)'E', (byte)'S', (byte)'S' };
20 |
21 | ///
22 | /// Header marker bytes.
23 | ///
24 | public static readonly byte[] head = { (byte)'H', (byte)'E', (byte)'A', (byte)'D' };
25 | }
26 | }
--------------------------------------------------------------------------------
/Cavern.QuickEQ.Format/FilterSet/WiiMFilterSet.cs:
--------------------------------------------------------------------------------
1 | using System.IO;
2 |
3 | using Cavern.Channels;
4 |
5 | namespace Cavern.Format.FilterSet {
6 | ///
7 | /// IIR filter set for WiiM devices.
8 | ///
9 | internal class WiiMFilterSet : IIRFilterSet {
10 | ///
11 | public override int Bands => 10;
12 |
13 | ///
14 | public override double MinGain => -12;
15 |
16 | ///
17 | public override double MaxGain => 12;
18 |
19 | ///
20 | public override double GainPrecision => .1f;
21 |
22 | ///
23 | /// IIR filter set for WiiM devices.
24 | ///
25 | public WiiMFilterSet(int channels, int sampleRate) : base(channels, sampleRate) { }
26 |
27 | ///
28 | /// IIR filter set for WiiM devices.
29 | ///
30 | public WiiMFilterSet(ReferenceChannel[] channels, int sampleRate) : base(channels, sampleRate) { }
31 |
32 | ///
33 | public override void Export(string path) => File.WriteAllText(path, Export(false));
34 | }
35 | }
--------------------------------------------------------------------------------
/CavernSamples/CavernPipeClient/CavernPipeClient.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 | Exe
4 | net8.0
5 | enable
6 | disable
7 | VoidX
8 | CavernPipe Client
9 | Reference implementation of the CavernPipe protocol with rendering content according to Cavern settings on the network.
10 | Copyright © Bence Sgánetz 2016-2025
11 | https://cavern.sbence.hu/
12 | https://github.com/VoidXH/Cavern/
13 | git
14 | en
15 | ..\Icon.ico
16 |
17 |
18 |
19 | false
20 | none
21 | true
22 |
23 |
24 |
25 |
26 |
27 |
--------------------------------------------------------------------------------
/CavernSamples/FilterStudio/Windows/ConvolutionLengthDialog.xaml.cs:
--------------------------------------------------------------------------------
1 | using System;
2 |
3 | using Cavern.WPF.BaseClasses;
4 |
5 | namespace FilterStudio.Windows {
6 | ///
7 | /// Shows a filter length selector when converting a filter graph to convolution filters.
8 | ///
9 | public partial class ConvolutionLengthDialog : OkCancelDialog {
10 | ///
11 | /// The user-selected number of convolution samples per filter.
12 | ///
13 | public int Size => size.Value;
14 |
15 | ///
16 | /// Shows a filter length selector when converting a filter graph to convolution filters.
17 | ///
18 | public ConvolutionLengthDialog() {
19 | Resources.MergedDictionaries.Add(new() {
20 | Source = new Uri($";component/Resources/Styles.xaml", UriKind.RelativeOrAbsolute)
21 | });
22 | Resources.MergedDictionaries.Add(Consts.Language.GetConvolutionLengthDialogStrings());
23 | Resources.MergedDictionaries.Add(Cavern.WPF.Consts.Language.GetCommonStrings());
24 | InitializeComponent();
25 | }
26 | }
27 | }
--------------------------------------------------------------------------------
/Cavern.QuickEQ.Format/FilterSet/AUNBandEQ.cs:
--------------------------------------------------------------------------------
1 | using System.IO;
2 |
3 | using Cavern.Channels;
4 |
5 | namespace Cavern.Format.FilterSet {
6 | ///
7 | /// IIR filter set for AU N-Band EQ software.
8 | ///
9 | public class AUNBandEQ : IIRFilterSet {
10 | ///
11 | public override int Bands => 16;
12 |
13 | ///
14 | public override double MinGain => -96;
15 |
16 | ///
17 | public override double MaxGain => 24;
18 |
19 | ///
20 | public override double GainPrecision => .1;
21 |
22 | ///
23 | /// IIR filter set for AU N-Band EQ software.
24 | ///
25 | public AUNBandEQ(int channels, int sampleRate) : base(channels, sampleRate) { }
26 |
27 | ///
28 | /// IIR filter set for AU N-Band EQ software.
29 | ///
30 | public AUNBandEQ(ReferenceChannel[] channels, int sampleRate) : base(channels, sampleRate) { }
31 |
32 | ///
33 | public override void Export(string path) => File.WriteAllText(path, Export(false));
34 | }
35 | }
--------------------------------------------------------------------------------
/CavernSamples/CavernPipeServer.Windows/ThreadSafeChannelMeters.cs:
--------------------------------------------------------------------------------
1 | using System.Windows.Controls;
2 |
3 | namespace CavernPipeServer.Windows;
4 |
5 | ///
6 | /// Multithreaded version of , for use outside dispatchers.
7 | ///
8 | /// Add meters as children of this control
9 | /// Reference channel name display
10 | /// Reference meter display
11 | public class ThreadSafeChannelMeters(Panel canvas, TextBlock labelProto, ProgressBar barProto) : ChannelMeters(canvas, labelProto, barProto) {
12 | ///
13 | public override void Enable() {
14 | lock (canvas) {
15 | canvas.Dispatcher.Invoke(base.Enable);
16 | }
17 | }
18 |
19 | ///
20 | public override void Disable() {
21 | lock (canvas) {
22 | canvas.Dispatcher.Invoke(base.Disable);
23 | }
24 | }
25 |
26 | ///
27 | protected override void UpdateUI(float[] meters) {
28 | lock (canvas) {
29 | canvas.Dispatcher.Invoke(base.UpdateUI, meters);
30 | }
31 | }
32 | }
33 |
--------------------------------------------------------------------------------
/CavernSamples/VoidX.WPF/NumericUpDown.xaml:
--------------------------------------------------------------------------------
1 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
--------------------------------------------------------------------------------
/Tests/Test.Cavern/QMath_Tests.cs:
--------------------------------------------------------------------------------
1 | using Cavern.Filters.Utilities;
2 | using Cavern.Utilities;
3 |
4 | namespace Test.Cavern {
5 | ///
6 | /// Tests the class.
7 | ///
8 | [TestClass]
9 | public class QMath_Tests {
10 | ///
11 | /// Tests if works correctly.
12 | ///
13 | [TestMethod, Timeout(1000)]
14 | public void ToStringLimitDecimals() {
15 | Assert.AreEqual("0", QMath.ToStringLimitDecimals(1E-10, 5));
16 | Assert.AreEqual("0.2", QMath.ToStringLimitDecimals(0.15, 1));
17 | Assert.AreEqual("0.707", QMath.ToStringLimitDecimals(QFactor.reference, 3));
18 | }
19 |
20 | ///
21 | /// Tests if works correctly.
22 | ///
23 | [TestMethod, Timeout(1000)]
24 | public void TrailingZeros() {
25 | Assert.AreEqual(0, QMath.TrailingZeros(int.MaxValue));
26 | Assert.AreEqual(3, QMath.TrailingZeros(8));
27 | Assert.AreEqual(4, QMath.TrailingZeros(2064));
28 | }
29 | }
30 | }
--------------------------------------------------------------------------------
/Tests/Test.Cavern.QuickEQ/Consts/TestUtils.cs:
--------------------------------------------------------------------------------
1 | namespace Test.Cavern.QuickEQ {
2 | ///
3 | /// Common utilities used in testing like assertions.
4 | ///
5 | internal static class TestUtils {
6 | ///
7 | /// Test if an between the given limits is strictly monotonously decreasing,
8 | /// but allowing an error margin of .
9 | ///
10 | public static void AssertDecrease(float[] array, int from, int to, float delta) {
11 | for (int i = from + 1; i < to; i++) {
12 | if (array[i - 1] + delta <= array[i]) {
13 | Assert.Fail();
14 | }
15 | }
16 | }
17 |
18 | ///
19 | /// Test if all values of both arrays are in the expected margin of error () from each other.
20 | ///
21 | public static void AssertArrayEquals(float[] expected, float[] actual, float delta) {
22 | for (int i = 0; i < expected.Length; i++) {
23 | Assert.AreEqual(expected[i], actual[i], delta);
24 | }
25 | }
26 | }
27 | }
--------------------------------------------------------------------------------
/CavernSamples/Reusable/Cavernize.Logic/Models/RenderTargets/DriverRenderTarget.cs:
--------------------------------------------------------------------------------
1 | using Cavern;
2 | using Cavern.Channels;
3 |
4 | namespace Cavernize.Logic.Models.RenderTargets;
5 |
6 | ///
7 | /// Applies the layout that's set up in the Cavern Driver.
8 | ///
9 | public class DriverRenderTarget : RenderTarget {
10 | ///
11 | /// Applies the layout that's set up in the Cavern Driver.
12 | ///
13 | public DriverRenderTarget() : base(targetName, GetChannels()) { }
14 |
15 | ///
16 | /// Gets the channels set up in the Cavern Driver.
17 | ///
18 | static ReferenceChannel[] GetChannels() {
19 | new Listener();
20 | ReferenceChannel[] result = new ReferenceChannel[Listener.Channels.Length];
21 | for (int i = 0; i < result.Length; i++) {
22 | result[i] = ChannelPrototype.GetReference(Listener.Channels[i]);
23 | }
24 | return result;
25 | }
26 |
27 | ///
28 | public override void Apply(bool _) => new Listener();
29 |
30 | ///
31 | /// Name of this render target.
32 | ///
33 | const string targetName = "Cavern Driver";
34 | }
35 |
--------------------------------------------------------------------------------
/Cavern.QuickEQ.Format/FilterSet/Multiband10FilterSet.cs:
--------------------------------------------------------------------------------
1 | using Cavern.Channels;
2 |
3 | namespace Cavern.Format.FilterSet {
4 | ///
5 | /// Traditional 31-band graphic equalizer.
6 | ///
7 | public class Multiband10FilterSet : MultibandPEQFilterSet {
8 | ///
9 | public override int LFEBands => 3;
10 |
11 | ///
12 | public Multiband10FilterSet(string path, int sampleRate) : base(path, sampleRate) { }
13 |
14 | ///
15 | public Multiband10FilterSet(int channels, int sampleRate) : this(channels, sampleRate, true) { }
16 |
17 | ///
18 | public Multiband10FilterSet(int channels, int sampleRate, bool roundedBands) :
19 | base(channels, sampleRate, 31.25, 1, 10, roundedBands) { }
20 |
21 | ///
22 | public Multiband10FilterSet(ReferenceChannel[] channels, int sampleRate) : this(channels, sampleRate, true) { }
23 |
24 | ///
25 | public Multiband10FilterSet(ReferenceChannel[] channels, int sampleRate, bool roundedBands) :
26 | base(channels, sampleRate, 31.25, 1, 10, roundedBands) { }
27 | }
28 | }
29 |
--------------------------------------------------------------------------------
/Cavern.QuickEQ.Format/FilterSet/YPAOLiteFilterSet.cs:
--------------------------------------------------------------------------------
1 | using Cavern.Channels;
2 |
3 | namespace Cavern.Format.FilterSet {
4 | ///
5 | /// Filter set limited to 4/3 octave band choices for Yamaha CX-A series amplifiers.
6 | ///
7 | public class YPAOLiteFilterSet : MultibandPEQFilterSet {
8 | ///
9 | public override int LFEBands => 2;
10 |
11 | ///
12 | public override double MinGain => -6;
13 |
14 | ///
15 | public override double GainPrecision => .5;
16 |
17 | ///
18 | public override bool RoundedBands => true;
19 |
20 | ///
21 | /// Filter set limited to 4/3 octave band choices for Yamaha CX-A series amplifiers.
22 | ///
23 | public YPAOLiteFilterSet(int channels, int sampleRate) : base(channels, sampleRate, 62.5, .75, 7) { }
24 |
25 | ///
26 | /// Filter set limited to 4/3 octave band choices for Yamaha CX-A series amplifiers.
27 | ///
28 | public YPAOLiteFilterSet(ReferenceChannel[] channels, int sampleRate) : base(channels, sampleRate, 62.5, .75, 7) { }
29 | }
30 | }
--------------------------------------------------------------------------------
/docs/Format bitstream definitions/Convolution Box Format.md:
--------------------------------------------------------------------------------
1 | # Convolution Box Format Structure
2 | A file format for easy to implement DSP, only using channel copy and convolution
3 | filters. Channels are numbered from 0 to the number of system channels. Negative
4 | channel indices mean virtual channels, of which any number can be created.
5 | All values are little endian.
6 | * 4 bytes: "CBFM" marker (magic number: 0x4D464243)
7 | * 4 bytes: system sample rate, used for all convolutions
8 | * 4 bytes: number of filter entries
9 |
10 | For each filter entry:
11 | * 1 byte: filter type
12 | * 0 - Copy (matrix mixer) filter:
13 | * 4 bytes: number of copy operations
14 | * For each copy entry:
15 | * 4 bytes: source channel index
16 | * 4 bytes: number of target channels
17 | * Serially: 4 byte indices of all target channels
18 | * Merging of channels is allowed, but it is described in two distinct
19 | copy entries.
20 | * 1 - Convolution filter:
21 | * 4 bytes: index of the affected channel
22 | * 4 bytes: length of the convolution in samples (must be a power of 2)
23 | * Serially: single precision floating point samples of the filter
24 |
--------------------------------------------------------------------------------
/CavernAmp/measurements.h:
--------------------------------------------------------------------------------
1 | #ifndef MEASUREMENTS_H
2 | #define MEASUREMENTS_H
3 |
4 | #include "complex.h"
5 | #include "export.h"
6 | #include "fftcache.h"
7 |
8 | #ifdef __cplusplus
9 | extern "C" {
10 | #endif
11 |
12 | // Actual FFT processing, somewhat in-place.
13 | void DLL_EXPORT ProcessFFT(Complex *samples, int sampleCount, FFTCache *cache, int depth);
14 | // Fourier-transform a signal in 1D. The result is the spectral power.
15 | void DLL_EXPORT ProcessFFT1D(float *samples, int sampleCount, FFTCache *cache);
16 | // Fast Fourier transform a 2D signal while keeping the source array allocation.
17 | void DLL_EXPORT InPlaceFFT(Complex *samples, int sampleCount, FFTCache *cache);
18 | // Spectrum of a signal's FFT while keeping the source array allocation.
19 | void DLL_EXPORT InPlaceFFT1D(float *samples, int sampleCount, FFTCache *cache);
20 | // Outputs IFFT(X) * N.
21 | void DLL_EXPORT ProcessIFFT(Complex *samples, int sampleCount, FFTCache *cache, int depth);
22 | // Inverse Fast Fourier Transform of a transformed signal, while keeping the source array allocation.
23 | void DLL_EXPORT InPlaceIFFT(Complex *samples, int sampleCount, FFTCache *cache);
24 |
25 | #ifdef __cplusplus
26 | }
27 | #endif
28 |
29 | #endif // MEASUREMENTS_H
30 |
--------------------------------------------------------------------------------
/Cavern.Format/Container/MP4/ChunkOffsetBox.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 | /// Box of offsets for all chunks.
10 | ///
11 | internal class ChunkOffsetBox : Box {
12 | ///
13 | /// Start offset in the file for each chunk.
14 | ///
15 | public readonly ulong[] offsets;
16 |
17 | ///
18 | /// Box of offsets for all chunks.
19 | ///
20 | public ChunkOffsetBox(uint length, uint header, Stream reader) : base(length, header, reader) {
21 | reader.Position += 4; // Version byte and zero flags
22 | offsets = new ulong[reader.ReadUInt32BE()];
23 | if (header == chunkOffset32) {
24 | for (int i = 0; i < offsets.Length; i++) {
25 | offsets[i] = reader.ReadUInt32BE();
26 | }
27 | } else {
28 | for (int i = 0; i < offsets.Length; i++) {
29 | offsets[i] = reader.ReadUInt64BE();
30 | }
31 | }
32 | }
33 | }
34 | }
--------------------------------------------------------------------------------
/Cavern.Format/Transcoders/EnhancedAC3Enums.cs:
--------------------------------------------------------------------------------
1 | namespace Cavern.Format.Transcoders {
2 | static partial class EnhancedAC3 {
3 | ///
4 | /// Supported decoder versions.
5 | ///
6 | public enum Decoders {
7 | AlternateAC3 = 6,
8 | AC3 = 8,
9 | EAC3 = 16
10 | }
11 |
12 | ///
13 | /// Types of programs in a single frame of a stream.
14 | ///
15 | public enum StreamTypes {
16 | ///
17 | /// Main program, can be decoded on its own.
18 | ///
19 | Independent,
20 | ///
21 | /// Should be decoded with the associated independent substream.
22 | ///
23 | Dependent,
24 | ///
25 | /// This frame was converted from AC-3, the E-AC-3 extra data will follow.
26 | /// Usually used to go beyond 5.1, up to 16 discrete channels.
27 | ///
28 | Repackaged,
29 | ///
30 | /// Unused type.
31 | ///
32 | Reserved
33 | }
34 | }
35 | }
--------------------------------------------------------------------------------
/Tests/Test.Cavern/Filters/QFactor_Tests.cs:
--------------------------------------------------------------------------------
1 | using Cavern.Filters.Utilities;
2 |
3 | namespace Test.Cavern.Filters {
4 | ///
5 | /// Tests the class.
6 | ///
7 | [TestClass]
8 | public class QFactor_Tests {
9 | ///
10 | /// Tests if bandwidth conversions work correctly.
11 | ///
12 | [TestMethod, Timeout(1000)]
13 | public void Bandwidth() {
14 | const double inQ = 10,
15 | inBandwidth = 0.1442094593213907;
16 | Assert.AreEqual(inBandwidth, QFactor.ToBandwidth(inQ), Consts.delta);
17 | Assert.AreEqual(inQ, QFactor.FromBandwidth(inBandwidth), Consts.delta);
18 | }
19 |
20 | ///
21 | /// Tests if slope conversions work correctly.
22 | ///
23 | [TestMethod, Timeout(1000)]
24 | public void Slope() {
25 | const double inQ = 10,
26 | inSlope = 4.9293152597075665,
27 | gain = 6;
28 | Assert.AreEqual(inSlope, QFactor.ToSlope(inQ, gain), Consts.delta);
29 | Assert.AreEqual(inQ, QFactor.FromSlope(inSlope, gain), Consts.delta);
30 | }
31 | }
32 | }
--------------------------------------------------------------------------------
/CavernSamples/Reusable/CavernPipeServer.Logic/_Exceptions.cs:
--------------------------------------------------------------------------------
1 | namespace CavernPipeServer.Logic;
2 |
3 | ///
4 | /// Tells if CavernPipe is already running.
5 | ///
6 | public sealed class CavernPipeAlreadyRunningException(bool restarting) : Exception(restarting ? restartMessage : runningMessage) {
7 | ///
8 | /// The server is currently restarting, this is why it's not available.
9 | ///
10 | public bool Restarting { get; } = restarting;
11 |
12 | ///
13 | /// This error message is thrown when CavernPipe is already initializing by a different operation/host.
14 | ///
15 | const string restartMessage = "CavernPipe's restart is already in progress.";
16 |
17 | ///
18 | /// This error message is thrown when the pipe can't be created.
19 | ///
20 | const string runningMessage = "CavernPipe is already running, or a pipe called CavernPipe was created by a different application.";
21 | }
22 |
23 | ///
24 | /// Tells if CavernPipe failed to launch in the hardcoded timeout.
25 | ///
26 | public sealed class CavernPipeLaunchTimeoutException() : Exception($"CavernPipe failed to start in {PipeHandler.timeout} seconds.");
27 |
--------------------------------------------------------------------------------
/Cavern.QuickEQ/Crossover/BasicCrossover.cs:
--------------------------------------------------------------------------------
1 | using Cavern.Filters;
2 |
3 | namespace Cavern.QuickEQ.Crossover {
4 | ///
5 | /// A generic crossover used most of the time. This will use Equalizer APO's included lowpass/highpass filters to create the crossover,
6 | /// but that can be overridden to create any custom mains-to-LFE crossover function.
7 | ///
8 | public class BasicCrossover : Crossover {
9 | ///
10 | /// Create a biquad crossover with frequencies for each channel. Only values over 0 mean crossovered channels.
11 | ///
12 | /// Crossover frequencies for each channel, only values over 0 mean crossovered channels
13 | /// Channels to route bass to
14 | public BasicCrossover(float[] frequencies, bool[] subs) : base(frequencies, subs) { }
15 |
16 | ///
17 | public override Filter GetHighpassOptimized(int sampleRate, float frequency, int length) => new Highpass(sampleRate, frequency);
18 |
19 | ///
20 | public override Filter GetLowpassOptimized(int sampleRate, float frequency, int length) => new Lowpass(sampleRate, frequency);
21 | }
22 | }
--------------------------------------------------------------------------------
/Cavern.Format/Consts/MXFConsts.cs:
--------------------------------------------------------------------------------
1 | using Cavern.Format.Container.MXF;
2 |
3 | namespace Cavern.Format.Consts {
4 | ///
5 | /// Constant values used for Material eXchange Format.
6 | ///
7 | internal static class MXFConsts {
8 | ///
9 | /// The first 4 bytes of every MXF . Also the magic number for an MXF file.
10 | ///
11 | public const int universalLabel = 0x342B0E06;
12 |
13 | ///
14 | /// The first 4 bytes of every MXF as it's stored in the memory.
15 | ///
16 | public const int universalLabelLE = 0x060E2B34;
17 |
18 | ///
19 | /// Registry header of value dictionaries.
20 | ///
21 | public const int packRegistry = 0x02050101;
22 |
23 | ///
24 | /// Registry header of immersive audio elements.
25 | ///
26 | public const int immersiveAudioRegistry = 0x01020105;
27 |
28 | ///
29 | /// Marks an immersive audio essence block.
30 | ///
31 | public const ulong immersiveAudioEssence = 0x0E09060100000001;
32 | }
33 | }
--------------------------------------------------------------------------------
/CavernAmp/peakingEqualizer.h:
--------------------------------------------------------------------------------
1 | #ifndef PEAKINGEQUALIZER_H
2 | #define PEAKINGEQUALIZER_H
3 |
4 | #include "filterAnalyzer.h"
5 |
6 | #define LOG10_20 1.3010299956639811952137388947245
7 |
8 | struct PeakingEQ {
9 | double centerFreq;
10 | double q;
11 | double gain;
12 | };
13 |
14 | // Measure a filter candidate for "BruteForceQ".
15 | float BruteForceStepInternal(float *target, int targetLength, float *&changedTarget, FilterAnalyzer *analyzer);
16 |
17 | #ifdef __cplusplus
18 | extern "C" {
19 | #endif
20 |
21 | // Measure a filter candidate for "BruteForceQ".
22 | float DLL_EXPORT BruteForceStep(float *target, int targetLength, float *changedTarget, FilterAnalyzer *analyzer);
23 | // Find the filter with the best Q for the given frequency and gain in "target".
24 | // Correct "target" to the frequency response with the inverse of the found filter.
25 | PeakingEQ DLL_EXPORT BruteForceQ(float *target, int targetLength, FilterAnalyzer *analyzer, double freq, double gain);
26 | // Finds a PeakingEQ to correct the worst problem on the input spectrum.
27 | PeakingEQ DLL_EXPORT BruteForceBand(float *target, int targetLength, FilterAnalyzer *analyzer, int startPos, int stopPos);
28 |
29 | #ifdef __cplusplus
30 | }
31 | #endif
32 |
33 | #endif // PEAKINGEQUALIZER_H
34 |
--------------------------------------------------------------------------------
/Cavern.Format/Renderers/MeridianLosslessPackingRenderer.cs:
--------------------------------------------------------------------------------
1 | using Cavern.Channels;
2 | using Cavern.Format.Decoders;
3 | using Cavern.Format.Renderers.BaseClasses;
4 |
5 | namespace Cavern.Format.Renderers {
6 | ///
7 | /// Renders a decoded MLP stream with Cavern.
8 | ///
9 | public class MeridianLosslessPackingRenderer : Renderer, IMixedBedObjectRenderer {
10 | ///
11 | /// Renders a decoded MLP stream with Cavern.
12 | ///
13 | public MeridianLosslessPackingRenderer(MeridianLosslessPackingDecoder stream) : base(stream) {
14 | if (stream.TracksIn16CH != 0) {
15 | SetupObjects(stream.TracksIn16CH);
16 | } else {
17 | SetupChannels();
18 | }
19 | }
20 |
21 | ///
22 | public override ReferenceChannel[] GetChannels() => ((MeridianLosslessPackingDecoder)stream).Beds;
23 |
24 | ///
25 | public ReferenceChannel[] GetStaticChannels() => ((MeridianLosslessPackingDecoder)stream).Beds;
26 |
27 | ///
28 | public override void Update(int samples) {
29 | throw new System.NotImplementedException();
30 | }
31 | }
32 | }
33 |
--------------------------------------------------------------------------------
/Cavern.QuickEQ.Format/FilterSet/MultEQXRawFilterSet.cs:
--------------------------------------------------------------------------------
1 | using Cavern.Channels;
2 |
3 | namespace Cavern.Format.FilterSet {
4 | ///
5 | /// IIR filter set for MultEQ-X's PEQ import.
6 | ///
7 | public class MultEQXRawFilterSet : IIRFilterSet {
8 | ///
9 | /// Maximum number of peaking EQ filters per channel.
10 | ///
11 | public override int Bands => 10;
12 |
13 | ///
14 | /// Minimum gain of a single peaking EQ band in decibels.
15 | ///
16 | public override double MinGain => -12;
17 |
18 | ///
19 | /// Maximum gain of a single peaking EQ band in decibels.
20 | ///
21 | public override double MaxGain => 6;
22 |
23 | ///
24 | /// Create a MultEQ-X configuration file for EQ export.
25 | ///
26 | public MultEQXRawFilterSet(int channels, int sampleRate) : base(channels, sampleRate) { }
27 |
28 | ///
29 | /// Create a MultEQ-X configuration file for EQ export.
30 | ///
31 | public MultEQXRawFilterSet(ReferenceChannel[] channels, int sampleRate) : base(channels, sampleRate) { }
32 | }
33 | }
--------------------------------------------------------------------------------