22{
33 using UnityEngine ;
44 using System . Collections ;
5+ using Malimbe . MemberClearanceMethod ;
56 using Malimbe . PropertySerializationAttribute ;
67 using Malimbe . XmlDocumentationAttribute ;
78
@@ -17,6 +18,10 @@ public class AudioSourceHapticPulser : RoutineHapticPulser
1718 [ field: DocumentedByXml ]
1819 public AudioSource AudioSource { get ; set ; }
1920
21+ /// <summary>
22+ /// Observer added to <see cref="AudioSource"/>.
23+ /// </summary>
24+ protected AudioSourceHapticPulserDataObserver observer ;
2025 /// <summary>
2126 /// <see cref="AudioSettings.dspTime"/> of the last <see cref="OnAudioFilterRead"/>.
2227 /// </summary>
@@ -30,6 +35,17 @@ public class AudioSourceHapticPulser : RoutineHapticPulser
3035 /// </summary>
3136 protected int filterReadChannels ;
3237
38+ protected virtual void OnEnable ( )
39+ {
40+ AddDataObserver ( ) ;
41+ }
42+
43+ protected override void OnDisable ( )
44+ {
45+ base . OnDisable ( ) ;
46+ RemoveDataObserver ( ) ;
47+ }
48+
3349 /// <inheritdoc />
3450 public override bool IsActive ( )
3551 {
@@ -45,10 +61,11 @@ protected override IEnumerator HapticProcessRoutine()
4561 int outputSampleRate = AudioSettings . outputSampleRate ;
4662 while ( AudioSource . isPlaying )
4763 {
48- int sampleIndex = ( int ) ( ( AudioSettings . dspTime - filterReadDspTime ) * outputSampleRate ) ;
4964 float currentSample = 0 ;
50- if ( filterReadData != null && sampleIndex * filterReadChannels < filterReadData . Length )
65+ if ( filterReadData != null )
5166 {
67+ int sampleIndex = ( int ) ( ( AudioSettings . dspTime - filterReadDspTime ) * outputSampleRate ) * filterReadChannels ;
68+ sampleIndex = Mathf . Min ( sampleIndex , filterReadData . Length - filterReadChannels ) ;
5269 for ( int i = 0 ; i < filterReadChannels ; ++ i )
5370 {
5471 currentSample += filterReadData [ sampleIndex + i ] ;
@@ -63,15 +80,67 @@ protected override IEnumerator HapticProcessRoutine()
6380 }
6481
6582 /// <summary>
66- /// Store currently playing audio data and additional data.
83+ /// Adds a <see cref="AudioSourceHapticPulserDataObserver"/> to the <see cref="AudioSource"/>.
84+ /// </summary>
85+ protected virtual void AddDataObserver ( )
86+ {
87+ if ( AudioSource == null )
88+ {
89+ return ;
90+ }
91+
92+ observer = AudioSource . gameObject . AddComponent < AudioSourceHapticPulserDataObserver > ( ) ;
93+ observer . Source = this ;
94+ }
95+
96+ /// <summary>
97+ /// Remove the <see cref="AudioSourceHapticPulserDataObserver"/> from the <see cref="AudioSource"/>.
98+ /// </summary>
99+ protected virtual void RemoveDataObserver ( )
100+ {
101+ if ( observer == null )
102+ {
103+ return ;
104+ }
105+
106+ Destroy ( observer ) ;
107+ observer = null ;
108+ }
109+
110+ /// <summary>
111+ /// Receive audio data from <see cref="AudioSourceHapticPulserDataObserver"/>.
112+ /// </summary>
113+ public void Receive ( double dspTime , float [ ] data , int channels )
114+ {
115+ filterReadDspTime = dspTime ;
116+ filterReadData = data ;
117+ filterReadChannels = channels ;
118+ }
119+ }
120+
121+ /// <summary>
122+ /// Sends currently playing audio data and additional data back to <see cref="AudioSourceHapticPulser"/>
123+ /// </summary>
124+ public class AudioSourceHapticPulserDataObserver : MonoBehaviour
125+ {
126+ /// <summary>
127+ /// The <see cref="AudioSourceHapticPulser"/> that receives audio data.
128+ /// </summary>
129+ [ Serialized , Cleared ]
130+ [ field: DocumentedByXml ]
131+ public AudioSourceHapticPulser Source { get ; set ; }
132+
133+ /// <summary>
134+ /// Sends currently playing audio data and additional data back to <see cref="Source"/>.
67135 /// </summary>
68136 /// <param name="data">An array of floats comprising the audio data.</param>
69137 /// <param name="channels">An int that stores the number of channels of audio data passed to this delegate.</param>
70138 protected virtual void OnAudioFilterRead ( float [ ] data , int channels )
71139 {
72- filterReadDspTime = AudioSettings . dspTime ;
73- filterReadData = data ;
74- filterReadChannels = channels ;
140+ if ( Source )
141+ {
142+ Source . Receive ( AudioSettings . dspTime , data , channels ) ;
143+ }
75144 }
76145 }
77146}
0 commit comments