/flash/MP3FileReferenceLoaderLib/src/org/audiofx/mp3/MP3FileReferenceLoader.as

http://echo-nest-remix.googlecode.com/ · ActionScript · 149 lines · 93 code · 15 blank · 41 comment · 6 complexity · 657440cfac2c2b5ebc819cce51a6820b MD5 · raw file

  1. /*
  2. Copyright (c) 2008 Christopher Martin-Sperry (audiofx.org@gmail.com)
  3. Permission is hereby granted, free of charge, to any person obtaining a copy
  4. of this software and associated documentation files (the "Software"), to deal
  5. in the Software without restriction, including without limitation the rights
  6. to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  7. copies of the Software, and to permit persons to whom the Software is
  8. furnished to do so, subject to the following conditions:
  9. The above copyright notice and this permission notice shall be included in
  10. all copies or substantial portions of the Software.
  11. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  12. IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  13. FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  14. AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  15. LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  16. OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
  17. THE SOFTWARE.
  18. */
  19. package org.audiofx.mp3
  20. {
  21. import flash.display.Loader;
  22. import flash.display.LoaderInfo;
  23. import flash.events.Event;
  24. import flash.events.EventDispatcher;
  25. import flash.media.Sound;
  26. import flash.net.FileReference;
  27. import flash.utils.ByteArray;
  28. import flash.utils.Endian;
  29. /**
  30. * Dispatched when the MP3 data is loaded
  31. * @eventType org.audiofx.mp3.MP3SoundEvent.COMPLETE
  32. *
  33. */
  34. [Event(name="complete", type="org.audiofx.mp3.MP3SoundEvent")]
  35. /**
  36. * Class for loading MP3 files from a FileReference
  37. * @author spender
  38. * @see flash.net.FileReference
  39. */
  40. public class MP3FileReferenceLoader extends EventDispatcher
  41. {
  42. private var mp3Parser:MP3Parser;
  43. /**
  44. * Constructs an new MP3FileReferenceLoader instance
  45. *
  46. */
  47. public function MP3FileReferenceLoader()
  48. {
  49. mp3Parser=new MP3Parser();
  50. mp3Parser.addEventListener(Event.COMPLETE,parserCompleteHandler);
  51. }
  52. /**
  53. * Once a FileReference instance has been obtained, and the user has browsed to a file, call getSound to start loading the MP3 data.
  54. * When the data is ready, an <code>MP3SoundEvent.COMPLETE</code> event is emitted.
  55. * @param fr A reference to a local file.
  56. * @see MP3SoundEvent
  57. */
  58. public function getSound(fr:FileReference):void
  59. {
  60. mp3Parser.loadFileRef(fr);
  61. }
  62. private function parserCompleteHandler(ev:Event):void
  63. {
  64. var parser:MP3Parser=ev.currentTarget as MP3Parser;
  65. generateSound(parser);
  66. }
  67. private function generateSound(mp3Source:MP3Parser):Boolean
  68. {
  69. var swfBytes:ByteArray=new ByteArray();
  70. swfBytes.endian=Endian.LITTLE_ENDIAN;
  71. for(var i:uint=0;i<SoundClassSwfByteCode.soundClassSwfBytes1.length;++i)
  72. {
  73. swfBytes.writeByte(SoundClassSwfByteCode.soundClassSwfBytes1[i]);
  74. }
  75. var swfSizePosition:uint=swfBytes.position;
  76. swfBytes.writeInt(0); //swf size will go here
  77. for(i=0;i<SoundClassSwfByteCode.soundClassSwfBytes2.length;++i)
  78. {
  79. swfBytes.writeByte(SoundClassSwfByteCode.soundClassSwfBytes2[i]);
  80. }
  81. var audioSizePosition:uint=swfBytes.position;
  82. swfBytes.writeInt(0); //audiodatasize+7 to go here
  83. swfBytes.writeByte(1);
  84. swfBytes.writeByte(0);
  85. mp3Source.writeSwfFormatByte(swfBytes);
  86. var sampleSizePosition:uint=swfBytes.position;
  87. swfBytes.writeInt(0); //number of samples goes here
  88. swfBytes.writeByte(0); //seeksamples
  89. swfBytes.writeByte(0);
  90. var frameCount:uint=0;
  91. var byteCount:uint=0; //this includes the seeksamples written earlier
  92. for(;;)
  93. {
  94. var seg:ByteArraySegment=mp3Source.getNextFrame();
  95. if(seg==null)break;
  96. swfBytes.writeBytes(seg.byteArray,seg.start,seg.length);
  97. byteCount+=seg.length;
  98. frameCount++;
  99. }
  100. if(byteCount==0)
  101. {
  102. return false;
  103. }
  104. byteCount+=2;
  105. var currentPos:uint=swfBytes.position;
  106. swfBytes.position=audioSizePosition;
  107. swfBytes.writeInt(byteCount+7);
  108. swfBytes.position=sampleSizePosition;
  109. swfBytes.writeInt(frameCount*1152);
  110. swfBytes.position=currentPos;
  111. for(i=0;i<SoundClassSwfByteCode.soundClassSwfBytes3.length;++i)
  112. {
  113. swfBytes.writeByte(SoundClassSwfByteCode.soundClassSwfBytes3[i]);
  114. }
  115. swfBytes.position=swfSizePosition;
  116. swfBytes.writeInt(swfBytes.length);
  117. swfBytes.position=0;
  118. var swfBytesLoader:Loader=new Loader();
  119. swfBytesLoader.contentLoaderInfo.addEventListener(Event.COMPLETE,swfCreated);
  120. swfBytesLoader.loadBytes(swfBytes);
  121. return true;
  122. }
  123. private function swfCreated(ev:Event):void
  124. {
  125. var loaderInfo:LoaderInfo=ev.currentTarget as LoaderInfo;
  126. var soundClass:Class=loaderInfo.applicationDomain.getDefinition("SoundClass") as Class;
  127. var sound:Sound=new soundClass();
  128. dispatchEvent(new MP3SoundEvent(MP3SoundEvent.COMPLETE,sound));
  129. }
  130. }
  131. }