AudioEditorForm.cs

Download AudioEditorForm.cs File

using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq; using System.Text; using System.Text.RegularExpressions; using System.Threading.Tasks; using System.Windows.Forms; using System.IO; using NAudio; using NAudio.Wave; using System.Speech; using System.Speech.Recognition; using Microsoft.VisualBasic; namespace VoiceEditor_Capstone { public partial class VoiceEditorForm : Form { public VoiceEditorForm() { InitializeComponent(); } //DATA BITS// static string directoryPath = AppDomain.CurrentDomain.BaseDirectory.ToString(); static string voiceDirectory = directoryPath + @ " Voices\ " ; static string workingDirectory = directoryPath + @ " WorkingData\ " ; string selectedVoiceDirectory = null; string selectedRecordDirectory = null; List < string > voices = null; string selectedVoice = null; private WaveFileReader waveReader = null; private DirectSoundOut waveOut = null; private WaveIn wi = null; private WaveOut wo = null; private WaveFileWriter waveWriter = null; bool recording = false; string recordedFilePath = null; string sourceWavefile = null; string workingWavefile = null; string constructWavefile = null; string latestRecording = null; string trimmedWav = null; string oldTrimmedWav = null; string construct = null; private void VoiceEditorForm_Load(object sender, EventArgs e) { this.WindowState = FormWindowState.Maximized; //ensure working directory exists directoryExist(workingDirectory); //populate voice directory voices = new List < string > (); directoryExist(voiceDirectory); foreach(var directory in Directory.GetDirectories(voiceDirectory)) voices.Add(directory); voicesComboBox.Items.Add( " < Add New Voice > " ); foreach (var voice in voices) voicesComboBox.Items.Add(Path.GetFileName(voice)); } //OPEN WAV FILES// private void openSourceWav(string file) { sourceWavefile = file; sourceWaveViewer.WaveStream = new WaveFileReader(file); sourceWaveViewer.FitToScreen(); } private void openWorkingWav(string file) { workingWavefile = file; workingWaveViewer.WaveStream = new WaveFileReader(file); workingWaveViewer.FitToScreen(); } private void openConstructWav(string file) { constructWavefile = file; constructWaveViewer.WaveStream = new WaveFileReader(file); constructWaveViewer.FitToScreen(); } //SHOW WAVEFORM// private void openToolStripMenuItem_Click(object sender, EventArgs e) { OpenFileDialog open = new OpenFileDialog(); open.Filter = " Wave File (*.wav)|*.wav; " ; if (open.ShowDialog() != DialogResult.OK) return; openSourceWav(open.FileName); } //PLAYING WAV FILES// private void playWav(string waveFile) { disposeWave(); waveReader = new WaveFileReader(waveFile); waveOut = new DirectSoundOut(); waveOut.Init(new WaveChannel32(waveReader)); if (waveOut != null) { waveOut.Play(); } } private void playToolStripMenuItem1_Click(object sender, EventArgs e) { playWav(sourceWavefile); //disposeWave(); //waveReader = new WaveFileReader(sourceWavefile); //waveOut = new DirectSoundOut(); //waveOut.Init(new WaveChannel32(waveReader)); //if (waveOut != null) //{ // waveOut.Play(); //} } //RECORDING WAV FILES// private void wi_DataAvailable(object sender, WaveInEventArgs e) { waveWriter.Write(e.Buffer, 0, e.BytesRecorded); int seconds = (int)(waveWriter.Length / waveWriter.WaveFormat.AverageBytesPerSecond); if (seconds > 120) wi.StopRecording(); } private void wi_RecordingStopped(object sender, EventArgs e) { wi.Dispose(); waveWriter.Close(); waveWriter.Dispose(); waveWriter = null; updateOpenSourceWav(latestRecording); } private void updateOpenSourceWav(string wavFilePath) { if (File.Exists(wavFilePath)) openSourceWav(wavFilePath); } //TRIM WAVE FILES// public void TrimWave(string waveIn, string waveOut, TimeSpan fromStart, TimeSpan fromEnd) { disposeWave(); using(WaveFileReader wfr = new WaveFileReader(waveIn)) { using (WaveFileWriter wfw = new WaveFileWriter(waveOut, wfr.WaveFormat)) { int bytesPerMillisecond = wfr.WaveFormat.AverageBytesPerSecond / 1000; int start = (int)fromStart.TotalMilliseconds * bytesPerMillisecond; start = start - start % wfr.WaveFormat.BlockAlign; //move start back to nearest block int endBytes = (int)fromEnd.TotalMilliseconds * bytesPerMillisecond; endBytes = endBytes - endBytes % wfr.WaveFormat.BlockAlign; int end = (int)wfr.Length - endBytes; TrimWaveFile(wfr, wfw, start, end); //wfr.Dispose(); //wfw.Dispose(); } } } private void TrimWaveFile(WaveFileReader wfr, WaveFileWriter wfw, int startPos, int endPos) { { wfr.Position = startPos; byte[] buffer = new byte[1024]; while (wfr.Position < endPos) { int bytesRequired = (int)(endPos - wfr.Position); if (bytesRequired > 0) { int bytesToRead = Math.Min(bytesRequired, buffer.Length); int bytesRead = wfr.Read(buffer, 0, bytesToRead); if (bytesRead > 0) { wfw.Write(buffer, 0, bytesRead); } } } } } //JOINING WAVE FILES// public static void Concatenate(string outputFile, IEnumerable < string > sourceFiles) { byte[] buffer = new byte[1024]; WaveFileWriter wfw = null; try { foreach(string file in sourceFiles) { using(WaveFileReader reader = new WaveFileReader(file)) { if (wfw == null) wfw = new WaveFileWriter(outputFile, reader.WaveFormat); else { if (!reader.WaveFormat.Equals(wfw.WaveFormat)) throw new InvalidOperationException( " Can't concatenate. Filetype mismatch. " ); } int read; while ((read = reader.Read(buffer, 0, buffer.Length)) > 0) wfw.Write(buffer, 0, read); } } } finally { if (wfw != null) wfw.Dispose(); } } //ADDING NEW VOICE DIRECTORIES// private void addVoiceDirectory(string directoryPath) { Directory.CreateDirectory(directoryPath); } //OTHER TOOLS// private void directoryExist(string directory) //Determines if a given directory exists. If not, creates it. { if(!Directory.Exists(directory)) { Directory.CreateDirectory(directory); } } //PLAYING TIMER / POSITION TRACKER// public Timer playTimer; double wavPosition; double lastWavPosition; public void sourcePlayLine() { if(playTimer != null) disposePlayTimer(); wavPosition = (double)(sourceWaveViewer.pixelPerMillisecond() * waveReader.CurrentTime.TotalMilliseconds); lastWavPosition = wavPosition; sourceWaveViewer.drawWavePosition(wavPosition); playTimer = new Timer(); playTimer.Interval = 1; playTimer.Tick += new EventHandler(sourcePlayTimer_Tick); playTimer.Enabled = true; playTimer.Start(); } private void sourcePlayTimer_Tick(object sender, EventArgs e) { wavPosition = (double)(sourceWaveViewer.pixelPerMillisecond() * waveReader.CurrentTime.TotalMilliseconds); sourceWaveViewer.drawWavePosition(lastWavPosition); sourceWaveViewer.drawWavePosition(wavPosition); lastWavPosition = wavPosition; if (wavPosition > = sourceWaveViewer.Width) { playTimer.Enabled = false; sourceWaveViewer.drawWavePosition(lastWavPosition); disposePlayTimer(); } } public void workingPlayLine() { if (playTimer != null) disposePlayTimer(); wavPosition = (double)(workingWaveViewer.pixelPerMillisecond() * waveReader.CurrentTime.TotalMilliseconds); lastWavPosition = wavPosition; workingWaveViewer.drawWavePosition(wavPosition); playTimer = new Timer(); playTimer.Interval = 1; playTimer.Tick += new EventHandler(workingPlayTimer_Tick); playTimer.Enabled = true; playTimer.Start(); } private void workingPlayTimer_Tick(object sender, EventArgs e) { wavPosition = (double)(workingWaveViewer.pixelPerMillisecond() * waveReader.CurrentTime.TotalMilliseconds); workingWaveViewer.drawWavePosition(lastWavPosition); workingWaveViewer.drawWavePosition(wavPosition); lastWavPosition = wavPosition; if (wavPosition > = workingWaveViewer.Width) { playTimer.Enabled = false; workingWaveViewer.drawWavePosition(lastWavPosition); disposePlayTimer(); } } public void constructPlayLine() { if (playTimer != null) disposePlayTimer(); wavPosition = (double)(constructWaveViewer.pixelPerMillisecond() * waveReader.CurrentTime.TotalMilliseconds); lastWavPosition = wavPosition; constructWaveViewer.drawWavePosition(wavPosition); playTimer = new Timer(); playTimer.Interval = 1; playTimer.Tick += new EventHandler(constructPlayTimer_Tick); playTimer.Enabled = true; playTimer.Start(); } private void constructPlayTimer_Tick(object sender, EventArgs e) { wavPosition = (double)(constructWaveViewer.pixelPerMillisecond() * waveReader.CurrentTime.TotalMilliseconds); constructWaveViewer.drawWavePosition(lastWavPosition); constructWaveViewer.drawWavePosition(wavPosition); lastWavPosition = wavPosition; if (wavPosition > = constructWaveViewer.Width) { playTimer.Enabled = false; constructWaveViewer.drawWavePosition(lastWavPosition); disposePlayTimer(); } } private void disposePlayTimer() { if(playTimer != null) { playTimer.Stop(); playTimer.Enabled = false; playTimer.Dispose(); playTimer = null; } sourceWaveViewer.FitToScreen(); workingWaveViewer.FitToScreen(); constructWaveViewer.FitToScreen(); } //CLEANUP// private void disposeWave() { if(waveOut != null) { if (waveOut.PlaybackState == NAudio.Wave.PlaybackState.Playing) waveOut.Stop(); waveOut.Dispose(); waveOut = null; } if(waveReader != null) { waveReader.Dispose(); waveReader = null; } } private void VoiceEditorForm_FormClosing(object sender, FormClosingEventArgs e) { disposeWave(); } //BUTTON CLICK EVENTS// private void sourcePlayBtn_Click(object sender, EventArgs e) { if (sourceWavefile != null) { playWav(sourceWavefile); sourcePlayLine(); } } private void workingPlayBtn_Click(object sender, EventArgs e) { if (workingWavefile != null) { playWav(workingWavefile); workingPlayLine(); } } private void sourceRecordBtn_Click(object sender, EventArgs e) { if (!recording) { if (sourceWavefile != null) { var userConfirm = MessageBox.Show( " An audio wave source already exists. If you continue, any unsaved data will be lost. " , " Continue? " , MessageBoxButtons.YesNo); if (userConfirm == DialogResult.No) return; } recording = true; sourceRecordBtn.Text = " Stop Recording " ; wi = new WaveIn(WaveCallbackInfo.FunctionCallback()); latestRecording = selectedRecordDirectory + " recordedWav( " + DateTime.Now.ToString( " yyyy-MM-dd_hh-mm-ss " ) + " ).wav " ; waveWriter = new WaveFileWriter(latestRecording, wi.WaveFormat); wi.DataAvailable += new EventHandler < WaveInEventArgs > (wi_DataAvailable); wi.RecordingStopped += new EventHandler < StoppedEventArgs > (wi_RecordingStopped); wi.WaveFormat = new WaveFormat(8000, 1); wi.StartRecording(); } else //recording { recording = false; sourceRecordBtn.Text = " Record " ; wi.StopRecording(); //wi.Dispose(); //waveWriter.Dispose(); //openSourceWav(latestRecording); } } private void sourceTrimBtn_Click(object sender, EventArgs e) { disposePlayTimer(); trimmedWav = selectedRecordDirectory + @ " trimmedSource " + DateTime.Now.ToString( " yyyy-MM-dd_hh-mm-ss " ) + " ).wav " ; TrimWave(sourceWavefile, trimmedWav, sourceWaveViewer.fromStart, sourceWaveViewer.fromEnd); //playWav(trimmedWav); openWorkingWav(trimmedWav); } private void workingSaveBtn_Click(object sender, EventArgs e) { if (wordTxtbox.Text == null) { MessageBox.Show( " Please enter what word is being saved in the textbox to the right. " ); return; } if (File.Exists(selectedVoiceDirectory + " \\ " + wordTxtbox.Text + " .wav " )) { var userConfirm = MessageBox.Show( " An audio clip for this word already exists for the selected user. Overwrite with the new clip? " , " Overwrite? " , MessageBoxButtons.YesNo); if (userConfirm == DialogResult.No) return; else File.Delete(selectedVoiceDirectory + " \\ " + wordTxtbox.Text + " .wav " ); } File.Copy(trimmedWav, selectedVoiceDirectory + " \\ " + wordTxtbox.Text + " .wav " ); } private void constructPlayBtn_Click(object sender, EventArgs e) { if (constructWavefile != null) { playWav(constructWavefile); constructPlayLine(); } } //WIP FUNCTIONS// private void voicesComboBox_SelectedIndexChanged(object sender, EventArgs e) { if (voicesComboBox.Text == " < Add New Voice > " ) { string input = Interaction.InputBox( " Enter voice name. " , " Add New Voice " , " " , -1, -1); Regex rgx = new Regex(@ " [^\w\s] " ); string cleanedInput = rgx.Replace(input, string.Empty); if (cleanedInput != " " ) { bool voiceExists = false; foreach (string name in voicesComboBox.Items) { if (name == cleanedInput) { MessageBox.Show( " Voice files already exist under this name. " ); voiceExists = true; } } if (!voiceExists) { voicesComboBox.Items.Add(cleanedInput); directoryExist(voiceDirectory + cleanedInput); voicesComboBox.Text = cleanedInput; selectedVoice = cleanedInput; } } else { if(input != " " ) MessageBox.Show(input); } } else { selectedVoice = voicesComboBox.Text; selectedVoiceDirectory = voiceDirectory + selectedVoice + @ " \VoiceData " ; selectedRecordDirectory = voiceDirectory + selectedVoice + @ " \RawData " ; directoryExist(selectedVoiceDirectory); directoryExist(selectedRecordDirectory); } } private void constructButton_Click(object sender, EventArgs e) { if(selectedVoice != null) { string concatenation = null; string desiredPhrase = phraseBox.Text; Regex rgx = new Regex( " [^a-zA-Z -] " ); string parsedPhrase = rgx.Replace(desiredPhrase, " " ); parsedPhrase = parsedPhrase.ToLower(); string[] phrase = parsedPhrase.Split(' '); List < string > files = new List < string > (); foreach (string word in phrase) { string findFile = selectedVoiceDirectory + " \\ " + word + " .wav " ; //string findFile = @ " C:\Users\Anumidium\Desktop\Capstone Project\VoiceEditor_Capstone\VoiceEditor_Capstone\bin\Debug\VoiceData\bradblank\hello.wav " ; if (File.Exists(findFile)) files.Add(findFile); else MessageBox.Show( " No match for ' " + word + " ' in " + voicesComboBox.Text + " 's directory. " ); } concatenation = desiredPhrase + " ( " + DateTime.Now.ToString( " yyyy-MM-dd_hh-mm-ss " ) + " ) " ; Concatenate(workingDirectory + concatenation + " .wav " , files); openConstructWav(workingDirectory + concatenation + " .wav " ); } } private void playSelectedToolStripMenuItem_Click(object sender, EventArgs e) { string trimmedWav = workingDirectory + @ " trimmedSource.wav " ; TrimWave(sourceWavefile, trimmedWav, sourceWaveViewer.fromStart, sourceWaveViewer.fromEnd); playWav(trimmedWav); openWorkingWav(trimmedWav); } private void reTrimButton_Click(object sender, EventArgs e) { disposePlayTimer(); oldTrimmedWav = trimmedWav; trimmedWav = selectedRecordDirectory + @ " trimmedSource " + DateTime.Now.ToString( " yyyy-MM-dd_hh-mm-ss " ) + " ).wav " ; TrimWave(oldTrimmedWav, trimmedWav, workingWaveViewer.fromStart, workingWaveViewer.fromEnd); openWorkingWav(trimmedWav); workingUndoButton.Enabled = true; } private void workingUndo_Click(object sender, EventArgs e) { workingUndoButton.Enabled = false; if(oldTrimmedWav != null) { trimmedWav = oldTrimmedWav; oldTrimmedWav = null; openWorkingWav(trimmedWav); } } private void stopButton_Click(object sender, EventArgs e) { disposePlayTimer(); disposeWave(); } } }