PageRenderTime 363ms CodeModel.GetById 181ms app.highlight 5ms RepoModel.GetById 176ms app.codeStats 0ms

/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
 7package com.ryanberdeen.audio {
 8  import flash.media.Sound;
 9  import flash.utils.ByteArray;
10
11  /**
12  * Varies the playback rate.
13  **/
14  public class SpeedChangingSampleSource implements ISampleSource {
15    private var _sampleSource:ISampleSource;
16    private var _playbackSpeed:Number = 1;
17    private var _phase:Number = 0;
18
19    public function set sampleSource(sampleSource:ISampleSource):void {
20      _sampleSource = sampleSource;
21    }
22
23    /**
24    * The speed at which to play back the samples.
25    *
26    * <p>If this value is changed while playing, <code>length</code> and
27    * <code>toSourcePosition()</code> will be inaccurate</p>
28    */
29    public function set playbackSpeed(playbackSpeed:Number):void {
30      if (playbackSpeed < 0) {
31        throw new ArgumentError('Playback speed must be positive');
32      }
33      _playbackSpeed = playbackSpeed;
34    }
35
36    public function extract(target:ByteArray, length:Number, startPosition:Number = -1):Number {
37      var p:int;
38
39      var loadedSamples:ByteArray = new ByteArray();
40      var sourceStartPosition:int = startPosition == -1 ? int(_phase) : startPosition * _playbackSpeed;
41
42      _sampleSource.extract(loadedSamples, int(length * _playbackSpeed), sourceStartPosition);
43      loadedSamples.position = 0;
44
45      while (loadedSamples.bytesAvailable > 0) {
46        p = int(_phase - sourceStartPosition) * 8;
47
48        if (p < loadedSamples.length - 8 && target.length <= length * 8) {
49          loadedSamples.position = p;
50
51          target.writeBytes(loadedSamples, p, 8);
52        }
53        else {
54          loadedSamples.position = loadedSamples.length;
55        }
56
57        _phase += _playbackSpeed;
58      }
59
60      return target.length / 8;
61    }
62
63    public function toSourcePosition(position:Number):Number {
64      return _sampleSource.toSourcePosition(position * _playbackSpeed);
65    }
66
67    public function get length():Number {
68      return _sampleSource.length * _playbackSpeed;
69    }
70  }
71}