ProjectPSX/ProjectPSX.OpenTK/AudioPlayer.cs
2020-09-19 19:32:08 +02:00

66 lines
2.1 KiB
C#

using System;
using OpenTK.Audio.OpenAL;
using OpenTK.Mathematics;
namespace ProjectPSX.OpenTK {
public class AudioPlayer {
int audioSource;
ALDevice audioDevice;
ALContext audioContext;
int queueLength = 0;
public bool fastForward;
public bool audioDisabled;
public AudioPlayer() {
audioDevice = ALC.OpenDevice(null);
if (audioDevice == null) {
Console.WriteLine("Unable to create audio device");
return;
}
audioContext = ALC.CreateContext(audioDevice, (int[])null);
ALC.MakeContextCurrent(audioContext);
audioSource = AL.GenSource();
AL.Listener(ALListener3f.Position, 0, 0, 0);
AL.Listener(ALListener3f.Velocity, 0, 0, 0);
var orientation = new Vector3(0, 0, 0);
AL.Listener(ALListenerfv.Orientation, ref orientation, ref orientation);
fastForward = false;
audioDisabled = false;
}
public unsafe void UpdateAudio(byte[] samples) {
int processed = 0;
int alBuffer = 0;
while (true) {
AL.GetSource(audioSource, ALGetSourcei.BuffersProcessed, out processed);
while (processed-- > 0) {
AL.SourceUnqueueBuffers(audioSource, 1, ref alBuffer);
AL.DeleteBuffer(alBuffer);
queueLength--;
}
if (queueLength < 5 || fastForward) break;
}
if (queueLength < 5) {
alBuffer = AL.GenBuffer();
AL.BufferData(alBuffer, ALFormat.Stereo16, samples, 44100);
AL.SourceQueueBuffer(audioSource, alBuffer);
queueLength++;
}
if (AL.GetSourceState(audioSource) != ALSourceState.Playing)
AL.SourcePlay(audioSource);
}
// Is this automatically called by GC?
~AudioPlayer() {
ALC.DestroyContext(audioContext);
ALC.CloseDevice(audioDevice);
}
}
}