Beispiel #1
0
        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);
        }
Beispiel #2
0
        /// <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);
        }
Beispiel #3
0
        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);
        }
Beispiel #4
0
        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");
        }
Beispiel #5
0
        /// <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();
            }
        }
Beispiel #6
0
        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();
        }
Beispiel #7
0
        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);
        }
Beispiel #8
0
        /// <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);
        }
Beispiel #9
0
        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);
        }
Beispiel #10
0
        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);
        }
Beispiel #11
0
        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.");
        }
Beispiel #12
0
        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);
        }
Beispiel #13
0
        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
        }