public void TestAdaptiveSpectrogram() { // test variables var audioSystem = BassProxy.Instance; // 0. Get Audio Data float[] audioSamples = BassProxy.ReadMonoFromFile(WAVE_INPUT_FILEPATH, SAMPLING_RATE); var aspec = new AdaptiveSpectrogram(SAMPLING_RATE); int blockSize = aspec.GetPreferredBlockSize(); // 2048 int stepSize = aspec.GetPreferredStepSize(); // 1024 = 50% overlap // print out a normal spectrogram for comparison double[][] spec1 = FFTUtils.CreateSpectrogramLomont(audioSamples, blockSize, stepSize); var spec1M = new Matrix(spec1).Transpose(); spec1M.DrawMatrixImage("spec1_normal.png", -1, -1, true, true); // split the signal into chunks to feed the AdaptiveSpectrogram var chunks = MathUtils.Split(audioSamples, stepSize, false); int chunkLength = chunks.Count(); Console.WriteLine("Chunk count: {0}", chunkLength); int count = 1; IEnumerable <double[]> spec = new double[0][]; float[] lastChunk = null; foreach (var chunk in chunks) { Console.Write("Processing chunk: {0} \r", count); if (lastChunk != null) { // add two chunks together, because adaptive spectrogram expects 50% overlap var z = new float[lastChunk.Length + chunk.Count()]; lastChunk.CopyTo(z, 0); chunk.ToArray().CopyTo(z, chunk.Count()); // process two last chunks as one (e.g. 50% overlap) var chunkData = aspec.Process(z); // store in spectrogram spec = spec.Concat(chunkData); //var chunkM = new Matrix(chunkData); //chunkM.WriteCSV("chunkData_" + count + ".csv"); } lastChunk = chunk.ToArray(); count++; } var specM = new Matrix(spec.ToArray()).Transpose(); //specM.WriteCSV("spec_all.csv"); specM.DrawMatrixImage("spec_adaptive.png", -1, -1, true, true); }
/// <summary> /// Create log-spectrogram (spaced according to manager's parameters) /// </summary> /// <param name = "proxy">Proxy used in generating the spectrogram</param> /// <param name = "filename">Filename to be processed</param> /// <param name = "milliseconds">Milliseconds to be analyzed</param> /// <param name = "startmilliseconds">Starting point</param> /// <returns>Logarithmically spaced bins within the power spectrum</returns> public float[][] CreateLogSpectrogram(IWaveformPlayer proxy, string filename, int milliseconds, int startmilliseconds) { //read 5512 Hz, Mono, PCM, with a specific proxy float[] samples = BassProxy.ReadMonoFromFile(filename, SampleRate, milliseconds, startmilliseconds); //NormalizeInPlace(samples); int overlap = Overlap; int fftWindowsSize = WdftSize; double[] windowArray = FFTWindow.GetWindowFunction(FFTWindowType.HANNING, fftWindowsSize); int width = (samples.Length - fftWindowsSize) / overlap; /*width of the image*/ float[][] frames = new float[width][]; float[] complexSignal = new float[2 * fftWindowsSize]; /*even - Re, odd - Img*/ for (int i = 0; i < width; i++) { //take 371 ms each 11.6 ms (2048 samples each 64 samples) for (int j = 0; j < fftWindowsSize /*2048*/; j++) { // Weight by Hann Window complexSignal[2 * j] = (float)(windowArray[j] * samples[i * overlap + j]); //complexSignal[2*j] = (float) (_windowArray[j]*samples[i*overlap + j]); /*Weight by Hann Window*/ complexSignal[2 * j + 1] = 0; } //FFT transform for gathering the spectrum Fourier.FFT(complexSignal, fftWindowsSize, FourierDirection.Forward); frames[i] = ExtractLogBins(complexSignal); } return(frames); }
public void TestMethod() { const double silence = 0.0001; var wavDataSmall = new float[] { 0.0001f, -0.8f, 0.05f, -0.05f, 0.2f, 0.4f, 1.0f, 0.0001f }; Bitmap png = AudioAnalyzer.DrawWaveformMono(wavDataSmall, new Size(1000, 600), 1, 1, 0, 44100); string fileName = String.Format("wave-small-dataset-{0}.png", 1); png.Save(fileName); // crop float[] wavDataSmallCropped = AudioUtils.CropAudioAtSilence(wavDataSmall, silence, false, 0); png = AudioAnalyzer.DrawWaveformMono(wavDataSmallCropped, new Size(1000, 600), 1, 1, 0, 44100); fileName = String.Format("wave-small-dataset-cropped{0}.png", 1); png.Save(fileName); // init audio system var audioSystem = BassProxy.Instance; float[] wavDataBig = BassProxy.ReadMonoFromFile(WAVE_INPUT_FILEPATH, 44100, 10, 0); png = AudioAnalyzer.DrawWaveformMono(wavDataBig, new Size(1000, 600), 2000, 1, 0, 44100); fileName = String.Format("wave-big-dataset-{0}.png", 1); png.Save(fileName); // crop float[] wavDataBigCropped = AudioUtils.CropAudioAtSilence(wavDataBig, silence, false, 0); png = AudioAnalyzer.DrawWaveformMono(wavDataBigCropped, new Size(1000, 600), 1, 1, 0, 44100); fileName = String.Format("wave-big-dataset-cropped{0}.png", 1); png.Save(fileName); }
public void TestSpectrogram() { // harmor_LQ.bmp = 1645 (width) x 255 (height) 32 bit // harmor_HQ.bmp = 1645 (width) x 511 (height) 32 bit // test variables var audioSystem = BassProxy.Instance; // 0. Get Audio Data float[] audioSamples = BassProxy.ReadMonoFromFile(WAVE_INPUT_FILEPATH, SAMPLING_RATE); /* * // generate spectrogram * Bitmap spectroBW = AudioAnalyzer.GetSpectrogramImage(audioSamples, -1, 591, SAMPLING_RATE, WINDOW_SIZE, OVERLAP, ColorUtils.ColorPaletteType.BLACK_AND_WHITE, true); * spectroBW.Save(@"spectrogram-log-blackwhite.png"); * * Bitmap spectro = AudioAnalyzer.GetSpectrogramImage(audioSamples, -1, 591, SAMPLING_RATE, WINDOW_SIZE, OVERLAP, ColorUtils.ColorPaletteType.PHOTOSOUNDER, true); * spectro.Save(@"spectrogram-log-photosounder.png"); * * Bitmap spectro2 = AudioAnalyzer.GetSpectrogramImage(audioSamples, -1, 591, SAMPLING_RATE, WINDOW_SIZE, OVERLAP, ColorUtils.ColorPaletteType.REW, true); * spectro2.Save(@"spectrogram-log-rew.png"); * * Bitmap spectro3 = AudioAnalyzer.GetSpectrogramImage(audioSamples, -1, 591, SAMPLING_RATE, WINDOW_SIZE, OVERLAP, ColorUtils.ColorPaletteType.SOX, true); * spectro3.Save(@"spectrogram-log-sox.png"); * * Bitmap spectro4 = AudioAnalyzer.GetSpectrogramImage(audioSamples, -1, 591, SAMPLING_RATE, WINDOW_SIZE, OVERLAP, ColorUtils.ColorPaletteType.MATLAB, true); * spectro4.Save(@"spectrogram-log-matlab.png"); */ //double minFrequency = 27.5; //double maxFrequency = SAMPLING_RATE / 2; //int logBins = 512; //var logFrequenciesIndex = new int[1]; //var logFrequencies = new float[1]; // find the time int wanted_width = 1645; //int width = (audioSamples.Length - WINDOW_SIZE)/ OVERLAP; int OVERLAP = (int)((double)(audioSamples.Length - WINDOW_SIZE) / (double)wanted_width); // int OVERLAP = WINDOW_SIZE/2; int numberOfSamples = audioSamples.Length; double seconds = numberOfSamples / SAMPLING_RATE; float[][] spectrogram = AudioAnalyzer.CreateSpectrogramLomont(audioSamples, WINDOW_SIZE, OVERLAP); int width = spectrogram.Length + 2 * 60; int height = spectrogram[0].Length + 2 * 40; Bitmap bmp1 = AudioAnalyzer.GetSpectrogramImage(spectrogram, width, height, seconds * 1000, SAMPLING_RATE, ColorUtils.ColorPaletteType.BLACK_AND_WHITE, false, null, null); bmp1.Save(@"spectrogram-blackwhite.png"); Bitmap bmp2 = AudioAnalyzer.GetSpectrogramImage(audioSamples, width, height, SAMPLING_RATE, WINDOW_SIZE, OVERLAP, ColorUtils.ColorPaletteType.BLACK_AND_WHITE, true); bmp2.Save(@"spectrogram-blackwhite-2.png"); }
/// <summary> /// Load one file into a specific cell /// </summary> /// <param name="file">file info</param> /// <param name="selectedCell">selectedCell cell</param> void LoadFileIntoCell(FileInfo file, int selectedCell) { if (file.Extension.Equals(".h2p")) { var wavetable = Zebra2OSCPreset.Read(file.FullName); if (wavetable != null) { // clear first ClearAllCells(); // set the data for (int i = 0; i < wavetable.Length; i++) { Array.Copy(wavetable[i], 0, this.soundData[i], 0, 128); // store the raw waves into the morphed data as this is used to morph between this.morphedData[i] = this.soundData[i]; // update the wave displays as well this.waveDisplays[i].WaveData = this.soundData[i]; this.waveDisplays[i].MorphedData = this.morphedData[i]; // TODO: use loaded instead of filename to determine that these are also loaded this.waveDisplays[i].FileName = file.FullName; this.waveDisplays[i].Loaded = true; this.waveDisplays[i].Refresh(); } } else { throw new FileLoadException("Could not read the u-he Zebra 2 Oscillator preset file.", file.FullName); } } else { float[] tempAudioBuffer = BassProxy.ReadMonoFromFile(file.FullName); float[] tempAudioBuffer2 = MathUtils.Resample(tempAudioBuffer, 128); Array.Copy(tempAudioBuffer2, 0, this.soundData[selectedCell], 0, 128); // store the raw waves into the morphed data as this is used to morph between this.morphedData[selectedCell] = this.soundData[selectedCell]; // update the wave displays as well this.waveDisplays[selectedCell].WaveData = this.soundData[selectedCell]; this.waveDisplays[selectedCell].MorphedData = this.morphedData[selectedCell]; this.waveDisplays[selectedCell].FileName = file.FullName; this.waveDisplays[selectedCell].Loaded = true; this.waveDisplays[selectedCell].Refresh(); } }
public virtual void SetImportSound(FileInfo file, int selected) { float[] tempAudioBuffer = bassProxy.ReadMonoFromFile(file.FullName, 5512); float[] tempAudioBuffer2 = MathUtils.ReSampleToArbitrary(tempAudioBuffer, 128); Array.Copy(tempAudioBuffer2, 0, this.soundData[selected], 0, 128); // TODO: use lomont instead this.harmonicsData[selected] = Conversions.DFT(this.soundData[selected]); //this.harmonicsData[selected] = Fourier.DFTTransformer.AbsFFT(this.soundData[selected]); this.dftData[selected] = Conversions.iDFT(this.harmonicsData[selected]); //this.dftData[selected] = Fourier.DFTTransformer.IFFT(this.harmonicsData[selected], false, false); this.waveDisplays[selected].HarmonicsData = this.harmonicsData[selected]; this.waveDisplays[selected].WaveData = this.soundData[selected]; this.waveDisplays[selected].DftData = this.dftData[selected]; this.waveDisplays[selected].Refresh(); }
void Audio2MidiInitialise(string inputFilepath) { // init audio system var audioSystem = BassProxy.Instance; //float[] wavData = BassProxy.ReadMonoFromFile(inputFilepath, (int) sampleRate, 1000, 0); float[] wavData = BassProxy.ReadMonoFromFile(inputFilepath, (int)sampleRate); // calculate number of frames and the duration frames = MathUtils.RoundAwayFromZero((double)wavData.Length / (double)bufferSize); audioLength = (double)wavData.Length / (double)sampleRate * 1000; audio2midi = new Audio2Midi(); audio2midi.IsTrackLoaded = true; audio2midi.Initialize(sampleRate, audioChannels, audioLength, frames); ProcessWaveform(audio2midi, wavData); }
/// <summary> /// Create spectrogram of the input file /// </summary> /// <param name = "proxy">Proxy used to read from file</param> /// <param name = "filename">Filename</param> /// <param name = "milliseconds">Milliseconds to process</param> /// <param name = "startmilliseconds">Starting point of the processing</param> /// <returns>Spectrogram</returns> public float[][] CreateSpectrogram(IWaveformPlayer proxy, string filename, int milliseconds, int startmilliseconds, bool doNormalise) { //read 5512 Hz, Mono, PCM, with a specific proxy float[] samples = BassProxy.ReadMonoFromFile(filename, SampleRate, milliseconds, startmilliseconds); if (doNormalise) { NormalizeInPlace(samples); } int overlap = Overlap; int fftWindowsSize = WdftSize; // aka N = FFT Length double[] windowArray = FFTWindow.GetWindowFunction(FFTWindowType.HANNING, fftWindowsSize); int width = (samples.Length - fftWindowsSize) / overlap; /*width of the image*/ float[][] frames = new float[width][]; float[] complexSignal = new float[2 * fftWindowsSize]; /*even - Re, odd - Img*/ for (int i = 0; i < width; i++) { //take 371 ms each 11.6 ms (2048 samples each 64 samples) // apply Hanning Window for (int j = 0; j < fftWindowsSize /*2048*/; j++) { // Weight by Hann Window complexSignal[2 * j] = (float)(windowArray[j] * samples[i * overlap + j]); //complexSignal[2*j] = (float) ((4.0/(fftWindowsSize - 1)) * windowArray[j]*samples[i*overlap + j]); /*Weight by Hann Window*/ complexSignal[2 * j + 1] = 0; // need to clear out as fft modifies buffer } //FFT transform for gathering the spectrum Fourier.FFT(complexSignal, fftWindowsSize, FourierDirection.Forward); float[] band = new float[fftWindowsSize / 2 + 1]; for (int j = 0; j < fftWindowsSize / 2 + 1; j++) { double re = complexSignal[2 * j]; double img = complexSignal[2 * j + 1]; //double img = 0.0; // TODO: Zero out the imaginary component (phase) ? / need to clear out as fft modifies buffer band[j] = (float)Math.Sqrt(re * re + img * img); } frames[i] = band; } return(frames); }
public void TestMelFrequencyFiltering() { var audio = BassProxy.Instance; //const string fileName = @"Tests\Passacaglia, Handel-Saw-86bmp.wav"; const string fileName = @"Tests\Passacaglia, Handel-Sine-86bmp.wav"; const int sampleRate = 44100; const int fftWindowsSize = 2048; const int fftOverlap = 1024; const bool colorize = true; const int melFilters = 120; var monoSignal = BassProxy.ReadMonoFromFile(fileName, sampleRate); double[][] specNormal = FFTUtils.CreateSpectrogramLomont(monoSignal, fftWindowsSize, fftOverlap); var specNormalMat = new Matrix(specNormal).Transpose(); specNormalMat.DrawMatrixImage("spec_normal.png", -1, -1, colorize, true); // Mel Scale Filterbank // Mel-frequency is proportional to the logarithm of the linear frequency, // reflecting similar effects in the human's subjective aural perception) var melFilter = new MelFilter(fftWindowsSize, sampleRate, melFilters, 0); var specNormalMelMat = melFilter.FilterWeights * specNormalMat; specNormalMelMat.DrawMatrixImage("spec_normal_mel.png", -1, -1, colorize, true); melFilter.FilterWeights.WriteCSV("melfilter_orig.csv"); melFilter.FilterWeights.DrawMatrixGraph("melfilter_orig.png"); var melFilterBank = new MelFilterBank(0, sampleRate / 2, melFilters, fftOverlap, sampleRate); var melFilterBankMat = melFilterBank.Matrix; melFilterBankMat.WriteCSV("melfilter_new.csv"); melFilterBankMat.DrawMatrixGraph("melfilter_new.png"); var specNormalMelMatNew = melFilterBankMat * specNormalMat; specNormalMelMatNew.DrawMatrixImage("spec_normal_mel_new.png", -1, -1, colorize, true); }
public static float[] Decode(string fileIn, int srate, int secondsToAnalyze) { DbgTimer t = new DbgTimer(); t.Start(); float[] floatBuffer = null; // check if file exists if (fileIn != null && fileIn != "") { FileInfo fi = new FileInfo(fileIn); if (!fi.Exists) { Console.Out.WriteLine("No file found {0}!", fileIn); return(null); } } // Try to use Un4Seen Bass BassProxy bass = BassProxy.Instance; double duration = bass.GetDurationInSeconds(fileIn); if (duration > 0) { Dbg.WriteLine("Using BASS to decode the file ..."); // duration in seconds if (duration > secondsToAnalyze) { // find segment to extract double startSeconds = (duration / 2 - (secondsToAnalyze / 2)); if (startSeconds < 0) { startSeconds = 0; } floatBuffer = bass.ReadMonoFromFile(fileIn, srate, secondsToAnalyze * 1000, (int)(startSeconds * 1000)); // if this failes, the duration read from the tags was wrong or it is something wrong with the audio file if (floatBuffer == null) { IOUtils.LogMessageToFile(Mir.WARNING_FILES_LOG, fileIn); } } else { // return whole file floatBuffer = bass.ReadMonoFromFile(fileIn, srate, 0, 0); // if this failes, the duration read from the tags was wrong or it is something wrong with the audio file if (floatBuffer == null) { IOUtils.LogMessageToFile(Mir.WARNING_FILES_LOG, fileIn); } } } // Bass failed reading or never even tried, so use another alternative if (floatBuffer == null) { Dbg.WriteLine("Using MPlayer and SOX to decode the file ..."); fileIn = Regex.Replace(fileIn, "%20", " "); floatBuffer = DecodeUsingMplayerAndSox(fileIn, srate, secondsToAnalyze); } return(floatBuffer); }
public void TestFFTAudioMatrixMethod() { // harmor_HQ.bmp = 1645 (width) x 511 (height) 32 bit // test variables const string outputDirectoryFilePath = "test"; var audioSystem = BassProxy.Instance; // 0. Get Audio Data float[] audioSamples = BassProxy.ReadMonoFromFile(WAVE_INPUT_FILEPATH, SAMPLING_RATE); int width = 1645; //int width = (audioSamples.Length - WINDOW_SIZE)/ OVERLAP; int OVERLAP = (int)((double)(audioSamples.Length - WINDOW_SIZE) / (double)width); // 1. Explode samples to the range of 16 bit shorts (–32,768 to 32,767) // Matlab multiplies with 2^15 (32768) // e.g. if( max(abs(speech))<=1 ), speech = speech * 2^15; end; MathUtils.Multiply(ref audioSamples, AUDIO_MULTIPLIER); // zero pad if the audio file is too short to perform a fft if (audioSamples.Length < (WINDOW_SIZE + OVERLAP)) { int lenNew = WINDOW_SIZE + OVERLAP; Array.Resize <float>(ref audioSamples, lenNew); } // 2. Windowing // 3. FFT #region Windowing and FFT var stft = new STFT(FFTWindowType.HANNING, WINDOW_SIZE, OVERLAP); var stftdata = stft.Apply(audioSamples); // same as specgram(audio*32768, 2048, 44100, hanning(2048), 1024); stftdata.DrawMatrixImageLogValues(outputDirectoryFilePath + "_specgram.png", true, false, -1, -1, false); var spect2 = FFTUtils.CreateSpectrogramFFTW(audioSamples, WINDOW_SIZE, OVERLAP); var stftdata2 = new Matrix(spect2).Transpose(); // same as specgram(audio*32768, 2048, 44100, hanning(2048), 1024); stftdata2.DrawMatrixImageLogValues(outputDirectoryFilePath + "_specgram2.png", true, false, -1, -1, false); var spect3 = FFTUtils.CreateSpectrogramLomont(audioSamples, WINDOW_SIZE, OVERLAP); var stftdata3 = new Matrix(spect3).Transpose(); // same as specgram(audio*32768, 2048, 44100, hanning(2048), 1024); stftdata3.DrawMatrixImageLogValues(outputDirectoryFilePath + "_specgram3.png", true, false, -1, -1, false); #endregion // the matrix are too different so comparing them always fails! //Assert.That(stftdata2, Is.EqualTo(stftdata3).AsCollection.Within(0.001), "fail at [0]"); #region Inverse FFT // Perform inverse stft as well double[] audiodata_inverse_stft = stft.InverseStft(stftdata); // divide or normalize //MathUtils.Divide(ref audiodata_inverse_stft, AUDIO_MULTIPLIER); MathUtils.Normalize(ref audiodata_inverse_stft); Export.DrawGraph(audiodata_inverse_stft, outputDirectoryFilePath + "_audiodata_inverse_stft.png"); float[] audiodata_inverse_float = MathUtils.DoubleToFloat(audiodata_inverse_stft); BassProxy.SaveFile(audiodata_inverse_float, outputDirectoryFilePath + "_inverse_stft.wav", 1, SAMPLING_RATE, 32); #endregion Assert.Pass("This test was succesful."); }
public static void Main(string[] args) { /* * int nFFT = 1024; * int samplerate = 44100; * int length = samplerate * 10; // 10 sec * * double freq1, freq2; * int i1, i2; * for (int i = 0; i < nFFT + 1; i++) { * freq1 = MathUtils.Index2Freq(i, samplerate, nFFT); * freq2 = MathUtils.IndexToFreq(i, samplerate, nFFT); * i1 = MathUtils.Freq2Index(freq1, samplerate, nFFT); * i2 = MathUtils.FreqToIndex((float)freq2, samplerate, nFFT); * } */ /* * List<Color> rew_hsb_gradients = ColorUtils.GetHSBColorGradients(256, ColorUtils.ColorPaletteType.REW); * ColorUtils.SaveColorGradients("rew-hsb-gradients.png", rew_hsb_gradients, 40); * List<Color> rew_hsl_gradients = ColorUtils.GetHSLColorGradients(256, ColorUtils.ColorPaletteType.REW); * ColorUtils.SaveColorGradients("rew-hsl-gradients.png", rew_hsl_gradients, 40); * * List<Color> sox_hsb_gradients = ColorUtils.GetHSBColorGradients(256, ColorUtils.ColorPaletteType.SOX); * ColorUtils.SaveColorGradients("sox-hsb-gradients.png", sox_hsb_gradients, 40); * List<Color> sox_hsl_gradients = ColorUtils.GetHSLColorGradients(256, ColorUtils.ColorPaletteType.SOX); * ColorUtils.SaveColorGradients("sox-hsl-gradients.png", sox_hsl_gradients, 40); * * List<Color> photosounder_hsb_gradients = ColorUtils.GetHSBColorGradients(256, ColorUtils.ColorPaletteType.PHOTOSOUNDER); * ColorUtils.SaveColorGradients("photosounder_hsb_gradients.png", photosounder_hsb_gradients, 40); * List<Color> photosounder_hsl_gradients = ColorUtils.GetHSLColorGradients(256, ColorUtils.ColorPaletteType.PHOTOSOUNDER); * ColorUtils.SaveColorGradients("photosounder_hsl_gradients.png", photosounder_hsl_gradients, 40); * List<Color> photosounder_rgb_gradients = ColorUtils.GetRGBColorGradients(255, ColorUtils.ColorPaletteType.PHOTOSOUNDER); * ColorUtils.SaveColorGradients("photosounder_rgb_gradients.png", photosounder_rgb_gradients, 40); * * List<Color> grey_hsb_gradients = ColorUtils.GetHSBColorGradients(256, ColorUtils.ColorPaletteType.BLACK_AND_WHITE); * ColorUtils.SaveColorGradients("grey-hsb-gradients.png", grey_hsb_gradients, 40); * * ReadColorPaletteBar(@"C:\Users\perivar.nerseth\OneDrive\Temp\sox_colorbar.png", "sox_colorbar.csv"); * ReadColorPaletteBar(@"C:\Users\perivar.nerseth\OneDrive\Temp\soundforge_colorbar.png", "soundforge_colorbar.csv"); * ReadColorPaletteBar(@"C:\Users\perivar.nerseth\OneDrive\Temp\rew_colorbar.png", "rew_colorbar.csv"); * ReadColorPaletteBar(@"C:\Users\perivar.nerseth\OneDrive\Temp\sox_colorbar.png", "sox_colorbar.csv"); * ReadColorPaletteBar(@"C:\Users\perivar.nerseth\OneDrive\Temp\thermal_colorbar.png", "thermal_colorbar.csv"); */ Console.WriteLine("Analyzer starting ..."); int sampleRate = 44100; // 44100, default 5512 int fftWindowsSize = 16384; //32768 16384 8192 4096 2048, default 256*8 (2048) to 256*128 (32768), reccomended: 256*64 = 16384 int fftOverlap = fftWindowsSize / 2; // 32768:990, 16384:990, 8192:990, 4096:990 float fftOverlapPercentage = 94.0f; // 99.0f number between 0 and 100 string fileName = @"C:\Users\perivar.nerseth\Documents\My Projects\AudioVSTToolbox\ARSSCSharp\Ariana Grande 32bit.wav"; var bass = BassProxy.Instance; float[] wavDataBass = BassProxy.ReadMonoFromFile(fileName, sampleRate); //MathUtils.NormalizeInPlace(wavDataBass); //Export.ExportCSV(@"c:\BassAudio.csv", wavDataBass); // VB6 //var vb6Spect = new VB6Spectrogram(); //vb6Spect.ComputeColorPalette(); //float[][] vb6Spectrogram = vb6Spect.Compute(wavDataBass, sampleRate, fftWindowsSize, fftOverlapPercentage); //Export.ExportCSV (@"VB6_spectrogram-full.csv", vb6Spectrogram); // Exocortex.DSP FFT /* * int numberOfSamples = wavDataNaudio.Length; * fftOverlapPercentage = fftOverlapPercentage / 100; * long ColSampleWidth = (long)(fftWindowsSize * (1 - fftOverlapPercentage)); * double fftOverlapSamples = fftWindowsSize * fftOverlapPercentage; * long NumCols = numberOfSamples / ColSampleWidth; * * int fftOverlap = (int)((numberOfSamples - fftWindowsSize) / NumCols); * int numberOfSegments = (numberOfSamples - fftWindowsSize)/fftOverlap; */ //System.Console.Out.WriteLine(String.Format("EXO: fftWindowsSize: {0}, Overlap samples: {1:n2}.", fftWindowsSize, fftOverlap )); //VIPSLib.Audio.WAVFile wavefile = new VIPSLib.Audio.WAVFile(); //wavefile.ReadFromFileToDouble(fileName.Substring(0, fileName.LastIndexOf(".")) + ".wav"); //RiffRead riff = new RiffRead(fileName.Substring(0, fileName.LastIndexOf(".")) + ".wav"); //riff.Process(); /* * VIPSLib.Audio.MFCC mfcclib = new VIPSLib.Audio.MFCC((float)sampleRate); * double[][] data = riff.SoundData; * double min; * double max; * MathUtils.ComputeMinAndMax(data, out min, out max); * double[][] mfcc = mfcclib.Process(MathUtils.FloatToDouble(wavDataVB6)); * * float fmin; * float fmax; * MathUtils.ComputeMinAndMax(wavDataVB6, out fmin, out fmax); */ //double[][] mfcc = mfcclib.Process(riff.SoundData[0]); //float[][] mfccFloats = MathUtils.DoubleToFloat(mfcc); // GENERATE SPECTROGRAM Bitmap spectro = AudioAnalyzer.GetSpectrogramImage(wavDataBass, 1200, 600, sampleRate, fftWindowsSize, fftOverlap, ColorUtils.ColorPaletteType.PHOTOSOUNDER, true); spectro.Save(@"spectrogram-log-photosounder.png"); Bitmap spectro2 = AudioAnalyzer.GetSpectrogramImage(wavDataBass, 1200, 600, sampleRate, fftWindowsSize, fftOverlap, ColorUtils.ColorPaletteType.REW, true); spectro2.Save(@"spectrogram-log-rew.png"); Bitmap spectro3 = AudioAnalyzer.GetSpectrogramImage(wavDataBass, 1200, 600, sampleRate, fftWindowsSize, fftOverlap, ColorUtils.ColorPaletteType.SOX, true); spectro3.Save(@"spectrogram-log-sox.png"); //float[][] data = AudioAnalyzer.CreateSpectrogramLomont(wavDataBass, fftWindowsSize, fftOverlap); //Bitmap image = AudioAnalyzer.GetSpectrogramImage(data, 1200, 600); //image.Save(@"spectrogram.jpg", ImageFormat.Jpeg); //float[][] logSpectrogram = manager.CreateLogSpectrogram(repositoryGateway._proxy, fileName, secondsToSample*1000, 0); //Bitmap logspectro = AudioAnalyzer.GetSpectrogramImage(logSpectrogram, 1200, 600, secondsToSample*1000, sampleRate, ColorUtils.ColorPaletteType.REW); //logspectro.Save(@"c:\spectrogram-log.png"); //Bitmap waveform = AudioAnalyzer.DrawWaveform(wavDataVB6, new Size (1200, 600), 0, 1, 0, sampleRate); //waveform.Save(@"c:\waveform.png"); //Bitmap waveform = AudioAnalyzer.DrawWaveform(wavDataNaudio, 1200, 600); //waveform.Save(@"c:\waveform.png"); Console.Write("Press any key to continue . . . "); Console.ReadKey(true); }
static void SplitIntoSingleCycleWaveforms(string baseDirectory, string wavPath, int singleCycleLength, Dictionary <string, MassiveMapElement> map, string outputDirectory, float[] sineData) { // use path after the base dir as map key string mapKey = IOUtils.GetRightPartOfPath(wavPath, baseDirectory + Path.DirectorySeparatorChar); #region Output Correct Filenames // determine correct filename if (map.ContainsKey(mapKey)) { var mapElement = map[mapKey]; if (!mapElement.GroupName.Equals("") && !mapElement.CorrectFileName.Equals("")) { // create single cycle directory string singleCycleDirectory = Path.Combine(outputDirectory, "Single Cycle Waveforms", StringUtils.MakeValidFileName(mapElement.GroupName)); if (!Directory.Exists(singleCycleDirectory)) { Directory.CreateDirectory(singleCycleDirectory); } // create preset file directory string presetFileDirectory = Path.Combine(outputDirectory, "Zebra2 Osc Presets", StringUtils.MakeValidFileName(mapElement.GroupName)); if (!Directory.Exists(presetFileDirectory)) { Directory.CreateDirectory(presetFileDirectory); } // read audio data as mono int sampleRate = -1; int bitsPerSample = -1; long byteLength = -1; float[] audioData = BassProxy.ReadMonoFromFile(wavPath, out sampleRate, out bitsPerSample, out byteLength, BassProxy.MonoSummingType.Mix); // temporary storage for the 128 single cycle samples var waveforms = new List <float[]>(); int cycleCount = 1; // find each single cycle waveforms for (int i = 0; i < audioData.Length; i += singleCycleLength) { var singleCycleData = new float[singleCycleLength]; Array.Copy(audioData, i, singleCycleData, 0, singleCycleLength); // output the corrected filenames string newFileName = string.Format("{0}_{1}_{2}.wav", mapElement.GroupIndex, mapElement.CorrectFileName, cycleCount); string newFilePath = Path.Combine(singleCycleDirectory, newFileName); Console.Out.WriteLine("Creating file {0}.", newFilePath); BassProxy.SaveFile(singleCycleData, newFilePath, 1, sampleRate, bitsPerSample); // resample to 128 samples for u-he zebra conversion float[] singeCycle128 = MathUtils.Resample(singleCycleData, 128); // zebra only supports 16 slots if (cycleCount < 17) { waveforms.Add(singeCycle128); } else { Console.Out.WriteLine("Zebra only support 16 waves in it's wavetables."); break; } cycleCount++; } #region Save a non-morphed and a morphed version of the zebra preset // single cycle waveform array for non-morphed data float[][] soundData = MathUtils.CreateJaggedArray <float[][]>(16, 128); // single cycle waveform arrays for morphed daya float[][] morphData = MathUtils.CreateJaggedArray <float[][]>(16, 128); // distribute the waves found evenly within the 16 available slots var evenDistribution = MathUtils.GetEvenDistributionPreferEdges(waveforms.Count, 16); var indices = MathUtils.IndexOf(evenDistribution, 1); if (waveforms.Count() == 1) { // set sine data to last element (for morphing later) Array.Copy(sineData, 0, morphData[15], 0, 128); } if (indices.Count() == waveforms.Count()) { var enabledMorphSlots = new bool[16]; var enabledSoundSlots = new bool[16]; for (int i = 0; i < waveforms.Count; i++) { // add the waves successively to the normal sound data Array.Copy(waveforms[i], 0, soundData[i], 0, 128); enabledSoundSlots[i] = true; // spread out the waves to later be morphed int index = indices[i]; Array.Copy(waveforms[i], 0, morphData[index], 0, 128); enabledMorphSlots[index] = true; // before morphing this is used to tell what slots are loaded } // morph between the added waveforms (slots) Zebra2OSCPreset.MorphAllSegments(enabledMorphSlots, ref morphData); // before writing the file ensure all of the morhp slots are enabled for (int j = 0; j < 16; j++) { enabledMorphSlots[j] = true; } // save the non-morphed u-he zebra preset string zebraPreset = string.Format("{0}_{1}.h2p", mapElement.GroupIndex, mapElement.CorrectFileName); string zebraPresetFilePath = Path.Combine(presetFileDirectory, zebraPreset); Zebra2OSCPreset.Write(soundData, enabledSoundSlots, zebraPresetFilePath); // save the morphed u-he zebra preset string zebraMorphPreset = string.Format("{0}_{1}_Morph.h2p", mapElement.GroupIndex, mapElement.CorrectFileName); string zebraMorphPresetFilePath = Path.Combine(presetFileDirectory, zebraMorphPreset); Zebra2OSCPreset.Write(morphData, enabledMorphSlots, zebraMorphPresetFilePath); #endregion } else { // this should never happen Console.Out.WriteLine("Failed! Could not set wavetables correctly."); } } } #endregion }