LNXSDK/Kha/Backends/HTML5/kha/audio2/VirtualStreamChannel.hx
2025-01-22 16:18:30 +01:00

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);
}
}
}