Advertisement
Guest User

Untitled

a guest
Oct 25th, 2015
77
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Haxe 8.05 KB | None | 0 0
  1. package openfl._legacy.media; #if (openfl_legacy && !disable_legacy_audio)
  2.  
  3.  
  4. import openfl._legacy.Assets;
  5. import openfl.errors.Error;
  6. import openfl.events.EventDispatcher;
  7. import openfl._legacy.events.IEventDispatcher;
  8. import openfl.events.Event;
  9. import openfl.events.IOErrorEvent;
  10. import openfl.events.SampleDataEvent;
  11. import openfl.media.ID3Info;
  12. import openfl.media.SoundLoaderContext;
  13. import openfl.media.SoundTransform;
  14. import openfl.net.URLRequest;
  15. import openfl.utils.ByteArray;
  16. import openfl.utils.Endian;
  17. import openfl.Lib;
  18.  
  19. #if lime_hybrid
  20. import lime.audio.AudioBuffer;
  21. #end
  22.  
  23.  
  24. @:autoBuild(openfl._legacy.Assets.embedSound())
  25.  
  26.  
  27. class Sound extends EventDispatcher {
  28.    
  29.    
  30.     public var bytesLoaded (default, null):Int;
  31.     public var bytesTotal (default, null):Int;
  32.     public var id3 (get, null):ID3Info;
  33.     public var isBuffering (get, null):Bool;
  34.     public var length (get, null):Float;
  35.     public var url (default, null):String;
  36.    
  37.     @:noCompletion public var __audioType:InternalAudioType;
  38.    
  39.     @:noCompletion public var __handle:Dynamic;
  40.     @:noCompletion private var __loading:Bool;
  41.     @:noCompletion private var __dynamicSound:Bool;
  42.    
  43.    
  44.     public function new (stream:URLRequest = null, context:SoundLoaderContext = null, forcePlayAsMusic:Bool = false) {
  45.        
  46.         super ();
  47.        
  48.         __audioType = (forcePlayAsMusic) ? InternalAudioType.MUSIC : InternalAudioType.SOUND;
  49.        
  50.         bytesLoaded = 0;
  51.         bytesTotal = 0;
  52.         __loading = false;
  53.         __dynamicSound = false;
  54.        
  55.         if (stream != null) {
  56.            
  57.             load (stream, context, forcePlayAsMusic);
  58.            
  59.         }
  60.        
  61.     }
  62.    
  63.    
  64.     override public function addEventListener (type:String, listener:Function, useCapture:Bool = false, priority:Int = 0, useWeakReference:Bool = false):Void {
  65.        
  66.         super.addEventListener (type, listener, useCapture, priority, useWeakReference);
  67.        
  68.         if (type == SampleDataEvent.SAMPLE_DATA) {
  69.            
  70.             if (__handle != null) {
  71.                
  72.                 throw "Can't use dynamic sound once file loaded";
  73.                
  74.             }
  75.            
  76.             __dynamicSound = true;
  77.             __loading = false;
  78.            
  79.         }
  80.        
  81.     }
  82.    
  83.    
  84.     public function close ():Void {
  85.        
  86.         if (__handle != null) {
  87.            
  88.             lime_sound_close (__handle);
  89.            
  90.         }
  91.        
  92.         __handle = 0;
  93.         __loading = false;
  94.        
  95.     }
  96.    
  97.    
  98.     #if lime_hybrid
  99.     public static function fromAudioBuffer (buffer:AudioBuffer):Sound {
  100.        
  101.         var sound = new Sound ();
  102.         sound.loadPCMFromByteArray (ByteArray.fromBytes (buffer.data.buffer), buffer.bitsPerSample, "short", buffer.channels > 1, buffer.sampleRate);
  103.         return sound;
  104.        
  105.     }
  106.     #end
  107.    
  108.    
  109.     public function load (stream:URLRequest, context:SoundLoaderContext = null, forcePlayAsMusic:Bool = false):Void {
  110.        
  111.         bytesLoaded = 0;
  112.         bytesTotal = 0;
  113.        
  114.         __handle = lime_sound_from_file (stream.url, forcePlayAsMusic);
  115.        
  116.         if (__handle == null) {
  117.            
  118.             trace ("Error: Could not load \"" + stream.url + "\"");
  119.             dispatchEvent (new IOErrorEvent (IOErrorEvent.IO_ERROR));
  120.            
  121.         } else {
  122.            
  123.             url = stream.url;
  124.             __loading = true;
  125.             __checkLoading ();
  126.             __loading = false;
  127.             dispatchEvent (new Event (Event.COMPLETE));
  128.            
  129.         }
  130.        
  131.        
  132.     }
  133.    
  134.    
  135.     public function loadCompressedDataFromByteArray (bytes:ByteArray, length:Int, forcePlayAsMusic:Bool = false):Void {
  136.        
  137.         bytesLoaded = length;
  138.         bytesTotal = length;
  139.        
  140.         __handle = lime_sound_from_data (bytes, length, forcePlayAsMusic);
  141.        
  142.         if (__handle == null) {
  143.            
  144.             throw ("Could not load buffer with length: " + length);
  145.            
  146.         }
  147.        
  148.     }
  149.    
  150.    
  151.     public function loadPCMFromByteArray (bytes:ByteArray, samples:Int, format:String = "float", stereo:Bool = true, sampleRate:Float = 44100.0):Void {
  152.        
  153.         var wav = new ByteArray ();
  154.         wav.endian = Endian.LITTLE_ENDIAN;
  155.        
  156.         var audioFormat:Int = switch (format) {
  157.            
  158.             case "float": 3;
  159.             case "short": 1;
  160.             default: throw (new Error ('Unsupported format $format'));
  161.            
  162.         }
  163.        
  164.         var numChannels = stereo ? 2 : 1;
  165.         var sampleRate = Std.int (sampleRate);
  166.         var bitsPerSample = switch(format) {
  167.            
  168.             case "float": 32;
  169.             case "short": 16;
  170.             default: throw (new Error ('Unsupported format $format'));
  171.            
  172.         };
  173.        
  174.         var byteRate:Int = Std.int (sampleRate * numChannels * bitsPerSample / 8);
  175.         var blockAlign:Int = Std.int(numChannels * bitsPerSample / 8);
  176.         var numSamples:Int = Std.int(bytes.length / blockAlign);
  177.        
  178.         wav.writeUTFBytes ("RIFF");
  179.         wav.writeInt (36 + bytes.length);
  180.         wav.writeUTFBytes ("WAVE");
  181.         wav.writeUTFBytes ("fmt ");
  182.         wav.writeInt (16);
  183.         wav.writeShort ((audioFormat));
  184.         wav.writeShort ((numChannels));
  185.         wav.writeInt ((sampleRate));
  186.         wav.writeInt ((byteRate));
  187.         wav.writeShort ((blockAlign));
  188.         wav.writeShort ((bitsPerSample));
  189.         wav.writeUTFBytes ("data");
  190.         wav.writeInt ((bytes.length));
  191.         wav.writeBytes (bytes, 0, bytes.length);
  192.        
  193.         wav.position = 0;
  194.         loadCompressedDataFromByteArray (wav, wav.length);
  195.        
  196.     }
  197.    
  198.    
  199.     public function play (startTime:Float = 0, loops:Int = 0, soundTransform:SoundTransform = null):SoundChannel {
  200.        
  201.         __checkLoading ();
  202.        
  203.         if (__dynamicSound) {
  204.            
  205.             var request = new SampleDataEvent (SampleDataEvent.SAMPLE_DATA);
  206.             dispatchEvent (request);
  207.            
  208.             if (request.data.length > 0) {
  209.                
  210.                 __handle = lime_sound_channel_create_dynamic (request.data, soundTransform);
  211.                
  212.             }
  213.            
  214.             if (__handle == null) {
  215.                
  216.                 var channel = new SoundChannel (null, startTime, loops, soundTransform);
  217.                 channel.__soundInstance = this;
  218.                
  219.                 return channel;
  220.                
  221.             }
  222.            
  223.             var result = SoundChannel.createDynamic (__handle, soundTransform, this);
  224.             __handle = null;
  225.             return result;
  226.            
  227.         } else {
  228.            
  229.             if (__handle == null || __loading) {
  230.                
  231.                 var channel = new SoundChannel (null, startTime, loops, soundTransform);
  232.                 channel.__soundInstance = this;
  233.  
  234.                 return channel;
  235.                
  236.             }
  237.            
  238.             var channel = new SoundChannel (__handle, startTime, loops, soundTransform);
  239.             channel.__soundInstance = this;
  240.            
  241.             return channel;
  242.            
  243.         }
  244.        
  245.     }
  246.    
  247.    
  248.     @:noCompletion private function __checkLoading ():Void {
  249.        
  250.         if (!__dynamicSound && __loading && __handle != null) {
  251.            
  252.             var status:Dynamic = lime_sound_get_status (__handle);
  253.            
  254.             if (status == null) {
  255.                
  256.                 throw "Could not get sound status";
  257.                
  258.             }
  259.            
  260.             bytesLoaded = status.bytesLoaded;
  261.             bytesTotal = status.bytesTotal;
  262.             __loading = bytesLoaded < bytesTotal;
  263.            
  264.             if (status.error != null) {
  265.                
  266.                 throw (status.error);
  267.                
  268.             }
  269.            
  270.         }
  271.        
  272.     }
  273.    
  274.    
  275.     @:noCompletion private function __onError (msg:String):Void {
  276.        
  277.         dispatchEvent (new IOErrorEvent (IOErrorEvent.IO_ERROR, true, false, msg));
  278.         __handle = null;
  279.         __loading = true;
  280.        
  281.     }
  282.    
  283.    
  284.    
  285.    
  286.     // Getters & Setters
  287.    
  288.    
  289.    
  290.    
  291.     private function get_id3 ():ID3Info {
  292.        
  293.         __checkLoading ();
  294.        
  295.         if (__handle == null || __loading) {
  296.            
  297.             return new ID3Info ();
  298.            
  299.         }
  300.        
  301.         var id3 = new ID3Info ();
  302.         lime_sound_get_id3 (__handle, id3);
  303.         return id3;
  304.        
  305.     }
  306.    
  307.    
  308.     private function get_isBuffering ():Bool {
  309.        
  310.         __checkLoading ();
  311.         return (__loading && __handle == null);
  312.        
  313.     }
  314.    
  315.    
  316.     private function get_length ():Float {
  317.        
  318.         if (__handle == null || __loading) {
  319.            
  320.             return 0;
  321.            
  322.         }
  323.        
  324.         return lime_sound_get_length (__handle);
  325.        
  326.     }
  327.    
  328.    
  329.    
  330.    
  331.     // Native Methods
  332.    
  333.    
  334.    
  335.    
  336.     private static var lime_sound_from_file = Lib.load ("lime-legacy", "lime_legacy_sound_from_file", 2);
  337.     private static var lime_sound_from_data = Lib.load ("lime-legacy", "lime_legacy_sound_from_data", 3);
  338.     private static var lime_sound_get_id3 = Lib.load ("lime-legacy", "lime_legacy_sound_get_id3", 2);
  339.     private static var lime_sound_get_length = Lib.load ("lime-legacy", "lime_legacy_sound_get_length", 1);
  340.     private static var lime_sound_close = Lib.load ("lime-legacy", "lime_legacy_sound_close", 1);
  341.     private static var lime_sound_get_status = Lib.load ("lime-legacy", "lime_legacy_sound_get_status", 1);
  342.     private static var lime_sound_channel_create_dynamic = Lib.load ("lime-legacy", "lime_legacy_sound_channel_create_dynamic", 2);
  343.    
  344.    
  345. }
  346.  
  347.  
  348. @:noCompletion enum InternalAudioType {
  349.    
  350.     MUSIC;
  351.     SOUND;
  352.     UNKNOWN;
  353.    
  354. }
  355.  
  356.  
  357. #else
  358. typedef Sound = openfl.media.Sound;
  359. #end
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement