private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e) { int startPos = (int)numericStartPos.Value; int outputSamples = (int)numericOutputSamples.Value; string path = textBoxReadWavFile.Text; WavData wavData = new WavData(); Console.WriteLine(rm.GetString("ReadFileStarted"), path); using (BinaryReader br1 = new BinaryReader(File.Open(path, FileMode.Open))) { if (!wavData.Read(br1)) { resultString = string.Format(rm.GetString("ReadFileFailFormat"), path) + "\r\n"; e.Result = false; return; } if (wavData.NumSamples < startPos + outputSamples) { resultString = string.Format(rm.GetString("WavFileTooShort"), startPos + outputSamples, wavData.NumSamples, path) + "\r\n"; e.Result = false; return; } } Console.WriteLine(rm.GetString("WavFileSummary"), wavData.NumSamples); resultString += string.Format(rm.GetString("WavFileSummary"), wavData.NumSamples); double offset = (double)numericUpDownSubSampleOffset.Value; if (checkBoxCh0.Checked && !checkBoxCh1.Checked) { using (StreamWriter sw = new StreamWriter(textBoxWriteFile.Text)) { for (int i=startPos; i < startPos + outputSamples; ++i) { sw.WriteLine("{0} {1}", i+offset, wavData.Sample16Get(0, i)); } } } else if (!checkBoxCh0.Checked && checkBoxCh1.Checked) { using (StreamWriter sw = new StreamWriter(textBoxWriteFile.Text)) { for (int i=startPos; i < startPos + outputSamples; ++i) { sw.WriteLine("{0} {1}", i + offset, wavData.Sample16Get(1, i)); } } } else if (checkBoxCh0.Checked && checkBoxCh1.Checked) { using (StreamWriter sw = new StreamWriter(textBoxWriteFile.Text)) { for (int i=startPos; i < startPos + outputSamples; ++i) { sw.WriteLine("{0} {1} {2}", i + offset, wavData.Sample16Get(0, i), wavData.Sample16Get(1, i)); } } } e.Result = true; }
private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e) { int sampleDelay; double w1w2VolumeRatio; if (!SampleDelay(wavRead1, wavRead2, out sampleDelay, out w1w2VolumeRatio)) { e.Result = false; resultString = rm.GetString("TwoWavFilesTooDifferent"); return; } if (!checkBoxAutoAdjustVolumeDifference.Checked) { w1w2VolumeRatio = 1.0; } int numSamples = wavRead1.NumSamples - 2 * Math.Abs(sampleDelay); if (wavRead2.NumSamples < wavRead1.NumSamples) { numSamples = wavRead2.NumSamples - 2 * Math.Abs(sampleDelay); } List <PcmSamples1Channel> samples = new List <PcmSamples1Channel>(); for (int i = 0; i < wavRead1.NumChannels; ++i) { PcmSamples1Channel ps = new PcmSamples1Channel(numSamples, wavRead1.BitsPerSample); samples.Add(ps); } long acc = 0; int maxDiff = 0; float magnitude = (float)Magnitude; if (0 <= sampleDelay) { for (int ch = 0; ch < wavRead1.NumChannels; ++ch) { PcmSamples1Channel ps = samples[ch]; for (int sample = 0; sample < numSamples; ++sample) { int diff = (int)(wavRead1.Sample16Get(ch, sample) - wavRead2.Sample16Get(ch, sample + sampleDelay) * w1w2VolumeRatio); int absDiff = Math.Abs(diff); acc += absDiff; if (maxDiff < absDiff) { maxDiff = absDiff; } ps.Set16(sample, (short)(diff * magnitude)); } } } else { // sampleDelay < 0 for (int ch = 0; ch < wavRead1.NumChannels; ++ch) { PcmSamples1Channel ps = samples[ch]; for (int sample = 0; sample < numSamples; ++sample) { int diff = (int)(wavRead1.Sample16Get(ch, sample - sampleDelay) - wavRead2.Sample16Get(ch, sample) * w1w2VolumeRatio); int absDiff = Math.Abs(diff); acc += absDiff; if (maxDiff < absDiff) { maxDiff = absDiff; } ps.Set16(sample, (short)(diff * magnitude)); } } } if (0 == acc) { e.Result = false; resultString = rm.GetString("TwoWavFilesAreExactlyTheSame"); return; } WavData wav = new WavData(); wav.Create(wavRead1.SampleRate, wavRead1.BitsPerSample, samples); if (0 < maxDiff) { int maxMagnitude = 32767 / maxDiff; resultString = string.Format(rm.GetString("DiffStatistics"), (double)acc / wav.NumSamples, maxDiff, maxMagnitude); Console.WriteLine(resultString); if (32767 < maxDiff * magnitude) { Console.WriteLine(rm.GetString("OutputFileLevelOver"), maxMagnitude); } } try { using (BinaryWriter bw = new BinaryWriter(File.Open(textBoxWrite.Text, FileMode.CreateNew))) { wav.Write(bw); } } catch (Exception ex) { resultString = ex.ToString(); e.Result = false; } e.Result = true; }
/** @param delay_return [out] (0 < delay_return) w1 is delayed by delay samples * (delay_return < 0) w2 is delayed by delay samples * @param w1w2VolumeRatio_return [out] >1: w1 volume is larger than w2, <1: w1 volume is smaller than w2 */ private bool SampleDelay(WavData w1, WavData w2, out int delay_return, out double w1w2VolumeRatio_return) { float ACCUMULATE_SECONDS_MAX = (float)AccumulateSecondsMax; float DELAY_SECONDS_MAX = (float)DelaySecondsMax; delay_return = 0; SortedDictionary<long, VolumeInfo> delayValueAndPos = new SortedDictionary<long, VolumeInfo>(); int samplesPerSecond = w1.SampleRate; /* assume w1 is delayed (0 < delay) */ for (int delay=0; delay < samplesPerSecond * DELAY_SECONDS_MAX; ++delay) { VolumeInfo vi = new VolumeInfo(); vi.delay = delay; for (int pos=0; pos < samplesPerSecond * ACCUMULATE_SECONDS_MAX; ++pos) { int w1Value = Math.Abs(w1.Sample16Get(0, pos)); int w2Value = Math.Abs(w2.Sample16Get(0, pos + delay)); vi.w1Volume += w1Value; vi.w2Volume += w2Value; vi.accumulatedDiff += Math.Abs(w1Value - w2Value); } // Console.Write("[{0} {1}]", delay, acc); if (!delayValueAndPos.ContainsKey(vi.accumulatedDiff)) { delayValueAndPos[vi.accumulatedDiff] = vi; } backgroundWorker1.ReportProgress(delay * 50 / (int)(samplesPerSecond * DELAY_SECONDS_MAX)); } /* assume w2 is delayed (delay < 0) */ for (int delay=1; delay < samplesPerSecond * DELAY_SECONDS_MAX; ++delay) { VolumeInfo vi = new VolumeInfo(); vi.delay = -delay; for (int pos=0; pos < samplesPerSecond * ACCUMULATE_SECONDS_MAX; ++pos) { int w1Value = Math.Abs(w1.Sample16Get(0, pos + delay)); int w2Value = Math.Abs(w2.Sample16Get(0, pos)); vi.w1Volume += w1Value; vi.w2Volume += w2Value; vi.accumulatedDiff += Math.Abs(w1Value - w2Value); } // Console.Write("[{0} {1}]", -delay, acc); if (!delayValueAndPos.ContainsKey(vi.accumulatedDiff)) { delayValueAndPos[vi.accumulatedDiff] = vi; } backgroundWorker1.ReportProgress(50 + delay * 50 / (int)(samplesPerSecond * DELAY_SECONDS_MAX)); } SortedDictionary<long, VolumeInfo>.Enumerator e = delayValueAndPos.GetEnumerator(); e.MoveNext(); w1w2VolumeRatio_return = (double)e.Current.Value.w1Volume / e.Current.Value.w2Volume; delay_return = e.Current.Value.delay; Console.WriteLine(); Console.WriteLine(rm.GetString("SampleDelaySummary"), delay_return, (double)delay_return / samplesPerSecond, (double)e.Current.Key / (samplesPerSecond * DELAY_SECONDS_MAX), w1w2VolumeRatio_return); if (w1w2VolumeRatio_return < 0.5 || 2.0 < w1w2VolumeRatio_return) { return false; } return true; }
/** @param delay_return [out] (0 < delay_return) w1 is delayed by delay samples * (delay_return < 0) w2 is delayed by delay samples * @param w1w2VolumeRatio_return [out] >1: w1 volume is larger than w2, <1: w1 volume is smaller than w2 */ private bool SampleDelay(WavData w1, WavData w2, out int delay_return, out double w1w2VolumeRatio_return) { float ACCUMULATE_SECONDS_MAX = (float)AccumulateSecondsMax; float DELAY_SECONDS_MAX = (float)DelaySecondsMax; delay_return = 0; SortedDictionary <long, VolumeInfo> delayValueAndPos = new SortedDictionary <long, VolumeInfo>(); int samplesPerSecond = w1.SampleRate; /* assume w1 is delayed (0 < delay) */ for (int delay = 0; delay < samplesPerSecond * DELAY_SECONDS_MAX; ++delay) { VolumeInfo vi = new VolumeInfo(); vi.delay = delay; for (int pos = 0; pos < samplesPerSecond * ACCUMULATE_SECONDS_MAX; ++pos) { int w1Value = Math.Abs(w1.Sample16Get(0, pos)); int w2Value = Math.Abs(w2.Sample16Get(0, pos + delay)); vi.w1Volume += w1Value; vi.w2Volume += w2Value; vi.accumulatedDiff += Math.Abs(w1Value - w2Value); } // Console.Write("[{0} {1}]", delay, acc); if (!delayValueAndPos.ContainsKey(vi.accumulatedDiff)) { delayValueAndPos[vi.accumulatedDiff] = vi; } backgroundWorker1.ReportProgress(delay * 50 / (int)(samplesPerSecond * DELAY_SECONDS_MAX)); } /* assume w2 is delayed (delay < 0) */ for (int delay = 1; delay < samplesPerSecond * DELAY_SECONDS_MAX; ++delay) { VolumeInfo vi = new VolumeInfo(); vi.delay = -delay; for (int pos = 0; pos < samplesPerSecond * ACCUMULATE_SECONDS_MAX; ++pos) { int w1Value = Math.Abs(w1.Sample16Get(0, pos + delay)); int w2Value = Math.Abs(w2.Sample16Get(0, pos)); vi.w1Volume += w1Value; vi.w2Volume += w2Value; vi.accumulatedDiff += Math.Abs(w1Value - w2Value); } // Console.Write("[{0} {1}]", -delay, acc); if (!delayValueAndPos.ContainsKey(vi.accumulatedDiff)) { delayValueAndPos[vi.accumulatedDiff] = vi; } backgroundWorker1.ReportProgress(50 + delay * 50 / (int)(samplesPerSecond * DELAY_SECONDS_MAX)); } SortedDictionary <long, VolumeInfo> .Enumerator e = delayValueAndPos.GetEnumerator(); e.MoveNext(); w1w2VolumeRatio_return = (double)e.Current.Value.w1Volume / e.Current.Value.w2Volume; delay_return = e.Current.Value.delay; Console.WriteLine(); Console.WriteLine(rm.GetString("SampleDelaySummary"), delay_return, (double)delay_return / samplesPerSecond, (double)e.Current.Key / (samplesPerSecond * DELAY_SECONDS_MAX), w1w2VolumeRatio_return); if (w1w2VolumeRatio_return < 0.5 || 2.0 < w1w2VolumeRatio_return) { return(false); } return(true); }