/// ======================================================================================================= public static byte[] CreateBlankWave(uint length_ms, WAVFormat fmt) { uint newdatasize = ConvertMsToNumberOfBytes(length_ms, new WAVFormat(fmt.NumberOfChannels, fmt.SampleRate, fmt.ByteDepth)); uint defaultheadersize = 44; byte[] newdata = new byte[defaultheadersize + newdatasize]; int count = 0; string text = "RIFF4567WAVEfmt 67890123456789012345data0123"; // number stubs are replaced below foreach (char c in text) { newdata[count] = Convert.ToByte(c); count++; } Serialise(ref newdata, 4, newdata.Length - 4, 4); // RIFF chunk size Serialise(ref newdata, 16, 16, 4); // fmt chunk size - PCM i.e. no extra parameters Serialise(ref newdata, 20, 1, 2); // audio format - no compression Serialise(ref newdata, 22, (int)fmt.NumberOfChannels, 2); // number of channels Serialise(ref newdata, 24, (int)fmt.SampleRate, 4); // sample rate Serialise(ref newdata, 28, (int)(fmt.SampleRate * fmt.NumberOfChannels * fmt.ByteDepth), 4); // byte rate Serialise(ref newdata, 32, (int)(fmt.NumberOfChannels * fmt.ByteDepth), 2); // bytes per sample Serialise(ref newdata, 34, 24, 2); // bit depth Serialise(ref newdata, 40, (int)newdatasize, 4); // data length return(newdata); }
public static API.Return WAV_GRAPH(string path, string start_ms, string end_ms, string timebase_ms) { int reduction = 10; // Note this is adequate for reporting and fourier transforms path = API.DISK.AutoAddExt(path, ".wav"); List <CATMessage> cm = new List <CATMessage>(); if (File.Exists(path)) { byte[] alldata = File.ReadAllBytes(path); WAVFormat fmt = ReadFormat(alldata); int startofdata = GetStartOfDataIndex(alldata); uint start = 0; uint end = fmt.Length; uint timebasems = 1000; try { start = string.IsNullOrWhiteSpace(start_ms) ? 0 : ConvertMsToNumberOfBytes(Convert.ToUInt32(start_ms), fmt); } catch (Exception e) { cm.Add(new CATMessage(CAT.ErrorMsg(e), CAT.Status.FAIL)); } try { end = string.IsNullOrWhiteSpace(end_ms) ? fmt.Length : ConvertMsToNumberOfBytes((Convert.ToUInt32(end_ms)), fmt); } catch (Exception e) { cm.Add(new CATMessage(CAT.ErrorMsg(e), CAT.Status.FAIL)); } try { timebasems = string.IsNullOrWhiteSpace(timebase_ms) ? 1000 : Convert.ToUInt32(Convert.ToDouble(timebase_ms)); } catch (Exception e) { cm.Add(new CATMessage(CAT.ErrorMsg(e), CAT.Status.FAIL)); } cm.Add(new CATMessage("Start:" + ConvertNumberOfBytesToMs(start, fmt) + "ms End:" + ConvertNumberOfBytesToMs(end, fmt) + "ms Timebase:" + timebasems, CAT.Status.INFO)); byte[] newdata = new byte[end - start]; Array.Copy(alldata, startofdata + start, newdata, 0, end - start); List <List <API.Xy> > timewaves = BytesToWave(newdata, fmt, reduction); List <API.ChartData> allcharts = new List <API.ChartData> { new API.ChartData(timewaves, new API.TimeData(timebasems), path) }; return(new API.Return(allcharts, cm)); } return(new Return(new CATMessage(path + " does not exist or has issues"))); }
/// ======================================================================================================= public static void WAV_MAKE(string length_ms, string tone_path, string tone_note, string new_note, string output_folder, string decay_norm, string number_of_channels, string sample_rate, string byte_depth) { WAVFormat fmt = new WAVFormat(number_of_channels, sample_rate, byte_depth); uint length = Convert.ToUInt32(length_ms); byte[] newdata = CreateBlankWave(length, fmt); string[] alllines = File.ReadAllLines(tone_path); double tone_frequency = GetFrequency(tone_note); // Relative base frequency double new_frequency = GetFrequency(new_note); double decay = string.IsNullOrWhiteSpace(decay_norm) ? 0.99999 : Convert.ToDouble(decay_norm); foreach (string line in alllines) { string[] split = line.Split('\t'); AddFrequency(new_frequency * Convert.ToDouble(split[0]) / tone_frequency, ref newdata, fmt, Convert.ToDouble(split[1]), decay); } if (!Directory.Exists(output_folder)) { Directory.CreateDirectory(output_folder); } File.WriteAllBytes(DISK.AutoIncrementFilename(output_folder + @"\" + new_note + ".wav"), newdata); }
/// ======================================================================================================= public static string WAV_MIN_MAX(string path) { if (File.Exists(path)) { byte[] alldata = File.ReadAllBytes(path); WAVFormat fmt = ReadFormat(alldata); int startofdata = GetStartOfDataIndex(alldata); double max = 0; double min = 0; for (int i = startofdata; i < alldata.Length - startofdata; i += (int)fmt.ByteDepth) { int sample = Deserialise(alldata, i, (int)fmt.ByteDepth); double norm = Normalise(sample, (int)fmt.ByteDepth); if (norm > max) { max = norm; } if (norm < min) { min = norm; } } return(max.ToString() + " - " + min.ToString()); } return("File not found"); }
/// ======================================================================================================= public static void WAV_CUT_ALL(string path, string start_offset_ms, string cut_size_ms, string shift_length_ms) { byte[] alldata = File.ReadAllBytes(path); WAVFormat fmt = ReadFormat(alldata); uint startoffset = ConvertMsToNumberOfBytes(Convert.ToUInt32(start_offset_ms), fmt); uint cutsize = ConvertMsToNumberOfBytes(Convert.ToUInt32(cut_size_ms), fmt); uint shiftlength = ConvertMsToNumberOfBytes(Convert.ToUInt32(shift_length_ms), fmt); int datasize; int headersize = GetStartOfDataIndex(alldata, out datasize); long newfilesize = cutsize + headersize; long newdatasize = cutsize; while (datasize > shiftlength && datasize > cutsize) // ensure reduced alldata is larger than cutsize and shiftlength { // Build newdata, as cutsize from startoffset GetStartOfDataIndex(alldata, out datasize); byte[] newdata = new byte[newfilesize]; Array.Copy(alldata, 0, newdata, 0, headersize); // copy header SetDataSize(ref newdata, headersize, (int)newdatasize); SetRiffSize(ref newdata, (int)newfilesize - 8); Array.Copy(alldata, headersize + startoffset, newdata, headersize, newdatasize); // copy wave data // Reduce alldata by shift length byte[] bufdata = new byte[alldata.Length - shiftlength]; Array.Copy(alldata, 0, bufdata, 0, headersize); // copy header Array.Copy(alldata, headersize + shiftlength, bufdata, headersize, bufdata.Length - headersize); // copy wave data from shiftlength alldata = bufdata; SetDataSize(ref alldata, headersize, bufdata.Length - headersize); SetRiffSize(ref newdata, bufdata.Length - 8); path = DISK.AutoIncrementFilename(path); File.WriteAllBytes(DISK.AutoIncrementFilename(path), newdata); } }
/// ======================================================================================================= public static void WAV_TRIM(string path, string front_ms, string back_ms, string over_write) { byte[] alldata = File.ReadAllBytes(path); WAVFormat fmt = ReadFormat(alldata); bool overwrite = Convert.ToBoolean(over_write); uint front_trim_length = ConvertMsToNumberOfBytes(Convert.ToUInt32(front_ms), fmt); uint back_trim_length = ConvertMsToNumberOfBytes(Convert.ToUInt32(back_ms), fmt); int datasize; int headersize = GetStartOfDataIndex(alldata, out datasize); while (front_trim_length % fmt.ByteDepth != 0) { front_trim_length++; } long newfilesize = alldata.Length - front_trim_length - back_trim_length; long newdatasize = datasize - front_trim_length - back_trim_length; byte[] newdata = new byte[newfilesize]; Array.Copy(alldata, 0, newdata, 0, headersize); // copy header SetDataSize(ref newdata, headersize, (int)newdatasize); SetRiffSize(ref newdata, (int)newfilesize - 8); Array.Copy(alldata, headersize + front_trim_length, newdata, headersize, newdatasize); if (overwrite) { File.WriteAllBytes(path, newdata); } else { File.WriteAllBytes(DISK.AutoIncrementFilename(path), newdata); } }
/// ======================================================================================================= public static void WAV_STRETCH(string path, string factor) { byte[] alldata = File.ReadAllBytes(path); WAVFormat fmt = ReadFormat(alldata); double sampletofactor = Convert.ToDouble(factor); int startofdata = GetStartOfDataIndex(alldata); uint newdatasize = (uint)((double)alldata.Length * sampletofactor); long newfilesize = newdatasize + startofdata; byte[] newdata = new byte[newdatasize]; Array.Copy(alldata, 0, newdata, 0, startofdata); // copy header SetDataSize(ref newdata, startofdata, (int)newdatasize); SetRiffSize(ref newdata, (int)newfilesize - 8); for (int i = 0; i < newdatasize; i += (int)fmt.ByteDepth) { double newid = i / sampletofactor; int ni = (int)Math.Round(newid); int newi = ni / ((int)fmt.ByteDepth * 2); newi = newi * ((int)fmt.ByteDepth * 2); if (startofdata + newi < alldata.Length - 100) { int sample = Deserialise(alldata, startofdata + newi, (int)fmt.ByteDepth); Serialise(ref newdata, i + startofdata, (int)sample, (int)fmt.ByteDepth); } } File.WriteAllBytes(DISK.AutoIncrementFilename(path), newdata); }
/// ======================================================================================================= public static void GetDoubleArrayFromBytes(byte[] alldata, out double[] left, out double[] right) { WAVFormat fmt = ReadFormat(alldata); long sample_rate = fmt.NumberOfChannels * fmt.SampleRate; int startofdata = GetStartOfDataIndex(alldata); int arraylength = (alldata.Length - startofdata) / (int)(fmt.NumberOfChannels * fmt.ByteDepth); left = new double[arraylength]; right = new double[arraylength]; int sample_count = 0; for (int i = startofdata; i < alldata.Length - startofdata; i += (int)fmt.NumberOfChannels * (int)fmt.ByteDepth) { int sample = Deserialise(alldata, i, (int)fmt.ByteDepth); double norm_sample = Normalise(sample, (int)fmt.ByteDepth); left[sample_count] = norm_sample; if (fmt.NumberOfChannels == 2) { sample = Deserialise(alldata, i + (int)fmt.ByteDepth, (int)fmt.ByteDepth); norm_sample = Normalise(sample, (int)fmt.ByteDepth); right[sample_count] = norm_sample; } sample_count++; } }
/// ======================================================================================================= public static uint ConvertNumberOfBytesToMs(uint numberbytes, WAVFormat fmt) { // Many ulong casts required to ensure that there is no integer overflow ulong temp = (ulong)((ulong)numberbytes * 1000 / ((ulong)fmt.NumberOfChannels * (ulong)fmt.SampleRate * (ulong)fmt.ByteDepth)); return((uint)temp); }
// FEATURES /// ======================================================================================================= public static void WAV_CUT(string path, string start_offset_ms, string cut_size_ms, string over_write) { byte[] alldata = File.ReadAllBytes(path); WAVFormat fmt = ReadFormat(alldata); bool overwrite = Convert.ToBoolean(over_write); uint startoffset = ConvertMsToNumberOfBytes(Convert.ToUInt32(start_offset_ms), fmt); uint cutsize = ConvertMsToNumberOfBytes(Convert.ToUInt32(cut_size_ms), fmt); int startofdata = GetStartOfDataIndex(alldata); int newfilesize = (int)cutsize + startofdata; int newdatasize = (int)cutsize; byte[] newdata = new byte[newfilesize]; Array.Copy(alldata, 0, newdata, 0, startofdata); // copy header SetDataSize(ref newdata, startofdata, newdatasize); SetRiffSize(ref newdata, newfilesize - 8); Array.Copy(alldata, startofdata + startoffset, newdata, startofdata, newdatasize); if (overwrite) { File.WriteAllBytes(path, newdata); } else { File.WriteAllBytes(DISK.AutoIncrementFilename(path), newdata); } }
// TODO unused: /// ======================================================================================================= public static List <API.Xy> GetWave(byte[] snippet, SterioChannel channel, WAVFormat fmt) { long sample_rate = fmt.NumberOfChannels * fmt.SampleRate; List <API.Xy> wave = new List <API.Xy>(); int sample_count = 0; int sample = 0; double norm_sample = 0; for (int i = 0; i < snippet.Length - (int)fmt.ByteDepth; i += (int)fmt.ByteDepth) { if (fmt.NumberOfChannels == 2) { if (sample_count % 2 == 0 && channel == SterioChannel.Left) { sample = Deserialise(snippet, i, (int)fmt.ByteDepth); norm_sample = Normalise(sample, (int)fmt.ByteDepth); wave.Add(new API.Xy((double)sample_count / (double)sample_rate, norm_sample)); } else { sample = Deserialise(snippet, i, (int)fmt.ByteDepth); norm_sample = Normalise(sample, (int)fmt.ByteDepth); wave.Add(new API.Xy((double)sample_count / (double)sample_rate, norm_sample)); } } else { sample = Deserialise(snippet, i, (int)fmt.ByteDepth); norm_sample = Normalise(sample, (int)fmt.ByteDepth); wave.Add(new API.Xy((double)sample_count / (double)sample_rate, norm_sample)); } sample_count++; } return(wave); }
// FEATURES /// ======================================================================================================= public static Return READ_FMT(string path) { byte[] header = new byte[1024]; FileStream fs = new FileStream(path, FileMode.Open); fs.Read(header, 0, header.Length); fs.Close(); WAVFormat fmt = ReadFormat(header); return(new Return("NumberofChannels:" + fmt.NumberOfChannels, "SampleRate:" + fmt.SampleRate, "ByteDepth:" + fmt.ByteDepth, "Length:" + ConvertNumberOfBytesToMs(fmt.Length, fmt) + "ms")); }
/// ======================================================================================================= public static void WAV_VOL(string path, string vol_0_to_1) { byte[] alldata = File.ReadAllBytes(path); WAVFormat fmt = ReadFormat(alldata); int startofdata = GetStartOfDataIndex(alldata); for (int i = startofdata; i < alldata.Length - startofdata; i += (int)fmt.ByteDepth) { int sample = Deserialise(alldata, i, (int)fmt.ByteDepth); double temp = (double)sample * Convert.ToDouble(vol_0_to_1); Serialise(ref alldata, i, (int)temp, (int)fmt.ByteDepth); } File.WriteAllBytes(DISK.AutoIncrementFilename(path), alldata); }
// FEATURES /// ======================================================================================================= public static void WAV_LP_FILTER(string path, string cut_off_hz, string start_ms, string end_ms) { byte[] alldata = File.ReadAllBytes(path); double cutoff = Convert.ToDouble(cut_off_hz); int startofdata = GetStartOfDataIndex(alldata); WAVFormat fmt = ReadFormat(alldata); uint total = (uint)(alldata.Length - startofdata) / (fmt.NumberOfChannels * fmt.ByteDepth); uint start = 0; try { start = ConvertMsToNumberOfBytes(Convert.ToUInt32(start_ms), fmt) / (fmt.NumberOfChannels * fmt.ByteDepth); } catch { } uint end = total; try { end = ConvertMsToNumberOfBytes(Convert.ToUInt32(end_ms), fmt) / (fmt.NumberOfChannels * fmt.ByteDepth); } catch { } double[] left; double[] right; GetDoubleArrayFromBytes(alldata, out left, out right); double[] leftsection = new double[end - start]; double[] rightsection = new double[end - start]; Array.Copy(left, start, leftsection, 0, leftsection.Length); Array.Copy(right, start, rightsection, 0, rightsection.Length); LPFilter.Butterworth(ref leftsection, fmt.SampleRate, cutoff); LPFilter.Butterworth(ref rightsection, fmt.SampleRate, cutoff); Array.Copy(leftsection, 0, left, start, leftsection.Length); Array.Copy(rightsection, 0, right, start, rightsection.Length); double[,] allsamples = new double[fmt.NumberOfChannels, left.Length]; for (int i = 0; i < fmt.NumberOfChannels; i++) { for (int j = 0; j < left.Length; j++) { if (i == 0) { allsamples[i, j] = left[j]; } else { allsamples[i, j] = right[j]; } } } byte[] data = GetBytesFromDoubleArray(allsamples, fmt); Array.Copy(data, 0, alldata, startofdata, data.Length); File.WriteAllBytes(DISK.AutoIncrementFilename(path), alldata); }
/// ======================================================================================================= public static byte[] GetBytesFromDoubleArray(double[,] input_data, WAVFormat fmt) { byte[] data = new byte[input_data.GetLength(1) * fmt.ByteDepth * fmt.NumberOfChannels]; int count = 0; for (int i = 0; i < input_data.GetLength(1); i++) { for (int j = 0; j < fmt.NumberOfChannels; j++) { Serialise(ref data, count, Denormalise(input_data[j, i], (int)fmt.ByteDepth), (int)fmt.ByteDepth); count += (int)fmt.ByteDepth; } } return(data); }
// Utilities /// ======================================================================================================= public static List <Section> GetActivatedSections(byte[] alldata, double activation_amplitude_norm, uint activation_duration_ms, uint activation_negative_offset_ms) { WAVFormat fmt = ReadFormat(alldata); uint duration = WAV.ConvertMsToNumberOfBytes(activation_duration_ms, fmt); int startofdata = GetStartOfDataIndex(alldata); int newfilesize = alldata.Length; List <Section> sections = new List <Section>(); int activator = 0; bool activated = false; double sectionstart = 0.0; double sectionpeak = 0.0; for (int i = startofdata; i < newfilesize - startofdata; i += (int)fmt.ByteDepth) { int sample = WAV.Deserialise(alldata, i, (int)fmt.ByteDepth); double norm_sample = WAV.Normalise(sample, (int)fmt.ByteDepth); if (Math.Abs(norm_sample) > activation_amplitude_norm) { activated = true; if (activator == 0) { sectionstart = WAV.ConvertNumberOfBytesToMs((uint)i, fmt); if (sectionstart > activation_negative_offset_ms) { sectionstart = sectionstart - activation_negative_offset_ms; } } sectionpeak = norm_sample > sectionpeak ? norm_sample : sectionpeak; activator = (int)duration; } else { if (activated && activator == 0) { uint sectionend = WAV.ConvertNumberOfBytesToMs((uint)i, fmt); sections.Add(new Section(sectionstart, sectionend, sectionpeak)); sectionpeak = 0.0; activated = false; } } activator = activator - (int)fmt.ByteDepth <= 0 ? 0 : activator - (int)fmt.ByteDepth; } if (activated) { sections.Add(new Section(sectionstart, WAV.ConvertNumberOfBytesToMs((uint)(newfilesize - startofdata), fmt), sectionpeak)); } return(sections); }
/// ======================================================================================================= public static void WAV_SNIP(string path, string from_start_offset_ms, string from_end_offset_ms, string over_write) { byte[] alldata = File.ReadAllBytes(path); WAVFormat fmt = ReadFormat(alldata); bool overwrite = Convert.ToBoolean(over_write); uint start = Convert.ToUInt32(from_start_offset_ms); uint end = Convert.ToUInt32(from_end_offset_ms); if (overwrite) { File.WriteAllBytes(path, WavSnip(alldata, start, end)); } else { File.WriteAllBytes(DISK.AutoIncrementFilename(path), WavSnip(alldata, start, end)); } }
/// ======================================================================================================= public static List <List <API.Xy> > GetWaves(byte[] alldata) { WAVFormat fmt = ReadFormat(alldata); long sample_rate = fmt.NumberOfChannels * fmt.SampleRate; int startofdata = GetStartOfDataIndex(alldata); List <API.Xy> left = new List <API.Xy>(); List <API.Xy> right = new List <API.Xy>(); int sample_count = 0; for (int i = startofdata; i < alldata.Length - startofdata; i += (int)fmt.ByteDepth) { int sample = Deserialise(alldata, i, (int)fmt.ByteDepth); double norm_sample = Normalise(sample, (int)fmt.ByteDepth); if (fmt.NumberOfChannels == 2) { if (sample_count % 2 == 0) { left.Add(new API.Xy((double)sample_count / (double)sample_rate, norm_sample)); } else { right.Add(new API.Xy((double)sample_count / (double)sample_rate, norm_sample)); } } else { left.Add(new API.Xy((double)sample_count / (double)sample_rate, norm_sample)); } sample_count++; } if (fmt.NumberOfChannels == 2) { return(new List <List <API.Xy> >() { left, right }); } else { return(new List <List <API.Xy> >() { left }); } }
// FEATURES /// ======================================================================================================= public static API.Return WAV_FFT(string path, string max_frequency) { byte[] alldata = File.ReadAllBytes(path); int max = string.IsNullOrWhiteSpace(max_frequency) ? 1000 : Convert.ToInt32(max_frequency); WAVFormat fmt = ReadFormat(alldata); List <List <API.Xy> > waves = GetWaves(alldata); List <List <API.Xy> > frequency = null; if (fmt.NumberOfChannels == 2) { frequency = GetWAVFFT(waves[0], waves[1], max); } else { frequency = GetWAVFFT(waves[0], null, max); } return(new API.Return(new API.ChartData(frequency, new API.FrequencyData(1), path))); }
/// ======================================================================================================= public static void AddFrequency(double frequency, ref byte[] newdata, WAVFormat fmt, double vol, double decay) { double x = 0.0; double newvol = 1000 * vol / frequency; int startofdata = GetStartOfDataIndex(newdata); double scroller = frequency * 2.0 * Math.PI / fmt.SampleRate; double bitdepth = Math.Pow(2, (8 * fmt.ByteDepth)); int increment = (int)(fmt.NumberOfChannels * fmt.ByteDepth); for (int i = startofdata; i < newdata.Length; i += increment) { int y = Deserialise(newdata, i, (int)fmt.ByteDepth); y += (int)(newvol * bitdepth * Math.Sin(x)); Serialise(ref newdata, i, y, (int)fmt.ByteDepth); x += scroller; newvol = newvol * decay; } }
// FEATURES /// ======================================================================================================= public static void WAV_FADE(string file_path, string front_ms, string back_ms, string over_write) { byte[] alldata = File.ReadAllBytes(file_path); WAVFormat fmt = ReadFormat(alldata); uint front_fade_length = ConvertMsToNumberOfBytes(Convert.ToUInt32(front_ms), fmt); uint back_fade_length = ConvertMsToNumberOfBytes(Convert.ToUInt32(back_ms), fmt); bool overwrite = string.IsNullOrWhiteSpace(over_write) ? false : Convert.ToBoolean(over_write); int datasize; int headersize = GetStartOfDataIndex(alldata, out datasize); long endoffile = headersize + datasize; double plusser = front_fade_length == 0 ? 1.0 : 0.0; uint stepsize = fmt.ByteDepth; for (int i = headersize; i < endoffile - stepsize; i += (int)stepsize) { int sample = Deserialise(alldata, i, (int)fmt.ByteDepth); if (i < front_fade_length) { double temp = plusser * (double)sample; plusser = plusser + ((double)stepsize / front_fade_length); sample = (int)temp; Serialise(ref alldata, i, sample, (int)fmt.ByteDepth); } else if (i > endoffile - back_fade_length) { double temp = plusser * (double)sample; plusser = plusser - ((double)stepsize / back_fade_length); sample = (int)temp; Serialise(ref alldata, i, sample, (int)fmt.ByteDepth); } else if (i > front_fade_length) { plusser = 1.0; } } if (overwrite) { File.WriteAllBytes(file_path, alldata); } else { File.WriteAllBytes(DISK.AutoIncrementFilename(file_path), alldata); } }
/// ======================================================================================================= public static void WAV_VOL_STERIO(string path, string vol_left_0_to_1, string vol_right_0_to_1) { byte[] alldata = File.ReadAllBytes(path); WAVFormat fmt = ReadFormat(alldata); int startofdata = GetStartOfDataIndex(alldata); bool alternator = true; double volleft = Convert.ToDouble(vol_left_0_to_1); double volright = Convert.ToDouble(vol_right_0_to_1); for (int i = startofdata; i < alldata.Length - startofdata; i += (int)fmt.ByteDepth) { int sample = Deserialise(alldata, i, (int)fmt.ByteDepth); double vol = alternator ? volleft : volright; alternator = !alternator; double temp = (double)sample * vol; Serialise(ref alldata, i, (int)temp, (int)fmt.ByteDepth); } File.WriteAllBytes(DISK.AutoIncrementFilename(path), alldata); }
// FEATURES /// ======================================================================================================= public static void WAV_DFT(string path, string max_frequency, string activation_amplitude_norm) { byte[] alldata = File.ReadAllBytes(path); int max = string.IsNullOrWhiteSpace(max_frequency) ? 1000 : Convert.ToInt32(max_frequency); double amplitude = Convert.ToDouble(activation_amplitude_norm); WAVFormat fmt = ReadFormat(alldata); List <List <API.Xy> > waves = GetWaves(alldata); List <List <API.Xy> > frequency = null; if (fmt.NumberOfChannels == 2) { frequency = GetWAVDFT(waves[0], waves[1], max); } else { frequency = GetWAVDFT(waves[0], null, max); } API.Graph.Milliseconds(new API.ChartData(frequency, new API.FrequencyData(1), path), "DFT"); // TODO }
/// ======================================================================================================= public static List <List <API.Xy> > BytesToWave(byte[] alldata, WAVFormat fmt, int reduction_factor = 10) { double sample_rate = fmt.NumberOfChannels * fmt.SampleRate / reduction_factor; List <API.Xy> left = new List <API.Xy>(); List <API.Xy> right = new List <API.Xy>(); int sample_count = 0; for (int i = 0; i < alldata.Length - (2 * fmt.ByteDepth * reduction_factor); i += ((int)fmt.ByteDepth * reduction_factor)) { int sample = Deserialise(alldata, i, (int)fmt.ByteDepth); double norm_sample = Normalise(sample, (int)fmt.ByteDepth); if (fmt.NumberOfChannels == 2) { if (sample_count % 2 == 0) { left.Add(new API.Xy(sample_count / sample_rate, norm_sample)); } else { right.Add(new API.Xy(sample_count / sample_rate, norm_sample)); } } else { left.Add(new API.Xy(sample_count / sample_rate, norm_sample)); } sample_count++; } if (fmt.NumberOfChannels == 2) { return(new List <List <API.Xy> >() { left, right }); } else { return(new List <List <API.Xy> >() { left }); } }
/// ======================================================================================================= public static void WAV_STERIO_SWAP(string path) { byte[] alldata = File.ReadAllBytes(path); WAVFormat fmt = ReadFormat(alldata); if (fmt.NumberOfChannels == 2) { int startofdata = GetStartOfDataIndex(alldata); for (int i = startofdata; i < alldata.Length - startofdata - fmt.ByteDepth; i += (int)fmt.ByteDepth * 2) { int sampleleft = Deserialise(alldata, i, (int)fmt.ByteDepth); int sampleright = Deserialise(alldata, i + (int)fmt.ByteDepth, (int)fmt.ByteDepth); int newleft = sampleright; int newright = sampleleft; Serialise(ref alldata, i, (int)newleft, (int)fmt.ByteDepth); Serialise(ref alldata, i + (int)fmt.ByteDepth, (int)newright, (int)fmt.ByteDepth); } File.WriteAllBytes(DISK.AutoIncrementFilename(path), alldata); } }
/// ======================================================================================================= public static byte[] GetBytesFromWaves(List <List <API.Xy> > waves, WAVFormat fmt) { byte[] data = new byte[waves[0].Count * fmt.ByteDepth * fmt.NumberOfChannels]; int count = 0; foreach (API.Xy sample in waves[0]) { Serialise(ref data, count, Denormalise(sample.Y, (int)fmt.ByteDepth), (int)fmt.ByteDepth); count += (int)fmt.ByteDepth * (int)fmt.NumberOfChannels; } if (fmt.NumberOfChannels == 2) { count = (int)fmt.ByteDepth; foreach (API.Xy sample in waves[1]) { Serialise(ref data, count, Denormalise(sample.Y, (int)fmt.ByteDepth), (int)fmt.ByteDepth); count += (int)fmt.ByteDepth * (int)fmt.NumberOfChannels; } } return(data); }
/// ======================================================================================================= public static byte[] WavSnip(byte[] alldata, uint from_start_offset_ms, uint from_end_offset_ms) { WAVFormat fmt = ReadFormat(alldata); uint startoffset = ConvertMsToNumberOfBytes(from_start_offset_ms, fmt); while (startoffset % fmt.ByteDepth != 0) { startoffset++; } uint cutsize = ConvertMsToNumberOfBytes((from_end_offset_ms - from_start_offset_ms), fmt); int startofdata = GetStartOfDataIndex(alldata); long newfilesize = cutsize + startofdata; long newdatasize = cutsize; byte[] newdata = new byte[newfilesize]; Array.Copy(alldata, 0, newdata, 0, startofdata); // copy header SetDataSize(ref newdata, startofdata, (int)newdatasize); SetRiffSize(ref newdata, (int)newfilesize - 8); Array.Copy(alldata, startofdata + startoffset, newdata, startofdata, newdatasize); return(newdata); }
// FEATURES /// ======================================================================================================= public static void WAV_MAKE_ALL(string length_ms, string tone_path, string tone_note, string output_folder, string decay_norm, string number_of_channels, string sample_rate, string byte_depth) { WAVFormat fmt = new WAVFormat(number_of_channels, sample_rate, byte_depth); uint length = Convert.ToUInt32(length_ms); string[] alltonelines = File.ReadAllLines(tone_path); double tone_frequency = GetFrequency(tone_note); // Relative base frequency double decay = string.IsNullOrWhiteSpace(decay_norm) ? 0.99999 : Convert.ToDouble(decay_norm); for (int i = 1; i < 7; i++) // Above the 7th octave, the sound becomes too high pitched for music { foreach (KeyValuePair <string, double> note in Notes) { string new_note = note.Key + i; string filename = DISK.AutoAddBaseDirectory(output_folder + "\\" + new_note + ".wav"); if (!File.Exists(filename)) { byte[] newdata = CreateBlankWave(length, fmt); double new_frequency = GetFrequency(new_note); foreach (string line in alltonelines) { string[] split = line.Split('\t'); AddFrequency(new_frequency * Convert.ToDouble(split[0]) / tone_frequency, ref newdata, fmt, Convert.ToDouble(split[1]), decay); } if (!Directory.Exists(output_folder)) { Directory.CreateDirectory(output_folder); } File.WriteAllBytes(filename, newdata); } } } }
// FEATURES /// ======================================================================================================= public static void WAV_SHIFT_RIGHT(string path, string offset_ms) // This adds presence by offsetting right from left { byte[] alldata = File.ReadAllBytes(path); WAVFormat fmt = new WAVFormat(1, 96000, 3); // Use the highest quality possible uint offset = ConvertMsToNumberOfBytes(Convert.ToUInt32(offset_ms), fmt); while (offset % fmt.ByteDepth != 0) { offset++; } int startofdata = GetStartOfDataIndex(alldata); int datasize = (int)GetRiffSize(alldata) - startofdata; byte[] newdata = CreateBlankWave(ConvertNumberOfBytesToMs((uint)datasize, fmt), fmt); int newdatapos = 44; for (int alldatapos = startofdata; alldatapos < alldata.Length - (int)fmt.ByteDepth - (2 * offset); alldatapos += (int)(fmt.NumberOfChannels * fmt.ByteDepth)) { Serialise(ref newdata, newdatapos, Deserialise(alldata, alldatapos, (int)fmt.ByteDepth), (int)fmt.ByteDepth); Serialise(ref newdata, newdatapos + (int)fmt.ByteDepth, Deserialise(alldata, alldatapos + (int)fmt.ByteDepth + (int)offset, (int)fmt.ByteDepth), (int)fmt.ByteDepth); newdatapos += (int)(fmt.NumberOfChannels * fmt.ByteDepth); } File.WriteAllBytes(DISK.AutoIncrementFilename(path), newdata); }
/// ======================================================================================================= public static void WAV_TONE(string path, string output_path, string activation_amplitude_norm) { byte[] alldata = File.ReadAllBytes(path); double amplitude = Convert.ToDouble(activation_amplitude_norm) - 0.5; WAVFormat fmt = ReadFormat(alldata); List <List <Xy> > waves = GetWaves(alldata); List <List <Xy> > fft = null; if (fmt.NumberOfChannels == 2) { fft = GetWAVFFT(waves[0], waves[1], 3000); } else { fft = GetWAVFFT(waves[0], null, 3000); } string output_text = ""; foreach (Section section in WAV.GetActivatedFrequencies(fft, amplitude)) { output_text += section.X1 + "\t" + (section.Peak + 0.5) + "\n"; } File.WriteAllText(DISK.AutoIncrementFilename(output_path), output_text); }
/// <summary> /// Returns a WAVFormat struct containing audio format information /// (# channels, sample rate, and bits per sample) for a WAV file. /// </summary> /// <param name="pFilename">The name of the file about which to retrieve format information</param> /// <returns>A WAVFormat struct object containing the audio format information for the open file</returns> public static WAVFormat GetAudioFormat(String pFilename) { WAVFormat format = new WAVFormat(); WAVFile audioFile = new WAVFile(); if (audioFile.Open(pFilename, WAVFileMode.READ) == "") { format.BitsPerSample = audioFile.mBitsPerSample; format.NumChannels = audioFile.mNumChannels; format.SampleRateHz = audioFile.mSampleRateHz; audioFile.Close(); } return (format); }