public void SetVelocity(Vector3 pos) { if (Active) { Al.alSource3f(ID, Al.AL_VELOCITY, pos.X, pos.Y, pos.Z); } Al.CheckErrors(); }
public void SetPitch(float pitch) { if (Active) { Al.alSourcef(ID, Al.AL_PITCH, pitch); } Al.CheckErrors(); }
public void SetAttenuation(float attenuation) { if (Active) { Al.alSourcef(ID, Al.AL_GAIN, ALUtils.DbToAlGain(attenuation) * man.GetVolume(SoundType.Sfx)); } Al.CheckErrors(); }
public void SetGain(float gain) { if (Active) { Al.alSourcef(ID, Al.AL_GAIN, gain); } Al.CheckErrors(); }
public void Stop() { if (Active) { Al.alSourceStopv(1, ref ID); Al.CheckErrors(); Active = false; } }
public void SetPosition(Vector3 pos) { if (float.IsNaN(pos.X) || float.IsNaN(pos.Y) || float.IsNaN(pos.Z)) { //NaN ??? - Exit FLLog.Error("Sound", "Attempted to set NaN pos"); return; } if (Active) { Al.alSource3f(ID, Al.AL_POSITION, pos.X, pos.Y, pos.Z); } Al.CheckErrors(); }
void Cleanup() { playing = false; Al.alSourceStopv(1, ref ID); Al.CheckErrors(); int p = 0; Al.alGetSourcei(ID, Al.AL_BUFFERS_PROCESSED, out p); Al.CheckErrors(); for (int i = 0; i < p; i++) { uint buf = 0; Al.alSourceUnqueueBuffers(ID, 1, ref buf); Al.CheckErrors(); manager.Buffers.Enqueue(buf); } sound.Data.Seek(0, SeekOrigin.Begin); }
void _Begin() { if (playing) { Cleanup(); } dataleft = true; playing = true; var bytes = ArrayPool <byte> .Shared.Rent(POOL_BUFFER_SIZE); for (int i = 0; i < 3; i++) { var b = manager.Buffers.Dequeue(); int read = sound.Data.Read(bytes, 0, POOL_BUFFER_SIZE); if (read != 0) { Al.BufferData(b, sound.Format, bytes, read, sound.Frequency); Al.CheckErrors(); Al.alSourceQueueBuffers(ID, 1, ref b); Al.CheckErrors(); } else { manager.Buffers.Enqueue(b); } if (read < POOL_BUFFER_SIZE) { if (!looping) { dataleft = false; break; } else { sound.Data.Seek(0, SeekOrigin.Begin); } } } ArrayPool <byte> .Shared.Return(bytes); Al.alSourcef(ID, Al.AL_GAIN, ALUtils.ClampVolume(_gain)); Al.alSourcePlay(ID); Al.CheckErrors(); manager.activeStreamers.Add(this); }
static void SetPropertiesAl(uint src, ref SourceProperties prop, int flags) { if ((flags & FLAG_POS) == FLAG_POS) { Al.alSourcei(src, Al.AL_SOURCE_RELATIVE, prop.Is3D ? 0 : 1); Al.alSource3f(src, Al.AL_POSITION, prop.Position.X, prop.Position.Y, prop.Position.Z); Al.CheckErrors(); } if ((flags & FLAG_VEL) == FLAG_VEL) { Al.alSource3f(src, Al.AL_VELOCITY, prop.Velocity.X, prop.Velocity.Y, prop.Velocity.Z); Al.CheckErrors(); } if ((flags & FLAG_DIRECTION) == FLAG_DIRECTION) { Al.alSource3f(src, Al.AL_DIRECTION, prop.Direction.X, prop.Direction.Y, prop.Direction.Z); Al.CheckErrors(); } if ((flags & FLAG_GAIN) == FLAG_GAIN) { Al.alSourcef(src, Al.AL_GAIN, prop.Gain); Al.CheckErrors(); } if ((flags & FLAG_PITCH) == FLAG_PITCH) { Al.alSourcef(src, Al.AL_PITCH, prop.Pitch); Al.CheckErrors(); } if ((flags & FLAG_DIST) == FLAG_DIST) { Al.alSourcef(src, Al.AL_REFERENCE_DISTANCE, prop.ReferenceDistance); Al.CheckErrors(); Al.alSourcef(src, Al.AL_MAX_DISTANCE, prop.MaxDistance); Al.CheckErrors(); } if ((flags & FLAG_CONE) == FLAG_CONE) { Al.alSourcef(src, Al.AL_CONE_INNER_ANGLE, prop.ConeInnerAngle); Al.CheckErrors(); Al.alSourcef(src, Al.AL_CONE_OUTER_ANGLE, prop.ConeOuterAngle); Al.CheckErrors(); Al.alSourcef(src, Al.AL_CONE_OUTER_GAIN, prop.ConeOuterGain); Al.CheckErrors(); } }
void _Begin() { if (playing) { Cleanup(); } dataleft = true; playing = true; var bytes = BufferAllocator.AllocateBytes(); for (int i = 0; i < 3; i++) { var b = manager.Buffers.Dequeue(); int read = sound.Data.Read(bytes, 0, bytes.Length); if (read != 0) { Al.BufferData(b, sound.Format, bytes, read, sound.Frequency); Al.CheckErrors(); Al.alSourceQueueBuffers(ID, 1, ref b); Al.CheckErrors(); } else { manager.Buffers.Enqueue(b); } if (read < bytes.Length) { if (!looping) { dataleft = false; break; } else { sound.Data.Seek(0, SeekOrigin.Begin); } } } BufferAllocator.Free(bytes); Al.alSourcef(ID, Al.AL_GAIN, ALUtils.ClampVolume(_gain)); Al.alSourcePlay(ID); Al.CheckErrors(); manager.activeStreamers.Add(this); }
public void LoadStream(Stream stream) { using (var snd = SoundLoader.Open(stream)) { byte[] data; if (snd.Size != -1) { data = new byte[snd.Size]; System.Diagnostics.Trace.Assert(snd.Data.Read(data, 0, snd.Size) == snd.Size); } else { using (var mem = new MemoryStream()) { snd.Data.CopyTo(mem); data = mem.ToArray(); } } Al.BufferData(ID, snd.Format, data, data.Length, snd.Frequency); Al.CheckErrors(); } }
public bool Update() { bool hadData = dataleft; //Do things if (dataleft) { int processed; Al.alGetSourcei(ID, Al.AL_BUFFERS_PROCESSED, out processed); Al.CheckErrors(); var bytes = BufferAllocator.AllocateBytes(); for (int i = 0; i < processed; i++) { uint buf = 0; Al.alSourceUnqueueBuffers(ID, 1, ref buf); int read = sound.Data.Read(bytes, 0, bytes.Length); if (read != 0) { Al.BufferData(buf, sound.Format, bytes, read, sound.Frequency); Al.CheckErrors(); Al.alSourceQueueBuffers(ID, 1, ref buf); Al.CheckErrors(); if (read < bytes.Length) { if (looping) { sound.Data.Seek(0, SeekOrigin.Begin); } else { dataleft = false; } } } else { if (looping) { sound.Data.Seek(0, SeekOrigin.Begin); read = sound.Data.Read(bytes, 0, bytes.Length); Al.BufferData(buf, sound.Format, bytes, read, sound.Frequency); Al.CheckErrors(); Al.alSourceQueueBuffers(ID, 1, ref buf); Al.CheckErrors(); } else { dataleft = false; manager.Buffers.Enqueue(buf); break; } } } BufferAllocator.Free(bytes); } //Return buffers int val; Al.alGetSourcei(ID, Al.AL_SOURCE_STATE, out val); Al.CheckErrors(); if (val != Al.AL_PLAYING && val != Al.AL_PAUSED) { if (hadData) { FLLog.Warning("Audio", "Buffer underrun"); Al.alSourcePlay(ID); Al.CheckErrors(); } else { CleanupDelayed(); return(false); } } return(true); }
void UpdateThread() { //Init context IntPtr dev = Alc.alcOpenDevice(null); IntPtr ctx = Alc.alcCreateContext(dev, IntPtr.Zero); Alc.alcMakeContextCurrent(ctx); for (int i = 0; i < MAX_SOURCES; i++) { freeSources.Enqueue(Al.GenSource()); } for (int i = 0; i < MAX_BUFFERS; i++) { Buffers.Enqueue(Al.GenBuffer()); } uint musicSource; for (int i = 0; i < 2; i++) { while (!freeSources.TryDequeue(out musicSource)) { } streamingSources.Enqueue(musicSource); } FLLog.Debug("Audio", "Audio initialised"); Ready = true; while (running) { //insert into items to update while (toAdd.Count > 0) { SoundInstance item; if (toAdd.TryDequeue(out item)) { sfxInstances.Add(item); } } Action toRun; if (Actions.TryDequeue(out toRun)) { toRun(); } //update SFX for (int i = sfxInstances.Count - 1; i >= 0; i--) { int state; Al.alGetSourcei(sfxInstances[i].ID, Al.AL_SOURCE_STATE, out state); Al.CheckErrors(); if (state != Al.AL_PLAYING) { sfxInstances[i].Active = false; if (sfxInstances[i].Dispose != null) { sfxInstances[i].Dispose.Dispose(); } if (sfxInstances[i].OnFinish != null) { UIThread.QueueUIThread(sfxInstances[i].OnFinish); } freeSources.Enqueue(sfxInstances[i].ID); sfxInstances.RemoveAt(i); i--; } } //update Streaming foreach (var item in activeStreamers) { item.Update(); } foreach (var item in toRemove) { activeStreamers.Remove(item); if (item.Stopped != null) { item.OnStopped(); } } Thread.Sleep(5); } //Delete context Alc.alcMakeContextCurrent(IntPtr.Zero); Alc.alcDestroyContext(ctx); Alc.alcCloseDevice(ctx); }
void UpdateThread() { audioThreadId = Thread.CurrentThread.ManagedThreadId; //Init context IntPtr dev = Alc.alcOpenDevice(null); IntPtr ctx = Alc.alcCreateContext(dev, IntPtr.Zero); Alc.alcMakeContextCurrent(ctx); Al.CheckErrors(); for (int i = 0; i < MAX_SOURCES; i++) { freeSources.Enqueue(Al.GenSource()); } for (int i = 0; i < MAX_STREAM_BUFFERS; i++) { Buffers.Enqueue(Al.GenBuffer()); } Instances = new InstanceInfo[MAX_INSTANCES]; for (int i = 0; i < MAX_INSTANCES; i++) { Instances[i].Source = uint.MaxValue; freeInstances.Enqueue((uint)i); } uint musicSource; for (int i = 0; i < 2; i++) { while (!freeSources.TryDequeue(out musicSource)) { } streamingSources.Enqueue(musicSource); } FLLog.Debug("Audio", "Audio initialised"); Ready = true; Al.alListenerf(Al.AL_GAIN, ALUtils.ClampVolume(ALUtils.LinearToAlGain(_masterVolume))); while (running) { //Run actions Action toRun; while (actions.TryDequeue(out toRun)) { toRun(); } //update SFX for (int i = sfxInstances.Count - 1; i >= 0; i--) { var src = Instances[sfxInstances[i]].Source; var instance = Instances[sfxInstances[i]].Instance; int state; Al.alGetSourcei(src, Al.AL_SOURCE_STATE, out state); Al.CheckErrors(); if (state == Al.AL_STOPPED) { Al.alSourcei(src, Al.AL_BUFFER, 0); freeSources.Enqueue(src); Instances[sfxInstances[i]].Source = uint.MaxValue; instance?.Stopped(); sfxInstances.RemoveAt(i); i--; } } //update Streaming foreach (var item in activeStreamers) { item.Update(); } foreach (var item in toRemove) { activeStreamers.Remove(item); item.OnStopped(); } toRemove.Clear(); Thread.Sleep((sfxInstances.Count > 0 || activeStreamers.Count > 0) ? 1 : 5); } //Delete context Alc.alcMakeContextCurrent(IntPtr.Zero); Alc.alcDestroyContext(ctx); Alc.alcCloseDevice(dev); }