var X_WebAudio_context = // 4s 以下ではない iPad 2G または iPad mini 1G 以下ではない, iPod touch 4G 以下ではない
- !X_UA[ 'iPhone_4s' ] && !X_UA[ 'iPad_2Mini1' ] && !X_UA[ 'iPod_4' ] &&
+ !X_UA[ 'iPhone_4s' ] && !X_UA[ 'iPad_2Mini1' ] && !X_UA[ 'iPod_4' ] &&
+ // iOS7 以上で HTML Audio が鳴らない問題を見ていくよ
+ // !X_UA[ 'iOS' ] &&
// Android2 + Gecko で WebAudio が極めて不安定
!( X_UA[ 'Fennec' ] && X_UA[ 'Android' ] < 3 ) &&
// AOSP でも WebAudio を不完全に実装するものがある, touch の有無も不明のため一律に切ってしまう
//!X_UA[ 'Blink' ] &&
// Firefox40.0.5 + Windows8 で音声が途中から鳴らなくなる
// Firefox41.0.1 + Windows8 で音声が途中から鳴らなくなる
- !( 40 <= X_UA[ 'Gecko' ] && X_UA[ 'Gecko' ] < 42 && X_UA[ 'Windows' ] ) &&
+ !( 40 <= X_UA[ 'Gecko' ] && X_UA[ 'Gecko' ] < 46 && X_UA[ 'Windows' ] ) &&
( window[ 'AudioContext' ] || window[ 'webkitAudioContext' ] ),
X_WebAudio_BUFFER_LIST = [],
X_WebAudio_need1stTouch = X_UA[ 'iOS' ],
_onDecodeSuccess : function( buffer ){
this.onDecodeSuccess && this._onDecodeComplete();
- if ( !buffer ) {
+ if( !buffer ){
this.errorState = 2;
this[ 'asyncDispatch' ]( X_EVENT_COMPLETE );
return;
unregister : function( webAudio ){
var list = this.webAudioList,
i = list.indexOf( webAudio );
+
if( 0 < i ){
list.splice( i, 1 );
if( !list.length ){
_startPos : 0,
_endPosition : 0,
_startTime : 0,
- _timerID : 0,
+ //_timerID : 0,
_interval : 0,
audioBuffer : null,
bufferSource : null,
gainNode : null,
- _onended : null,
+ //_onended : null,
'Constructor' : function( disatcher, url, option ){
var i = 0,
this.playing && this.actualPause();
this.bufferSource && this._sourceDispose();
- this._onended && X_Closure_correct( this._onended );
+ //this._onended && X_Closure_correct( this._onended );
this.gainNode && this.gainNode.disconnect();
},
if ( !buffer ) {
this.error = loader.errorState;
-
this.disatcher[ 'dispatch' ]({
type : X_EVENT_ERROR,
error : loader.errorState,
end = X_Audio_getEndTime( this );
begin = X_Audio_getStartTime( this, end, true );
- console.log( '[WebAudio] play ' + begin + ' -> ' + end );
+ console.log( '[WebAudio] play ' + begin + ' -> ' + end + ' loop: ' + this.autoLoop + ' :' + this.loopStartTime + ' -> ' + this.loopEndTime );
if( this.bufferSource ) this._sourceDispose();
if( !this.gainNode ){
this.gainNode = X_WebAudio_context[ 'createGain' ] ? X_WebAudio_context[ 'createGain' ]() : X_WebAudio_context[ 'createGainNode' ]();
- this.gainNode[ 'connect' ]( X_WebAudio_context[ 'destination' ] );
+ this.gainNode[ 'connect' ]( X_WebAudio_context[ 'destination' ] );
};
+
this.bufferSource = X_WebAudio_context[ 'createBufferSource' ]();
this.bufferSource.buffer = this.audioBuffer;
- this.bufferSource[ 'connect' ]( this.gainNode );
+ /* win8.1 Firefox45, win8.1 Chrome48 で動かなくなる...
+ if( this.bufferSource[ 'loop' ] = this.autoLoop ){
+ this.bufferSource[ 'loopStart' ] = 0 <= this.loopStartTime ? this.loopStartTime / 1000 : begin / 1000;
+ this.bufferSource[ 'loopEnd' ] = 0 <= this.loopEndTime ? this.loopEndTime / 1000 : end / 1000;
+ }; */
+
+ this.bufferSource[ 'connect' ]( this.gainNode );
this.gainNode[ 'gain' ].value = this.gain;
// おかしい、stop 前に外していても呼ばれる、、、@Firefox33.1
//console.log( '> use onended' );
//this.bufferSource.onended = this._onended || ( this._onended = X_Closure_create( this, this._onEnded ) );
//} else {
- this._timerID && X_Timer_remove( this._timerID );
- this._timerID = X_Timer_once( end - begin, this, this._onEnded );
+ //this._timerID && X_Timer_remove( this._timerID );
+ //this._timerID = X_Timer_once( end - begin, this, this._onEnded );
//};
if( this.bufferSource.start ){
- this.bufferSource.start( 0, begin / 1000, end / 1000 );
+ this.bufferSource.start( 0, begin / 1000, ( end - begin ) / 1000 );
+ } else
+ if( this.bufferSource[ 'noteOn' ] ){
+ this.bufferSource[ 'noteOn' ]( 0, begin / 1000, ( end - begin ) / 1000 );
} else {
- this.bufferSource[ 'noteGrainOn' ]( 0, begin / 1000, end / 1000 );
+ this.bufferSource[ 'noteGrainOn' ]( 0, begin / 1000, ( end - begin ) / 1000 );
};
this.playing = true;
this._startPos = begin;
this._endPosition = end;
this._startTime = X_WebAudio_context.currentTime * 1000;
- this._interval = this._interval || X_Timer_add( 1000, 0, this, this._onInterval );
+ this._interval = this._interval || X_Timer_add( 100, 0, this, this._onInterval );
},
_sourceDispose : function(){
delete this.bufferSource;
},
+ /*
_onInterval : function(){
if( !this.playing ){
delete this._interval;
return X_CALLBACK_UN_LISTEN;
};
this.disatcher[ 'dispatch' ]( X_EVENT_MEDIA_PLAYING );
- },
-
- _onEnded : function(){
+ }, */
+
+ _onInterval : function(){
var time;
- delete this._timerID;
if( this.playing ){
+ // TODO 再生中に終了時間だけ変えた場合!
time = X_WebAudio_context.currentTime * 1000 - this._startTime - this._endPosition + this._startPos | 0;
//console.log( '> onEnd ' + ( this.playing && ( X_WebAudio_context.currentTime * 1000 - this._startTime ) ) + ' < ' + ( this._endPosition - this._startPos ) );
- if( this._onended ){
- // Firefox 用の対策,,,
- if( time < 0 ) return;
- } else {
- if( time < 0 ){
- //console.log( '> onEnd crt:' + ( X_WebAudio_context.currentTime * 1000 ) + ' startTime:' + this._startTime +
- // ' from:' + this._startPos + ' to:' + this._endPosition );
- this._timerID = X_Timer_once( -time, this, this._onEnded );
- return;
- };
- };
+
+ if( time < 0 ){
+ this.disatcher[ 'dispatch' ]( X_EVENT_MEDIA_PLAYING );
+ return;
+ };
if( this.autoLoop ){
if( !( this.disatcher[ 'dispatch' ]( X_EVENT_MEDIA_BEFORE_LOOP ) & X_CALLBACK_PREVENT_DEFAULT ) ){
this.looped = true;
this.disatcher[ 'dispatch' ]( X_EVENT_MEDIA_LOOPED );
this.actualPlay();
+ } else {
+ delete this._interval;
+ return X_CALLBACK_UN_LISTEN;
};
} else {
this.actualPause();
actualPause : function(){
console.log( '[WebAudio] pause' );
- this._timerID && X_Timer_remove( this._timerID );
- delete this._timerID;
+ this._interval && X_Timer_remove( this._interval );
+ delete this._interval;
delete this.playing;
if( this.bufferSource ){
- //if( this.bufferSource.onended ) delete this.bufferSource.onended;
-
this.bufferSource.stop ?
this.bufferSource.stop( 0 ) : this.bufferSource[ 'noteOff' ]( 0 );
};