Esempio n. 1
0
        /// <summary>
        /// Pans a sound.
        /// This method was initially written using the guide at https://docs.microsoft.com/en-us/windows/win32/xaudio2/how-to--pan-a-sound
        /// The code has finally been improved thanks to the MonoGame framework code: https://github.com/MonoGame/MonoGame
        /// </summary>
        /// <param name="sound">The sound to pan.</param>
        /// <param name="pan">The value by which to pan the sound. -1.0f is completely left, and 1.0f is completely right. 0.0f is center.</param>
        public static void setPan(ExtendedAudioBuffer sound, float pan)
        {
            SpeakerConfiguration mask;

            if (mainSoundDevice.Version == XAudio2Version.Version27)
            {
                WaveFormatExtensible deviceFormat = mainSoundDevice.GetDeviceDetails(0).OutputFormat;
                mask = (SpeakerConfiguration)deviceFormat.ChannelMask;
            }
            else
            {
                mask = (SpeakerConfiguration)mainMasteringVoice.ChannelMask;
            }
            VoiceDetails soundDetails     = sound.getVoiceDetails();
            VoiceDetails masteringDetails = mainMasteringVoice.VoiceDetails;
            int          srcChannelCount  = soundDetails.InputChannelCount;
            int          dstChannelCount  = masteringDetails.InputChannelCount;

            // Create an array to hold the output matrix. Warning : the minimum size of the output matrix is the number of channels in the source voice times the number of channels in the output voice.
            // Note that the outputMatrix indices are placed in the same order as the SharpDX.Multimedia.Speakers enum.
            // Don't forget there are two times more cells in the matrix if the source sound is stereo)
            float[] outputMatrix = new float[srcChannelCount * dstChannelCount];
            Array.Clear(outputMatrix, 0, outputMatrix.Length);
            // From there, we'll hope that the sound file is either mono or stereo. If the WAV had more than 2 channels, it would be to difficult to handle.
            // Similarly, we'll also only output to the front-left and front-right speakers for simplicity, e.g. like the XNA framework does.
            if (srcChannelCount == 1)             // Mono source
            {
                // Left/Right output levels:
                //   Pan -1.0: L = 1.0, R = 0.0
                //   Pan  0.0: L = 1.0, R = 1.0
                //   Pan +1.0: L = 0.0, R = 1.0
                outputMatrix[0] = (pan > 0f) ? ((1f - pan)) : 1f; // Front-left output
                outputMatrix[1] = (pan < 0f) ? ((1f + pan)) : 1f; // Front-right output
            }
            else if (srcChannelCount == 2)                        // Stereo source
            {
                // Left/Right input (Li/Ri) mix for Left/Right outputs (Lo/Ro):
                //   Pan -1.0: Lo = 0.5Li + 0.5Ri, Ro = 0.0Li + 0.0Ri
                //   Pan  0.0: Lo = 1.0Li + 0.0Ri, Ro = 0.0Li + 1.0Ri
                //   Pan +1.0: Lo = 0.0Li + 0.0Ri, Ro = 0.5Li + 0.5Ri
                if (pan <= 0f)
                {
                    outputMatrix[0] = 1f + pan * 0.5f;        // Front-left output, Left input
                    outputMatrix[1] = -pan * 0.5f;            // Front-left output, Right input
                    outputMatrix[2] = 0f;                     // Front-right output, Left input
                    outputMatrix[3] = 1f + pan;               // Front-right output, Right input
                }
                else
                {
                    outputMatrix[0] = 1f - pan;               // Front-left output, Left input
                    outputMatrix[1] = 0f;                     // Front-left output, Right input
                    outputMatrix[2] = pan * 0.5f;             // Front-right output, Left input
                    outputMatrix[3] = 1f - pan * 0.5f;        // Front-right output, Right input
                }
            }
            sound.setOutputMatrix(soundDetails.InputChannelCount, masteringDetails.InputChannelCount, outputMatrix);
        }
Esempio n. 2
0
 public static void unloadSound(ref ExtendedAudioBuffer sound)
 {
     if (sound == null)
     {
         return;
     }
     sound.stop();
     sound.Dispose();
     sound = null;
 }
Esempio n. 3
0
        /// <summary>
        ///  Loads and plays the specified wave file, and disposes it after it is done playing.
        /// </summary>
        /// <param name="fn">The name of the file to play.</param>
        public static void playAndWait(String fn)
        {
            ExtendedAudioBuffer s = LoadSound(fn);

            PlaySound(s, true, false);
            while (isPlaying(s))
            {
                Thread.Sleep(100);
            }
            s.Dispose();
            s = null;
        }
Esempio n. 4
0
        /// <summary>
        /// Pans a sound.
        /// This method was written using the guide at https://docs.microsoft.com/en-us/windows/win32/xaudio2/how-to--pan-a-sound
        /// </summary>
        /// <param name="sound">The sound to pan.</param>
        /// <param name="pan">The value by which to pan the sound. -1.0f is completely left, and 1.0f is completely right. 0.0f is center.</param>
        public static void setPan(ExtendedAudioBuffer sound, float pan)
        {
            SpeakerConfiguration mask = (SpeakerConfiguration)mainMasteringVoice.ChannelMask;

            float[] outputMatrix = new float[8];
            float   left         = 0.5f - pan / 2;
            float   right        = 0.5f + pan / 2;

            switch (mask)
            {
            case SpeakerConfiguration.mono:
                outputMatrix[0] = 1.0f;
                break;

            case SpeakerConfiguration.stereo:
            case SpeakerConfiguration.twoPointOne:
            case SpeakerConfiguration.surround:
                outputMatrix[0] = left;
                outputMatrix[1] = right;
                break;

            case SpeakerConfiguration.quad:
                outputMatrix[0] = outputMatrix[2] = left;
                outputMatrix[1] = outputMatrix[3] = right;
                break;

            case SpeakerConfiguration.fourPointOne:
                outputMatrix[0] = outputMatrix[3] = left;
                outputMatrix[1] = outputMatrix[4] = right;
                break;

            case SpeakerConfiguration.fivePointOne:
            case SpeakerConfiguration.sevenPointOne:
            case SpeakerConfiguration.fivePointOneSurround:
                outputMatrix[0] = outputMatrix[4] = left;
                outputMatrix[1] = outputMatrix[5] = right;
                break;

            case SpeakerConfiguration.sevenPointOneSurround:
                outputMatrix[0] = outputMatrix[4] = outputMatrix[6] = left;
                outputMatrix[1] = outputMatrix[5] = outputMatrix[7] = right;
                break;
            }
            VoiceDetails soundDetails     = sound.getVoiceDetails();
            VoiceDetails masteringDetails = mainMasteringVoice.VoiceDetails;

            sound.setOutputMatrix(soundDetails.InputChannelCount, masteringDetails.InputChannelCount, outputMatrix);
        }
Esempio n. 5
0
        /// <summary>
        /// Positions a sound in 3-D space
        /// </summary>
        /// <param name="sound">The ExtendedAudioBuffer to play.</param>
        /// <param name="stop">If true, will stop the sound and return its position to 0 before playing it. Passing false will have the effect of resuming the sound from the last position it was stopped at.</param>
        /// <param name="loop">Whether or not to loop the sound.</param>
        /// <param name="x">The x coordinate of the source.</param>
        /// <param name="y">The y coordinate of the source.</param>
        /// <param name="z">The z coordinate of the source.</param>
        /// <param name="vx">The x component of the velocity vector.</param>
        /// <param name="vy">The y component of the velocity  vector.</param>
        /// <param name="vz">The z component of the velocity vector.</param>
        /// <param name="flags">The 3D flags to calculate. The default will calculate volume and doppler shift. This parameter is useful if it is not desirable for XAudio2 to calculate doppler on sounds that modify their own frequencies as an example; in this case, the flags should omit doppler.</param>
        public static void PlaySound3d(ExtendedAudioBuffer sound, bool stop, bool loop, float x, float y, float z, float vx = 0, float vy = 0, float vz = 0, CalculateFlags flags = CalculateFlags.Matrix | CalculateFlags.Doppler)
        {
            Emitter emitter = new Emitter {
                ChannelCount        = 1,
                CurveDistanceScaler = 1.0f,
                OrientFront         = new Vector3(0, 0, 1),
                OrientTop           = new Vector3(0, 1, 0),
                Position            = new Vector3(x, y, z),
                Velocity            = new Vector3(vx, vy, vz)
            };

            sound.play(stop, loop);
            DspSettings dspSettings = x3DAudio.Calculate(listener, emitter, flags, sound.getVoiceDetails().InputChannelCount, mainMasteringVoice.VoiceDetails.InputChannelCount);

            sound.apply3D(dspSettings, sound.getVoiceDetails().InputChannelCount, mainMasteringVoice.VoiceDetails.InputChannelCount, flags);
        }
Esempio n. 6
0
 /// <summary>
 ///  Checks to see if a sound is playing.
 /// </summary>
 /// <param name="s">The sound to check</param>
 /// <returns>True if the sound is playing, false otherwise</returns>
 public static bool isPlaying(ExtendedAudioBuffer s)
 {
     return(s.state == ExtendedAudioBuffer.State.playing);
 }
Esempio n. 7
0
 /// <summary>
 /// Plays a sound.
 /// </summary>
 /// <param name="sound">The ExtendedAudioBuffer to play.</param>
 /// <param name="stop">If true, will stop the sound and return its position to 0 before playing it. Passing false will have the effect of resuming the sound from the last position it was stopped at.</param>
 /// <param name="loop">Whether or not to loop the sound.</param>
 public static void PlaySound(ExtendedAudioBuffer sound, bool stop, bool loop)
 {
     sound.play(stop, loop);
 }