public static bool Convert2ReaEQ(REWEQFilters filters, string filePath) { List <ReaEQBand> ReaEqBands = new List <ReaEQBand>(); foreach (REWEQBand filter in filters) { ReaEQBand band = new ReaEQBand(); band.LogScaleAutoFreq = true; band.FilterFreq = filter.FilterFreq; band.FilterGain = filter.FilterGain; band.FilterBWOct = filter.FilterBWOct; band.Enabled = filter.Enabled; switch (filter.FilterType) { case REWEQFilterType.PK: band.FilterType = ReaEQFilterType.Band; break; case REWEQFilterType.LP: band.FilterType = ReaEQFilterType.LowPass; break; case REWEQFilterType.HP: band.FilterType = ReaEQFilterType.HighPass; break; case REWEQFilterType.LS: band.FilterType = ReaEQFilterType.LowShelf; break; case REWEQFilterType.HS: band.FilterType = ReaEQFilterType.HighShelf; break; default: band.FilterType = ReaEQFilterType.Band; break; } ReaEqBands.Add(band); } // store to file FXP fxp = new FXP(); FXP.FxProgramSet fxpContent = new FXP.FxProgramSet(); fxp.Content = fxpContent; fxpContent.ChunkMagic = "CcnK"; fxpContent.ByteSize = 0; // will be set correctly by FXP class fxpContent.FxMagic = "FPCh"; // FPCh = FXP (preset), FBCh = FXB (bank) fxpContent.Version = 1; // Format Version (should be 1) fxpContent.FxID = "reeq"; fxpContent.FxVersion = 1100; fxpContent.NumPrograms = 1; fxpContent.Name = ""; using (MemoryStream memStream = new MemoryStream(10)) { BinaryFile binFile = new BinaryFile(memStream, BinaryFile.ByteOrder.LittleEndian); binFile.Write((int)33); binFile.Write((int)ReaEqBands.Count); foreach (ReaEQBand band in ReaEqBands) { binFile.Write((int)band.FilterType); binFile.Write((int)(band.Enabled ? 1 : 0)); binFile.Write((double)band.FilterFreq); binFile.Write((double)Decibel2AmplitudeRatio(band.FilterGain)); binFile.Write((double)band.FilterBWOct); binFile.Write((byte)1); } binFile.Write((int)1); binFile.Write((int)1); binFile.Write((double)Decibel2AmplitudeRatio(0.00)); binFile.Write((int)0); memStream.Flush(); byte[] chunkData = memStream.GetBuffer(); fxpContent.ChunkSize = chunkData.Length; fxpContent.ChunkData = chunkData; } fxp.Write(filePath); return(true); }
/// <summary> /// Parse a REW filters output file /// The users regional locale is also taken into consideration /// </summary> /// <param name="filePath">path to file</param> /// <returns>a rew eq filter object</returns> public static REWEQFilters ReadREWEQFiltersFile(string filePath) { REWEQFilters filters = new REWEQFilters(); // Get current culture's NumberFormatInfo object. NumberFormatInfo nfi = CultureInfo.CurrentCulture.NumberFormat; //NumberFormatInfo nfi = CultureInfo.InvariantCulture.NumberFormat; // For debugging // Assign needed property values to variables. string decimalSeparator = nfi.NumberDecimalSeparator; // Form regular expression pattern using the current culture's decimal seperator. Regex digitsAndDecimalSeparatorOnly = new Regex(@"[^\d" + Regex.Escape(decimalSeparator) + "]"); using (StreamReader r = new StreamReader(filePath)) { string line; int filterCount = 0; string regexpPattern = @"^Filter\s+\d+"; bool usingBWOct = false; while ((line = r.ReadLine()) != null) { if (line.StartsWith("Equaliser:")) { // find out what filter parse rule to use if (line.Equals("Equaliser: FBQ2496")) { // Filter 1: ON PEQ Fc 64,0 Hz Gain -5,0 dB BW Oct 0,167 regexpPattern = @"^Filter\s+\d+:\s(\w+)\s+(\w+)\s+Fc ([\D\d" + Regex.Escape(decimalSeparator) + @"]+) Hz Gain ([\s\d" + Regex.Escape(decimalSeparator) + @"\-]+) dB BW Oct ([\s\d" + Regex.Escape(decimalSeparator) + @"]+)$"; usingBWOct = true; } else if (line.Equals("Equaliser: Generic")) { // Filter 1: ON PK Fc 63,8 Hz Gain -5,0 dB Q 8,06 regexpPattern = @"^Filter\s+\d+:\s(\w+)\s+(\w+)\s+Fc ([\D\d" + Regex.Escape(decimalSeparator) + @"]+) Hz Gain ([\s\d" + Regex.Escape(decimalSeparator) + @"\-]+) dB Q ([\s\d" + Regex.Escape(decimalSeparator) + @"]+)$"; usingBWOct = false; } else { Log.Error("No known equaliser format!", line); return(null); } } // skip all lines that does not start with "Filter <number>:" if (Regex.IsMatch(line, @"^Filter\s+\d+:")) { // remove any non breaking spaces line = Regex.Replace(line, "\xA0", String.Empty); // skip line if filter type is "None" if (Regex.Match(line, @"^Filter\s+\d+:\s+ON\s+None.*$").Success) { continue; } Match match = Regex.Match(line, regexpPattern); if (match.Success) { filterCount++; string enabled = match.Groups[1].Value.Trim(); string type = match.Groups[2].Value.Trim(); string freq = match.Groups[3].Value.Trim(); freq = digitsAndDecimalSeparatorOnly.Replace(freq, ""); string gain = match.Groups[4].Value.Trim(); string q = match.Groups[5].Value.Trim(); REWEQBand band = new REWEQBand(); if (enabled.Equals("ON")) { band.Enabled = true; } if (type.Equals("PEQ") || type.Equals("PK")) { band.FilterType = REWEQFilterType.PK; } try { band.FilterFreq = Double.Parse(freq, nfi); band.FilterGain = Double.Parse(gain, nfi); if (usingBWOct) { band.FilterBWOct = Double.Parse(q, nfi); band.FilterQ = BWOct2Q(band.FilterBWOct); } else { band.FilterQ = Double.Parse(q, nfi); band.FilterBWOct = Q2BWOct(band.FilterQ); } } catch (Exception e) { Log.Error("Parse error", e.Message); return(null); } filters.EqBands.Add(band); } else { // By some reason we failed parsing the Filter line which should have worked! // probably a locale problem Log.Error("Could not parse line: {0}", line); return(null); } } } } return(filters); }
public static FabfilterProQ ToFabfilterProQ(this REWEQFilters filters) { var preset = new FabfilterProQ(); preset.Version = 2; preset.Bands = new List <ProQBand>(); foreach (REWEQBand filter in filters) { var band = new ProQBand(); band.Frequency = filter.FilterFreq; band.Gain = filter.FilterGain; band.Q = filter.FilterQ; band.Enabled = filter.Enabled; switch (filter.FilterType) { case REWEQFilterType.PK: band.Shape = ProQShape.Bell; break; case REWEQFilterType.LP: band.Shape = ProQShape.HighCut; break; case REWEQFilterType.HP: band.Shape = ProQShape.LowCut; break; case REWEQFilterType.LS: band.Shape = ProQShape.LowShelf; break; case REWEQFilterType.HS: band.Shape = ProQShape.HighShelf; break; default: band.Shape = ProQShape.Bell; break; } band.LPHPSlope = ProQLPHPSlope.Slope24dB_oct; band.StereoPlacement = ProQStereoPlacement.Stereo; preset.Bands.Add(band); } // Add empty bands for (int i = preset.Bands.Count; i < 24; i++) { var band = new ProQBand(); band.Frequency = FabfilterProQ.FreqConvert(1000); band.Gain = 0; band.Q = FabfilterProQ.QConvert(1); band.Enabled = true; band.Shape = ProQShape.Bell; band.LPHPSlope = ProQLPHPSlope.Slope24dB_oct; band.StereoPlacement = ProQStereoPlacement.Stereo; preset.Bands.Add(band); } preset.OutputGain = 0; // -1 to 1 (- Infinity to +36 dB , 0 = 0 dB) preset.OutputPan = 0; // -1 to 1 (0 = middle) preset.DisplayRange = 2; // 0 = 6dB, 1 = 12dB, 2 = 30dB, 3 = 3dB preset.ProcessMode = 0; // 0 = zero latency, 1 = lin.phase.low - medium - high - maximum preset.ChannelMode = 0; // 0 = Left/Right, 1 = Mid/Side preset.Bypass = 0; // 0 = No bypass preset.ReceiveMidi = 0; // 0 = Enabled? preset.Analyzer = 3; // 0 = Off, 1 = Pre, 2 = Post, 3 = Pre+Post preset.AnalyzerResolution = 1; // 0 - 3 : low - medium[x] - high - maximum preset.AnalyzerSpeed = 2; // 0 - 3 : very slow, slow, medium[x], fast preset.SoloBand = -1; // -1 return(preset); }