@@ -1454,6 +1454,22 @@ function SoundManager(smURL, smID) {
1454
1454
1455
1455
var s = this , resetProperties , add_html5_events , remove_html5_events , stop_html5_timer , start_html5_timer , attachOnPosition , onplay_called = false , onPositionItems = [ ] , onPositionFired = 0 , detachOnPosition , applyFromTo , lastURL = null , lastHTML5State , urlOmitted ;
1456
1456
1457
+ //HTML5 audio sampling properties
1458
+ this . _useAdvancedHTML5 = false ;
1459
+ this . _useMoz = false ;
1460
+ this . _fftLeft ;
1461
+ this . _fftRight ;
1462
+ this . _fftRightO ; //For when we set right = left but want to preserve the original
1463
+ this . _waveformLeft ;
1464
+ this . _waveformRight ;
1465
+ this . _audioContext ;
1466
+ this . _processingNode ;
1467
+ this . _sourceNode ;
1468
+ this . _fbLength ;
1469
+ this . _sample_size ;
1470
+ this . _sample_rate ;
1471
+
1472
+
1457
1473
lastHTML5State = {
1458
1474
// tracks duration + position (time)
1459
1475
duration : null ,
@@ -1726,6 +1742,10 @@ function SoundManager(smURL, smID) {
1726
1742
} else {
1727
1743
1728
1744
stop_html5_timer ( ) ;
1745
+
1746
+ if ( s . _useAdvancedHTML5 && ! s . _useMoz ) {
1747
+ this . _destroy_WebAudio_Waveform_Parser ( ) ;
1748
+ }
1729
1749
1730
1750
if ( s . _a ) {
1731
1751
s . _a . pause ( ) ;
@@ -2767,6 +2787,87 @@ function SoundManager(smURL, smID) {
2767
2787
2768
2788
resetProperties ( ) ;
2769
2789
2790
+ var audioProcessEvent = function ( e ) {
2791
+ if ( s . paused ) return ;
2792
+ //When we're processing some data through the HTML WebAudio API
2793
+ var buffers = [ ] ;
2794
+ var channels , resolution ;
2795
+ channels = s . _channels = e . inputBuffer . numberOfChannels ;
2796
+
2797
+ s . _waveformLeft = e . inputBuffer . getChannelData ( 0 ) ;
2798
+ if ( s . instanceOptions . useEQData ) {
2799
+ s . _fftLeft . forward ( s . _waveformLeft ) ;
2800
+ }
2801
+
2802
+ if ( channels > 1 ) {
2803
+ s . _waveformRight = e . inputBuffer . getChannelData ( 1 ) ;
2804
+ if ( s . instanceOptions . useEQData ) {
2805
+ s . _fftRight = s . _fftRightO ;
2806
+ s . _fftRight . forward ( s . _waveformRight ) ;
2807
+ }
2808
+ } else {
2809
+ s . _waveformRight = s . _waveformLeft ;
2810
+ s . _fftRight = s . _fftLeft ;
2811
+ }
2812
+
2813
+ s . _onTimer ( true ) ;
2814
+ } ;
2815
+
2816
+ this . _create_WebAudio_Waveform_Parser = function ( ) {
2817
+ //Initialisation for Google Chrome/Web Audio compatible browsers
2818
+
2819
+ s . _sample_rate = 44100 ;
2820
+ s . _sample_size = 2048 ;
2821
+ if ( s . instanceOptions . useWaveformData || s . instanceOptions . useEQData || s . instanceOptions . usePeakData ) {
2822
+ var context = s . _audioContext ;
2823
+
2824
+ var source = s . _sourceNode = context . createMediaElementSource ( s . _a ) ;
2825
+
2826
+ var proc = s . _processingNode = context . createJavaScriptNode ( s . _sample_size / 2 , 1 , 1 ) ;
2827
+
2828
+ source . connect ( proc ) ;
2829
+
2830
+ proc . connect ( context . destination ) ;
2831
+
2832
+ source . connect ( context . destination ) ;
2833
+
2834
+ proc . onaudioprocess = audioProcessEvent ;
2835
+
2836
+ s . _fftLeft = new FFT ( s . _sample_size / 2 , s . _sample_rate ) ;
2837
+ s . _fftRight = s . _fftRightO = new FFT ( s . _sample_size / 2 , s . _sample_rate ) ;
2838
+ }
2839
+
2840
+ } ;
2841
+
2842
+ this . _destroy_WebAudio_Waveform_Parser = function ( ) {
2843
+ if ( s . _sourceNode )
2844
+ s . _sourceNode . disconnect ( 0 ) ;
2845
+
2846
+ if ( s . _processingNode )
2847
+ s . _processingNode . disconnect ( 0 ) ;
2848
+ } ;
2849
+
2850
+ this . _create_Mozilla_Waveform_Parser = function ( ) {
2851
+ //Initialisation for Mozilla Firefox
2852
+
2853
+ s . _fbLength = s . _a . mozFrameBufferLength ;
2854
+ s . _channels = s . _a . mozChannels ;
2855
+ s . _sample_rate = s . _a . mozSampleRate ;
2856
+
2857
+ if ( s . instanceOptions . useWaveformData || s . instanceOptions . useEQData || s . instanceOptions . usePeakData ) {
2858
+ s . _waveformLeft = new Float32Array ( s . _fbLength / s . _channels ) ;
2859
+ s . _waveformRight = new Float32Array ( s . _fbLength / s . _channels ) ;
2860
+ }
2861
+
2862
+ if ( s . instanceOptions . useEQData || s . instanceOptions . usePeakData ) {
2863
+ s . _fftLeft = new FFT ( s . _fbLength / s . _channels , s . _sample_rate ) ;
2864
+ s . _fftRight = s . _fftLeft ;
2865
+ if ( s . _channels > 1 ) {
2866
+ s . _fftRight = new FFT ( s . _fbLength / s . _channels , s . _sample_rate ) ;
2867
+ }
2868
+ }
2869
+ } ;
2870
+
2770
2871
/**
2771
2872
* Pseudo-private SMSound internals
2772
2873
* --------------------------------
@@ -2781,6 +2882,10 @@ function SoundManager(smURL, smID) {
2781
2882
*/
2782
2883
2783
2884
var duration , isNew = false , time , x = { } ;
2885
+ var peakData = x ;
2886
+ var waveformLeft = x ;
2887
+ var waveformRight = x ;
2888
+ var eqData = x ;
2784
2889
2785
2890
if ( s . _hasTimer || bForce ) {
2786
2891
@@ -2812,7 +2917,18 @@ function SoundManager(smURL, smID) {
2812
2917
2813
2918
if ( isNew || bForce ) {
2814
2919
2815
- s . _whileplaying ( time , x , x , x , x ) ;
2920
+ if ( s . _useAdvancedHTML5 ) {
2921
+ if ( s . instanceOptions . useWaveformData ) {
2922
+ waveformLeft = s . _waveformLeft ;
2923
+ waveformRight = s . _waveformRight ;
2924
+ }
2925
+ if ( s . instanceOptions . useEQData ) {
2926
+ eqData = { leftEQ : s . _fftLeft . spectrum ,
2927
+ rightEQ : s . _fftRight . spectrum } ;
2928
+ }
2929
+ }
2930
+
2931
+ s . _whileplaying ( time , peakData , waveformLeft , waveformRight , eqData ) ;
2816
2932
2817
2933
}
2818
2934
@@ -2946,7 +3062,7 @@ function SoundManager(smURL, smID) {
2946
3062
a = s . _a ;
2947
3063
2948
3064
a . _called_load = false ;
2949
-
3065
+
2950
3066
if ( useGlobalHTML5Audio ) {
2951
3067
2952
3068
globalHTML5Audio = a ;
@@ -2956,6 +3072,21 @@ function SoundManager(smURL, smID) {
2956
3072
}
2957
3073
2958
3074
s . isHTML5 = true ;
3075
+
3076
+ if ( FFT && Float32Array ) {
3077
+ //Use html5 for spectrum/waveform (dsp.js must be available)
3078
+ if ( window . AudioProcessingEvent && ( window . AudioContext || window . webkitAudioContext ) ) {
3079
+ //Webkit and WebAudio API
3080
+ s . _useAdvancedHTML5 = true ;
3081
+ s . _audioContext = new ( window . AudioContext || window . webkitAudioContext ) ( ) ;
3082
+ sm2 . _wD ( s . id + ': Using HTML5 Audio for eqData and waveform' ) ;
3083
+ } else if ( a . mozSetup ) {
3084
+ //Mozilla Firefox
3085
+ sm2 . _wD ( s . id + ': Using Mozilla Audio for eqData and waveform' ) ;
3086
+ s . _useAdvancedHTML5 = true ;
3087
+ s . _useMoz = true ;
3088
+ }
3089
+ }
2959
3090
2960
3091
// store a ref on the track
2961
3092
s . _a = a ;
@@ -3212,7 +3343,7 @@ function SoundManager(smURL, smID) {
3212
3343
this . _whileplaying = function ( nPosition , oPeakData , oWaveformDataLeft , oWaveformDataRight , oEQData ) {
3213
3344
3214
3345
var instanceOptions = s . _iO ,
3215
- eqLeft ;
3346
+ eqLeft , eqRight ;
3216
3347
3217
3348
if ( isNaN ( nPosition ) || nPosition === null ) {
3218
3349
// flash safety net
@@ -3224,7 +3355,7 @@ function SoundManager(smURL, smID) {
3224
3355
3225
3356
s . _processOnPosition ( ) ;
3226
3357
3227
- if ( ! s . isHTML5 && fV > 8 ) {
3358
+ if ( ! s . isHTML5 && fV > 8 || s . _useAdvancedHTML5 ) {
3228
3359
3229
3360
if ( instanceOptions . usePeakData && oPeakData !== _undefined && oPeakData ) {
3230
3361
s . peakData = {
@@ -3234,21 +3365,41 @@ function SoundManager(smURL, smID) {
3234
3365
}
3235
3366
3236
3367
if ( instanceOptions . useWaveformData && oWaveformDataLeft !== _undefined && oWaveformDataLeft ) {
3237
- s . waveformData = {
3238
- left : oWaveformDataLeft . split ( ',' ) ,
3239
- right : oWaveformDataRight . split ( ',' )
3240
- } ;
3368
+ if ( typeof ( oWaveformDataLeft ) == 'string' ) {
3369
+ s . waveformData = {
3370
+ left : oWaveformDataLeft . split ( ',' ) ,
3371
+ right : oWaveformDataRight . split ( ',' )
3372
+ } ;
3373
+ } else {
3374
+ s . waveformData = {
3375
+ left : oWaveformDataLeft ,
3376
+ right : oWaveformDataRight
3377
+ } ;
3378
+ }
3241
3379
}
3242
3380
3243
3381
if ( instanceOptions . useEQData ) {
3382
+
3244
3383
if ( oEQData !== _undefined && oEQData && oEQData . leftEQ ) {
3245
- eqLeft = oEQData . leftEQ . split ( ',' ) ;
3246
- s . eqData = eqLeft ;
3247
- s . eqData . left = eqLeft ;
3248
- if ( oEQData . rightEQ !== _undefined && oEQData . rightEQ ) {
3249
- s . eqData . right = oEQData . rightEQ . split ( ',' ) ;
3384
+ if ( typeof ( oEQData . leftEQ ) == 'string' ) {
3385
+ eqLeft = oEQData . leftEQ . split ( ',' ) ;
3386
+ } else {
3387
+ eqLeft = oEQData . leftEQ ;
3388
+ eqRight = eqLeft ;
3250
3389
}
3251
3390
}
3391
+
3392
+ if ( oEQData . rightEQ !== _undefined && oEQData . rightEQ ) {
3393
+ if ( typeof ( oEQData . rightEQ ) == 'string' ) {
3394
+ eqRight = oEQData . rightEQ . split ( ',' ) ;
3395
+ } else {
3396
+ eqRight = oEQData . rightEQ ;
3397
+ }
3398
+ }
3399
+
3400
+ s . eqData = { } ;
3401
+ s . eqData . left = eqLeft ;
3402
+ s . eqData . right = eqRight ;
3252
3403
}
3253
3404
3254
3405
}
@@ -3687,10 +3838,9 @@ function SoundManager(smURL, smID) {
3687
3838
// wrap html5 event handlers so we don't call them on destroyed and/or unloaded sounds
3688
3839
3689
3840
return function ( e ) {
3690
-
3691
3841
var s = this . _s ,
3692
3842
result ;
3693
-
3843
+
3694
3844
if ( ! s || ! s . _a ) {
3695
3845
// <d>
3696
3846
if ( s && s . id ) {
@@ -3722,7 +3872,7 @@ function SoundManager(smURL, smID) {
3722
3872
3723
3873
// enough has loaded to play
3724
3874
3725
- canplay : html5_event ( function ( ) {
3875
+ canplay : html5_event ( function ( e ) {
3726
3876
3727
3877
var s = this . _s ,
3728
3878
position1K ;
@@ -3754,6 +3904,14 @@ function SoundManager(smURL, smID) {
3754
3904
s . _iO . _oncanplay ( ) ;
3755
3905
}
3756
3906
3907
+ if ( s . _useAdvancedHTML5 ) {
3908
+ if ( s . _useMoz ) {
3909
+ s . _create_Mozilla_Waveform_Parser ( ) ;
3910
+ } else {
3911
+ s . _create_WebAudio_Waveform_Parser ( ) ;
3912
+ }
3913
+ }
3914
+
3757
3915
} ) ,
3758
3916
3759
3917
canplaythrough : html5_event ( function ( ) {
@@ -3938,6 +4096,8 @@ function SoundManager(smURL, smID) {
3938
4096
3939
4097
timeupdate : html5_event ( function ( ) {
3940
4098
4099
+ var s = this . _s ;
4100
+ if ( s . _useAdvancedHTML5 ) return ;
3941
4101
this . _s . _onTimer ( ) ;
3942
4102
3943
4103
} ) ,
@@ -3952,6 +4112,27 @@ function SoundManager(smURL, smID) {
3952
4112
// playback faster than download rate, etc.
3953
4113
s . _onbufferchange ( 1 ) ;
3954
4114
4115
+ } ) ,
4116
+
4117
+ // only for firefox
4118
+ MozAudioAvailable : html5_event ( function ( e ) {
4119
+ var s = this . _s ;
4120
+ if ( ! s . _useAdvancedHTML5 || ! s . _useMoz ) return ;
4121
+ if ( s . _channels < 2 ) {
4122
+ s . _waveformLeft = e . frameBuffer ;
4123
+ s . _waveformRight = e . frameBuffer ;
4124
+ } else {
4125
+ var per_channel = s . _fbLength / s . _channels ;
4126
+ for ( var i = 0 ; i < per_channel ; i ++ ) {
4127
+ s . _waveformLeft [ i ] = e . frameBuffer [ i * s . _channels ] ;
4128
+ s . _waveformRight [ i ] = e . frameBuffer [ i * s . _channels + 1 ] ;
4129
+ }
4130
+ }
4131
+ s . _fftLeft . forward ( s . _waveformLeft ) ;
4132
+ if ( s . _channels > 1 ) {
4133
+ s . _fftRight . forward ( s . _waveformRight ) ;
4134
+ }
4135
+ s . _onTimer ( true ) ;
3955
4136
} )
3956
4137
3957
4138
} ;
@@ -5938,4 +6119,4 @@ if (window.SM2_DEFER === undefined || !SM2_DEFER) {
5938
6119
window . SoundManager = SoundManager ; // constructor
5939
6120
window . soundManager = soundManager ; // public API, flash callbacks etc.
5940
6121
5941
- } ( window ) ) ;
6122
+ } ( window ) ) ;
0 commit comments