public float GetVariable(string name) { if (String.IsNullOrEmpty(name)) { throw new ArgumentNullException("name"); } ushort variable = FAudio.FACTCue_GetVariableIndex( handle, name ); if (variable == FAudio.FACTVARIABLEINDEX_INVALID) { throw new InvalidOperationException( "Invalid variable name!" ); } float result; FAudio.FACTCue_GetVariable( handle, variable, out result ); return(result); }
internal unsafe void INTERNAL_applyReverb(float rvGain) { if (handle == IntPtr.Zero) { return; } if (!usingReverb) { SoundEffect.Device().AttachReverb(handle); usingReverb = true; } // Re-using this float array... float *outputMatrix = (float *)dspSettings.pMatrixCoefficients; outputMatrix[0] = rvGain; if (dspSettings.SrcChannelCount == 2) { outputMatrix[1] = rvGain; } FAudio.FAudioVoice_SetOutputMatrix( handle, SoundEffect.Device().ReverbVoice, dspSettings.SrcChannelCount, 1, dspSettings.pMatrixCoefficients, 0 ); }
public WaveBank( AudioEngine audioEngine, string nonStreamingWaveBankFilename ) { if (audioEngine == null) { throw new ArgumentNullException("audioEngine"); } if (String.IsNullOrEmpty(nonStreamingWaveBankFilename)) { throw new ArgumentNullException("nonStreamingWaveBankFilename"); } buffer = TitleContainer.ReadAllBytes( nonStreamingWaveBankFilename ); pin = GCHandle.Alloc(buffer, GCHandleType.Pinned); FAudio.FACTAudioEngine_CreateInMemoryWaveBank( audioEngine.handle, pin.AddrOfPinnedObject(), (uint)buffer.Length, 0, 0, out handle ); engine = audioEngine; selfReference = new WeakReference(this, true); engine.RegisterWaveBank(handle, selfReference); IsDisposed = false; }
public void SetGlobalVariable(string name, float value) { if (String.IsNullOrEmpty(name)) { throw new ArgumentNullException("name"); } ushort variable = FAudio.FACTAudioEngine_GetGlobalVariableIndex( handle, name ); if (variable == FAudio.FACTVARIABLEINDEX_INVALID) { throw new InvalidOperationException( "Invalid variable name!" ); } FAudio.FACTAudioEngine_SetGlobalVariable( handle, variable, value ); }
public Cue GetCue(string name) { if (String.IsNullOrEmpty(name)) { throw new ArgumentNullException("name"); } ushort cue = FAudio.FACTSoundBank_GetCueIndex( handle, name ); if (cue == FAudio.FACTINDEX_INVALID) { throw new InvalidOperationException( "Invalid cue name!" ); } IntPtr result; FAudio.FACTSoundBank_Prepare( handle, cue, 0, 0, out result ); return(new Cue(result, name, this)); }
public void PlayCue(string name) { if (String.IsNullOrEmpty(name)) { throw new ArgumentNullException("name"); } ushort cue = FAudio.FACTSoundBank_GetCueIndex( handle, name ); if (cue == FAudio.FACTINDEX_INVALID) { throw new InvalidOperationException( "Invalid cue name!" ); } FAudio.FACTSoundBank_Play( handle, cue, 0, 0, IntPtr.Zero ); }
public static void Create() { IntPtr ctx; try { FAudio.FAudioCreate( out ctx, 0, FAudio.FAUDIO_DEFAULT_PROCESSOR ); } catch { /* FAudio is missing, bail! */ return; } uint devices; FAudio.FAudio_GetDeviceCount( ctx, out devices ); if (devices == 0) { /* No sound cards, bail! */ FAudio.FAudio_Release(ctx); return; } Context = new FAudioContext(ctx, devices); }
public WaveBank( AudioEngine audioEngine, string nonStreamingWaveBankFilename ) { if (audioEngine == null) { throw new ArgumentNullException("audioEngine"); } if (String.IsNullOrEmpty(nonStreamingWaveBankFilename)) { throw new ArgumentNullException("nonStreamingWaveBankFilename"); } bankData = TitleContainer.ReadToPointer( nonStreamingWaveBankFilename, out bankDataLen ); FAudio.FACTAudioEngine_CreateInMemoryWaveBank( audioEngine.handle, bankData, (uint)bankDataLen, 0, 0, out handle ); engine = audioEngine; selfReference = new WeakReference(this, true); engine.RegisterWaveBank(handle, selfReference); IsDisposed = false; }
public void SubmitBuffer(byte[] buffer, int offset, int count) { IntPtr next = Marshal.AllocHGlobal(count); Marshal.Copy(buffer, offset, next, count); lock (queuedBuffers) { queuedBuffers.Add(next); if (State != SoundState.Stopped) { FAudio.FAudioBuffer buf = new FAudio.FAudioBuffer(); buf.AudioBytes = (uint)count; buf.pAudioData = next; buf.PlayLength = ( buf.AudioBytes / (uint)channels / (uint)(format.wBitsPerSample / 8) ); FAudio.FAudioSourceVoice_SubmitSourceBuffer( handle, ref buf, IntPtr.Zero ); } else { queuedSizes.Add((uint)count); } } }
public void Stop(bool immediate) { if (handle == IntPtr.Zero) { return; } if (immediate) { FAudio.FAudioSourceVoice_Stop(handle, 0, 0); FAudio.FAudioSourceVoice_FlushSourceBuffers(handle); FAudio.FAudioVoice_DestroyVoice(handle); handle = IntPtr.Zero; usingReverb = false; INTERNAL_state = SoundState.Stopped; if (isDynamic) { FrameworkDispatcher.Streams.Remove( this as DynamicSoundEffectInstance ); (this as DynamicSoundEffectInstance).ClearBuffers(); } } else { if (isDynamic) { throw new InvalidOperationException(); } FAudio.FAudioSourceVoice_ExitLoop(handle, 0); } }
public void Dispose() { if (stbVorbisData != IntPtr.Zero) { FAudio.stb_vorbis_close(stbVorbisData); stbVorbisData = IntPtr.Zero; } }
public static void GetVisualizationData(VisualizationData data) { FAudio.XNA_GetSongVisualizationData( data.freq, data.samp, VisualizationData.Size ); }
internal static void DisposeIfNecessary() { if (initialized) { FAudio.XNA_SongQuit(); initialized = false; } }
public void Pause() { if (handle != IntPtr.Zero && State == SoundState.Playing) { FAudio.FAudioSourceVoice_Stop(handle, 0, 0); INTERNAL_state = SoundState.Paused; } }
private FAudioContext(IntPtr ctx, uint devices) { Handle = ctx; uint i; for (i = 0; i < devices; i += 1) { FAudio.FAudio_GetDeviceDetails( Handle, i, out DeviceDetails ); if ((DeviceDetails.Role & FAudio.FAudioDeviceRole.FAudioDefaultGameDevice) == FAudio.FAudioDeviceRole.FAudioDefaultGameDevice) { break; } } if (i == devices) { i = 0; /* Oh well. */ FAudio.FAudio_GetDeviceDetails( Handle, i, out DeviceDetails ); } if (FAudio.FAudio_CreateMasteringVoice( Handle, out MasterVoice, FAudio.FAUDIO_DEFAULT_CHANNELS, FAudio.FAUDIO_DEFAULT_SAMPLERATE, 0, i, IntPtr.Zero ) != 0) { FAudio.FAudio_Release(ctx); Handle = IntPtr.Zero; FNALoggerEXT.LogError( "Failed to create mastering voice!" ); return; } CurveDistanceScaler = 1.0f; DopplerScale = 1.0f; SpeedOfSound = 343.5f; Handle3D = new byte[FAudio.F3DAUDIO_HANDLE_BYTESIZE]; FAudio.F3DAudioInitialize( DeviceDetails.OutputFormat.dwChannelMask, SpeedOfSound, Handle3D ); Context = this; }
public static unsafe SoundEffect DecodeVorbis(byte *start, byte *end, int expectedSampleCount, int loopStart, int loopLength) { int error; var vorbis = FAudio.stb_vorbis_open_memory((IntPtr)start, (int)(end - start), out error, IntPtr.Zero); Debug.Assert(vorbis != IntPtr.Zero); if (vorbis == IntPtr.Zero) { return(null); } var info = FAudio.stb_vorbis_get_info(vorbis); var audioDataFloat = new float[expectedSampleCount * info.channels]; // A cusory read of stb_vorbis suggests that it will never partially fill our buffer int readSamples = FAudio.stb_vorbis_get_samples_float_interleaved(vorbis, info.channels, audioDataFloat, audioDataFloat.Length); Debug.Assert(readSamples == expectedSampleCount); // <- If this fires, the package is corrupt somehow (in release builds, just silently fail) // Annoying conversion: var audioDataShort = new byte[readSamples * info.channels * 2]; // *2 for 16-bit audio // This is taken from stb_vorbis FAST_SCALED_FLOAT_TO_INT / copy_samples // (Because the FAudio version of stb_vorbis is compiled without an integer conversion, we'll do it ourselves) const int shift = 15; const float magic = (1.5f * (1 << (23 - shift)) + 0.5f / (1 << shift)); const int addend = (((150 - shift) << 23) + (1 << 22)); fixed(float *sourcePinned = audioDataFloat) { fixed(byte *destinationPinnedBytes = audioDataShort) { float *source = sourcePinned; short *destination = (short *)destinationPinnedBytes; int length = readSamples * info.channels; for (int i = 0; i < length; i++) { int temp; *(float *)&temp = source[i] + magic; temp -= addend; if ((uint)(temp + 32768) > 65535) // <- Clamp { temp = (temp < 0) ? -32768 : 32767; } destination[i] = (short)temp; } } } FAudio.stb_vorbis_close(vorbis); return(new SoundEffect(audioDataShort, 0, audioDataShort.Length, (int)info.sample_rate, (AudioChannels)info.channels, loopStart, loopLength)); }
internal void Play() { FAudio.stb_vorbis_seek_start(stbVorbisData); queueBuffer(); soundStream.BufferNeeded += BufferNeeded; soundStream.Play(); }
public void Stop(AudioStopOptions options) { FAudio.FACTCue_Stop( handle, (options == AudioStopOptions.Immediate) ? FAudio.FACT_FLAG_STOP_IMMEDIATE : FAudio.FACT_FLAG_STOP_RELEASE ); }
public static void Resume() { if (State != MediaState.Paused) { return; } FAudio.XNA_ResumeSong(); timer.Start(); State = MediaState.Playing; }
private static void PlaySong(Song song) { if (!initialized) { FAudio.XNA_SongInit(); initialized = true; } song.Duration = TimeSpan.FromSeconds(FAudio.XNA_PlaySong(song.handle)); timer.Start(); State = MediaState.Playing; }
public void SetVolume(float volume) { lock (parent.gcSync) { if (parent.IsDisposed) { return; } FAudio.FACTAudioEngine_SetVolume(parent.handle, index, volume); } }
public void Resume() { lock (parent.gcSync) { if (parent.IsDisposed) { return; } FAudio.FACTAudioEngine_Pause(parent.handle, index, 0); } }
public void Dispose() { if (ReverbVoice != IntPtr.Zero) { FAudio.FAudioVoice_DestroyVoice(ReverbVoice); ReverbVoice = IntPtr.Zero; Marshal.FreeHGlobal(reverbSends.pSends); } FAudio.FAudioVoice_DestroyVoice(MasterVoice); FAudio.FAudio_Release(Handle); Context = null; }
public static void Pause() { if (State != MediaState.Playing || Queue.ActiveSong == null) { return; } FAudio.XNA_PauseSong(); timer.Stop(); State = MediaState.Paused; }
public void Resume() { if (handle == IntPtr.Zero) { // XNA4 just plays if we've not started yet. Play(); } else if (State == SoundState.Paused) { FAudio.FAudioSourceVoice_Start(handle, 0, 0); INTERNAL_state = SoundState.Playing; } }
private unsafe void FillBuffer(object sender, EventArgs e) { int totalSamples = 0; if (vorbis != IntPtr.Zero) { fixed(float *audioBufferPinned = audioBuffer) { int previousSamples = -1; // <- Just silence if we cannot read anything even after seeking do { int samples = stb_vorbis_get_samples_float_interleaved(vorbis, channels, audioBufferPinned + totalSamples * channels, audioBuffer.Length - totalSamples * channels); Debug.Assert(samples >= 0); // <- stb_vorbis should never return negative samples! totalSamples += samples; if (samples == 0) { if (IsLooped && previousSamples != 0) { if (loopStart == 0) { FAudio.stb_vorbis_seek_start(vorbis); } else { FAudio.stb_vorbis_seek(vorbis, (uint)loopStart); } } else { break; } } previousSamples = samples; }while(totalSamples < bufferSamples); } } Debug.Assert(totalSamples <= bufferSamples); if (totalSamples < bufferSamples) { Array.Clear(audioBuffer, totalSamples * channels, audioBuffer.Length - totalSamples * channels); totalSamples = bufferSamples; } instance.SubmitFloatBufferEXT(audioBuffer, 0, totalSamples * channels); }
public static int PlaySound(string fileName, float volume = 1.0f) { if (volume * seBalance <= 0f) { return(0); } //don't play more than X sound effects in one frame if (soundIndex == playedSounds.Length) { return(0); } //don't play more than one instance of the same sound in one frame for (int ii = 0; ii < soundIndex; ii++) { if (fileName == playedSounds[ii]) { return(0); } } playedSounds[soundIndex] = fileName; soundIndex++; IntPtr stbVorbisData = FAudio.stb_vorbis_open_filename(fileName, out int error, IntPtr.Zero); FAudio.stb_vorbis_info fileInfo = FAudio.stb_vorbis_get_info(stbVorbisData); long total_samples = FAudio.stb_vorbis_stream_length_in_samples(stbVorbisData); long total_frames = total_samples * 60 / fileInfo.sample_rate; float[] chunk = new float[fileInfo.channels * total_samples]; int framesRead = FAudio.stb_vorbis_get_samples_float_interleaved(stbVorbisData, fileInfo.channels, chunk, fileInfo.channels * (int)total_samples); FAudio.stb_vorbis_close(stbVorbisData); DynamicSoundEffectInstance soundStream = new DynamicSoundEffectInstance( (int)fileInfo.sample_rate, (fileInfo.channels == 1) ? AudioChannels.Mono : AudioChannels.Stereo ); soundStream.Volume = volume * seBalance; soundStream.SubmitFloatBufferEXT(chunk, 0, framesRead * fileInfo.channels); soundStream.Play(); return((int)total_frames); }
public void Close() { if (instance != null) { instance.BufferNeeded -= FillBuffer; instance.Dispose(); instance = null; } if (vorbis != IntPtr.Zero) { FAudio.stb_vorbis_close(vorbis); } vorbis = IntPtr.Zero; }
public void PlayCue( string name, AudioListener listener, AudioEmitter emitter ) { if (String.IsNullOrEmpty(name)) { throw new ArgumentNullException("name"); } if (listener == null) { throw new ArgumentNullException("listener"); } if (emitter == null) { throw new ArgumentNullException("emitter"); } ushort cue = FAudio.FACTSoundBank_GetCueIndex( handle, name ); if (cue == FAudio.FACTINDEX_INVALID) { throw new InvalidOperationException( "Invalid cue name!" ); } emitter.emitterData.ChannelCount = dspSettings.SrcChannelCount; emitter.emitterData.CurveDistanceScaler = float.MaxValue; FAudio.FACT3DCalculate( engine.handle3D, ref listener.listenerData, ref emitter.emitterData, ref dspSettings ); FAudio.FACTSoundBank_Play3D( handle, cue, 0, 0, ref dspSettings, IntPtr.Zero ); }
internal void OnWaveBankDestroyed() { IsDisposed = true; if (buffer != null) { pin.Free(); buffer = null; } else if (ioStream != IntPtr.Zero) { FAudio.FAudio_close(ioStream); ioStream = IntPtr.Zero; } handle = IntPtr.Zero; selfReference = null; }