void ApplyFilter() { if (applyFilter && controller.Filter > 0) { var freq = frequency / 20000f; var lf = 1.0f - freq; var efx = OpenALSoundController.Efx; efx.Filter(controller.Filter, EfxFilteri.FilterType, (int)filterType); ALHelper.CheckError("Failed to set filter."); switch (filterType) { case EfxFilterType.Lowpass: efx.Filter(controller.Filter, EfxFilterf.LowpassGainHF, freq); ALHelper.CheckError("Failed to set LowpassGainHF."); break; case EfxFilterType.Highpass: efx.Filter(controller.Filter, EfxFilterf.HighpassGainLF, freq); ALHelper.CheckError("Failed to set HighpassGainLF."); break; case EfxFilterType.Bandpass: efx.Filter(controller.Filter, EfxFilterf.BandpassGainHF, freq); ALHelper.CheckError("Failed to set BandpassGainHF."); efx.Filter(controller.Filter, EfxFilterf.BandpassGainLF, lf); ALHelper.CheckError("Failed to set BandpassGainLF."); break; } AL.Source(SourceId, ALSourcei.EfxDirectFilter, controller.Filter); ALHelper.CheckError("Failed to set DirectFilter."); } }
/// <summary> /// Sets up the hardware resources used by the controller. /// </summary> private OpenALSoundController() { if (AL.NativeLibrary == IntPtr.Zero) { throw new DllNotFoundException("Couldn't initialize OpenAL because the native binaries couldn't be found."); } if (!OpenSoundController()) { throw new NoAudioHardwareException("OpenAL device could not be initialized, see console output for details."); } if (Alc.IsExtensionPresent(_device, "ALC_EXT_CAPTURE")) { Microphone.PopulateCaptureDevices(); } // We have hardware here and it is ready allSourcesArray = new int[MAX_NUMBER_OF_SOURCES]; AL.GenSources(allSourcesArray); ALHelper.CheckError("Failed to generate sources."); Filter = 0; if (Efx.IsInitialized) { Filter = Efx.GenFilter(); } availableSourcesCollection = new List <int>(allSourcesArray); inUseSourcesCollection = new List <int>(); }
public void Play() { switch (AL.GetSourceState(this.alSourceId)) { case ALSourceState.Playing: break; case ALSourceState.Paused: this.Resume(); break; default: if (this.bufferStack.Count == this.BufferCount) { this.Prepare(false); } else if (!this.FirstBufferPrecached) { ALHelper.Log(string.Concat(new object[4] { (object)"Buffers lost for ", (object)this.RealName, (object)" with source ", (object)this.alSourceId }), "OpenAL"); } AL.SourcePlay(this.alSourceId); this.Precaching = false; OggStreamer.Instance.AddStream(this); break; } }
public void Dispose() { var state = AL.GetSourceState(alSourceId); ALHelper.CheckError("Failed to get the source state."); if (state == ALSourceState.Playing || state == ALSourceState.Paused) { StopPlayback(); } lock (prepareMutex) { OggStreamer.Instance.RemoveStream(this); if (state != ALSourceState.Initial) { Empty(); } Close(); } AL.Source(alSourceId, ALSourcei.Buffer, 0); ALHelper.CheckError("Failed to free source from buffers."); OpenALSoundController.GetInstance.RecycleSource(alSourceId); AL.DeleteBuffers(alBufferIds); ALHelper.CheckError("Failed to delete buffer."); if (OggStreamer.Instance.Efx.IsInitialized) { OggStreamer.Instance.Efx.DeleteFilter(alFilterId); ALHelper.CheckError("Failed to delete EFX filter."); } }
/// <summary> /// Sets up the hardware resources used by the controller. /// </summary> private OpenALSoundController() { #if WINDOWS // On Windows, set the DLL search path for correct native binaries NativeHelper.InitDllDirectory(); #endif if (!OpenSoundController()) { return; } // We have hardware here and it is ready _bSoundAvailable = true; allSourcesArray = new int[MAX_NUMBER_OF_SOURCES]; AL.GenSources(allSourcesArray); ALHelper.CheckError("Failed to generate sources."); Filter = 0; #if SUPPORTS_EFX if (Efx.IsInitialized) { Filter = Efx.GenFilter(); } #endif availableSourcesCollection = new List <int>(allSourcesArray); inUseSourcesCollection = new List <int>(); }
public void BindDataBuffer(byte[] dataBuffer, ALFormat format, int size, int sampleRate, int sampleAlignment = 0) { if ((format == ALFormat.MonoMSAdpcm || format == ALFormat.StereoMSAdpcm) && !OpenALSoundController.GetInstance.SupportsAdpcm) { throw new InvalidOperationException("MS-ADPCM is not supported by this OpenAL driver"); } if ((format == ALFormat.MonoIma4 || format == ALFormat.StereoIma4) && !OpenALSoundController.GetInstance.SupportsIma4) { throw new InvalidOperationException("IMA/ADPCM is not supported by this OpenAL driver"); } openALFormat = format; dataSize = size; int unpackedSize = 0; if (sampleAlignment > 0) { AL.Bufferi(openALDataBuffer, ALBufferi.UnpackBlockAlignmentSoft, sampleAlignment); ALHelper.CheckError("Failed to fill buffer."); } AL.BufferData(openALDataBuffer, openALFormat, dataBuffer, size, sampleRate); ALHelper.CheckError("Failed to fill buffer."); int bits, channels; Duration = -1; AL.GetBuffer(openALDataBuffer, ALGetBufferi.Bits, out bits); ALHelper.CheckError("Failed to get buffer bits"); AL.GetBuffer(openALDataBuffer, ALGetBufferi.Channels, out channels); ALHelper.CheckError("Failed to get buffer channels"); AL.GetBuffer(openALDataBuffer, ALGetBufferi.Size, out unpackedSize); ALHelper.CheckError("Failed to get buffer size"); Duration = (float)(unpackedSize / ((bits / 8) * channels)) / (float)sampleRate; }
public void Dispose() { var state = AL.GetSourceState(alSourceId); ALHelper.CheckError("Failed to get the source state."); if (state == ALSourceState.Playing || state == ALSourceState.Paused) { StopPlayback(); } lock (prepareMutex) { OggStreamer.Instance.RemoveStream(this); if (state != ALSourceState.Initial) { Empty(); } Close(); } OpenALSoundController.Instance.RecycleSource(alSourceId); AL.DeleteBuffers(alBufferIds); ALHelper.CheckError("Failed to delete buffer."); }
/// <summary> /// Sets up the hardware resources used by the controller. /// </summary> private OpenALSoundController() { #if WINDOWS // On Windows, set the DLL search path for correct native binaries NativeHelper.InitDllDirectory(); #endif if (!OpenSoundController()) { throw new NoAudioHardwareException("OpenAL device could not be initialized, see console output for details."); } if (Alc.IsExtensionPresent(_device, "ALC_EXT_CAPTURE")) { Microphone.PopulateCaptureDevices(); } // We have hardware here and it is ready allSourcesArray = new int[MAX_NUMBER_OF_SOURCES]; AL.GenSources(allSourcesArray); ALHelper.CheckError("Failed to generate sources."); Filter = 0; if (Efx.IsInitialized) { Filter = Efx.GenFilter(); } availableSourcesCollection = new List <int>(allSourcesArray); inUseSourcesCollection = new List <int>(); }
private void PlatformStop(bool immediate) { if (HasSourceId) { if (!controller.CheckInitState()) { return; } AL.SourceStop(SourceId); ALHelper.CheckError("Failed to stop source."); #if SUPPORTS_EFX // Reset the SendFilter to 0 if we are NOT using revert since // sources are recyled OpenALSoundController.Efx.BindSourceToAuxiliarySlot(SourceId, 0, 0, 0); ALHelper.CheckError("Failed to unset reverb."); AL.Source(SourceId, ALSourcei.EfxDirectFilter, 0); ALHelper.CheckError("Failed to unset filter."); #endif AL.Source(SourceId, ALSourcei.Buffer, 0); ALHelper.CheckError("Failed to free source from buffer."); controller.FreeSource(this); } SoundState = SoundState.Stopped; }
private void FreeSource() { if (!HasSourceId) { return; } lock (sourceMutex) { if (HasSourceId && AL.IsSource(SourceId)) { AL.SourceStop(SourceId); ALHelper.CheckError("Failed to stop source."); // Reset the SendFilter to 0 if we are NOT using reverb since // sources are recycled if (OpenALSoundController.Instance.SupportsEfx) { OpenALSoundController.Efx.BindSourceToAuxiliarySlot(SourceId, 0, 0, 0); ALHelper.CheckError("Failed to unset reverb."); AL.Source(SourceId, ALSourcei.EfxDirectFilter, 0); ALHelper.CheckError("Failed to unset filter."); } controller.FreeSource(this); } } }
public void BindDataBuffer(byte[] dataBuffer, ALFormat format, int size, int sampleRate) { openALFormat = format; dataSize = size; this.sampleRate = sampleRate; AL.BufferData(openALDataBuffer, openALFormat, dataBuffer, dataSize, this.sampleRate); ALHelper.CheckError("Failed to fill buffer."); int bits, channels; AL.GetBuffer(openALDataBuffer, ALGetBufferi.Bits, out bits); ALError alError = AL.GetError(); if (alError != ALError.NoError) { Console.WriteLine("Failed to get buffer bits: {0}, format={1}, size={2}, sampleRate={3}", AL.GetErrorString(alError), format, size, sampleRate); Duration = -1; } else { AL.GetBuffer(openALDataBuffer, ALGetBufferi.Channels, out channels); alError = AL.GetError(); if (alError != ALError.NoError) { Console.WriteLine("Failed to get buffer bits: {0}, format={1}, size={2}, sampleRate={3}", AL.GetErrorString(alError), format, size, sampleRate); Duration = -1; } else { Duration = (float)(size / ((bits / 8) * channels)) / (float)sampleRate; } } //Console.WriteLine("Duration: " + Duration + " / size: " + size + " bits: " + bits + " channels: " + channels + " rate: " + sampleRate); }
/// <summary> /// Dispose of the OpenALSoundCOntroller. /// </summary> /// <param name="disposing">If true, the managed resources are to be disposed.</param> void Dispose(bool disposing) { if (!_isDisposed) { if (disposing) { #if DESKTOPGL if (_oggstreamer != null) { _oggstreamer.Dispose(); } #endif for (int i = 0; i < allSourcesArray.Length; i++) { AL.DeleteSource(allSourcesArray[i]); ALHelper.CheckError("Failed to delete source."); } if (Filter != 0 && Efx.IsInitialized) { Efx.DeleteFilter(Filter); } Microphone.StopMicrophones(); CleanUpOpenAL(); } _isDisposed = true; } }
private void Empty(bool giveUp = false) { int numEntries1; AL.GetSource(this.alSourceId, ALGetSourcei.BuffersQueued, out numEntries1); if (numEntries1 <= 0) { return; } AL.SourceUnqueueBuffers(this.alSourceId, numEntries1); if (!ALHelper.TryCheck() && !giveUp) { int numEntries2; AL.GetSource(this.alSourceId, ALGetSourcei.BuffersProcessed, out numEntries2); int[] bids = new int[numEntries2]; if (numEntries2 > 0) { AL.SourceUnqueueBuffers(this.alSourceId, numEntries2, bids); ALHelper.Check(); } AL.SourceStop(this.alSourceId); ALHelper.Check(); this.Empty(true); } }
public void Dispose() { if (this.IsDisposed) { return; } this.IsDisposed = true; ALSourceState sourceState = AL.GetSourceState(this.alSourceId); if (sourceState == ALSourceState.Playing || sourceState == ALSourceState.Paused) { this.StopPlayback(); } lock (this.prepareMutex) { if (OggStreamer.HasInstance) { OggStreamer.Instance.RemoveStream(this); } if (sourceState != ALSourceState.Initial) { this.Empty(false); } this.Close(); this.underlyingStream.Dispose(); } if (OpenALSoundController.Instance != null) { OpenALSoundController.Instance.ReturnSource(this.alSourceId); OpenALSoundController.Instance.ReturnBuffers(this.alBufferIds); } ALHelper.Check(); }
public void Stop() { var state = AL.GetSourceState(alSourceId); ALHelper.CheckError("Failed to get source state."); if (state == ALSourceState.Playing || state == ALSourceState.Paused) { StopPlayback(); } lock (stopMutex) { OggStreamer.Instance.RemoveStream(this); lock (prepareMutex) { if (state != ALSourceState.Initial) { Empty(); // force the queued buffers to be unqueued to avoid issues on Mac } } } AL.Source(alSourceId, ALSourcei.Buffer, 0); ALHelper.CheckError("Failed to free source from buffers."); }
/// <summary> /// Dispose of the OpenALSoundCOntroller. /// </summary> /// <param name="disposing">If true, the managed resources are to be disposed.</param> void Dispose(bool disposing) { if (!_isDisposed) { if (disposing) { if (_bSoundAvailable) { #if DESKTOPGL if (_oggstreamer != null) { _oggstreamer.Dispose(); } #endif for (int i = 0; i < allSourcesArray.Length; i++) { AL.DeleteSource(allSourcesArray[i]); ALHelper.CheckError("Failed to delete source."); } CleanUpOpenAL(); } } _isDisposed = true; } }
private void PlatformUpdateQueue() { // Get the completed buffers AL.GetError(); int numBuffers; AL.GetSource(SourceId, ALGetSourcei.BuffersProcessed, out numBuffers); ALHelper.CheckError("Failed to get processed buffer count."); // Unqueue them if (numBuffers > 0) { AL.SourceUnqueueBuffers(SourceId, numBuffers); ALHelper.CheckError("Failed to unqueue buffers."); for (int i = 0; i < numBuffers; i++) { var buffer = _queuedBuffers.Dequeue(); buffer.Dispose(); } } // Raise the event for each removed buffer, if needed for (int i = 0; i < numBuffers; i++) { CheckBufferCount(); } }
private void PlatformSubmitBuffer(byte[] buffer, int offset, int count) { // Get a buffer OALSoundBuffer oalBuffer = new OALSoundBuffer(); // Bind the data if (offset == 0) { oalBuffer.BindDataBuffer(buffer, _format, count, _sampleRate); } else { // BindDataBuffer does not support offset var offsetBuffer = new byte[count]; Array.Copy(buffer, offset, offsetBuffer, 0, count); oalBuffer.BindDataBuffer(offsetBuffer, _format, count, _sampleRate); } // Queue the buffer AL.SourceQueueBuffer(SourceId, oalBuffer.OpenALDataBuffer); ALHelper.CheckError(); _queuedBuffers.Enqueue(oalBuffer); // If the source has run out of buffers, restart it var sourceState = AL.GetSourceState(SourceId); if (_state == SoundState.Playing && sourceState == ALSourceState.Stopped) { AL.SourcePlay(SourceId); ALHelper.CheckError("Failed to resume source playback."); } }
void Empty() { int queued; AL.GetSource(alSourceId, ALGetSourcei.BuffersQueued, out queued); ALHelper.CheckError("Failed to fetch queued buffers."); if (queued > 0) { try { AL.SourceUnqueueBuffers(alSourceId, queued); ALHelper.CheckError("Failed to unqueue buffers (first attempt)."); } catch (InvalidOperationException) { // This is a bug in the OpenAL implementation // Salvage what we can int processed; AL.GetSource(alSourceId, ALGetSourcei.BuffersProcessed, out processed); ALHelper.CheckError("Failed to fetch processed buffers."); var salvaged = new int[processed]; if (processed > 0) { AL.SourceUnqueueBuffers(alSourceId, processed, salvaged); ALHelper.CheckError("Failed to unqueue buffers (second attempt)."); } // Try turning it off again? AL.SourceStop(alSourceId); ALHelper.CheckError("Failed to stop source."); Empty(); } } }
private void PlatformApply3D(AudioListener listener, AudioEmitter emitter) { // get AL's listener position float x, y, z; AL.GetListener(ALListener3f.Position, out x, out y, out z); ALHelper.CheckError("Failed to get source position."); // get the emitter offset from origin Vector3 posOffset = emitter.Position - listener.Position; // set up orientation matrix Matrix orientation = Matrix.CreateWorld(Vector3.Zero, listener.Forward, listener.Up); // set up our final position and velocity according to orientation of listener Vector3 finalPos = new Vector3(x + posOffset.X, y + posOffset.Y, z + posOffset.Z); finalPos = Vector3.Transform(finalPos, orientation); Vector3 finalVel = emitter.Velocity; finalVel = Vector3.Transform(finalVel, orientation); // set the position based on relative positon AL.Source(SourceId, ALSource3f.Position, finalPos.X, finalPos.Y, finalPos.Z); ALHelper.CheckError("Failed to set source position."); AL.Source(SourceId, ALSource3f.Velocity, finalVel.X, finalVel.Y, finalVel.Z); ALHelper.CheckError("Failed to Set source velocity."); }
public OggStream(string filename, Action finishedAction = null, int bufferCount = DefaultBufferCount) { oggFileName = filename; FinishedAction = finishedAction; BufferCount = bufferCount; alBufferIds = AL.GenBuffers(bufferCount); ALHelper.CheckError("Failed to generate buffers."); alSourceId = OpenALSoundController.GetInstance.ReserveSource(); if (OggStreamer.Instance.XRam.IsInitialized) { OggStreamer.Instance.XRam.SetBufferMode(BufferCount, ref alBufferIds[0], XRamExtension.XRamStorage.Hardware); ALHelper.CheckError("Failed to activate Xram."); } Volume = 1; if (OggStreamer.Instance.Efx.IsInitialized) { alFilterId = OggStreamer.Instance.Efx.GenFilter(); ALHelper.CheckError("Failed to generate Efx filter."); OggStreamer.Instance.Efx.Filter(alFilterId, EfxFilteri.FilterType, (int)EfxFilterType.Lowpass); ALHelper.CheckError("Failed to set Efx filter type."); OggStreamer.Instance.Efx.Filter(alFilterId, EfxFilterf.LowpassGain, 1); ALHelper.CheckError("Failed to set Efx filter value."); LowPassHFGain = 1; } }
private SoundState PlatformGetState() { if (!HasSourceId) { return(SoundState.Stopped); } var alState = AL.GetSourceState(SourceId); ALHelper.CheckError("Failed to get source state."); switch (alState) { case ALSourceState.Initial: case ALSourceState.Stopped: SoundState = SoundState.Stopped; break; case ALSourceState.Paused: SoundState = SoundState.Paused; break; case ALSourceState.Playing: SoundState = SoundState.Playing; break; } return(SoundState); }
void ApplyReverb() { if (reverb > 0f && SoundEffect.ReverbSlot != 0) { OpenALSoundController.Efx.BindSourceToAuxiliarySlot(SourceId, (int)SoundEffect.ReverbSlot, 0, 0); ALHelper.CheckError("Failed to set reverb."); } }
private void PlatformSetPitch(float value) { if (HasSourceId) { AL.Source(SourceId, ALSourcef.Pitch, XnaPitchToAlPitch(value)); ALHelper.CheckError("Failed to set source pitch."); } }
public double SourceCurrentPosition(int sourceId) { int pos; AL.GetSource(sourceId, ALGetSourcei.SampleOffset, out pos); ALHelper.CheckError("Failed to set source offset."); return(pos); }
private void PlatformSetPan(float value) { if (HasSourceId) { AL.Source(SourceId, ALSource3f.Position, value, 0.0f, 0.1f); ALHelper.CheckError("Failed to set source pan."); } }
internal void Precache(bool asynchronous = false) { if (!asynchronous) { OggStreamer.Instance.FillBuffer(this, this.alBufferIds[0]); AL.SourceQueueBuffer(this.alSourceId, this.alBufferIds[0]); ALHelper.Check(); } OggStreamer.Instance.AddStream(this); }
private void PlatformSetVolume(float value) { _alVolume = value; if (HasSourceId) { AL.Source(SourceId, ALSourcef.Gain, _alVolume); ALHelper.CheckError("Failed to set source volume."); } }
private void PlatformSetIsLooped(bool value) { _looped = value; if (HasSourceId) { AL.Source(SourceId, ALSourceb.Looping, _looped); ALHelper.CheckError("Failed to set source loop state."); } }
internal bool RefreshState() { if (this.soundState != SoundState.Playing || AL.GetSourceState(this.sourceId) != ALSourceState.Stopped) { return(false); } ALHelper.Check(); this.soundState = SoundState.Stopped; return(true); }