아래 스펙트럼 대역에 대한 내용을 보고 와주세요!
움짤을 보면 아시겠지만 서브 베이스랑 베이스, 미드 레인지(하)가 가장 강하네요!
AudioPeer 수정
이전 Audio Peer 코드는 이전 글을 참고해주세요.
2024.03.25 - [Unity/Study] - 유니티 Audio Spectrum을 이용한 큐브 스케일 변화 시키기 #기초
using UnityEngine;
public class AudioPeer : MonoBehaviour
{
public static AudioPeer Instance;
public enum AudioChannel
{
Left = 0,
Right = 1,
Center = 2,
LFE = 3,
RearLeft = 4,
RearRight = 5
}
[Header("[Ref]")]
[SerializeField] private AudioSource audioSource;
[Space(3)]
[Header("[Value]")]
[SerializeField, Tooltip("첫 번째 (왼쪽) 스테레오 채널 또는 모노 채널 \n두 번째 (오른쪽) 스테레오 채널 \n센터 채널 \nLFE (저주파 효과) 채널 \n후방 왼쪽 채널 \n후방 오른쪽 채널")] private AudioChannel channel = AudioChannel.Left;
[Range(3, 12)] public int Pow = 8;
[SerializeField] private int FreqBandSize = 8;
public int FreqBandPower = 1;
[Space(3)]
[Header("[OutPut]")]
public float[] Samples;
public float[] FreqBand;
private void Awake()
{
Instance = this;
Samples = new float[(int)Mathf.Pow(2,Pow)];
FreqBand = new float[FreqBandSize];
}
private void Update()
{
GetSpectrumAudioSource();
MakeFrequencyBand();
}
private void GetSpectrumAudioSource()
{
audioSource.GetSpectrumData(samples: Samples, channel: (int)channel, FFTWindow.Blackman);
}
private void MakeFrequencyBand()
{
int count = 0;
for (int i = 0; i < 8; i++)
{
float average = 0;
int sampleCount = (int)Mathf.Pow(2, i) * 2;
if (i == 7)
{
sampleCount += 2;
}
for (int j = 0; j < sampleCount; j++)
{
average += Samples[count];
count++;
}
average /= sampleCount;
FreqBand[i] = average * FreqBandPower;
}
}
}
새롭게 추가된 함수는 MakeFrequencyBand입니다.
이 함수는 Sample의 개수를 512개를 예시로 합니다.
512개로 한 이유는 2을 한 번 제곱할 때 마다 대역이 나뉜다고 생각하시면 되고, 서브 베이스부터 하이 레인지까지 총 8개가 존재하므로 2의 8제곱인 512로 정했습니다.
각 제곱별로 평균을 내어 FreqBand에 집어 넣어 주었습니다.
SpawnCubes 수정
이전 Spawn Cubes 스크립트도 이전 글을 참고해주세요.
using UnityEngine;
using UnityEngine.UIElements;
public class SpawnCubes : MonoBehaviour
{
[SerializeField] private GameObject radiusObject;
[SerializeField] private GameObject paramCube;
private GameObject[] spawnedRadiusObjects;
private GameObject[] spawnedParamCube;
public float Radius = 3f;
[SerializeField] private float sizePower = 10f;
[SerializeField] private float minYScale = 1f;
private float x = 0.3f;
private float z = 0.3f;
private int SampleLength;
private bool isStart;
private int length;
private void Start()
{
SampleLength = AudioPeer.Instance.Samples.Length;
length = AudioPeer.Instance.FreqBand.Length;
}
private void Spawn()
{
spawnedRadiusObjects = new GameObject[SampleLength];
for (int i = 0; i < SampleLength; i++)
{
float angle = i * 360f / SampleLength;
transform.rotation = Quaternion.Euler(0, angle, 0);
GameObject go = Instantiate(radiusObject, transform.forward * Radius, Quaternion.identity);
go.name = "Cube" + i;
spawnedRadiusObjects[i] = go;
}
spawnedParamCube = new GameObject[length];
for (int i = 0; i < length; i++)
{
GameObject go = Instantiate(paramCube, new Vector3((-length / 2f) + i * 1.3f, 0, 0), Quaternion.identity);
go.name = "ParamCube" + i;
spawnedParamCube[i] = go;
}
isStart = true;
}
private void Update()
{
if (!isStart) return;
for (int i = 0; i < SampleLength; i++)
{
spawnedRadiusObjects[i].transform.localScale = new Vector3(x, (AudioPeer.Instance.Samples[i] * sizePower) + minYScale, z);
}
for (int i = 0; i < length; i++)
{
spawnedParamCube[i].transform.localScale = new Vector3(0.5f, (AudioPeer.Instance.FreqBand[i] * sizePower) + minYScale, 0.5f);
}
}
}
달라진 점은 Update에서 FreqBand, 밴드별로 나뉜 것을 참조해서 총 8개의 큐브의 사이즈를 조절하는 것이 추가되었다는 것입니다.