public bool ReadFFP(BinaryFile binFile) { Version = binFile.ReadInt32(); ParameterCount = binFile.ReadInt32(); // parametercount = 334 // 24 bands with 13 parameters each = 312 // and then 22 parameters at the end Bands = new List <ProQ3Band>(); for (int i = 0; i < 24; i++) { var band = new ProQ3Band(); // 1 = Enabled, 0 = Disabled var fEnabled = binFile.ReadSingle(); band.Enabled = fEnabled == 1 ? true : false; Log.Debug("Band: {0} => enabled: {1}", i + 1, fEnabled); // unknown 1 var fUnknown1 = binFile.ReadSingle(); Log.Debug("Band: {0} => unknown 1: {1}", i + 1, fUnknown1); // frequency var fFreq = binFile.ReadSingle(); band.Frequency = FreqConvertBack(fFreq); Log.Debug("Band: {0} => freq: {1} => {2}", i + 1, fFreq, band.Frequency); // gain var fGain = binFile.ReadSingle(); band.Gain = fGain; // actual gain in dB Log.Debug("Band: {0} => gain: {1}", i + 1, fGain); // dynamic range (if band is dynamic) var fDynamicRange = binFile.ReadSingle(); band.DynamicRange = fDynamicRange; Log.Debug("Band: {0} => dynamic range: {1}", i + 1, fDynamicRange); // unknown 3 var fUnknown3 = binFile.ReadSingle(); Log.Debug("Band: {0} => unknown 3: {1}", i + 1, fUnknown3); // dynamic threshold in dB (1 = auto) - don't know how to convert this to dB // example numbers: // -1 dbFS 0.9833333 // -90 dbFS 0 // -20 dbFS 0.6666667 // -54 dbFS 0.17500602 var fDynamicThreshold = binFile.ReadSingle(); band.DynamicThreshold = fDynamicThreshold; Log.Debug("Band: {0} => dynamic threshold: {1} => {2}", i + 1, fDynamicThreshold, band.DynamicThreshold); // Q var fQ = binFile.ReadSingle(); band.Q = QConvertBack(fQ); Log.Debug("Band: {0} => Q: {1} => {2}", i + 1, fQ, band.Q); // 0 - 8 var fFilterType = binFile.ReadSingle(); switch (fFilterType) { case (float)ProQ3Shape.Bell: band.Shape = ProQ3Shape.Bell; break; case (float)ProQ3Shape.LowShelf: band.Shape = ProQ3Shape.LowShelf; break; case (float)ProQ3Shape.LowCut: band.Shape = ProQ3Shape.LowCut; break; case (float)ProQ3Shape.HighShelf: band.Shape = ProQ3Shape.HighShelf; break; case (float)ProQ3Shape.HighCut: band.Shape = ProQ3Shape.HighCut; break; case (float)ProQ3Shape.Notch: band.Shape = ProQ3Shape.Notch; break; case (float)ProQ3Shape.BandPass: band.Shape = ProQ3Shape.BandPass; break; case (float)ProQ3Shape.TiltShelf: band.Shape = ProQ3Shape.TiltShelf; break; case (float)ProQ3Shape.FlatTilt: band.Shape = ProQ3Shape.FlatTilt; break; default: throw new ArgumentOutOfRangeException(string.Format("Filter type is outside range: {0}", fFilterType)); } Log.Debug("Band: {0} => filterType: {1} => {2}", i + 1, fFilterType, band.Shape); // 0 - 9 var fFilterSlope = binFile.ReadSingle(); switch (fFilterSlope) { case (float)ProQ3Slope.Slope6dB_oct: band.Slope = ProQ3Slope.Slope6dB_oct; break; case (float)ProQ3Slope.Slope12dB_oct: band.Slope = ProQ3Slope.Slope12dB_oct; break; case (float)ProQ3Slope.Slope18dB_oct: band.Slope = ProQ3Slope.Slope18dB_oct; break; case (float)ProQ3Slope.Slope24dB_oct: band.Slope = ProQ3Slope.Slope24dB_oct; break; case (float)ProQ3Slope.Slope30dB_oct: band.Slope = ProQ3Slope.Slope30dB_oct; break; case (float)ProQ3Slope.Slope36dB_oct: band.Slope = ProQ3Slope.Slope36dB_oct; break; case (float)ProQ3Slope.Slope48dB_oct: band.Slope = ProQ3Slope.Slope48dB_oct; break; case (float)ProQ3Slope.Slope72dB_oct: band.Slope = ProQ3Slope.Slope72dB_oct; break; case (float)ProQ3Slope.Slope96dB_oct: band.Slope = ProQ3Slope.Slope96dB_oct; break; case (float)ProQ3Slope.SlopeBrickwall: band.Slope = ProQ3Slope.SlopeBrickwall; break; default: throw new ArgumentOutOfRangeException(string.Format("Filter slope is outside range: {0}", fFilterSlope)); } Log.Debug("Band: {0} => filterSlope: {1} => {2}", i + 1, fFilterSlope, band.Slope); // 0 = Left, 1 = Right, 2 = Stereo, 3 = Mid, 4 = Side var fFilterStereoPlacement = binFile.ReadSingle(); switch (fFilterStereoPlacement) { case (float)ProQ3StereoPlacement.Left: band.StereoPlacement = ProQ3StereoPlacement.Left; break; case (float)ProQ3StereoPlacement.Right: band.StereoPlacement = ProQ3StereoPlacement.Right; break; case (float)ProQ3StereoPlacement.Stereo: band.StereoPlacement = ProQ3StereoPlacement.Stereo; break; case (float)ProQ3StereoPlacement.Mid: band.StereoPlacement = ProQ3StereoPlacement.Mid; break; case (float)ProQ3StereoPlacement.Side: band.StereoPlacement = ProQ3StereoPlacement.Side; break; default: throw new ArgumentOutOfRangeException(string.Format("Filter stereo placement is outside range: {0}", fFilterStereoPlacement)); } Log.Debug("Band: {0} => filterStereoPlacement: {1} => {2}", i + 1, fFilterStereoPlacement, band.StereoPlacement); // unknown band parameters for (int j = 0; j < 2; j++) { var fUnknown = binFile.ReadSingle(); Log.Debug("Band: {0} => unknown {1}: {2}", i + 1, j + 5, fUnknown); } Bands.Add(band); } // read the remaining floats UnknownParameters = new List <float>(); int remainingParameterCount = ParameterCount - 13 * Bands.Count; for (int i = 0; i < remainingParameterCount; i++) { var fUnknown = binFile.ReadSingle(); Log.Debug("Param unknown {0}: {1}", i + 1, fUnknown); UnknownParameters.Add(fUnknown); } return(true); }
private static void SetBand(ProQ3Band band, int bandNumber, SteinbergFrequency frequency) { if (band != null) { frequency.Parameters[String.Format("equalizerAbandon{0}", bandNumber)].Number = band.Enabled ? 1.00 : 0.00; string channel = ""; // empty for main channel (channel 1). 'Ch2' for secondary channel // due to the way fabfilter have only one stereo placement per band (frequency has two) we need to modify both channels in frequency // we could have in theory instead updated both channels per band in frequency if (band.StereoPlacement != ProQ3StereoPlacement.Stereo) { switch (band.StereoPlacement) { case ProQ3StereoPlacement.Left: frequency.Parameters[String.Format("equalizerAon{0}", bandNumber)].Number = 1.0; frequency.Parameters[String.Format("equalizerAon{0}Ch2", bandNumber)].Number = 0.0; frequency.Parameters[String.Format("equalizerAeditchannel{0}", bandNumber)].Number = SteinbergFrequency.ChannelMode.LeftRightModeLeft; break; case ProQ3StereoPlacement.Mid: frequency.Parameters[String.Format("equalizerAon{0}", bandNumber)].Number = 1.0; frequency.Parameters[String.Format("equalizerAon{0}Ch2", bandNumber)].Number = 0.0; frequency.Parameters[String.Format("equalizerAeditchannel{0}", bandNumber)].Number = SteinbergFrequency.ChannelMode.MidSideModeMid; break; case ProQ3StereoPlacement.Right: frequency.Parameters[String.Format("equalizerAon{0}", bandNumber)].Number = 0.0; frequency.Parameters[String.Format("equalizerAon{0}Ch2", bandNumber)].Number = 1.0; channel = "Ch2"; frequency.Parameters[String.Format("equalizerAeditchannel{0}", bandNumber)].Number = SteinbergFrequency.ChannelMode.LeftRightModeRight; break; case ProQ3StereoPlacement.Side: frequency.Parameters[String.Format("equalizerAon{0}", bandNumber)].Number = 0.0; frequency.Parameters[String.Format("equalizerAon{0}Ch2", bandNumber)].Number = 1.0; channel = "Ch2"; frequency.Parameters[String.Format("equalizerAeditchannel{0}", bandNumber)].Number = SteinbergFrequency.ChannelMode.MidSideModeSide; break; case ProQ3StereoPlacement.Stereo: // don't change - this is the default break; } } frequency.Parameters[String.Format("equalizerAgain{0}{1}", bandNumber, channel)].Number = band.Gain; frequency.Parameters[String.Format("equalizerAfreq{0}{1}", bandNumber, channel)].Number = band.Frequency; frequency.Parameters[String.Format("equalizerAq{0}{1}", bandNumber, channel)].Number = band.Q; switch (band.Shape) { case ProQ3Shape.BandPass: case ProQ3Shape.TiltShelf: case ProQ3Shape.Bell: if (bandNumber == 1 || bandNumber == 8) { frequency.Parameters[String.Format("equalizerAtype{0}{1}", bandNumber, channel)].Number = SteinbergFrequency.BandMode1And8.Peak; } else { frequency.Parameters[String.Format("equalizerAtype{0}{1}", bandNumber, channel)].Number = SteinbergFrequency.BandMode2To7.Peak; } break; case ProQ3Shape.LowShelf: if (bandNumber == 1 || bandNumber == 8) { frequency.Parameters[String.Format("equalizerAtype{0}{1}", bandNumber, channel)].Number = SteinbergFrequency.BandMode1And8.LowShelf; } else { frequency.Parameters[String.Format("equalizerAtype{0}{1}", bandNumber, channel)].Number = SteinbergFrequency.BandMode2To7.LowShelf; } break; case ProQ3Shape.LowCut: switch (band.Slope) { case ProQ3Slope.Slope6dB_oct: frequency.Parameters[String.Format("equalizerAtype{0}{1}", bandNumber, channel)].Number = SteinbergFrequency.BandMode1And8.Cut6; break; case ProQ3Slope.Slope12dB_oct: case ProQ3Slope.Slope18dB_oct: frequency.Parameters[String.Format("equalizerAtype{0}{1}", bandNumber, channel)].Number = SteinbergFrequency.BandMode1And8.Cut12; break; case ProQ3Slope.Slope24dB_oct: case ProQ3Slope.Slope30dB_oct: frequency.Parameters[String.Format("equalizerAtype{0}{1}", bandNumber, channel)].Number = SteinbergFrequency.BandMode1And8.Cut24; break; case ProQ3Slope.Slope36dB_oct: case ProQ3Slope.Slope48dB_oct: frequency.Parameters[String.Format("equalizerAtype{0}{1}", bandNumber, channel)].Number = SteinbergFrequency.BandMode1And8.Cut48; break; case ProQ3Slope.Slope72dB_oct: case ProQ3Slope.Slope96dB_oct: frequency.Parameters[String.Format("equalizerAtype{0}{1}", bandNumber, channel)].Number = SteinbergFrequency.BandMode1And8.Cut96; break; } break; case ProQ3Shape.HighShelf: if (bandNumber == 1 || bandNumber == 8) { frequency.Parameters[String.Format("equalizerAtype{0}{1}", bandNumber, channel)].Number = SteinbergFrequency.BandMode1And8.HighShelf; } else { frequency.Parameters[String.Format("equalizerAtype{0}{1}", bandNumber, channel)].Number = SteinbergFrequency.BandMode2To7.HighShelf; } break; case ProQ3Shape.HighCut: switch (band.Slope) { case ProQ3Slope.Slope6dB_oct: frequency.Parameters[String.Format("equalizerAtype{0}{1}", bandNumber, channel)].Number = SteinbergFrequency.BandMode1And8.Cut6; break; case ProQ3Slope.Slope12dB_oct: case ProQ3Slope.Slope18dB_oct: frequency.Parameters[String.Format("equalizerAtype{0}{1}", bandNumber, channel)].Number = SteinbergFrequency.BandMode1And8.Cut12; break; case ProQ3Slope.Slope24dB_oct: case ProQ3Slope.Slope30dB_oct: frequency.Parameters[String.Format("equalizerAtype{0}{1}", bandNumber, channel)].Number = SteinbergFrequency.BandMode1And8.Cut24; break; case ProQ3Slope.Slope36dB_oct: case ProQ3Slope.Slope48dB_oct: frequency.Parameters[String.Format("equalizerAtype{0}{1}", bandNumber, channel)].Number = SteinbergFrequency.BandMode1And8.Cut48; break; case ProQ3Slope.Slope72dB_oct: case ProQ3Slope.Slope96dB_oct: frequency.Parameters[String.Format("equalizerAtype{0}{1}", bandNumber, channel)].Number = SteinbergFrequency.BandMode1And8.Cut96; break; } break; case ProQ3Shape.Notch: if (bandNumber == 1 || bandNumber == 8) { frequency.Parameters[String.Format("equalizerAtype{0}{1}", bandNumber, channel)].Number = SteinbergFrequency.BandMode1And8.Notch; } else { frequency.Parameters[String.Format("equalizerAtype{0}{1}", bandNumber, channel)].Number = SteinbergFrequency.BandMode2To7.Notch; } break; } Log.Debug(band.ToString()); } else { // disable band frequency.Parameters[String.Format("equalizerAbandon{0}", bandNumber)].Number = 0.00; } }