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.ChunkMagic = "CcnK"; fxp.ByteSize = 0; // will be set correctly by FXP class fxp.FxMagic = "FPCh"; // FPCh = FXP (preset), FBCh = FXB (bank) fxp.Version = 1; // Format Version (should be 1) fxp.FxID = "reeq"; fxp.FxVersion = 1100; fxp.ProgramCount = 1; fxp.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(); fxp.ChunkSize = chunkData.Length; fxp.ChunkDataByteArray = chunkData; } fxp.WriteFile(filePath); return(true); }
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.ChunkMagic = "CcnK"; fxp.ByteSize = 0; // will be set correctly by FXP class fxp.FxMagic = "FPCh"; // FPCh = FXP (preset), FBCh = FXB (bank) fxp.Version = 1; // Format Version (should be 1) fxp.FxID = "reeq"; fxp.FxVersion = 1100; fxp.ProgramCount = 1; fxp.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(); fxp.ChunkSize = chunkData.Length; fxp.ChunkDataByteArray = chunkData; } fxp.WriteFile(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 { Console.Error.WriteLine("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) { Console.Error.WriteLine("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 Console.Error.WriteLine("Could not parse line: {0}", line); MessageBox.Show(new Form() { WindowState = FormWindowState.Maximized, TopMost = true }, "Failed parsing filter line using Culture: " + CultureInfo.CurrentCulture.DisplayName + ". Does the REW filter file use this Culture? (e.g. '" + nfi.NumberDecimalSeparator + "' as the Decimal Separator?)" + "\n\nUnparsable line:\n" + line, "Critical Warning!", MessageBoxButtons.OK, MessageBoxIcon.Warning); return null; } } } } return filters; }
public static bool Convert2FabfilterProQ(REWEQFilters filters, string filePath) { List<ProQBand> proQBands = new List<ProQBand>(); foreach (REWEQBand filter in filters) { ProQBand band = new ProQBand(); band.FilterFreq = filter.FilterFreq; band.FilterGain = filter.FilterGain; band.FilterQ = filter.FilterQ; band.Enabled = filter.Enabled; switch (filter.FilterType) { case REWEQFilterType.PK: band.FilterType = ProQFilterType.Bell; break; case REWEQFilterType.LP: band.FilterType = ProQFilterType.HighCut; break; case REWEQFilterType.HP: band.FilterType = ProQFilterType.LowCut; break; case REWEQFilterType.LS: band.FilterType = ProQFilterType.LowShelf; break; case REWEQFilterType.HS: band.FilterType = ProQFilterType.HighShelf; break; default: band.FilterType = ProQFilterType.Bell; break; } band.FilterLPHPSlope = ProQLPHPSlope.Slope24dB_oct; band.FilterStereoPlacement = ProQStereoPlacement.Stereo; proQBands.Add(band); } BinaryFile binFile = new BinaryFile(filePath, BinaryFile.ByteOrder.LittleEndian, true); binFile.Write("FPQr"); binFile.Write((int) 2); binFile.Write((int) 180); binFile.Write((float) proQBands.Count); for (int i = 0; i < 24; i++) { if (i < proQBands.Count) { binFile.Write((float) FreqConvert(proQBands[i].FilterFreq)); binFile.Write((float) proQBands[i].FilterGain); binFile.Write((float) QConvert(proQBands[i].FilterQ)); binFile.Write((float) proQBands[i].FilterType); binFile.Write((float) proQBands[i].FilterLPHPSlope); binFile.Write((float) proQBands[i].FilterStereoPlacement); binFile.Write((float) (proQBands[i].Enabled ? 1 : 0) ); } else { binFile.Write((float) FreqConvert(1000)); binFile.Write((float) 0); binFile.Write((float) QConvert(1)); binFile.Write((float) ProQFilterType.Bell); binFile.Write((float) ProQLPHPSlope.Slope24dB_oct); binFile.Write((float) ProQStereoPlacement.Stereo); binFile.Write((float) 1); } } binFile.Write((float) 0); // float output_gain; // -1 to 1 (- Infinity to +36 dB , 0 = 0 dB) binFile.Write((float) 0); // float output_pan; // -1 to 1 (0 = middle) binFile.Write((float) 2); // float display_range; // 0 = 6dB, 1 = 12dB, 2 = 30dB, 3 = 3dB binFile.Write((float) 0); // float process_mode; // 0 = zero latency, 1 = lin.phase.low - medium - high - maximum binFile.Write((float) 0); // float channel_mode; // 0 = Left/Right, 1 = Mid/Side binFile.Write((float) 0); // float bypass; // 0 = No bypass binFile.Write((float) 0); // float receive_midi; // 0 = Enabled? binFile.Write((float) 3); // float analyzer; // 0 = Off, 1 = Pre, 2 = Post, 3 = Pre+Post binFile.Write((float) 1); // float analyzer_resolution; // 0 - 3 : low - medium[x] - high - maximum binFile.Write((float) 2); // float analyzer_speed; // 0 - 3 : very slow, slow, medium[x], fast binFile.Write((float) -1); // float solo_band; // -1 binFile.Close(); return true; }
void MainForm_DragDrop(object sender, DragEventArgs e) { string[] files = (string[])e.Data.GetData(DataFormats.FileDrop); foreach (string inputFilePath in files) { string fileExtension = Path.GetExtension(inputFilePath); string directoryName = Path.GetDirectoryName(inputFilePath); string fileName = Path.GetFileNameWithoutExtension(inputFilePath); if (fileExtension.Equals(".txt")) { Boolean success = false; REWEQFilters filters = REWEQ.ReadREWEQFiltersFile(inputFilePath); if (filters != null && filters.Count > 0) { string outputFilePath = directoryName + Path.DirectorySeparatorChar + fileName; switch (listBoxPluginSelection.SelectedIndex) { // I added some asserts to ensure switch cases corresponds to the right plugin case 0: // ReaEQ Debug.Assert(listBoxPluginSelection.SelectedItem.ToString().ToLower().Contains("reaeq")); outputFilePath += ".fxp"; success = ReaEQ.Convert2ReaEQ(filters, outputFilePath); break; case 1: // EasyQ Debug.Assert(listBoxPluginSelection.SelectedItem.ToString().ToLower().Contains("easyq")); outputFilePath += ".xml"; // success = EasyQ.Convert2EasyQ(filters, outputFilePath); break; case 2: // FabFilter Pro-Q Debug.Assert(listBoxPluginSelection.SelectedItem.ToString().ToLower().Contains("fabfilter")); outputFilePath += ".ffp"; success = FabfilterProQ.Convert2FabfilterProQ(filters, outputFilePath); break; case -1: // No plugin selected MessageBox.Show(new Form() { WindowState = FormWindowState.Maximized, TopMost = true }, "Please select a plugin !", "Error", MessageBoxButtons.OK, MessageBoxIcon.Exclamation, MessageBoxDefaultButton.Button1); break; default: break; } } if (success) { MessageBox.Show(new Form() { WindowState = FormWindowState.Maximized, TopMost = true }, listBoxPluginSelection.SelectedItem.ToString() + " file generated (" + filters.Count + " filters)", "Success", MessageBoxButtons.OK, MessageBoxIcon.Information, MessageBoxDefaultButton.Button1); } else if (listBoxPluginSelection.SelectedIndex != -1) { MessageBox.Show(new Form() { WindowState = FormWindowState.Maximized, TopMost = true }, listBoxPluginSelection.SelectedItem.ToString() + " file not generated", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error, MessageBoxDefaultButton.Button1); break; } } } }
/// <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 { Console.Error.WriteLine("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) { Console.Error.WriteLine("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 Console.Error.WriteLine("Could not parse line: {0}", line); MessageBox.Show(new Form() { WindowState = FormWindowState.Maximized, TopMost = true }, "Failed parsing filter line using Culture: " + CultureInfo.CurrentCulture.DisplayName + ". Does the REW filter file use this Culture? (e.g. '" + nfi.NumberDecimalSeparator + "' as the Decimal Separator?)" + "\n\nUnparsable line:\n" + line, "Critical Warning!", MessageBoxButtons.OK, MessageBoxIcon.Warning); return(null); } } } } return(filters); }
public static bool Convert2FabfilterProQ(REWEQFilters filters, string filePath) { List <ProQBand> proQBands = new List <ProQBand>(); foreach (REWEQBand filter in filters) { ProQBand band = new ProQBand(); band.FilterFreq = filter.FilterFreq; band.FilterGain = filter.FilterGain; band.FilterQ = filter.FilterQ; band.Enabled = filter.Enabled; switch (filter.FilterType) { case REWEQFilterType.PK: band.FilterType = ProQFilterType.Bell; break; case REWEQFilterType.LP: band.FilterType = ProQFilterType.HighCut; break; case REWEQFilterType.HP: band.FilterType = ProQFilterType.LowCut; break; case REWEQFilterType.LS: band.FilterType = ProQFilterType.LowShelf; break; case REWEQFilterType.HS: band.FilterType = ProQFilterType.HighShelf; break; default: band.FilterType = ProQFilterType.Bell; break; } band.FilterLPHPSlope = ProQLPHPSlope.Slope24dB_oct; band.FilterStereoPlacement = ProQStereoPlacement.Stereo; proQBands.Add(band); } BinaryFile binFile = new BinaryFile(filePath, BinaryFile.ByteOrder.LittleEndian, true); binFile.Write("FPQr"); binFile.Write((int)2); binFile.Write((int)180); binFile.Write((float)proQBands.Count); for (int i = 0; i < 24; i++) { if (i < proQBands.Count) { binFile.Write((float)FreqConvert(proQBands[i].FilterFreq)); binFile.Write((float)proQBands[i].FilterGain); binFile.Write((float)QConvert(proQBands[i].FilterQ)); binFile.Write((float)proQBands[i].FilterType); binFile.Write((float)proQBands[i].FilterLPHPSlope); binFile.Write((float)proQBands[i].FilterStereoPlacement); binFile.Write((float)(proQBands[i].Enabled ? 1 : 0)); } else { binFile.Write((float)FreqConvert(1000)); binFile.Write((float)0); binFile.Write((float)QConvert(1)); binFile.Write((float)ProQFilterType.Bell); binFile.Write((float)ProQLPHPSlope.Slope24dB_oct); binFile.Write((float)ProQStereoPlacement.Stereo); binFile.Write((float)1); } } binFile.Write((float)0); // float output_gain; // -1 to 1 (- Infinity to +36 dB , 0 = 0 dB) binFile.Write((float)0); // float output_pan; // -1 to 1 (0 = middle) binFile.Write((float)2); // float display_range; // 0 = 6dB, 1 = 12dB, 2 = 30dB, 3 = 3dB binFile.Write((float)0); // float process_mode; // 0 = zero latency, 1 = lin.phase.low - medium - high - maximum binFile.Write((float)0); // float channel_mode; // 0 = Left/Right, 1 = Mid/Side binFile.Write((float)0); // float bypass; // 0 = No bypass binFile.Write((float)0); // float receive_midi; // 0 = Enabled? binFile.Write((float)3); // float analyzer; // 0 = Off, 1 = Pre, 2 = Post, 3 = Pre+Post binFile.Write((float)1); // float analyzer_resolution; // 0 - 3 : low - medium[x] - high - maximum binFile.Write((float)2); // float analyzer_speed; // 0 - 3 : very slow, slow, medium[x], fast binFile.Write((float)-1); // float solo_band; // -1 binFile.Close(); return(true); }