일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | |||||
3 | 4 | 5 | 6 | 7 | 8 | 9 |
10 | 11 | 12 | 13 | 14 | 15 | 16 |
17 | 18 | 19 | 20 | 21 | 22 | 23 |
24 | 25 | 26 | 27 | 28 | 29 | 30 |
- 모션
- LINQ
- enum
- 랜덤
- 프로그래머스
- canvasgroup
- UGUI
- Admob
- climbingtheleaderboard
- 유니티기초
- React Native
- http
- 애니메이션
- 열거형
- unity
- 코딩테스트
- 컴퓨터구조
- C#
- 애드몹
- ui
- 광고테스트
- unity3D
- 게임개발
- cs
- dotween
- scrollrect
- csvhelper
- Hackerrank
- 유니티
- 전면광고
- Today
- Total
Ruya Games
Audiosource 출력 소리의 스펙트럼(파형) 시각화하기 본문
**구현할때 DoTween을 사용합니다(DoScaleY). 구현시 transform.localScale로 변경 가능합니다.
소리의 스펙트럼을 게임오브젝트들로 표시하려면 먼저 audioSource로부터 스펙트럼 데이터를 받아와야 합니다.
이때 함수는 GetSpectrumData()를 사용하고, 이 함수는 float[] 형식으로 현재 시점의 스펙트럼 데이터를 리턴합니다.
리턴 받을 float[] 배열은 64, 128, 256 등등 2의 제곱수로 크기를 지정해주면 되고, 크기가 클수록 정확한 값을 리턴받을 수 있습니다.
다만 이 기능에서는 그정도까진 필요 없을듯해서 최소값인 64로 받아왔습니다.
기본적인 사용 방법은 아래와 같습니다.
private float[] spectrumData;
void Update() {
audioSource.GetSpectrumData(spectrumData, 0, FFTWindow.Hamming);
}
여기서 세번째 인자는 Fast Fourier Transform (FFT) 윈도우 함수들을 넣어주면 되는데, 각 함수별 특징은 아래와 같습니다.
- FFTWindow.Blackman: 주파수 누출을 매우 효과적으로 줄여줍니다. 이는 신호의 끝 부분을 부드럽게 만들어, 이웃하는 주파수 구성 요소 간의 간섭을 최소화합니다. 블랙맨 윈도우는 높은 주파수 해상도를 제공하지만, 다른 윈도우에 비해 약간 더 넓은 주파수 대역을 가집니다.
- FFTWindow.Hamming: 스펙트럼 누출을 줄이면서도 좋은 주파수 해상도를 유지합니다. 햄밍 윈도우는 주파수 구성 요소 간의 간섭을 줄이는 데 효과적이지만, 블랙맨 윈도우에 비해 주파수 누출을 덜 줄입니다.
- FFTWindow.Hanning: 부드러운 윈도우 함수로, 스펙트럼 누출을 줄이고 부드러운 전환을 제공합니다. 한닝 윈도우는 주파수 구성 요소 간의 간섭을 줄이면서도 상대적으로 좋은 시간 해상도를 제공합니다.
이 기능을 구현할때는 각 함수에 따른 특별한 변화는 없었습니다.
전체적인 구조는 Update에서 매 프레임마다 스펙트럼 데이터를 받아온 뒤, 게임 오브젝트를 해당 데이터값에 맞춰서 scale, position, color값들을 변화시키는 구조입니다. 여기서는 위아래로 움직이는 막대모양으로 구현할 예정이므로 scale을 변경시키고, DoScaleY를 사용합니다.
Update() 함수의 전체 코드는 아래와 같습니다.
void Update() {
currentUpdateTime += Time.deltaTime;
if (currentUpdateTime >= updateStep) {
currentUpdateTime = 0.0f;
audioSource.GetSpectrumData(spectrumData, 0, FFTWindow.Hamming);
for (int i = 0; i < visualizerObjects.Length; i++) {
if (visualizerObjects[i] != null) {
float height = spectrumData[i] * maxHeight;
visualizerObjects[i].transform.DOScaleY(height, updateStep).SetEase(Ease.Linear);
}
}
}
}
여기서 visualizerObjects 리스트는 파형에 따라 움직이는 gameObject막대들이 원소로 들어가있습니다.
제가 사용한 전체 코드는 아래와 같습니다.
public class AudioVisualizer : MonoBehaviour {
public AudioSource audioSource;
public GameObject[] visualizerObjects;
public float maxHeight = 1.0f; //최대로 커지는 scale값입니다.
public float updateStep = 0.1f;
private float currentUpdateTime = 0.0f;
private float[] spectrumData;
private const int SAMPLE_SIZE = 64;
void Start() {
spectrumData = new float[SAMPLE_SIZE];
}
void Update() {
currentUpdateTime += Time.deltaTime;
if (currentUpdateTime >= updateStep) {
currentUpdateTime = 0.0f;
audioSource.GetSpectrumData(spectrumData, 0, FFTWindow.Hamming);
for (int i = 0; i < visualizerObjects.Length; i++) {
if (visualizerObjects[i] != null) {
float height = spectrumData[i] * maxHeight;
visualizerObjects[i].transform.DOScaleY(height, updateStep).SetEase(Ease.Linear);
}
}
}
}
}
이후 에디터에서 아래와 같이 오브젝트들을 배치하고 할당하면 됩니다.(오브젝트의 개수, 모양은 어떻게 조정하셔도 상관없습니다)
동작 영상입니다 :)
'Unity' 카테고리의 다른 글
List 맨앞, 맨뒤 값 제거하는 방법 (1) | 2023.12.04 |
---|---|
유니티 실행환경 프레임 고정시키기 + 에디터에서 프레임 확인하기 (3) | 2023.12.03 |
Unity 인스펙터(inspector) 정리하기 (0) | 2023.12.01 |
Scene 변경시 이벤트 호출 (0) | 2023.11.30 |
Scene 이동시 이전 씬의 정보 저장 (0) | 2023.11.30 |