diff --git a/Cavern.QuickEQ.Format/FilterSet/BaseClasses/FilterSet.cs b/Cavern.QuickEQ.Format/FilterSet/BaseClasses/FilterSet.cs
index f4c4ba67..ea2471f8 100644
--- a/Cavern.QuickEQ.Format/FilterSet/BaseClasses/FilterSet.cs
+++ b/Cavern.QuickEQ.Format/FilterSet/BaseClasses/FilterSet.cs
@@ -103,6 +103,7 @@ public static FilterSet Create(FilterSetTarget device, int channels, int sampleR
FilterSetTarget.MultEQXRaw => new MultEQXRawFilterSet(channels, sampleRate),
FilterSetTarget.MultEQXTarget => new MultEQXTargetFilterSet(channels, sampleRate),
FilterSetTarget.YPAO => new YPAOFilterSet(channels, sampleRate),
+ FilterSetTarget.YPAOLite => new YPAOLiteFilterSet(channels, sampleRate),
_ => throw new NotSupportedException()
};
}
@@ -137,6 +138,7 @@ public static FilterSet Create(FilterSetTarget device, ReferenceChannel[] channe
FilterSetTarget.MultEQXRaw => new MultEQXRawFilterSet(channels, sampleRate),
FilterSetTarget.MultEQXTarget => new MultEQXTargetFilterSet(channels, sampleRate),
FilterSetTarget.YPAO => new YPAOFilterSet(channels, sampleRate),
+ FilterSetTarget.YPAOLite => new YPAOLiteFilterSet(channels, sampleRate),
_ => throw new NotSupportedException()
};
}
diff --git a/Cavern.QuickEQ.Format/FilterSet/BaseClasses/FilterSetTarget.cs b/Cavern.QuickEQ.Format/FilterSet/BaseClasses/FilterSetTarget.cs
index 2ea54f61..1b83e8e7 100644
--- a/Cavern.QuickEQ.Format/FilterSet/BaseClasses/FilterSetTarget.cs
+++ b/Cavern.QuickEQ.Format/FilterSet/BaseClasses/FilterSetTarget.cs
@@ -123,6 +123,10 @@ public enum FilterSetTarget {
/// Processors supporting the latest YPAO with additional fine tuning PEQs.
///
YPAO,
+ ///
+ /// Older Yamaha processors with fixed 7 bands.
+ ///
+ YPAOLite,
}
///
@@ -161,7 +165,8 @@ public static class FilterSetTargetExtensions {
FilterSetTarget.MultEQX => "MultEQ-X - MQX file",
FilterSetTarget.MultEQXRaw => "MultEQ-X - Peaking EQ",
FilterSetTarget.MultEQXTarget => "MultEQ-X - Filter curves",
- FilterSetTarget.YPAO => "YPAO",
+ FilterSetTarget.YPAO => "YPAO - free bands",
+ FilterSetTarget.YPAOLite => "YPAO - fixed bands",
_ => throw new NotSupportedException()
};
}
diff --git a/Cavern.QuickEQ.Format/FilterSet/DiracLiveBassControlFilterSet.cs b/Cavern.QuickEQ.Format/FilterSet/DiracLiveBassControlFilterSet.cs
index 0d0074c9..ea325ec6 100644
--- a/Cavern.QuickEQ.Format/FilterSet/DiracLiveBassControlFilterSet.cs
+++ b/Cavern.QuickEQ.Format/FilterSet/DiracLiveBassControlFilterSet.cs
@@ -68,14 +68,20 @@ public override void Export(string path) {
}
}
+ ///
+ /// Extracted channel pairs are for memory optimization.
+ ///
+ static readonly (string name, ReferenceChannel[] channels)
+ fronts = ("Fronts", new[] { ReferenceChannel.FrontLeft, ReferenceChannel.FrontRight }),
+ wides = ("Wide Surrounds", new[] { ReferenceChannel.WideLeft, ReferenceChannel.WideRight }),
+ sides = ("Side Surrounds", new[] { ReferenceChannel.SideLeft, ReferenceChannel.SideRight }),
+ rears = ("Rear Surrounds", new[] { ReferenceChannel.RearLeft, ReferenceChannel.RearRight });
+
///
/// The channels that are combined into one EQ group for DLBC versions where the height pairs are separate groups.
///
static readonly (string name, ReferenceChannel[] channels)[] groupsWithSeparateHeights = {
- ("Fronts", new[] { ReferenceChannel.FrontLeft, ReferenceChannel.FrontRight }),
- ("Wide Surrounds", new[] { ReferenceChannel.WideLeft, ReferenceChannel.WideRight }),
- ("Side Surrounds", new[] { ReferenceChannel.SideLeft, ReferenceChannel.SideRight }),
- ("Rear Surrounds", new[] { ReferenceChannel.RearLeft, ReferenceChannel.RearRight }),
+ fronts, wides, sides, rears,
("Front Heights", new[] { ReferenceChannel.TopFrontLeft, ReferenceChannel.TopFrontRight }),
("Side Heights", new[] { ReferenceChannel.TopSideLeft, ReferenceChannel.TopSideRight }),
("Rear Heights", new[] { ReferenceChannel.TopRearLeft, ReferenceChannel.TopRearRight })
@@ -85,10 +91,7 @@ static readonly (string name, ReferenceChannel[] channels)[] groupsWithSeparateH
/// The channels that are combined into one EQ group for DLBC versions where there are no different height pair groups.
///
static readonly (string name, ReferenceChannel[] channels)[] groupsWithCombinedHeights = {
- ("Fronts", new[] { ReferenceChannel.FrontLeft, ReferenceChannel.FrontRight }),
- ("Wide Surrounds", new[] { ReferenceChannel.WideLeft, ReferenceChannel.WideRight }),
- ("Side Surrounds", new[] { ReferenceChannel.SideLeft, ReferenceChannel.SideRight }),
- ("Rear Surrounds", new[] { ReferenceChannel.RearLeft, ReferenceChannel.RearRight }),
+ fronts, wides, sides, rears,
("Heights", new[] { ReferenceChannel.TopFrontLeft, ReferenceChannel.TopFrontCenter, ReferenceChannel.TopFrontRight,
ReferenceChannel.TopSideLeft, ReferenceChannel.GodsVoice, ReferenceChannel.TopSideRight,
ReferenceChannel.TopRearLeft, ReferenceChannel.TopRearCenter, ReferenceChannel.TopRearRight }),
diff --git a/Cavern.QuickEQ.Format/FilterSet/MultibandPEQFilterSet.cs b/Cavern.QuickEQ.Format/FilterSet/MultibandPEQFilterSet.cs
index 05be87e4..b4037ff5 100644
--- a/Cavern.QuickEQ.Format/FilterSet/MultibandPEQFilterSet.cs
+++ b/Cavern.QuickEQ.Format/FilterSet/MultibandPEQFilterSet.cs
@@ -1,6 +1,7 @@
using System.Collections.Generic;
using System.IO;
+using Cavern.Channels;
using Cavern.Filters;
using Cavern.QuickEQ.Equalization;
@@ -9,6 +10,17 @@ namespace Cavern.Format.FilterSet {
/// Exports a traditional multiband eqalizer with constant bandwidth bands.
///
public class MultibandPEQFilterSet : IIRFilterSet {
+ ///
+ public override double MinGain => -12;
+
+ ///
+ public override double MaxGain => 6;
+
+ ///
+ /// Limit the number of bands exported for the LFE channel.
+ ///
+ protected int LFEBands { get; set; }
+
///
/// Frequency of the first exported band.
///
@@ -17,7 +29,7 @@ public class MultibandPEQFilterSet : IIRFilterSet {
///
/// Number of bands for each octave.
///
- readonly int bandsPerOctave;
+ readonly double bandsPerOctave;
///
/// Number of total bands.
@@ -32,11 +44,28 @@ public class MultibandPEQFilterSet : IIRFilterSet {
/// Frequency of the first exported band
/// Number of bands for each octave
/// Number of total bands
- public MultibandPEQFilterSet(int channels, int sampleRate, double firstBand, int bandsPerOctave, int bandCount) :
+ public MultibandPEQFilterSet(int channels, int sampleRate, double firstBand, double bandsPerOctave, int bandCount) :
+ base(channels, sampleRate) {
+ this.firstBand = firstBand;
+ this.bandsPerOctave = bandsPerOctave;
+ this.bandCount = bandCount;
+ LFEBands = bandCount;
+ }
+
+ ///
+ /// Construct a traditional multiband eqalizer with constant bandwidth bands.
+ ///
+ /// Channels in the target system
+ /// Filter sample rate
+ /// Frequency of the first exported band
+ /// Number of bands for each octave
+ /// Number of total bands
+ public MultibandPEQFilterSet(ReferenceChannel[] channels, int sampleRate, double firstBand, double bandsPerOctave, int bandCount) :
base(channels, sampleRate) {
this.firstBand = firstBand;
this.bandsPerOctave = bandsPerOctave;
this.bandCount = bandCount;
+ LFEBands = bandCount;
}
///
@@ -44,8 +73,8 @@ public MultibandPEQFilterSet(int channels, int sampleRate, double firstBand, int
///
public PeakingEQ[] CalculateFilters(Equalizer targetToReach) {
PeakingEQ[] result = new PeakingEqualizer(targetToReach) {
- MinGain = -12,
- MaxGain = 6
+ MinGain = MinGain,
+ MaxGain = MaxGain
}.GetPeakingEQ(SampleRate, firstBand, bandsPerOctave, bandCount);
IReadOnlyList bands = targetToReach.Bands;
@@ -69,14 +98,16 @@ public override void Export(string path) {
for (int i = 0; i < Channels.Length; i++) {
IIRChannelData channelRef = (IIRChannelData)Channels[i];
result.Add(string.Empty);
- result.Add(channelRef.name);
- result.Add(new string('=', channelRef.name.Length));
+ string chName = GetLabel(i);
+ result.Add(chName);
+ result.Add(new string('=', chName.Length));
RootFileExtension(i, result);
if (channelRef.delaySamples != 0) {
result.Add("Delay: " + GetDelay(i).ToString("0.00 ms"));
}
BiquadFilter[] bands = channelRef.filters;
- for (int j = 0; j < bands.Length; j++) {
+ int bandc = channelRef.reference != ReferenceChannel.ScreenLFE ? bands.Length : LFEBands;
+ for (int j = 0; j < bandc; j++) {
result.Add($"{bands[j].CenterFreq:0} Hz:\t{bands[j].Gain:0.00} dB");
}
}
diff --git a/Cavern.QuickEQ.Format/FilterSet/YPAOFilterSet.cs b/Cavern.QuickEQ.Format/FilterSet/YPAOFilterSet.cs
index d753f24a..240c2bc3 100644
--- a/Cavern.QuickEQ.Format/FilterSet/YPAOFilterSet.cs
+++ b/Cavern.QuickEQ.Format/FilterSet/YPAOFilterSet.cs
@@ -7,31 +7,28 @@
namespace Cavern.Format.FilterSet {
///
- /// Filter set to fine tune an existing YPAO calibration with.
+ /// Filter set limited to 1/3 octave band choices for some versions of YPAO.
///
public class YPAOFilterSet : IIRFilterSet {
- ///
- /// Maximum number of peaking EQ filters per channel.
- ///
+ ///
public override int Bands => 7;
- ///
- /// Maximum gain of a single peaking EQ band in decibels.
- ///
+ ///
public override double MaxGain => 6;
- ///
- /// Round the gains to this precision.
- ///
+ ///
+ public override double MinGain => -6;
+
+ ///
public override double GainPrecision => .5f;
///
- /// Filter set to fine tune an existing YPAO calibration with.
+ /// Filter set limited to 1/3 octave band choices for some versions of YPAO.
///
public YPAOFilterSet(int channels, int sampleRate) : base(channels, sampleRate) { }
///
- /// Filter set to fine tune an existing YPAO calibration with.
+ /// Filter set limited to 1/3 octave band choices for some versions of YPAO.
///
public YPAOFilterSet(ReferenceChannel[] channels, int sampleRate) : base(channels, sampleRate) { }
@@ -46,7 +43,7 @@ public override void Export(string path) {
BiquadFilter[] filters = ((IIRChannelData)Channels[i]).filters;
for (int j = 0; j < filters.Length;) {
BiquadFilter filter = filters[j];
- result.Add($"Filter {++j} - Frequency: {bands.Nearest((float)filter.CenterFreq)}, Q factor: " +
+ result.Add($"Filter {++j} - Frequency: {frequencies.Nearest((float)filter.CenterFreq)}, Q factor: " +
$"{qFactors.Nearest((float)filter.Q)}, gain: {filter.Gain}");
}
}
@@ -56,7 +53,7 @@ public override void Export(string path) {
///
/// All the possible bands that can be selected for YPAO. These are 1/3 octaves apart.
///
- static readonly float[] bands = {
+ static readonly float[] frequencies = {
39.4f, 49.6f, 62.5f, 78.7f, 99.2f, 125.0f, 157.5f, 198.4f, 250, 315, 396.9f, 500, 630, 793.7f,
1000, 1260, 1590, 2000, 2520, 3170, 4000, 5040, 6350, 8000, 10100, 12700, 16000
};
diff --git a/Cavern.QuickEQ.Format/FilterSet/YPAOLiteFilterSet.cs b/Cavern.QuickEQ.Format/FilterSet/YPAOLiteFilterSet.cs
new file mode 100644
index 00000000..6fa97c4e
--- /dev/null
+++ b/Cavern.QuickEQ.Format/FilterSet/YPAOLiteFilterSet.cs
@@ -0,0 +1,21 @@
+using Cavern.Channels;
+
+namespace Cavern.Format.FilterSet {
+ ///
+ /// Filter set limited to 4/3 octave band choices for some versions of YPAO.
+ ///
+ public class YPAOLiteFilterSet : MultibandPEQFilterSet {
+ ///
+ public override double MinGain => -6;
+
+ ///
+ /// Filter set limited to 4/3 octave band choices for some versions of YPAO.
+ ///
+ public YPAOLiteFilterSet(int channels, int sampleRate) : base(channels, sampleRate, 62.5, .75, 7) => LFEBands = 2;
+
+ ///
+ /// Filter set limited to 4/3 octave band choices for some versions of YPAO.
+ ///
+ public YPAOLiteFilterSet(ReferenceChannel[] channels, int sampleRate) : base(channels, sampleRate, 62.5, .75, 7) => LFEBands = 2;
+ }
+}
\ No newline at end of file
diff --git a/Cavern.QuickEQ/Equalization/PeakingEqualizer.cs b/Cavern.QuickEQ/Equalization/PeakingEqualizer.cs
index a80e144f..5b642bdb 100644
--- a/Cavern.QuickEQ/Equalization/PeakingEqualizer.cs
+++ b/Cavern.QuickEQ/Equalization/PeakingEqualizer.cs
@@ -141,7 +141,7 @@ public PeakingEQ[] GetPeakingEQ(int sampleRate) {
///
/// Create a peaking EQ filter set with constant bandwidth between the frequencies. This mimics legacy x-band EQs.
///
- public PeakingEQ[] GetPeakingEQ(int sampleRate, double firstBand, int bandsPerOctave, int bands) {
+ public PeakingEQ[] GetPeakingEQ(int sampleRate, double firstBand, double bandsPerOctave, int bands) {
float[] target = source.Visualize(MinFrequency, MaxFrequency, 1024);
PeakingEQ[] result = new PeakingEQ[bands];
double bandwidth = 1.0 / bandsPerOctave;
diff --git a/Cavern/Remapping/DisassemblerUpmixer.cs b/Cavern/Remapping/DisassemblerUpmixer.cs
index d795f7a1..67bff13e 100644
--- a/Cavern/Remapping/DisassemblerUpmixer.cs
+++ b/Cavern/Remapping/DisassemblerUpmixer.cs
@@ -1,5 +1,6 @@
-using Cavern.Filters;
-using System.Numerics;
+using System.Numerics;
+
+using Cavern.Filters;
namespace Cavern.Remapping {
///