Esempio n. 1
0
File: Cue.cs Progetto: kiates/FNA
        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);
        }
Esempio n. 2
0
        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
                );
        }
Esempio n. 3
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;
        }
Esempio n. 4
0
        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
                );
        }
Esempio n. 5
0
        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));
        }
Esempio n. 6
0
        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
                );
        }
Esempio n. 7
0
            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);
            }
Esempio n. 8
0
        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;
        }
Esempio n. 9
0
        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);
                }
            }
        }
Esempio n. 10
0
        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);
            }
        }
Esempio n. 11
0
 public void Dispose()
 {
     if (stbVorbisData != IntPtr.Zero)
     {
         FAudio.stb_vorbis_close(stbVorbisData);
         stbVorbisData = IntPtr.Zero;
     }
 }
Esempio n. 12
0
 public static void GetVisualizationData(VisualizationData data)
 {
     FAudio.XNA_GetSongVisualizationData(
         data.freq,
         data.samp,
         VisualizationData.Size
         );
 }
Esempio n. 13
0
 internal static void DisposeIfNecessary()
 {
     if (initialized)
     {
         FAudio.XNA_SongQuit();
         initialized = false;
     }
 }
Esempio n. 14
0
 public void Pause()
 {
     if (handle != IntPtr.Zero && State == SoundState.Playing)
     {
         FAudio.FAudioSourceVoice_Stop(handle, 0, 0);
         INTERNAL_state = SoundState.Paused;
     }
 }
Esempio n. 15
0
            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;
            }
Esempio n. 16
0
        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));
        }
Esempio n. 17
0
        internal void Play()
        {
            FAudio.stb_vorbis_seek_start(stbVorbisData);

            queueBuffer();

            soundStream.BufferNeeded += BufferNeeded;
            soundStream.Play();
        }
Esempio n. 18
0
 public void Stop(AudioStopOptions options)
 {
     FAudio.FACTCue_Stop(
         handle,
         (options == AudioStopOptions.Immediate) ?
         FAudio.FACT_FLAG_STOP_IMMEDIATE :
         FAudio.FACT_FLAG_STOP_RELEASE
         );
 }
Esempio n. 19
0
        public static void Resume()
        {
            if (State != MediaState.Paused)
            {
                return;
            }

            FAudio.XNA_ResumeSong();
            timer.Start();
            State = MediaState.Playing;
        }
Esempio n. 20
0
 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;
 }
Esempio n. 21
0
 public void SetVolume(float volume)
 {
     lock (parent.gcSync)
     {
         if (parent.IsDisposed)
         {
             return;
         }
         FAudio.FACTAudioEngine_SetVolume(parent.handle, index, volume);
     }
 }
Esempio n. 22
0
 public void Resume()
 {
     lock (parent.gcSync)
     {
         if (parent.IsDisposed)
         {
             return;
         }
         FAudio.FACTAudioEngine_Pause(parent.handle, index, 0);
     }
 }
Esempio n. 23
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;
 }
Esempio n. 24
0
        public static void Pause()
        {
            if (State != MediaState.Playing || Queue.ActiveSong == null)
            {
                return;
            }

            FAudio.XNA_PauseSong();
            timer.Stop();

            State = MediaState.Paused;
        }
Esempio n. 25
0
 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;
     }
 }
Esempio n. 26
0
        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);
        }
Esempio n. 27
0
        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);
        }
Esempio n. 28
0
        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;
        }
Esempio n. 29
0
        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
                );
        }
Esempio n. 30
0
 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;
 }