~arkadini/fogg/trunk

« back to all changes in this revision

Viewing changes to org/xiph/system/AudioSink.hx

  • Committer: Arek Korbik
  • Date: 2008-10-02 01:21:02 UTC
  • Revision ID: arkadini@gmail.com-20081002012102-3fgmde20ual97w9v
Add a simple audio "sink".

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
package org.xiph.system;
 
2
 
 
3
//import org.xiph.system.Bytes;
 
4
 
 
5
import flash.Vector;
 
6
 
 
7
import flash.media.Sound;
 
8
import flash.media.SoundChannel;
 
9
import flash.events.SampleDataEvent;
 
10
 
 
11
 
 
12
class AudioSink {
 
13
    var buffer : Bytes;
 
14
    public var available : Int;
 
15
    var triggered : Bool;
 
16
    var trigger : Int;
 
17
    var fill : Bool;
 
18
    var size : Int;
 
19
 
 
20
    var s : Sound;
 
21
    var sch : SoundChannel;
 
22
 
 
23
    public function new(chunk_size : Int, fill = true, trigger = 0) {
 
24
        size = chunk_size;
 
25
        this.fill = fill;
 
26
        this.trigger = trigger;
 
27
        if (this.trigger == -1)
 
28
            this.trigger = size;
 
29
        triggered = false;
 
30
 
 
31
        buffer = new Bytes();
 
32
        available = 0;
 
33
        s = new Sound();
 
34
        sch = null;
 
35
    }
 
36
 
 
37
    public function play() : Void {
 
38
        trace("adding callback");
 
39
        s.addEventListener("sampleData", _data_cb);
 
40
        trace("playing");
 
41
        sch = s.play();
 
42
        trace(sch);
 
43
    }
 
44
 
 
45
    public function stop() : Void {
 
46
        if (sch != null) {
 
47
            sch.stop();
 
48
        }
 
49
    }
 
50
 
 
51
    function _data_cb(event : SampleDataEvent) : Void {
 
52
        var i : Int;
 
53
        var to_write : Int = available > size ? size : available;
 
54
        var missing = to_write < size ? size - to_write : 0;
 
55
        var bytes : Int = to_write * 8;
 
56
        if (to_write > 0) {
 
57
            event.data.writeBytes(buffer, 0, bytes);
 
58
            available -= to_write;
 
59
            System.bytescopy(buffer, bytes, buffer, 0, available * 8);
 
60
        }
 
61
        i = 0;
 
62
        if (missing > 0 && missing != size && fill) {
 
63
            trace("samples data underrun: " + missing);
 
64
            while (i < missing) {
 
65
                untyped {
 
66
                event.data.writeFloat(0.0);
 
67
                event.data.writeFloat(0.0);
 
68
                };
 
69
                i++;
 
70
            }
 
71
        } else if (missing > 0) {
 
72
            trace("not enough data, stopping");
 
73
            //stop();
 
74
        }
 
75
    }
 
76
 
 
77
    public function write(pcm : Array<Vector<Float>>, index : Vector<Int>,
 
78
                          samples : Int) : Void {
 
79
        var i : Int;
 
80
        var end : Int;
 
81
        buffer.position = available * 8; // 2 ch * 4 bytes per sample (float)
 
82
        if (pcm.length == 1) {
 
83
            // one channel
 
84
            var c = pcm[0];
 
85
            var s : Float;
 
86
            i = index[0];
 
87
            end = i + samples;
 
88
            while (i < samples) {
 
89
                s = c[i++];
 
90
                buffer.writeFloat(s);
 
91
                buffer.writeFloat(s);
 
92
            }
 
93
        } else if (pcm.length == 2) {
 
94
            // two channels
 
95
            var c1 = pcm[0];
 
96
            var c2 = pcm[1];
 
97
            i = index[0];
 
98
            var i2 = index[1];
 
99
            end = i + samples;
 
100
            while (i < end) {
 
101
                buffer.writeFloat(c1[i]);
 
102
                buffer.writeFloat(c2[i2++]);
 
103
                i++;
 
104
            }
 
105
        } else {
 
106
            throw "-EWRONGNUMCHANNELS";
 
107
        }
 
108
 
 
109
        available += samples;
 
110
        if (!triggered && trigger > 0 && available > trigger) {
 
111
            triggered = true;
 
112
            play();
 
113
        }
 
114
    }
 
115
}