public static double getAvgAmplitude(WaveAudio w)
 {
     double total=0;
     for (int i=0; i<w.LengthInSamples; i++)
         total += w.data[0][i]*w.data[0][i];
     return total/w.LengthInSamples;
 }
 public static WaveAudio Modulate(WaveAudio w1, WaveAudio w2)
 {
     ElementWiseCombinationFn fn = delegate(double v1, double v2)
     {
         return v1 * v2;
     };
     return elementWiseCombination(w1, w2, fn);
 }
 public static WaveAudio Mix(WaveAudio w1, double weight1, WaveAudio w2, double weight2)
 {
     ElementWiseCombinationFn fn = delegate(double v1, double v2)
     {
         return weight1 * v1 + weight2 * v2;
     };
     return elementWiseCombination(w1, w2, fn);
 }
 public static void placeAudio(WaveAudio target, WaveAudio source, int index)
 {
     for (int ch=0; ch<target.data.Length; ch++)
         for (int j = 0; j < source.data[0].Length; j++)
             if (j + index < target.data[0].Length)
             {
                 target.data[ch][j + index] += source.data[ch][j];
             }
 }
 public static WaveAudio Reverse(WaveAudio w1)
 {
     WaveAudio clone = w1.Clone();
     for (int ch = 0; ch < clone.data.Length; ch++)
     {
         Array.Reverse( clone.data[ch]);
     }
     return clone;
 }
 private void btnOpen_Click(object sender, EventArgs e)
 {
     string strFilename, strShortname; WaveAudio w;
     CommonWave.commonLoadWaveFile(out strFilename, out strShortname, out w);
     if (w==null)
         return;
     this.lblFilename.Text = "Loaded: " + strShortname;
     w.setNumChannels(1, true); //convert to mono
     this.m_currentSound = w;
 }
Beispiel #7
0
        public static double getAvgAmplitude(WaveAudio w)
        {
            double total = 0;

            for (int i = 0; i < w.LengthInSamples; i++)
            {
                total += w.data[0][i] * w.data[0][i];
            }
            return(total / w.LengthInSamples);
        }
Beispiel #8
0
        public static WaveAudio Reverse(WaveAudio w1)
        {
            WaveAudio clone = w1.Clone();

            for (int ch = 0; ch < clone.data.Length; ch++)
            {
                Array.Reverse(clone.data[ch]);
            }
            return(clone);
        }
Beispiel #9
0
        /// <summary>
        /// Create deep copy of audio object.
        /// </summary>
        public WaveAudio Clone()
        {
            WaveAudio copy = new WaveAudio(this.getSampleRate(), this.getNumChannels());

            for (int ch = 0; ch < copy.data.Length; ch++)
            {
                copy.data[ch] = new double[this.data[ch].Length];
                Array.Copy(this.data[ch], copy.data[ch], this.data[ch].Length);
            }
            return(copy);
        }
        /// <summary>
        /// Create a new sound by changing the speed/pitch of the old sound. 2.0 = an octave up, 1.0 = the same, 0.5 = down an octave
        /// </summary>
        public static WaveAudio ScalePitchAndDuration(WaveAudio w, double factor)
        {
            if (factor < 0) throw new ArgumentException("Factor must >= 0");
            WaveAudio res = new WaveAudio(w.getSampleRate(), w.getNumChannels());

            // do operation for all channels
            for (int i = 0; i < w.getNumChannels(); i++)
                res.data[i] = scalePitchAndDurationChannel(w.data[i], factor);

            return res;
        }
 public static WaveAudio GetSliceSample(WaveAudio wthis, int nStart, int nEnd)
 {
     WaveAudio slice = new WaveAudio(wthis.getSampleRate(), wthis.getNumChannels());
     if (nEnd <= nStart || nEnd > wthis.LengthInSamples || nStart < 0) throw new Exception("Invalid slice");
     for (int ch = 0; ch < slice.data.Length; ch++)
     {
         slice.data[ch] = new double[nEnd - nStart];
         Array.Copy(wthis.data[ch], nStart, slice.data[ch], 0, nEnd - nStart);
     }
     return slice;
 }
        public static WaveAudio Vibrato(WaveAudio wave, double freq, double width)
        {
            if (width < 0) throw new ArgumentException("Factor must >= 0");
            WaveAudio newwave = new WaveAudio(wave.getSampleRate(), wave.getNumChannels());
            
            // do operation for all channels
            for (int i = 0; i < wave.getNumChannels(); i++)
                newwave.data[i] = vibratoChannel(wave.data[i], wave.getSampleRate(), width, freq);

            return newwave;
        }
Beispiel #13
0
 public static WaveAudio hiPassFilter(WaveAudio w, double factor) //0.5
 {
     WaveAudio ret = new WaveAudio(w.getSampleRate(), w.getNumChannels());
     ret.LengthInSamples = w.LengthInSamples;
     for (int ch = 0; ch < w.getNumChannels(); ch++)
     {
         ret.data[ch][0] = w.data[ch][0];
         for (int i = 1; i < ret.data[ch].Length; i++)
             ret.data[ch][i] = factor * ret.data[ch][i - 1] + (factor) * (w.data[ch][i] - w.data[ch][i-1]);
     }
     return ret;
 }
Beispiel #14
0
        //could also get continuous with window.


        public static WaveAudio lowPassFilter(WaveAudio w, double factor) //0.5
        {
            //http://en.wikipedia.org/wiki/Low-pass_filter
            WaveAudio ret = new WaveAudio(w.getSampleRate(), w.getNumChannels());
            ret.LengthInSamples = w.LengthInSamples;
            for (int ch = 0; ch < w.getNumChannels(); ch++)
            {
                ret.data[ch][0] = w.data[ch][0];
                for (int i=1; i<ret.data[ch].Length; i++)
                    ret.data[ch][i] = (1-factor)*ret.data[ch][i-1] + (factor)*w.data[ch][i];
            }
            return ret;
        }
Beispiel #15
0
 public static void placeAudio(WaveAudio target, WaveAudio source, int index)
 {
     for (int ch = 0; ch < target.data.Length; ch++)
     {
         for (int j = 0; j < source.data[0].Length; j++)
         {
             if (j + index < target.data[0].Length)
             {
                 target.data[ch][j + index] += source.data[ch][j];
             }
         }
     }
 }
 public static void placeAudioRamp(WaveAudio target, WaveAudio source, int index, int rampWidth)
 {
     for (int ch=0; ch<target.data.Length; ch++)
         for (int j = 0; j < source.data[ch].Length; j++)
         {
             if (j < rampWidth)
                 target.data[ch][j + index] += source.data[ch][j] * (((double)j) / rampWidth);
             else if ((source.data[ch].Length - j) < rampWidth)
                 target.data[ch][j + index] += source.data[ch][j] * (((double)source.data[ch].Length - j) / rampWidth);
             else
                 target.data[ch][j + index] += source.data[ch][j];
         }
 }
        public void Play(WaveAudio a, bool bAsync)
        {
            m = new MemoryStream();
            bw = new BinaryWriter(m);
            a.SaveWaveFile(bw);

            SoundPlayer pl = new SoundPlayer(m);
            pl.Stream.Position = 0; // This line is necessary 
           
            if (bAsync)
                pl.Play();
            else
                pl.PlaySync();
        }
        // These work by shifting the signal until it seems to correlate with itself.
        // In other words if the signal looks very similar to (signal shifted 200 samples) than the fundamental period is probably 200 samples
        // Note that the algorithm only works well when there's only one prominent fundamental.
        // This could be optimized by looking at the rate of change to determine a maximum without testing all periods.
        private static double[] detectPitchCalculation(WaveAudio w, double minHz, double maxHz, int nCandidates, int nResolution, PitchDetectAlgorithm algorithm)
        {
            // note that higher frequency means lower period
            int nLowPeriodInSamples = hzToPeriodInSamples(maxHz, w.getSampleRate());
            int nHiPeriodInSamples = hzToPeriodInSamples(minHz, w.getSampleRate());
            if (nHiPeriodInSamples <= nLowPeriodInSamples) throw new Exception("Bad range for pitch detection.");
            if (w.getNumChannels() != 1) throw new Exception("Only mono supported.");
            double[] samples = w.data[0];
            if (samples.Length < nHiPeriodInSamples) throw new Exception("Not enough samples.");

            // both algorithms work in a similar way
            // they yield an array of data, and then we find the index at which the value is highest.
            double[] results = new double[nHiPeriodInSamples - nLowPeriodInSamples];

            if (algorithm == PitchDetectAlgorithm.Amdf)
            {
                for (int period = nLowPeriodInSamples; period < nHiPeriodInSamples; period += nResolution)
                {
                    double sum = 0;
                    // for each sample, see how close it is to a sample n away. Then sum these.
                    for (int i = 0; i < samples.Length - period; i++)
                        sum += Math.Abs(samples[i] - samples[i + period]);

                    double mean = sum / (double)samples.Length;
                    mean *= -1; //somewhat of a hack. We are trying to find the minimum value, but our findBestCandidates finds the max. value.
                    results[period - nLowPeriodInSamples] = mean;
                }
            }
            else if (algorithm == PitchDetectAlgorithm.Autocorrelation)
            {
                for (int period = nLowPeriodInSamples; period < nHiPeriodInSamples; period += nResolution)
                {
                    double sum = 0;
                    // for each sample, find correlation. (If they are far apart, small)
                    for (int i = 0; i < samples.Length - period; i++)
                        sum += samples[i] * samples[i + period];

                    double mean = sum / (double)samples.Length;
                    results[period - nLowPeriodInSamples] = mean;
                }
            }

            // find the best indices
            int[] bestIndices = findBestCandidates(nCandidates, ref results); //note findBestCandidates modifies parameter
            // convert back to Hz
            double[] res = new double[nCandidates];
            for (int i=0; i<nCandidates;i++)
                res[i] = periodInSamplesToHz(bestIndices[i]+nLowPeriodInSamples, w.getSampleRate());
            return res;
        }
        //get continuous value, with a window. the 'instantaneous amplitude'
        //note: only from 1st channel of audio.
        public static double[] getAmplitudesOverTimeContinuous(WaveAudio w, int nWindowSize)
        {
            double[] res = new double[w.LengthInSamples];
            double current=0;
            for (int i=0; i<w.LengthInSamples; i++)
            {
                current += w.data[0][i]*w.data[0][i];
                if (i>nWindowSize)
                    current-= w.data[0][i-nWindowSize]*w.data[0][i-nWindowSize];

                res[i] = current / nWindowSize;
            }
            return res;
        }
Beispiel #20
0
 private static void commonSaveWaveFile(WaveAudio w)
 {
     string strFilename = getSaveFilename();
     if (strFilename == null || strFilename == "") return;
     try
     {
         w.SaveWaveFile(strFilename);
     }
     catch (Exception er)
     {
         MessageBox.Show("Error when saving wave file: " + er.Message);
         return;
     }
 }
        public static void effectstest(AudioPlayer pl)
        {
            WaveAudio w = new WaveAudio(mediadir + "d44k16bit2ch.wav");
            pl.Play(Effects.Derivative(w));
            pl.Play(Effects.Flange(w));
            pl.Play(Effects.Reverse(w));
            pl.Play(Effects.ScalePitchAndDuration(w, 0.75));
            pl.Play(Effects.ScalePitchAndDuration(w, 1.25));
            pl.Play(Effects.Tremolo(w, 1.0, 1.0));
            pl.Play(Effects.Vibrato(w, 0.2, 0.5));

            w.setSampleRate(22050);
            pl.Play(w); // should sound "normal"
        }
 public static WaveAudio Derivative(WaveAudio wOriginal)
 {
     WaveAudio w = wOriginal.Clone();
     for (int ch = 0; ch < w.getNumChannels(); ch++)
     {
         for (int i = 0; i < w.data[ch].Length; i++)
         {
             if (i + 1 < w.data[ch].Length)
                 w.data[ch][i] = w.data[ch][i] - w.data[ch][i + 1];
             else
                 w.data[ch][i] = w.data[ch][i] - 0;
         }
     }
     return w;
 }
Beispiel #23
0
        public static WaveAudio hiPassFilter(WaveAudio w, double factor) //0.5
        {
            WaveAudio ret = new WaveAudio(w.getSampleRate(), w.getNumChannels());

            ret.LengthInSamples = w.LengthInSamples;
            for (int ch = 0; ch < w.getNumChannels(); ch++)
            {
                ret.data[ch][0] = w.data[ch][0];
                for (int i = 1; i < ret.data[ch].Length; i++)
                {
                    ret.data[ch][i] = factor * ret.data[ch][i - 1] + (factor) * (w.data[ch][i] - w.data[ch][i - 1]);
                }
            }
            return(ret);
        }
Beispiel #24
0
        public static WaveAudio GetSliceSample(WaveAudio wthis, int nStart, int nEnd)
        {
            WaveAudio slice = new WaveAudio(wthis.getSampleRate(), wthis.getNumChannels());

            if (nEnd <= nStart || nEnd > wthis.LengthInSamples || nStart < 0)
            {
                throw new Exception("Invalid slice");
            }
            for (int ch = 0; ch < slice.data.Length; ch++)
            {
                slice.data[ch] = new double[nEnd - nStart];
                Array.Copy(wthis.data[ch], nStart, slice.data[ch], 0, nEnd - nStart);
            }
            return(slice);
        }
Beispiel #25
0
        /// <summary>
        /// Create a new sound by changing the speed/pitch of the old sound. 2.0 = an octave up, 1.0 = the same, 0.5 = down an octave
        /// </summary>
        public static WaveAudio ScalePitchAndDuration(WaveAudio w, double factor)
        {
            if (factor < 0)
            {
                throw new ArgumentException("Factor must >= 0");
            }
            WaveAudio res = new WaveAudio(w.getSampleRate(), w.getNumChannels());

            // do operation for all channels
            for (int i = 0; i < w.getNumChannels(); i++)
            {
                res.data[i] = scalePitchAndDurationChannel(w.data[i], factor);
            }

            return(res);
        }
        private void button1_Click(object sender, EventArgs e)
        {
            WaveAudio test = new WaveAudio(44100, 1);
            test.LengthInSamples = 44100 * 7;
            double freq = 100;//300;
            PeriodicAlternative osc = new PAChangeSquare(4.0);//new PASin();
            for (int i = 0; i < test.LengthInSamples; i++)
            {
                test.data[0][i] = 0.9 * osc.GetValue(i * freq * 2.0 * Math.PI / (double)44100.0);
            }
            //player.Play(test, true);

            WaveAudio win = new WaveAudio(strMedia + "acoust.wav");
            WaveAudio wmixed = WaveAudio.Mix(WaveAudio.Modulate(test, win), 0.7, win, 0.3);
            player.Play(wmixed, true);
        }
 public static double[] getAmplitudesOverTimeSegment(WaveAudio w, int nPieceSize)
 {
     int nPieces = w.data[0].Length / nPieceSize;
     double[] res = new double[nPieces];
     for (int n = 0; n < nPieces; n++)
     {
         double total = 0;
         for (int i = n * nPieceSize; i < n * nPieceSize + nPieceSize; i++)
         {
             total += w.data[0][i] * w.data[0][i];
         }
         total /= nPieceSize;
         res[n] = total;
     }
     return res;
 }
Beispiel #28
0
        /// <summary>
        /// Find spectrum content of signal. Returns array, where each element represents energy at frequencies.
        /// For example, SpectrumContent(w, 8) returns 8 numbers. The first in the array is the amount of energy at low frequencies, and the last is the energy at highest frequencies.
        /// Note that FFT uses a power of 2 samples, and so all of the signal may not be used.
        /// </summary>
        /// <param name="w">Sound</param>
        /// <param name="nBins">Number of bins to return.</param>
        public static double[] SpectrumContent(WaveAudio w, int nBins)
        {
            if (w.getNumChannels() != 1) throw new Exception("Only mono supported.");
            double[] buffer;

            // FFT uses a power of 2 samples, so we might have to truncate.
            if (!isPowerOfTwo((uint) w.LengthInSamples))
            {
                int nSize = (int)findNearestPowerOfTwo((uint) w.LengthInSamples);
                buffer = new double[nSize];
                Array.Copy(w.data[0], buffer, nSize);
            }
            else 
                buffer = w.data[0];
            return getSpectrumContent(buffer, nBins);
        }
        public static WaveAudio Wahwah(WaveAudio wOriginal, double freq, double depth, double freqofs, double res)
        {
            double startphaseleft = 0;
            double startphaseright = startphaseleft + Math.PI; //note that left and right channels should start pi out of phase
            double freq_scaled = 2.0 * Math.PI * freq / (double)wOriginal.getSampleRate();

            WaveAudio w = wOriginal.Clone();
            if (w.getNumChannels() == 1)
                effect_wahwahaud_impl(w.data[0], startphaseleft, freq_scaled, depth, freqofs, res);
            else
            {
                effect_wahwahaud_impl(w.data[0], startphaseleft, freq_scaled, depth, freqofs, res);
                effect_wahwahaud_impl(w.data[1], startphaseright, freq_scaled, depth, freqofs, res);
            }
            return w;
        }
Beispiel #30
0
        public static WaveAudio Vibrato(WaveAudio wave, double freq, double width)
        {
            if (width < 0)
            {
                throw new ArgumentException("Factor must >= 0");
            }
            WaveAudio newwave = new WaveAudio(wave.getSampleRate(), wave.getNumChannels());

            // do operation for all channels
            for (int i = 0; i < wave.getNumChannels(); i++)
            {
                newwave.data[i] = vibratoChannel(wave.data[i], wave.getSampleRate(), width, freq);
            }

            return(newwave);
        }
        public static WaveAudio Phaser(WaveAudio wOriginal, double freq, double fb, int depth, int stages, int drywet)
        {
            double startphaseleft = 0;
            double startphaseright = startphaseleft + Math.PI; //note that left and right channels should start pi out of phase
            double freq_scaled = 2.0 * Math.PI * freq / (double)wOriginal.getSampleRate();

            WaveAudio w = wOriginal.Clone();
            if (w.getNumChannels() == 1)
                effect_phaseraud_impl(w.data[0], freq_scaled, startphaseleft, fb, depth, stages, drywet);
            else
            {
                effect_phaseraud_impl(w.data[0], freq_scaled, startphaseleft, fb, depth, stages, drywet);
                effect_phaseraud_impl(w.data[1], freq_scaled, startphaseright, fb, depth, stages, drywet);
            }
            return w;
        }
Beispiel #32
0
        //could also get continuous with window.


        public static WaveAudio lowPassFilter(WaveAudio w, double factor) //0.5
        {
            //http://en.wikipedia.org/wiki/Low-pass_filter
            WaveAudio ret = new WaveAudio(w.getSampleRate(), w.getNumChannels());

            ret.LengthInSamples = w.LengthInSamples;
            for (int ch = 0; ch < w.getNumChannels(); ch++)
            {
                ret.data[ch][0] = w.data[ch][0];
                for (int i = 1; i < ret.data[ch].Length; i++)
                {
                    ret.data[ch][i] = (1 - factor) * ret.data[ch][i - 1] + (factor) * w.data[ch][i];
                }
            }
            return(ret);
        }
Beispiel #33
0
        /// <summary>
        /// Returns a new audio object, containing a slice of the sound.
        /// </summary>
        public WaveAudio GetSlice(double fSecondsStart, double fSecondsEnd)
        {
            WaveAudio slice  = new WaveAudio(this.getSampleRate(), this.getNumChannels());
            int       nStart = (int)(fSecondsStart * this.m_currentSampleRate);
            int       nEnd   = (int)(fSecondsEnd * this.m_currentSampleRate);

            if (nEnd <= nStart || nEnd > this.LengthInSamples || nStart < 0)
            {
                throw new Exception("Invalid slice");
            }
            for (int ch = 0; ch < slice.data.Length; ch++)
            {
                slice.data[ch] = new double[nEnd - nStart];
                Array.Copy(this.data[ch], nStart, slice.data[ch], 0, nEnd - nStart);
            }
            return(slice);
        }
Beispiel #34
0
        //get continuous value, with a window. the 'instantaneous amplitude'
        //note: only from 1st channel of audio.
        public static double[] getAmplitudesOverTimeContinuous(WaveAudio w, int nWindowSize)
        {
            double[] res     = new double[w.LengthInSamples];
            double   current = 0;

            for (int i = 0; i < w.LengthInSamples; i++)
            {
                current += w.data[0][i] * w.data[0][i];
                if (i > nWindowSize)
                {
                    current -= w.data[0][i - nWindowSize] * w.data[0][i - nWindowSize];
                }

                res[i] = current / nWindowSize;
            }
            return(res);
        }
Beispiel #35
0
 private static void commonLoadWaveFile(out string strFilename, out string strShortname, out WaveAudio w)
 {
     w = null;  strShortname = null;
     strFilename = getOpenFilename();
     if (strFilename == null || strFilename == "") return;
     try
     {
         w = new WaveAudio(strFilename);
     }
     catch (Exception er)
     {
         MessageBox.Show("Error when loading wave file: " + er.Message);
         return;
     }
     string[] pathsplit = strFilename.Split(new char[] { '\\' });
     strShortname = pathsplit[pathsplit.Length - 1];
 }
Beispiel #36
0
        public static double[] getAmplitudesOverTime(WaveAudio w, int nPieceSize)
        {
            int nPieces = w.data[0].Length / nPieceSize;

            double[] res = new double[nPieces];
            for (int n = 0; n < nPieces; n++)
            {
                double total = 0;
                for (int i = n * nPieceSize; i < n * nPieceSize + nPieceSize; i++)
                {
                    total += w.data[0][i] * w.data[0][i];
                }
                total /= nPieceSize;
                res[n] = total;
            }
            return(res);
        }
        // The following create new audio without modifying original
        public static WaveAudio Concatenate(WaveAudio w1, WaveAudio w2)
        {
            // make sure sample rates match we could be nicer and convert automatically
            if (w1.m_currentSampleRate != w2.m_currentSampleRate) throw new Exception("Sample rates don't match");
            if (w2.getNumChannels() != w2.getNumChannels()) throw new Exception("Number of channels don't match");

            WaveAudio newwave = new WaveAudio(w1.getSampleRate(), w1.getNumChannels());
            newwave.LengthInSamples = w1.LengthInSamples + w2.LengthInSamples;

            for (int ch = 0; ch < w1.getNumChannels(); ch++)
            {
                //          source    sIndex, destination, destIndex,  length
                Array.Copy(w1.data[ch], 0, newwave.data[ch], 0, w1.data[ch].Length);
                Array.Copy(w2.data[ch], 0, newwave.data[ch], w1.data[ch].Length, w2.data[0].Length);
            }
            return newwave;
        }
        // Beat detection, algorithm put together by Ben Fisher after reading some things
        // numbers here are arbitrary, based on what seemed to work ok. I'm sure it could be better.
        public static double GuessBpm(WaveAudio input)
        {
            const double minBpm = 60, maxBpm = 150;

            WaveAudio w = Effects.Derivative(input); // take the derivative of samples.

            // divide samples into chunks of size 1024.
            int    nBufsize       = 1024;
            double chunkframerate = input.getSampleRate() / nBufsize; // the chunks go by at this rate.

            // do first FFT
            double[][] frequencyData = SpectrumContentOverTime(w, 4, nBufsize);

            // create a new signal in time, consisting of the energy at lowest 1/4 freqs of the chunks.
            int slength = (int)Fourier.findNearestPowerOfTwo((uint)frequencyData.Length);

            double[] lowerdata = new double[slength];
            for (int i = 0; i < slength; i++)
            {
                lowerdata[i] = frequencyData[i][0]; // the bottom 1/4 freqs (index 0-255,0Hz to 5512.5Hz  or something ?)
            }
            // now take a second FFT on this new signal. Frequency should be range 0.6 to 2.5 Hz (40 to 150 Bpm).
            double[] reout, imgout;
            RawSamplesToFrequency(lowerdata, out reout, out imgout);

            // only keep track of output inside the range we are interested in
            int minFreqindex = (int)(reout.Length * ((minBpm / 60) / chunkframerate));
            int maxFreqindex = (int)(reout.Length * ((maxBpm / 60) / chunkframerate));

            // find the best candidate
            double highestEnergy = -1; int highestEnergyIndex = -1;

            for (int b = minFreqindex; b < maxFreqindex; b++)
            {
                double magnitude = Math.Sqrt(reout[b] * reout[b] + imgout[b] + imgout[b]);
                if (magnitude > highestEnergy)
                {
                    highestEnergyIndex = b; highestEnergy = magnitude;
                }
            }
            double freqHertz = chunkframerate * (highestEnergyIndex / (double)reout.Length);
            double freqInBpm = freqHertz * 60;

            return(freqInBpm);
        }
Beispiel #39
0
        public void Play(WaveAudio a, bool bAsync)
        {
            m  = new MemoryStream();
            bw = new BinaryWriter(m);
            a.SaveWaveFile(bw);

            pl = new SoundPlayer(m);
            pl.Stream.Position = 0; // This line is necessary

            if (bAsync)
            {
                pl.Play();
            }
            else
            {
                pl.PlaySync();
            }
        }
 public static WaveAudio Mix(WaveAudio[] waves)
 {
     // all must have same length, sample rate, and no. of channels
     int nSamples = waves[0].LengthInSamples; foreach (WaveAudio w in waves) if (w.LengthInSamples != nSamples) throw new Exception("When mixing array of sounds, they all must be the same length.");
     int nSampleRate = waves[0].getSampleRate(); foreach (WaveAudio w in waves) if (w.getSampleRate() != nSampleRate) throw new Exception("When mixing array of sounds, they all must have same sample rate.");
     int nChannels = waves[0].getNumChannels(); foreach (WaveAudio w in waves) if (w.getNumChannels() != nChannels) throw new Exception("When mixing array of sounds, they all must have same amount of channels.");
     WaveAudio res = new WaveAudio(waves[0].getSampleRate(), waves[0].getNumChannels());
     res.LengthInSamples = nSamples;
     for (int ch = 0; ch < nChannels; ch++)
     {
         for (int i = 0; i < nSamples; i++)
         {
             double value = 0; foreach (WaveAudio w in waves) value += w.data[ch][i];
             res.data[ch][i] = value / waves.Length;
         }
     }
     return res;
 }
Beispiel #41
0
        public static double[][] SpectrumContentOverTime(WaveAudio w, int nBins, int nSize)
        {
            if (w.getNumChannels() != 1) throw new Exception("Only mono supported.");
            if (!isPowerOfTwo((uint) nSize)) throw new Exception("Size must be power of 2.");

            int nDatapoints = w.LengthInSamples / nSize - 1;
            double[][] res = new double[nDatapoints][];
            double[] buffer = new double[nSize];

            for (int i = 0; i < nDatapoints; i++)
            {
                // get samples from this slice of time. Put it into the buffer
                Array.Copy(w.data[0], i * nSize, buffer, 0, nSize);

                res[i] = getSpectrumContent(buffer, nBins);
            }
            return res;
        }
Beispiel #42
0
        public static WaveAudio Phaser(WaveAudio wOriginal, double freq, double fb, int depth, int stages, int drywet)
        {
            double startphaseleft  = 0;
            double startphaseright = startphaseleft + Math.PI; //note that left and right channels should start pi out of phase
            double freq_scaled     = 2.0 * Math.PI * freq / (double)wOriginal.getSampleRate();

            WaveAudio w = wOriginal.Clone();

            if (w.getNumChannels() == 1)
            {
                effect_phaseraud_impl(w.data[0], freq_scaled, startphaseleft, fb, depth, stages, drywet);
            }
            else
            {
                effect_phaseraud_impl(w.data[0], freq_scaled, startphaseleft, fb, depth, stages, drywet);
                effect_phaseraud_impl(w.data[1], freq_scaled, startphaseright, fb, depth, stages, drywet);
            }
            return(w);
        }
Beispiel #43
0
        public static WaveAudio Wahwah(WaveAudio wOriginal, double freq, double depth, double freqofs, double res)
        {
            double startphaseleft  = 0;
            double startphaseright = startphaseleft + Math.PI; //note that left and right channels should start pi out of phase
            double freq_scaled     = 2.0 * Math.PI * freq / (double)wOriginal.getSampleRate();

            WaveAudio w = wOriginal.Clone();

            if (w.getNumChannels() == 1)
            {
                effect_wahwahaud_impl(w.data[0], startphaseleft, freq_scaled, depth, freqofs, res);
            }
            else
            {
                effect_wahwahaud_impl(w.data[0], startphaseleft, freq_scaled, depth, freqofs, res);
                effect_wahwahaud_impl(w.data[1], startphaseright, freq_scaled, depth, freqofs, res);
            }
            return(w);
        }
Beispiel #44
0
            public WaveAudio doModify(WaveAudio src, int bufsize)
            {
                WaveAudio wout = new WaveAudio(src.getSampleRate(), 1);

                wout.LengthInSamples = src.LengthInSamples;

                //reuse the buffers.
                double[] ffreqmaghalfout = new double[bufsize / 2], ffreqanghalfout = new double[bufsize / 2];
                double[] ffreqmaghalfin  = new double[bufsize / 2], ffreqanghalfin = new double[bufsize / 2];
                double[] fbuffertime     = new double[bufsize];
                for (int partnum = 0; partnum < src.LengthInSamples / bufsize; partnum++)
                {
                    //copy into buffer.
                    Array.Copy(src.data[0], partnum * bufsize, fbuffertime, 0, bufsize);
                    double[] ffreqreal, ffreqimag;
                    Fourier.RawSamplesToFrequency(fbuffertime, out ffreqreal, out ffreqimag);
                    //we only care about the first half of these results.
                    for (int i = 0; i < bufsize / 2; i++)
                    {
                        ffreqmaghalfin[i] = Math.Sqrt(ffreqreal[i] * ffreqreal[i] + ffreqimag[i] * ffreqimag[i]);
                        ffreqanghalfin[i] = Math.Atan2(ffreqimag[i], ffreqreal[i]);
                    }
                    this.modifyAngular(ffreqmaghalfin, ffreqanghalfin, ffreqmaghalfout, ffreqanghalfout);
                    if (partnum == 0)
                    {
                        this.drawPlots(ffreqmaghalfin, ffreqanghalfin, ffreqmaghalfout, ffreqanghalfout);
                    }
                    for (int i = 0; i < ffreqreal.Length / 2; i++)
                    {
                        ffreqreal[i] = ffreqmaghalfout[i] * Math.Sin(ffreqanghalfout[i]);
                        ffreqimag[i] = ffreqmaghalfout[i] * Math.Cos(ffreqanghalfout[i]);
                    }
                    for (int i = ffreqreal.Length / 2; i < ffreqreal.Length; i++)
                    {
                        ffreqreal[i] = ffreqimag[i] = 0;
                    }
                    double[] fbufout;
                    Fourier.RawFrequencyToSamples(out fbufout, ffreqreal, ffreqimag);
                    Array.Copy(fbufout, 0, wout.data[0], partnum * bufsize, bufsize);
                }
                return(wout);
            }
Beispiel #45
0
            public WaveAudio doModify(WaveAudio src, int bufsize)
            {
                WaveAudio wout = new WaveAudio(src.getSampleRate(), 1);

                wout.LengthInSamples = src.LengthInSamples;

                //reuse the buffers.
                double[] ffreqmaghalfout = new double[bufsize / 2], ffreqanghalfout = new double[bufsize / 2];
                double[] ffreqmaghalfin  = new double[bufsize / 2], ffreqanghalfin = new double[bufsize / 2];
                double[] fbuffertime     = new double[bufsize];

                for (int index = 0; index < src.LengthInSamples - bufsize; index += bufsize / overlap)
                {
                    //copy into buffer.
                    Array.Copy(src.data[0], index, fbuffertime, 0, bufsize);
                    double[] ffreqreal, ffreqimag;
                    Fourier.RawSamplesToFrequency(fbuffertime, out ffreqreal, out ffreqimag);
                    //we only care about the first half of these results.
                    for (int i = 0; i < bufsize / 2; i++)
                    {
                        ffreqmaghalfin[i] = Math.Sqrt(ffreqreal[i] * ffreqreal[i] + ffreqimag[i] * ffreqimag[i]);
                        ffreqanghalfin[i] = Math.Atan2(ffreqimag[i], ffreqreal[i]);
                    }
                    this.modifyAngular(ffreqmaghalfin, ffreqanghalfin, ffreqmaghalfout, ffreqanghalfout);
                    for (int i = 0; i < ffreqreal.Length / 2; i++)
                    {
                        ffreqreal[i] = ffreqmaghalfout[i] * Math.Sin(ffreqanghalfout[i]);
                        ffreqimag[i] = ffreqmaghalfout[i] * Math.Cos(ffreqanghalfout[i]);
                    }
                    for (int i = ffreqreal.Length / 2; i < ffreqreal.Length; i++)
                    {
                        ffreqreal[i] = ffreqimag[i] = 0;
                    }
                    double[] fbufout;
                    Fourier.RawFrequencyToSamples(out fbufout, ffreqreal, ffreqimag);
                    WaveAudio ww = new WaveAudio(44100, 1);
                    ww.data[0] = fbufout;
                    //Array.Copy(fbufout, 0, wout.data[0], partnum*bufsize, bufsize);
                    ConstructionUtil.placeAudioRamp(wout, ww, index, (bufsize / overlapRamp));
                }
                return(wout);
            }
Beispiel #46
0
        public static WaveAudio Derivative(WaveAudio wOriginal)
        {
            WaveAudio w = wOriginal.Clone();

            for (int ch = 0; ch < w.getNumChannels(); ch++)
            {
                for (int i = 0; i < w.data[ch].Length; i++)
                {
                    if (i + 1 < w.data[ch].Length)
                    {
                        w.data[ch][i] = w.data[ch][i] - w.data[ch][i + 1];
                    }
                    else
                    {
                        w.data[ch][i] = w.data[ch][i] - 0;
                    }
                }
            }
            return(w);
        }
        public Form1()
        {
            InitializeComponent();
            this.m_audioPlayer = new AudioPlayer();

            this.savedNum = SetKeyState.GetNumState();
            this.savedScroll = SetKeyState.GetScrollState();
            this.savedCaps = SetKeyState.GetCapsState();

            if (File.Exists(@"..\..\cis.wav"))
                this.m_currentSound = new WaveAudio(@"..\..\cis.wav");
            else if (File.Exists(@"cis.wav"))
                this.m_currentSound = new WaveAudio(@"cis.wav");

            if (m_currentSound != null)
            {
                this.m_currentSound.setNumChannels(1, true);
                this.lblFilename.Text = "Loaded: cis.wav";
            }
        }
        public static void propertytests()
        {
            // these aren't the best tests.
            WaveAudio w1 = new WaveAudio(44100, 2);
            asserteq(w1.data.Length, 2, "channels");
            asserteq(w1.getNumChannels(), 2, "channels");
            assert(w1.data[0] != null && w1.data[1] != null, "channels");
            assert(w1.data[0].Length == 1 && w1.data[1].Length == 1, "004");
            asserteq(w1.getSampleRate(), 44100, "005");

            WaveAudio w1m = new WaveAudio(22050, 1);
            asserteq(w1m.data.Length, 1, "channels");
            assert(w1m.data[0] != null, "channels");
            asserteq(w1m.data[0].Length, 1, "004");
            asserteq(w1m.getSampleRate(), 22050, "005");

            // now set some properties
            w1m.LengthInSamples = 100;
            asserteq(w1m.data[0].Length, 100);
            asserteqf(w1m.LengthInSeconds, 100 / (double)w1m.getSampleRate(), 0.001);
        }
Beispiel #49
0
 public static void placeAudioRamp(WaveAudio target, WaveAudio source, int index, int rampWidth)
 {
     for (int ch = 0; ch < target.data.Length; ch++)
     {
         for (int j = 0; j < source.data[ch].Length; j++)
         {
             if (j < rampWidth)
             {
                 target.data[ch][j + index] += source.data[ch][j] * (((double)j) / rampWidth);
             }
             else if ((source.data[ch].Length - j) < rampWidth)
             {
                 target.data[ch][j + index] += source.data[ch][j] * (((double)source.data[ch].Length - j) / rampWidth);
             }
             else
             {
                 target.data[ch][j + index] += source.data[ch][j];
             }
         }
     }
 }
        /// <summary>
        /// Find spectrum content of signal. Returns array, where each element represents energy at frequencies.
        /// For example, SpectrumContent(w, 8) returns 8 numbers. The first in the array is the amount of energy at low frequencies, and the last is the energy at highest frequencies.
        /// Note that FFT uses a power of 2 samples, and so all of the signal may not be used.
        /// </summary>
        /// <param name="w">Sound</param>
        /// <param name="nBins">Number of bins to return.</param>
        public static double[] SpectrumContent(WaveAudio w, int nBins)
        {
            if (w.getNumChannels() != 1)
            {
                throw new Exception("Only mono supported.");
            }
            double[] buffer;

            // FFT uses a power of 2 samples, so we might have to truncate.
            if (!isPowerOfTwo((uint)w.LengthInSamples))
            {
                int nSize = (int)findNearestPowerOfTwo((uint)w.LengthInSamples);
                buffer = new double[nSize];
                Array.Copy(w.data[0], buffer, nSize);
            }
            else
            {
                buffer = w.data[0];
            }
            return(getSpectrumContent(buffer, nBins));
        }
Beispiel #51
0
        public static WaveAudio Mix(WaveAudio[] waves)
        {
            // all must have same length, sample rate, and no. of channels
            int nSamples = waves[0].LengthInSamples; foreach (WaveAudio w in waves)
            {
                if (w.LengthInSamples != nSamples)
                {
                    throw new Exception("When mixing array of sounds, they all must be the same length.");
                }
            }
            int nSampleRate = waves[0].getSampleRate(); foreach (WaveAudio w in waves)
            {
                if (w.getSampleRate() != nSampleRate)
                {
                    throw new Exception("When mixing array of sounds, they all must have same sample rate.");
                }
            }
            int nChannels = waves[0].getNumChannels(); foreach (WaveAudio w in waves)
            {
                if (w.getNumChannels() != nChannels)
                {
                    throw new Exception("When mixing array of sounds, they all must have same amount of channels.");
                }
            }
            WaveAudio res = new WaveAudio(waves[0].getSampleRate(), waves[0].getNumChannels());

            res.LengthInSamples = nSamples;
            for (int ch = 0; ch < nChannels; ch++)
            {
                for (int i = 0; i < nSamples; i++)
                {
                    double value = 0; foreach (WaveAudio w in waves)
                    {
                        value += w.data[ch][i];
                    }
                    res.data[ch][i] = value / waves.Length;
                }
            }
            return(res);
        }
        private WaveAudio Go(WaveAudio win)
        {
            WaveAudio wout = new WaveAudio(44100, 1);
            wout.LengthInSamples = win.LengthInSamples;

            List<ControlFeed> activeFeeds = new List<ControlFeed>();
            foreach (ControlFeed feed in this.controlArray)
                if (!feed.IsDisabled()) activeFeeds.Add(feed);
            ControlFeed[] feeds = activeFeeds.ToArray();

            //get delays... actually not too efficient in terms of mem. use to precalc this...
            int[][] delays = new int[feeds.Length][];
            for (int i = 0; i < feeds.Length; i++)
            {
                 delays[i] = feeds[i].Go(wout.LengthInSamples);
            }

            // now do this
            for (int i = 0; i < wout.LengthInSamples; i++)
            {
                double val=0;
                for (int j = 0; j < feeds.Length; j++)
                {
                        int index = i - delays[j][i];
                        double scaleFactor = feeds[j].GetMultiply();
                        val += getSample(win, index) * scaleFactor; // !!! !! !!!!
                        
                    // weird stuff here!!!
                    //if (j==0) val += getSample(win, index) * scaleFactor;
                    //else val += (getSample(win, index) * scaleFactor) + 0.7*getSample(wout, index) * scaleFactor;
                }
                wout.data[0][i] = val;
            }


            return wout;
        }
Beispiel #53
0
        // The following create new audio without modifying original
        public static WaveAudio Concatenate(WaveAudio w1, WaveAudio w2)
        {
            // make sure sample rates match we could be nicer and convert automatically
            if (w1.m_currentSampleRate != w2.m_currentSampleRate)
            {
                throw new Exception("Sample rates don't match");
            }
            if (w2.getNumChannels() != w2.getNumChannels())
            {
                throw new Exception("Number of channels don't match");
            }

            WaveAudio newwave = new WaveAudio(w1.getSampleRate(), w1.getNumChannels());

            newwave.LengthInSamples = w1.LengthInSamples + w2.LengthInSamples;

            for (int ch = 0; ch < w1.getNumChannels(); ch++)
            {
                //          source    sIndex, destination, destIndex,  length
                Array.Copy(w1.data[ch], 0, newwave.data[ch], 0, w1.data[ch].Length);
                Array.Copy(w2.data[ch], 0, newwave.data[ch], w1.data[ch].Length, w2.data[0].Length);
            }
            return(newwave);
        }
Beispiel #54
0
 public static WaveAudio Wahwah(WaveAudio wOriginal)
 {
     return(Wahwah(wOriginal, 1.5, 0.7, 0.1, 2.5));
 }
Beispiel #55
0
 // To reuse code, both "Mix" and "Modulate" use a helper fn, ElementWiseCombination
 // This makes the code less straight-forward, but shorter.
 // Alternative would be to find a more elegant way to write ElementWiseCombination.
 public static WaveAudio Mix(WaveAudio w1, WaveAudio w2)
 {
     return(Mix(w1, 0.5, w2, 0.5));
 }
Beispiel #56
0
        // Helper function. It's long and gross because either sound could be longer.
        // I could be more clever and use Math.Max / Min to have WaveAudio longer, WaveAudio shorter
        // , but at least now it is readable
        /// <summary>
        /// Element-wise combination of two audio clips. For example, adding, or modulation.
        /// </summary>
        internal static WaveAudio elementWiseCombination(WaveAudio w1, WaveAudio w2, ElementWiseCombinationFn fn)
        {
            if (w1.m_currentSampleRate != w2.m_currentSampleRate)
            {
                throw new Exception("Sample rates don't match");
            }
            if (w1.getNumChannels() != w2.getNumChannels())
            {
                throw new Exception("Number of channels don't match");
            }

            WaveAudio newwave = new WaveAudio(w1.getSampleRate(), w1.getNumChannels());

            newwave.LengthInSamples = Math.Max(w1.LengthInSamples, w2.LengthInSamples);
            double val;

            for (int ch = 0; ch < w1.getNumChannels(); ch++)
            {
                if (w1.LengthInSamples > w2.LengthInSamples)
                {
                    for (int i = 0; i < w1.LengthInSamples; i++)
                    {
                        if (i >= w2.LengthInSamples)
                        {
                            val = fn(w1.data[ch][i], 0);
                        }
                        else
                        {
                            val = fn(w1.data[ch][i], w2.data[ch][i]);
                        }

                        if (val > 1.0)
                        {
                            val = 1.0;
                        }
                        else if (val < -1.0)
                        {
                            val = -1.0;
                        }
                        newwave.data[ch][i] = val;
                    }
                }
                else
                {
                    for (int i = 0; i < w2.LengthInSamples; i++)
                    {
                        if (i >= w1.LengthInSamples)
                        {
                            val = fn(0, w2.data[ch][i]);
                        }
                        else
                        {
                            val = fn(w1.data[ch][i], w2.data[ch][i]);
                        }

                        if (val > 1.0)
                        {
                            val = 1.0;
                        }
                        else if (val < -1.0)
                        {
                            val = -1.0;
                        }
                        newwave.data[ch][i] = val;
                    }
                }
            }
            return(newwave);
        }
Beispiel #57
0
 public static WaveAudio Phaser(WaveAudio wOriginal, double freq)
 {
     return(Phaser(wOriginal, freq, -60, 130, 4, 255));
 }
Beispiel #58
0
 public static WaveAudio Vibrato(WaveAudio wave)
 {
     return(Vibrato(wave, 0.1, 2.0));
 }
Beispiel #59
0
 public static WaveAudio Phaser(WaveAudio wOriginal)
 {
     return(Phaser(wOriginal, .7, -60, 130, 4, 255));
 }
Beispiel #60
0
 public static WaveAudio Wahwah(WaveAudio wOriginal, double freq)
 {
     return(Wahwah(wOriginal, freq, 0.7, 0.1, 2.5));
 }