11// todo eliminate auxiliary classes
22class AudioSource {
3+ static ERROR_INVALID_PLAYBACK_RATE = "Cannot set negative or zero playback rate; only positive values are supported" ;
4+
35 playbackOptions = {
46 autoplay : true ,
57 loop : true ,
@@ -34,6 +36,9 @@ class AudioSource {
3436 this . playbackOptions = playbackOptions ;
3537 this . filePath = filePath ;
3638
39+ // BJS doesn't expose this, so we have to store it at this level (at the risk of being wrong)
40+ this . playbackRate = 1 ;
41+
3742 const resource = C_Decoding . decodeFile ( filePath ) ; // May be fetched from disk (TODO: It's blocking, use async?)
3843 this . uniqueID = new UniqueID ( ) ;
3944
@@ -66,7 +71,7 @@ class AudioSource {
6671 // validatePositiveInteger(newVolumePercentage);
6772 // validatePositiveInteger(timeToFullyApplyChangeInMilliseconds);
6873 this . sound . setVolume ( newVolumePercentage , timeToFullyApplyChangeInMilliseconds / 1000 ) ; // ms to sec
69- // todo write all this up to the audio options for easier manual testing?
74+ // TODO write all this up to the audio options for easier manual testing?
7075 }
7176 getVolume ( ) {
7277 return this . sound . getVolume ( ) ;
@@ -86,39 +91,26 @@ class AudioSource {
8691 // TODO fade in to set volume (take from settings)
8792 this . setVolume ( volumeGain , timeToFadeInCompletelyInMilliseconds ) ;
8893 }
89- // scene switch while scene is loading?
90- // combining looped/nonlooped sounds, use different tracks and AudioTrack.stopAllSounds
91- // analyzer
92- // playback rate
93- setPlaybackRate ( newRateAsPercentage ) {
94- // validatePositiveInteger(newRateAsPercentage);
95- this . sound . setPlaybackRate ( newRateAsPercentage ) ;
96- }
97- attachToUnit ( unitID ) {
98- // validateUnitID(unitID);
99- throw new NotYetImplementedError ( "AudioSource.attachToUnit" ) ;
100- }
101- attachToCamera ( ) {
102- throw new NotYetImplementedError ( "AudioSource.attachToCamera" ) ;
103- }
104- attachToSprite ( animatedSprite ) {
105- throw new NotYetImplementedError ( "AudioSource.attachToSprite" ) ;
94+ getPlaybackRate ( ) {
95+ return this . playbackRate ;
10696 }
107- attachToModel ( animatedModel ) {
108- throw new NotYetImplementedError ( "AudioSource.attachToMesh" ) ;
109- }
110- setWorldPosition ( worldX , worldY , worldZ ) {
111- // validateWorldPosition(worldX, worldY, worldZ);
112- throw new NotYetImplementedError ( "AudioSource.setWorldPosition" ) ;
113- }
114- setMapPosition ( mapU , mapV ) {
115- // validateMapPosition(mapU, mapV);
116- throw new NotYetImplementedError ( "AudioSource.setMapPosition" ) ;
97+ setPlaybackRate ( newPlaybackRate ) {
98+ validateNumber ( newPlaybackRate , "Usage: AudioSource.setPlaybackRate(Number newPlaybackRate)" ) ;
99+
100+ if ( newPlaybackRate <= 0 ) throw new RangeError ( AudioSource . ERROR_INVALID_PLAYBACK_RATE ) ;
101+
102+ this . playbackRate = newPlaybackRate ;
103+ this . sound . setPlaybackRate ( newPlaybackRate ) ;
117104 }
118- getSoundHandle ( ) {
105+ getUniqueID ( ) {
119106 return this . uniqueID . toString ( ) ;
120107 }
121108 destroy ( ) {
109+ if ( this . sound === null ) return false ; // Already destroyed; all operations should fail
110+
122111 this . sound . dispose ( ) ;
112+ this . sound = null ;
113+
114+ return true ;
123115 }
124116}
0 commit comments