void Process() { task.UpdateProgressBar(0); task.UpdateStatus("Reading headers..."); if (string.IsNullOrEmpty(path) || !Directory.Exists(path)) { ProcessError("No valid path was selected."); return; } string bassPath = Path.Combine(path, "bass.wav"), drumsPath = Path.Combine(path, "drums.wav"), otherPath = Path.Combine(path, "other.wav"), pianoPath = Path.Combine(path, "piano.wav"), vocalsPath = Path.Combine(path, "vocals.wav"); if (!File.Exists(bassPath) || !File.Exists(drumsPath) || !File.Exists(otherPath) || !File.Exists(vocalsPath)) { ProcessError("Essence files not found. Please export with at least 4 parts."); return; } RIFFWaveReader bassReader = null, drumsReader = null, otherReader = null, pianoReader = null, vocalsReader = null; try { bassReader = new RIFFWaveReader(new BinaryReader(File.Open(bassPath, FileMode.Open))); bassReader.ReadHeader(); drumsReader = new RIFFWaveReader(new BinaryReader(File.Open(drumsPath, FileMode.Open))); drumsReader.ReadHeader(); otherReader = new RIFFWaveReader(new BinaryReader(File.Open(otherPath, FileMode.Open))); otherReader.ReadHeader(); vocalsReader = new RIFFWaveReader(new BinaryReader(File.Open(vocalsPath, FileMode.Open))); vocalsReader.ReadHeader(); if (File.Exists(pianoPath)) { pianoReader = new RIFFWaveReader(new BinaryReader(File.Open(pianoPath, FileMode.Open))); pianoReader.ReadHeader(); } } catch (IOException ex) { if (bassReader != null) { bassReader.Dispose(); } if (drumsReader != null) { drumsReader.Dispose(); } if (pianoReader != null) { pianoReader.Dispose(); } if (otherReader != null) { otherReader.Dispose(); } if (vocalsReader != null) { vocalsReader.Dispose(); } ProcessError(ex.Message); return; } float[] finalMix = new float[bassReader.Length * 8]; float[] source = Read(bassReader, "bass", pianoReader == null ? .1 : .08); Render(source, finalMix, GetMatrix(bass), GetLFE(bassLFE), "bass", pianoReader == null ? .1 : .08); source = Read(drumsReader, "drums", pianoReader == null ? .1 : .08); Render(source, finalMix, GetMatrix(drums), GetLFE(drumsLFE), "drums", pianoReader == null ? .1 : .08); if (pianoReader != null) { source = Read(pianoReader, "piano", .08); Render(source, finalMix, GetMatrix(piano), GetLFE(pianoLFE), "piano", .08); } source = Read(otherReader, "other", pianoReader == null ? .1 : .08); Render(source, finalMix, GetMatrix(other), GetLFE(otherLFE), "other", pianoReader == null ? .1 : .08); source = Read(vocalsReader, "vocals", pianoReader == null ? .1 : .08); Render(source, finalMix, GetMatrix(vocals), GetLFE(vocalsLFE), "vocals", pianoReader == null ? .1 : .08); task.UpdateProgressBar(.8); task.UpdateStatus("Checking peaks..."); float peak = 1; for (long i = 0; i < finalMix.LongLength; ++i) { if (peak < Math.Abs(finalMix[i])) { peak = Math.Abs(finalMix[i]); } } if (peak != 1) { task.UpdateProgressBar(.85); task.UpdateStatus("Normalizing..."); float mul = 1 / peak; for (long i = 0; i < finalMix.LongLength; ++i) { finalMix[i] *= mul; } } task.UpdateProgressBar(.9); task.UpdateStatus("Exporting to render.wav (0.00%)..."); using (RIFFWaveWriter writer = new RIFFWaveWriter(new BinaryWriter(File.Open(Path.Combine(path, "render.wav"), FileMode.Create)), 8, bassReader.Length, bassReader.SampleRate, BitDepth.Int16)) { writer.WriteHeader(); const long blockSize = 8192; for (long sample = 0; sample < finalMix.LongLength;) { double progress = sample / (double)finalMix.LongLength; writer.WriteBlock(finalMix, sample, Math.Min(sample += blockSize, finalMix.LongLength)); task.UpdateProgressBar(.9 + .1 * progress); task.UpdateStatusLazy(string.Format("Exporting to render.wav ({0})...", progress.ToString("0.00%"))); } } task.UpdateProgressBar(1); task.UpdateStatus("Finished!"); }
private void LoadFiles(object sender, RoutedEventArgs e) { AudioReader responseReader = Import("Response.wav"); if (responseReader == null) { return; } AudioReader impulseReader = Import("Impulse.wav"); if (impulseReader == null) { return; } float[] response = responseReader.Read(), impulse = impulseReader.Read(); if (responseReader.SampleRate != impulseReader.SampleRate) { Error("The sample rate of the two clips don't match."); return; } int responseChannels = responseReader.ChannelCount, impulseChannels = impulseReader.ChannelCount; if (impulseChannels != 1 && impulseChannels != responseChannels) { Error("The channel count of the two clips don't match. A single-channel impulse is also acceptable."); return; } int fftSize = Math.Max( QMath.Base2Ceil((int)responseReader.Length), QMath.Base2Ceil((int)impulseReader.Length) ); if (padding.IsChecked.Value) { Array.Resize(ref response, fftSize + response.Length); Array.Copy(response, 0, response, fftSize, response.Length - fftSize); Array.Clear(response, 0, fftSize); fftSize = Math.Max(fftSize, QMath.Base2Ceil(response.Length)); } Complex[] impulseFFT = new Complex[fftSize], responseFFT = new Complex[fftSize]; FFTCache cache = new FFTCache(fftSize); float[] responseChannel = new float[response.Length / responseChannels]; for (int channel = 0; channel < responseChannels; ++channel) { if (channel < impulseChannels) // After the channel count check this runs once or for each channel { float[] impulseChannel = impulse; if (impulseChannels != 1) { impulseChannel = new float[impulseReader.Length]; WaveformUtils.ExtractChannel(impulse, impulseChannel, channel, impulseChannels); Array.Clear(impulseFFT, 0, fftSize); } for (int sample = 0; sample < impulseChannel.Length; ++sample) { impulseFFT[sample].Real = impulseChannel[sample]; } Measurements.InPlaceFFT(impulseFFT, cache); } if (responseChannels == 1) { responseChannel = response; } else { WaveformUtils.ExtractChannel(response, responseChannel, channel, responseChannels); } if (channel != 1) { Array.Clear(responseFFT, 0, fftSize); } for (int sample = 0; sample < responseChannel.Length; ++sample) { responseFFT[sample].Real = responseChannel[sample]; } Measurements.InPlaceFFT(responseFFT, cache); for (int sample = 0; sample < fftSize; ++sample) { responseFFT[sample].Divide(impulseFFT[sample]); } Measurements.InPlaceIFFT(responseFFT, cache); for (int i = 0, channels = responseChannels; i < responseChannel.Length; ++i) { response[channels * i + channel] = responseFFT[i].Real; } } exporter.FileName = "Deconvolved.wav"; if (exporter.ShowDialog().Value) { BinaryWriter handler = new BinaryWriter(File.OpenWrite(exporter.FileName)); using RIFFWaveWriter writer = new RIFFWaveWriter(handler, responseChannels, responseReader.Length, responseReader.SampleRate, responseReader.Bits); writer.Write(response); } }