Static class which provides a few audio related methods and constants. Methods that handle the actual sample processing will be found in the GATData class or in AGATFilter derived classes.
Beispiel #1
0
        /// <summary>
        /// Returns the sample closest to the provided midicode and a pitch shift value
        /// to be applied to the sample
        /// </summary>
        /// <returns>The sample index for midi code.</returns>
        /// <param name="midiCode">Midi code.</param>
        /// <param name="pitchShift">Pitch shift.</param>
        public GATData GetClosestSampleForMidiCode(float midiCode, out float pitchShift)
        {
            int           index = _allSamples.Count - 1;
            int           i;
            GATSampleInfo info;
            float         delta;
            float         minDelta = float.MaxValue;

            for (i = 0; i < _allSamples.Count; i++)
            {
                info = _soundBank.SampleInfos[i];

                delta = Mathf.Abs(midiCode - info.MidiCode);

                if (delta < minDelta)
                {
                    minDelta = delta;
                }
                else
                {
                    index = i - 1;
                    break;
                }
            }

            pitchShift = GATMaths.GetRatioForInterval(midiCode - ( float )_soundBank.SampleInfos[index].MidiCode);

            return(_allSamples[index]);
        }
Beispiel #2
0
 /// <summary>
 /// Creates a new PatternSample for insertion in a PulsedPatternModule.
 /// </summary>
 public PatternSample(string sampleName, float gain = 1f, int semiTones = 0)
 {
     _sampleName = sampleName;
     _gain       = gain;
     _semiTones  = semiTones;
     _pitch      = GATMaths.GetRatioForInterval(semiTones);
 }
Beispiel #3
0
        public void GetMidiCodes(int offset, int fftSize = 4096, int maxFreq = 5000)
        {
            AudioClip clip;

            float[]           real, im, window;
            FloatFFT          fft;
            string            assetPath;
            float             binWidth;
            List <FFTBinInfo> binInfos;
            int i;

            real   = new float[fftSize];
            im     = new float[fftSize];
            window = new float[fftSize];

            GATMaths.MakeHammingWindow(window);

            fft = new FloatFFT();
            fft.init(( uint )Mathf.Log(fftSize, 2));
            binWidth = ( float )_sampleRate / fftSize;

            int maxBin = ( int )(( float )maxFreq / binWidth);

            foreach (GATSampleInfo info in _sampleInfos)
            {
                assetPath = AssetDatabase.GUIDToAssetPath(info.GUID);
                clip      = AssetDatabase.LoadAssetAtPath(assetPath, typeof(AudioClip)) as AudioClip;
                if (clip.channels > 1)
                {
                    throw new GATException("Get Midi Codes is a beta feature only available for mono clips");
                }
                clip.GetData(real, offset);
                System.Array.Clear(im, 0, im.Length);
                fft.run(real, im);

                for (i = 0; i < maxBin; i++)
                {
                    real[i] = Mathf.Sqrt(real[i] * real[i] + im[i] * im[i]);
                }

                binInfos = FFTBinInfo.GetLowerMaxBins(real, 0, maxBin, binWidth, .2f);

                info.MidiCode = binInfos[binInfos.Count - 1].GetMidiCode();
            }

            SortByMidiCode();
        }
            void SetPitch(double newPitch)
            {
                if (newPitch == _nextPitch)
                {
                    return;
                }

                _nextPitch       = newPitch;
                _needsDataUpdate = true;


                if (envelope == GATEnvelope.nullEnvelope)
                {
                    _cachedLength      = GATMaths.ResampledLength(sourceSample.Count, _nextPitch);
                    _needsNewContainer = true;
                }
            }
Beispiel #5
0
        protected void FillWithResampledData(GATData sourceData, GATData targetData, int fromIndex, int targetLength, double pitch)
        {
            //check that we have enough samples to fulfill the request:
            int appliedLength = GATMaths.ClampedResampledLength(sourceData.Count - fromIndex, targetLength, pitch);

            if (appliedLength < 0)
            {
                                #if GAT_DEBUG
                Debug.LogWarning("requested offset is out of bounds.");
                                #endif
                return;
            }

            sourceData.ResampleCopyTo(fromIndex, targetData, appliedLength, pitch);

            //if we did not have enough samples, clear the rest:
            if (appliedLength < targetLength)
            {
                targetData.Clear(appliedLength, targetData.Count - appliedLength);
            }
        }
Beispiel #6
0
        public static List <FFTBinInfo> GetLowerMaxBins(float[] magnitudes, int fromIndex, int toIndex, float binFrequencyWidth, float magThresholdRatio)
        {
            List <FFTBinInfo> maxBins = new List <FFTBinInfo>();
            FFTBinInfo        binInfo;
            int   maxIndex;
            float magThreshold;

            fromIndex++;
            toIndex--;

            maxIndex = GATMaths.GetIndexOfMaxValue(magnitudes, fromIndex, toIndex);

            binInfo = new FFTBinInfo(magnitudes, maxIndex, binFrequencyWidth);

            maxBins.Add(binInfo);

            magThreshold = binInfo.InterpolatedMagnitude * magThresholdRatio;

            while (true)
            {
                toIndex = binInfo.BinIndex - 1;

                if (toIndex - fromIndex < 3)
                {
                    break;
                }

                maxIndex = GATMaths.GetIndexOfMaxValue(magnitudes, fromIndex, toIndex);
                binInfo  = new FFTBinInfo(magnitudes, maxIndex, binFrequencyWidth);

                if (binInfo.InterpolatedMagnitude < magThreshold)
                {
                    break;
                }

                maxBins.Add(binInfo);
            }

            return(maxBins);
        }
Beispiel #7
0
        /// <summary>
        /// Sets and pre-computes the specified
        /// WindowFunction for faster processing.
        /// </summary>
        public void SetWindow(WindowFunction windowFunction)
        {
            if (_windowData == null || _windowData.Length != _appliedFFTSize)
            {
                _windowData = new float[_appliedFFTSize];
            }

            switch (window)
            {
            case WindowFunction.Hanning:

                GATMaths.MakeHanningWindow(_windowData);

                break;

            case WindowFunction.Hamming:

                GATMaths.MakeHammingWindow(_windowData);

                break;
            }
        }