AudioSpectrumView.cs 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102
  1. using System;
  2. using System.Collections.Generic;
  3. using Unity.Collections;
  4. using UnityEngine;
  5. using Object = UnityEngine.Object;
  6. namespace Unity.RenderStreaming.Samples
  7. {
  8. class AudioSpectrumView : MonoBehaviour
  9. {
  10. [SerializeField] AudioSource target;
  11. [SerializeField] LineRenderer line;
  12. [SerializeField] Color[] lineColors;
  13. [SerializeField] RectTransform rectTransform;
  14. [SerializeField] float xRatio = 1f;
  15. [SerializeField] float yRatio = 1f;
  16. const int positionCount = 256;
  17. float[] spectrum = new float[2048];
  18. private AudioClip clip;
  19. Vector3[] array;
  20. List<LineRenderer> lines = new List<LineRenderer>();
  21. private Dictionary<AudioSpeakerMode, int> SpeakerModeToChannel = new Dictionary<AudioSpeakerMode, int>()
  22. {
  23. {AudioSpeakerMode.Mono, 1},
  24. {AudioSpeakerMode.Stereo, 2},
  25. {AudioSpeakerMode.Quad, 4},
  26. {AudioSpeakerMode.Surround, 5},
  27. {AudioSpeakerMode.Mode5point1, 6},
  28. {AudioSpeakerMode.Mode7point1, 8},
  29. };
  30. void Start()
  31. {
  32. array = new Vector3[positionCount];
  33. // This line object is used as a template.
  34. if(line.gameObject.activeInHierarchy)
  35. line.gameObject.SetActive(false);
  36. AudioSettings.OnAudioConfigurationChanged += OnAudioConfigurationChanged;
  37. }
  38. void OnAudioConfigurationChanged(bool deviceChanged)
  39. {
  40. // reset lines;
  41. clip = null;
  42. }
  43. void ResetLines(int channelCount)
  44. {
  45. foreach (var line in lines)
  46. {
  47. Object.Destroy(line.gameObject);
  48. }
  49. lines.Clear();
  50. for (int i = 0; i < channelCount; i++)
  51. {
  52. var line_ = GameObject.Instantiate(line, line.transform.parent);
  53. line_.gameObject.SetActive(true);
  54. line_.positionCount = positionCount;
  55. line_.startColor = lineColors[i];
  56. line_.endColor = lineColors[i];
  57. lines.Add(line_);
  58. }
  59. }
  60. void Update()
  61. {
  62. if (target.clip == null)
  63. {
  64. if(lines.Count > 0)
  65. ResetLines(0);
  66. clip = null;
  67. return;
  68. }
  69. if (clip != target.clip)
  70. {
  71. clip = target.clip;
  72. int channelCount = clip.channels;
  73. var conf = AudioSettings.GetConfiguration();
  74. int maxChannelCount = SpeakerModeToChannel[conf.speakerMode];
  75. channelCount = Math.Min(channelCount, maxChannelCount);
  76. ResetLines(channelCount);
  77. }
  78. for (int lineIndex = 0; lineIndex < lines.Count; lineIndex++)
  79. {
  80. target.GetSpectrumData(spectrum, lineIndex, FFTWindow.Rectangular);
  81. for (int i = 1; i < array.Length; i++)
  82. {
  83. float x = rectTransform.rect.width * i / array.Length * xRatio;
  84. float y = rectTransform.rect.height * Mathf.Log(spectrum[i] + 1) * yRatio;
  85. array[i] = new Vector3(x, y, 0);
  86. }
  87. lines[lineIndex].SetPositions(array);
  88. }
  89. }
  90. }
  91. }