127 lines
2.3 KiB
Haxe
127 lines
2.3 KiB
Haxe
|
package kha.audio2;
|
||
|
|
||
|
import kha.js.AEAudioChannel;
|
||
|
import kha.audio1.AudioChannel;
|
||
|
|
||
|
enum abstract PlayMode(Int) {
|
||
|
var Stopped;
|
||
|
var Paused;
|
||
|
var Playing;
|
||
|
}
|
||
|
|
||
|
class VirtualStreamChannel implements kha.audio1.AudioChannel {
|
||
|
var aeChannel: AEAudioChannel;
|
||
|
var mode = PlayMode.Playing;
|
||
|
var lastTickTime: Float;
|
||
|
var lastPosition: Float;
|
||
|
var looping: Bool;
|
||
|
|
||
|
public function new(aeChannel: AEAudioChannel, looping: Bool) {
|
||
|
this.aeChannel = aeChannel;
|
||
|
this.looping = looping;
|
||
|
lastTickTime = Scheduler.realTime();
|
||
|
lastPosition = 0;
|
||
|
}
|
||
|
|
||
|
public function wake(): Void {
|
||
|
updatePosition();
|
||
|
aeChannel.position = lastPosition;
|
||
|
aeChannel.play();
|
||
|
}
|
||
|
|
||
|
function updatePosition(): Void {
|
||
|
var now = Scheduler.realTime();
|
||
|
switch (mode) {
|
||
|
case Stopped:
|
||
|
lastPosition = 0;
|
||
|
case Paused:
|
||
|
// nothing
|
||
|
case Playing:
|
||
|
lastPosition += now - lastTickTime;
|
||
|
while (lastPosition > length) {
|
||
|
lastPosition -= length;
|
||
|
}
|
||
|
}
|
||
|
lastTickTime = now;
|
||
|
}
|
||
|
|
||
|
public function play(): Void {
|
||
|
if (SystemImpl.mobileAudioPlaying) {
|
||
|
aeChannel.play();
|
||
|
}
|
||
|
else {
|
||
|
updatePosition();
|
||
|
mode = Playing;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
public function pause(): Void {
|
||
|
if (SystemImpl.mobileAudioPlaying) {
|
||
|
aeChannel.pause();
|
||
|
}
|
||
|
else {
|
||
|
updatePosition();
|
||
|
mode = Paused;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
public function stop(): Void {
|
||
|
if (SystemImpl.mobileAudioPlaying) {
|
||
|
aeChannel.stop();
|
||
|
}
|
||
|
else {
|
||
|
updatePosition();
|
||
|
mode = Stopped;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
public var length(get, never): Float; // Seconds
|
||
|
|
||
|
function get_length(): Float {
|
||
|
return aeChannel.length;
|
||
|
}
|
||
|
|
||
|
public var position(get, set): Float; // Seconds
|
||
|
|
||
|
function get_position(): Float {
|
||
|
if (SystemImpl.mobileAudioPlaying) {
|
||
|
return aeChannel.position;
|
||
|
}
|
||
|
else {
|
||
|
updatePosition();
|
||
|
return lastPosition;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
function set_position(value: Float): Float {
|
||
|
if (SystemImpl.mobileAudioPlaying) {
|
||
|
return aeChannel.position = value;
|
||
|
}
|
||
|
else {
|
||
|
updatePosition();
|
||
|
return lastPosition = value;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
public var volume(get, set): Float;
|
||
|
|
||
|
function get_volume(): Float {
|
||
|
return aeChannel.volume;
|
||
|
}
|
||
|
|
||
|
function set_volume(value: Float): Float {
|
||
|
return aeChannel.volume = value;
|
||
|
}
|
||
|
|
||
|
public var finished(get, never): Bool;
|
||
|
|
||
|
function get_finished(): Bool {
|
||
|
if (SystemImpl.mobileAudioPlaying) {
|
||
|
return aeChannel.finished;
|
||
|
}
|
||
|
else {
|
||
|
return mode == Stopped || (!looping && position >= length);
|
||
|
}
|
||
|
}
|
||
|
}
|