/flash/flash-audio/src/com/ryanberdeen/audio/SpeedChangingSampleSource.as

http://echo-nest-remix.googlecode.com/ · ActionScript · 71 lines · 43 code · 14 blank · 14 comment · 6 complexity · 98074524583fe21cb0e49bb7605e9817 MD5 · raw file

  1. /*
  2. * Copyright 2009 Ryan Berdeen. All rights reserved.
  3. * Distributed under the terms of the MIT License.
  4. * See accompanying file LICENSE.txt
  5. */
  6. package com.ryanberdeen.audio {
  7. import flash.media.Sound;
  8. import flash.utils.ByteArray;
  9. /**
  10. * Varies the playback rate.
  11. **/
  12. public class SpeedChangingSampleSource implements ISampleSource {
  13. private var _sampleSource:ISampleSource;
  14. private var _playbackSpeed:Number = 1;
  15. private var _phase:Number = 0;
  16. public function set sampleSource(sampleSource:ISampleSource):void {
  17. _sampleSource = sampleSource;
  18. }
  19. /**
  20. * The speed at which to play back the samples.
  21. *
  22. * <p>If this value is changed while playing, <code>length</code> and
  23. * <code>toSourcePosition()</code> will be inaccurate</p>
  24. */
  25. public function set playbackSpeed(playbackSpeed:Number):void {
  26. if (playbackSpeed < 0) {
  27. throw new ArgumentError('Playback speed must be positive');
  28. }
  29. _playbackSpeed = playbackSpeed;
  30. }
  31. public function extract(target:ByteArray, length:Number, startPosition:Number = -1):Number {
  32. var p:int;
  33. var loadedSamples:ByteArray = new ByteArray();
  34. var sourceStartPosition:int = startPosition == -1 ? int(_phase) : startPosition * _playbackSpeed;
  35. _sampleSource.extract(loadedSamples, int(length * _playbackSpeed), sourceStartPosition);
  36. loadedSamples.position = 0;
  37. while (loadedSamples.bytesAvailable > 0) {
  38. p = int(_phase - sourceStartPosition) * 8;
  39. if (p < loadedSamples.length - 8 && target.length <= length * 8) {
  40. loadedSamples.position = p;
  41. target.writeBytes(loadedSamples, p, 8);
  42. }
  43. else {
  44. loadedSamples.position = loadedSamples.length;
  45. }
  46. _phase += _playbackSpeed;
  47. }
  48. return target.length / 8;
  49. }
  50. public function toSourcePosition(position:Number):Number {
  51. return _sampleSource.toSourcePosition(position * _playbackSpeed);
  52. }
  53. public function get length():Number {
  54. return _sampleSource.length * _playbackSpeed;
  55. }
  56. }
  57. }