Using AudioListener.GetSpectrumData will not work on particle system script

Using AudioListener.GetSpectrumData to get an audio spectrum to use to modulate the Max Particles in a particle system. I use this exact method with other parts of my sketch to modulate the intensity of Lighting, the size of Cubes, Spheres, and Text…) but this will not work on the Particle System. Any ideas?

using UnityEngine;

public class Max_Particles_Blow_Spectrum : MonoBehaviour {
[Range(1.0f, 30000.0f)]
public float phi = 0.0f;
private ParticleSystem ps;
void Start()
{
   ps = GetComponent<ParticleSystem>();
}

void Update()
{

    float[] phi = AudioListener.GetSpectrumData(1024, 0, FFTWindow.Hamming);
    var main = ps.main;
    float amplitude = Mathf.RoundToInt(phi[1]) ;
// i thought it was an issue with the float array to I tried converting it to an int
    main.maxParticles = Mathf.RoundToInt(amplitude);
}
void OnGUI()
{
   phi = GUI.HorizontalSlider(new Rect(25, 25, 100, 30), phi, 1f, 30000.0f);
}
}

and for example, here is code that works to adjust the intensity of a light:

using UnityEngine;
using System.Collections;

public class Light_Spectrum_Test : MonoBehaviour
{
    //public float duration = 1.0F;
    public Light lt;
    void Start()
    {
        lt = GetComponent<Light>();
    }
    void Update()
    {
        float[] phi = AudioListener.GetSpectrumData(1024, 0, FFTWindow.Hamming);
        //float phi = Time.time / duration * 2 * Mathf.PI;
        float amplitude = phi[1] * 20;
        lt.intensity = amplitude;
        //Debug.Log(Mathf.RoundToInt(amplitude));

    }
}

With your light you have a “magic number” of 20 that you multiply the result by before using it for intensity.

With the particles you don’t. What values are you expecting to get back and are they big enough to show you the number of particles you want?

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class SpectrumToParticle : MonoBehaviour {

        public AudioSource AudSauce;
        public ParticleSystem Part;

        private float posRateChange;
        public float posChangeTime = 0.3f;

        private float partRateChange;
        public float partChangeTime = 0.01f;

        private GameObject goPartParent;
        private int SamplesPowerOfTwo = 256;

        public int startBand = 0;
        public int endBand = 4;
        public float freqMultiplier = 5000f;
        public float particleThreshold = 35f;

        private float[] samps;
        private float[] specs;
        private float sumSamps;
        private float rmsValue;
        private float dbValue;
        private float sumFreq;

        private ParticleSystem.EmissionModule EmissionMod;

    // Use this for initialization
    void Start () {
                EmissionMod = Part.emission;
                goPartParent = Part.gameObject;
                samps = new float[SamplesPowerOfTwo];
                specs = new float[SamplesPowerOfTwo];
    }
  
    // Update is called once per frame
    void Update () {
                //Fetch samples for volume
                AudSauce.GetOutputData(samps, 0);

                //Sum the current batch
                sumSamps = 0;
                for (int i=0; i < SamplesPowerOfTwo; i++)
                {
                        sumSamps += samps[i]*samps[i]; // sum squared samples
                }

                rmsValue = Mathf.Sqrt(sumSamps/SamplesPowerOfTwo); // rms = square root of average
                dbValue = 20*Mathf.Log10(rmsValue/0.1f); // calculate dB
                if (dbValue < -80) dbValue = -80; // clamp it to -160dB

                float newY = goPartParent.transform.position.y;
                newY = Mathf.SmoothDamp(newY, Remap(dbValue, -80, 20f, 0f, 20f), ref posRateChange, posChangeTime);
                goPartParent.transform.position = new Vector3 (goPartParent.transform.position.x, newY ,goPartParent.transform.position.z);



                //Fetch spectrum data
                AudSauce.GetSpectrumData(specs, 0, FFTWindow.Hamming);

                sumFreq = 0f;
                //Sum the volumes of the frequencies within the range
                for (int i = startBand; i < endBand; i++) {
                        sumFreq += specs [i];
                }

                //Average the sum
                sumFreq /= endBand - startBand;
                //Multiply by a large number to get something meaningful
                sumFreq *= freqMultiplier;
                float newEm = 0f;
                if (sumFreq > particleThreshold) {
                        newEm = sumFreq;
                        newEm = Mathf.SmoothDamp (EmissionMod.rateOverTimeMultiplier, newEm, ref partRateChange, partChangeTime);
                }
                      
                EmissionMod.rateOverTimeMultiplier = newEm;

    }

    private float Remap(float s, float a1, float a2, float b1, float b2)
    {
            return b1 + (s-a1)*(b2-b1)/(a2-a1);
    }

}

Some reference code:

Thank you so much for your help, this is fantastic. This is really helping me learn about the best way to do these types procedures.
What I am really trying to achieve is that when I have low frequencies, let’s say, a bass drop, then I would get large numbers, like an explosion of particles. Would this work for something like that?

I’m not actually sure whether GetSpectrumData or GetOutputData is better for calculating overall volume.
GetOutputData might be better for doing that, that’s what’s being used in the example I linked to.

I don’t really have experience doing this, just played with it now.

It seems like you’d want to look at particular frequency bands (ranges).
Each of the elements in the array returned from GetSpectrumData actually represents a frequency band, but you could group them up further to reduce resolution, and/or change the size of the array to increase or decrease the resolution.Then you can watch for audio volume within a particular frequency range.

Start here to see how the array works, and how to pick out frequences

https://www.youtube.com/watch?v=V_8JSWVT36k

Then take a look at these
Fetching the average volume within a frequency range
https://answers.unity.com/questions/175173/audio-analysis-pass-filter.html
Dividing up an array into frequency ranges, and vizualizing their output by affecting objects
https://discussions.unity.com/t/445654/5

https://www.youtube.com/watch?v=dQKXLYrrxKg

I just changed the example above so that the overall volume is now affecting the particle gameobject transform position Y
And as for the frequency, you can select what elements of the frequency array you want to watch, and it averages the volume within those elements, and it checks to see if it meets a threshold and it will get the particle effect to emit particles if it exceeds the threshold.
I was trying to isolate a particular sound to certain elements and thresholds.
It’s only using 256 resolution though. Probably eaiser to draw a representation of the whole thing to get a visualization and more easily pinpoints the bands a sound affects.

I’m thinking there is merit in fetching the sum of a band, average of a band, peak and min of a band, because you might want to use all of those in calcs. Fetching the dominant band would be useful as well as just looking at specific bands.