OSDN Git Service

forgot to commit...
authoritozyun <itozyun@user.sourceforge.jp>
Tue, 11 Nov 2014 07:36:07 +0000 (16:36 +0900)
committeritozyun <itozyun@user.sourceforge.jp>
Tue, 11 Nov 2014 07:36:07 +0000 (16:36 +0900)
0.6.x/js/07_audio/01_XWebAudio.js [new file with mode: 0644]
0.6.x/js/import.js

diff --git a/0.6.x/js/07_audio/01_XWebAudio.js b/0.6.x/js/07_audio/01_XWebAudio.js
new file mode 100644 (file)
index 0000000..8299229
--- /dev/null
@@ -0,0 +1,283 @@
+
+var X_Audio_WebAudio_context   = window.webkitAudioContext || window.AudioContext,
+       X_Audio_WebAudio_LIVE_LIST = [],
+       X_Audio_WebAudio_POOL_LIST = [],
+       X_Audio_WebAudio, X_Audio_WebAudioWrapper, X_Audio_rawAudio;
+
+if( X_Audio_WebAudio_context ){
+       
+       X_Audio_WebAudio_context = new X_Audio_WebAudio_context;
+       
+       function getWebAudioWrapper( proxy ){
+               var i = X_Audio_WebAudio_LIVE_LIST.length;
+               for( ; i; ){
+                       if( X_Audio_WebAudio_LIVE_LIST[ --i ].proxy === proxy ) return X_Audio_WebAudio_LIVE_LIST[ i ];
+               };
+       };
+       
+       X_Audio_WebAudio = 
+               {
+                       backendName : 'Web Audio',
+
+                       detect : function( proxy, source, ext ){
+                               var ok = ext === 'mp3' || ext === 'ogg';
+                               
+                               proxy.asyncDispatch( ok ? 'support' : 'nosupport' );
+                       },
+                       
+                       register : function( proxy, source, option ){
+                               X_Audio_WebAudio_LIVE_LIST.push( new X_Audio_WebAudioWrapper( proxy, source, option ) );
+                       },
+                       
+                       close : function( proxy ){
+                               return getWebAudioWrapper( proxy ).close();
+                       },
+                       
+                       play : function( proxy, startTime, endTime, loop, loopStartTime ){
+                               return getWebAudioWrapper( proxy ).play( startTime, endTime, loop, loopStartTime );
+                       },
+                       
+                       pause : function( proxy ){
+                               return getWebAudioWrapper( proxy ).pause();
+                       },
+       
+                       state : function( proxy, obj ){
+                               return getWebAudioWrapper( proxy ).state( obj );
+                       }
+               };
+       
+       X_Audio_BACKENDS.push( X_Audio_WebAudio );
+       
+       X_Audio_WebAudioWrapper = X.EventDispatcher.inherits(
+               'X.AV.WebAudioWrapper',
+               X.Class.POOL_OBJECT,
+               {
+                       
+                       proxy           : null,
+                       
+                       startTime       : 0,
+                       endTime         : 0,
+                       loopStartTime   : 0,
+                       seekTime        : 0,
+                       duration        : 0,
+                       
+                       playing         : false,
+                       error           : 0,                    
+                       loop            : false,
+                       volume          : 0.5,
+                                               
+                       _startTime      : 0,
+                       _playTime       : 0,
+            _timerID        : 0,
+            _interval       : 0,
+               buffer          : null,
+            gainNode        : null,
+            _onended        : null,
+            
+            xhr             : null,
+            onDecodeSuccess : null,
+            onDecodeError   : null,
+            
+                       Constructor : function( proxy, source, option ){
+                               this.closed = false;
+                               this.proxy  = proxy;
+                               this.xhr    = X.Net.xhrGet( source, 'arraybuffer' )
+                                                               .listen( X.Event.PROGRESS, this )
+                                                               .listenOnce( [ X.Event.SUCCESS, X.Event.COMPLETE, X.Event.CANCELED ], this );
+                               X_AudioWrapper_updateStates( this, option );
+                       },
+                       
+                       handleEvent : function( e ){
+                               switch( e.type ){
+                                       case X.Event.PROGRESS :
+                                               e.percent ?
+                                                       this.proxy.dispatch( { type : 'progress', percent : e.percent } ) :
+                                                       this.proxy.dispatch( 'loadstart' );
+                                               return;
+                                       
+                                       case X.Event.SUCCESS :
+                                               X_Audio_WebAudio_context.decodeAudioData( e.data,
+                                                       this.callbackDecodeSuccess = X_Callback_create( this, this._onDecodeSuccess ),
+                                                       this.callbackDecodeError   = X_Callback_create( this, this._onDecodeError ) );
+                                               break;
+
+                                       case X.Event.CANCELED :
+                                               this.error = 1;
+                                               this.proxy.dispatch( 'aborted' );
+                                               break;
+
+                                       case X.Event.COMPLETE :
+                                               this.error = 2;                         
+                                               this.proxy.asyncDispatch( { type : 'error', message : 'xhr error' } );
+                                               break;
+                               };
+                               this.xhr.unlisten( [ X.Event.PROGRESS, X.Event.SUCCESS, X.Event.COMPLETE, X.Event.CANCELED ], this );
+                               delete this.xhr;
+                       },
+                       
+                               _onDecodeSuccess : function( buffer ){
+                                       this._onDecodeComplete();
+                                       
+                       if ( !buffer ) {
+                           this.proxy.asyncDispatch( { type : 'error', message : 'buffer is ' + buffer } );
+                           return;
+                       };
+       
+                       this.buffer   = buffer;
+                       this.duration = buffer.duration * 1000;
+                       this.endTime  = this.endTime || this.duration;
+                       
+                       this.proxy.asyncDispatch( 'loadedmetadata' );
+                       this.proxy.asyncDispatch( 'loadeddata' );
+                       this.proxy.asyncDispatch( 'canplay' );
+                       this.proxy.asyncDispatch( 'canplaythrough' );
+                               },
+                               
+                               _onDecodeError : function(){
+                                       this._onDecodeComplete();
+                                       this.error = 3;
+                                       this.proxy.asyncDispatch( { type : 'error', message : 'decode error' } );
+                               },
+                               
+                               _onDecodeComplete : function(){
+                                       X_Callback_correct( this.callbackDecodeSuccess );
+                                       delete this.callbackDecodeSuccess;
+                                       X_Callback_correct( this.callbackDecodeError );
+                                       delete this.callbackDecodeError;
+                               },
+                       
+                       close : function(){     
+                   delete this.buffer;
+       
+                               this.playing  && this.pause();
+                   this.source   && this._sourceDispose();
+       
+                   this._onended && X_Callback_correct( this._onended );       
+       
+                   this.gainNode && this.gainNode.disconnect();
+                       },
+                       
+                               _sourceDispose : function(){
+                           this.source && this.source.disconnect();
+                           delete this.source.onended;
+                           delete this.source;
+                       },
+                       
+                       play : function( seekTime ){
+                               var begin;
+                               
+                   if( !this.buffer ) return this;
+                               
+                               begin = ( seekTime || seekTime === 0 ) ? seekTime : this.playing ? this.loopStartTime : this.startTime;
+                               
+                               console.log( '[WebAudio] play' );
+                               
+                               if( this.source ) this._sourceDispose();
+                               if( !this.gainNode ) this.gainNode = X_Audio_WebAudio_context.createGain();
+                               
+                   this.source        = X_Audio_WebAudio_context.createBufferSource();
+                   this.source.buffer = this.buffer;
+                   this.source.connect( this.gainNode );
+                   
+                   this.gainNode.connect( X_Audio_WebAudio_context.destination );
+                   this.gainNode.gain.value = this.volume;
+                   
+                   this._timerID && X.Timer.remove( this._timerID );
+                   
+                   // おかしい、stop 前に外していても呼ばれる、、、@Firefox
+                if( this.source.onended !== undefined ){
+                       //console.log( '> use onended' );
+                       this.source.onended = this._onended || ( this._onended = X_Callback_create( this, this._onEnded ) );
+                } else {
+                                       this._timerID = X.Timer.once( this.endTime - begin, this, this._onEnded );
+                };
+       
+                   if( this.source.start ){
+                       this.source.start( 0, begin / 1000, this.endTime / 1000 );
+                   } else {
+                       this.source.noteGrainOn( 0, begin / 1000, this.endTime / 1000 );
+                   };
+                   
+                   this.playing    = true;
+                   this._startTime = begin;
+                   this._playTime  = X_Audio_WebAudio_context.currentTime * 1000;
+                   this._interval  = this._interval || X.Timer.add( 1000, 0, this, this._onInterval );
+                       },
+
+                               _onInterval : function(){
+                                       if( !this.playing ){
+                                               delete this._interval;
+                                               return X_Callback_UN_LISTEN;
+                                       };
+                                       this.proxy.dispatch( 'timeupdate' );
+                               },
+                                               
+                               _onEnded : function(){
+                                       delete this._timerID;
+                           if( this.playing ){
+                               console.log( '> onEnd ' + ( this.playing && ( X_Audio_WebAudio_context.currentTime * 1000 - this._playTime ) ) + ' < ' + ( this.endTime - this._startTime ) );
+                               // Firefox 用の対策,,,
+                               if( X_Audio_WebAudio_context.currentTime * 1000 - this._playTime < this.endTime - this._startTime ) return;
+                               
+                               if( this.loop ){
+                                       this.play();
+                               } else {
+                                       this.pause();
+                                       this.proxy.dispatch( 'ended' );
+                               };
+                           };
+                               },
+                       
+                       pause : function(){
+                               if( !this.playing ) return this;
+                               
+                               console.log( '[WebAudio] pause' );
+                               
+                   this._timerID && X.Timer.remove( this._timerID );
+                               delete this._timerID;
+                               delete this.playing;
+
+                   if( this.source ){
+                       if( this.source.onended ) delete this.source.onended;
+                       
+                       this.source.stop ? 
+                               this.source.stop( 0 ) : this.source.noteOff( 0 );
+                   };
+                       },
+       
+                       state : function( obj ){
+                               var time = this.playing ? ( X_Audio_WebAudio_context.currentTime * 1000 - this._playTime ) : 0,
+                                       result, halfway;
+                               
+                               if( obj === undefined ){
+                                   return {
+                                       startTime     : this.startTime,
+                                       endTime       : this.endTime,
+                                       loopStartTime : this.loopStartTime,
+                                       currentTime   : time + this._startTime,
+                                       loop          : this.loop,
+                                       volume        : this.volume,
+                                       error         : this.error,
+                                       playing       : this.playing,                           
+                                       duration      : this.duration
+                                   };                                  
+                               };
+                       
+                               result = X_AudioWrapper_updateStates( this, obj );
+                               
+                               if( result & 2 ){ // seek
+                       this.play( this.seekTime );
+                       delete this.seekTime;
+                               } else
+                               if( result & 1 ){
+                                       this.play();
+                               } else
+                               if( result & 4 ){
+                      this.gainNode.gain.value = this.volume;
+                               };
+                       }
+
+               }
+       );
+
+};
index dba0ff4..9dcc19f 100644 (file)
@@ -55,7 +55,7 @@ document.write( [
                'js/06_net/04_XNetImage.js',\r
                \r
                'js/07_audio/00_XAudio.js',\r
-               //'js/07_audio/01_XWebAudio.js',\r
+               'js/07_audio/01_XWebAudio.js',\r
                'js/07_audio/02_XHTMLAudio.js',\r
                'js/07_audio/03_XSilverlightAudio.js'\r
 \r