예제 #1
0
        internal MyInMemoryWave GetRandomWave(MySoundData cue, MySoundDimensions type, out int waveNumber, out CuePart part, int tryIgnoreWaveNumber = -1)
        {
            int counter = 0;

            foreach (var w in cue.Waves)
            {
                if (w.Type == type)
                {
                    counter++;
                }
            }
            waveNumber = MyUtils.GetRandomInt(counter);
            if (counter > 2 && waveNumber == tryIgnoreWaveNumber)
            {
                waveNumber = (waveNumber + 1) % (counter);                      // TODO: Do this better
            }
            var wave = GetWave(cue, type, waveNumber, CuePart.Start);

            if (wave != null)
            {
                part = CuePart.Start;
            }
            else
            {
                wave = GetWave(cue, type, waveNumber, CuePart.Loop);
                part = CuePart.Loop;
            }
            return(wave);
        }
예제 #2
0
        internal MyInMemoryWave GetWave(MySoundData cue, MySoundDimensions dim, int waveNumber, CuePart cuePart)
        {
            if (m_waveBank == null)
            {
                return(null);
            }
            foreach (var wave in cue.Waves)
            {
                if (wave.Type == dim)
                {
                    if (waveNumber == 0)
                    {
                        switch (cuePart)
                        {
                        case CuePart.Start:
                            return(m_waveBank.GetWave(wave.Start));

                        case CuePart.Loop:
                            return(m_waveBank.GetWave(wave.Loop));

                        case CuePart.End:
                            return(m_waveBank.GetWave(wave.End));
                        }
                    }
                    waveNumber--;
                }
            }
            return(null);
        }
예제 #3
0
        private void UpdatePlayback()
        {
            var now            = MySandboxGame.Static.UpdateTime;
            var speakerFadeout = MyEngineConstants.UPDATE_STEP_SIZE_IN_SECONDS * 60 * 1000;

            m_keys.AddRange(m_receivedVoiceData.Keys);
            foreach (var id in m_keys)
            {
                bool              update      = false;
                var               playerId    = id;
                var               data        = m_receivedVoiceData[id];
                var               player      = Sync.Players.TryGetPlayerById(new MyPlayer.PlayerId(playerId));
                float             maxDistance = 0;
                MySoundDimensions dimension   = MySoundDimensions.D2;
                if (data.Timestamp != MyTimeSpan.Zero && m_voiceChatLogic.ShouldPlayVoice(player, data.Timestamp, out dimension, out maxDistance))
                {
                    PlayVoice(data.UncompressedBuffer.ToArray(), data.UncompressedBuffer.Count, playerId, dimension, maxDistance);
                    data.ClearData();
                    update = true;
                }

                if (data.SpeakerTimestamp != MyTimeSpan.Zero && (now - data.SpeakerTimestamp).Miliseconds > speakerFadeout)
                {
                    data.ClearSpeakerTimestamp();
                    update = true;
                }

                if (update)
                {
                    m_receivedVoiceData[id] = data;
                }
            }
            m_keys.Clear();
        }
예제 #4
0
        internal MyInMemoryWave GetRandomWave(MySoundData cue, MySoundDimensions type, out int waveNumber, out CuePart part)
        {
            int counter = 0;

            foreach (var w in cue.Waves)
            {
                if (w.Type == type)
                {
                    counter++;
                }
            }
            waveNumber = MyUtils.GetRandomInt(counter);
            var wave = GetWave(cue, type, waveNumber, CuePart.Start);

            if (wave != null)
            {
                part = CuePart.Start;
            }
            else
            {
                wave = GetWave(cue, type, waveNumber, CuePart.Loop);
                part = CuePart.Loop;
            }
            return(wave);
        }
        private void UpdatePlayback()
        {
            var now            = MySandboxGame.Static.UpdateTime;
            var speakerFadeout = VRage.Game.MyEngineConstants.UPDATE_STEP_SIZE_IN_SECONDS * 60 * 1000;

            m_keys.AddRange(m_receivedVoiceData.Keys);
            foreach (var id in m_keys)
            {
                bool              update      = false;
                var               playerId    = id;
                var               data        = m_receivedVoiceData[id];
                var               player      = Sync.Players.GetPlayerById(new MyPlayer.PlayerId(playerId));
                float             maxDistance = 0;
                MySoundDimensions dimension   = MySoundDimensions.D2;
                if (data.Timestamp != MyTimeSpan.Zero &&
                    m_voiceChatLogic.ShouldPlayVoice(player, data.Timestamp, out dimension, out maxDistance))
                {
                    if (!MySandboxGame.Config.MutedPlayers.Contains(player.Id.SteamId))
                    {
                        PlayVoice(data.UncompressedBuffer.ToArray(), data.UncompressedBuffer.Count, playerId, dimension, maxDistance);
                        data.ClearData();
                        update = true;
                    }
                    else
                    {
                        // this player should be muted - send him a mute message
                        if (lastMessageTime == 0 || System.Environment.TickCount > lastMessageTime + 5000) // sending of mute messages is diluted
                        {
                            MutePlayerRequest(player.Id.SteamId, true);
                            lastMessageTime = System.Environment.TickCount;
                        }
                    }
                }

                if (data.SpeakerTimestamp != MyTimeSpan.Zero && (now - data.SpeakerTimestamp).Miliseconds > speakerFadeout)
                {
                    data.ClearSpeakerTimestamp();
                    update = true;
                }

                if (update)
                {
                    m_receivedVoiceData[id] = data;
                }
            }
            m_keys.Clear();
        }
        public bool ShouldPlayVoice(MyPlayer player, MyTimeSpan timestamp, out MySoundDimensions dimension, out float maxDistance)
        {
            MyTimeSpan now             = MySandboxGame.Static.UpdateTime;
            double     startPlaybackMs = VRage.Game.MyEngineConstants.UPDATE_STEP_SIZE_IN_SECONDS * 30 * 1000;

            if ((now - timestamp).Milliseconds > startPlaybackMs)
            {
                dimension   = MySoundDimensions.D3;
                maxDistance = float.MaxValue;
                return(true);
            }
            else
            {
                dimension   = MySoundDimensions.D2;
                maxDistance = 0;
                return(false);
            }
        }
예제 #7
0
        internal MySourceVoice GetSound(MyCueId cueId, out int waveNumber, IMy3DSoundEmitter source = null, MySoundDimensions type = MySoundDimensions.D2)
        {
			waveNumber = -1;
            //  If this computer can't play sound, we don't create cues
            if (cueId.Hash == MyStringHash.NullOrEmpty || !m_canPlay || m_cueBank == null)
                return null;

            //  If this is one-time cue, we check if it is close enough to hear it and if not, we don't even play - this is for optimization only.
            //  We must add loopable cues always, because if source of cue comes near the camera, we need to update the position, but of course we can do that only if we have reference to it.
            MySoundData cue = m_cueBank.GetCue(cueId);

            if ((SoloCue != null) && (SoloCue != cue))
                return null;

			int waveNumberToIgnore = (source != null ? source.LastPlayedWaveNumber : -1);
			var sound = m_cueBank.GetVoice(cueId, out waveNumber, type, waveNumberToIgnore);
            var originalType = type;
            if (sound == null && source != null && source.Force3D)
            {
                originalType = type == MySoundDimensions.D3 ? MySoundDimensions.D2 : MySoundDimensions.D3;
                sound = m_cueBank.GetVoice(cueId, out waveNumber, originalType, waveNumberToIgnore);
            }
            if (sound == null)
                return null;

            float volume = cue.Volume;
            if (source != null && source.CustomVolume.HasValue)
                volume = source.CustomVolume.Value;
            if (cue.VolumeVariation != 0f)
            {
                float variation = VolumeVariation(cue);
                volume = MathHelper.Clamp(volume + variation, 0f, 1f);
            }       
            sound.SetVolume(volume);
            var wave = m_cueBank.GetWave(m_sounds.ItemAt(0), MySoundDimensions.D2, 0, MyCueBank.CuePart.Start);

            float semitones = cue.Pitch;
            if (cue.PitchVariation != 0f)
                semitones += PitchVariation(cue);
            if (cue.DisablePitchEffects)
                semitones = 0f;
            if(semitones != 0f)
                sound.FrequencyRatio = SemitonesToFrequencyRatio(semitones);
            else
                sound.FrequencyRatio = 1f;

            if (cue.IsHudCue)
                sound.Voice.SetOutputVoices(m_hudAudioVoiceDesc);
            else
                sound.Voice.SetOutputVoices(m_gameAudioVoiceDesc);

            if (type == MySoundDimensions.D3)
            {
                m_helperEmitter.UpdateValuesOmni(source.SourcePosition, source.Velocity, cue, m_deviceDetails.OutputFormat.Channels, source.CustomMaxDistance);
                float maxDistance = source.CustomMaxDistance.HasValue ? source.CustomMaxDistance.Value : cue.MaxDistance;

                source.SourceChannels = 1;
                if (originalType == MySoundDimensions.D2)
                    source.SourceChannels = 2;
                sound.distanceToListener = m_x3dAudio.Apply3D(sound.Voice, m_listener, m_helperEmitter, source.SourceChannels, m_deviceDetails.OutputFormat.Channels, m_calculateFlags, maxDistance, sound.FrequencyRatio, sound.Silent, source.Realistic);

                Update3DCuesState();

                // why was this only for loops?
                //if (sound.IsLoopable)
                Add3DCueToUpdateList(source);

                ++m_soundInstancesTotal3D;
            }
            else
            {
                if (m_3Dsounds.Contains(source))
                    StopUpdating3DCue(source);
                ++m_soundInstancesTotal2D;
            }
            return sound;
        }
예제 #8
0
        IMySourceVoice IMyAudio.GetSound(IMy3DSoundEmitter source, int sampleRate, int channels, MySoundDimensions dimension)
        {
            if (!m_canPlay)
            {
                return(null);
            }

            var waveFormat = new WaveFormat(sampleRate, channels);

            source.SourceChannels = channels;
            var sourceVoice = new MySourceVoice(m_audioEngine, waveFormat);

            float volume      = source.CustomVolume.HasValue ? source.CustomVolume.Value : 1;
            float maxDistance = source.CustomMaxDistance.HasValue ? source.CustomMaxDistance.Value : 0;

            sourceVoice.SetVolume(volume);

            if (dimension == MySoundDimensions.D3)
            {
                m_helperEmitter.UpdateValuesOmni(source.SourcePosition, source.Velocity, maxDistance, m_deviceDetails.OutputFormat.Channels, MyCurveType.Linear);
                m_x3dAudio.Apply3D(sourceVoice.Voice, m_listener, m_helperEmitter, source.SourceChannels, m_deviceDetails.OutputFormat.Channels, m_calculateFlags, maxDistance, sourceVoice.FrequencyRatio);
                Update3DCuesState();
                Add3DCueToUpdateList(source);

                ++m_soundInstancesTotal3D;
            }

            return(sourceVoice);
        }
예제 #9
0
 IMySourceVoice IMyAudio.GetSound(MyStringId cueId, IMy3DSoundEmitter source, MySoundDimensions type)
 {
     return GetSound(cueId, source, type);
 }
예제 #10
0
 IMySourceVoice IMyAudio.GetSound(IMy3DSoundEmitter source, int sampleRate, int channels, MySoundDimensions dimension)
 {
     return(null);
 }
예제 #11
0
 IMySourceVoice IMyAudio.PlaySound(MyCueId cue, IMy3DSoundEmitter source, MySoundDimensions type, bool skipIntro, bool skipToEnd)
 {
     return(null);
 }
예제 #12
0
 IMySourceVoice IMyAudio.GetSound(MyCueId cue, IMy3DSoundEmitter source, MySoundDimensions type) { return null; }
예제 #13
0
 public bool ShouldPlayVoice(MyPlayer player, MyTimeSpan timestamp, out MySoundDimensions dimension, out float maxDistance)
 {
     dimension = MySoundDimensions.D2;
     maxDistance = 0;
     return false;
 }
예제 #14
0
        public MyInMemoryWave GetStreamedWave(string filename, MySoundData cue, MySoundDimensions dim = MySoundDimensions.D2)
        {
            if (string.IsNullOrEmpty(filename))
                return null;

            SharpDX.Multimedia.WaveFormatEncoding encoding = SharpDX.Multimedia.WaveFormatEncoding.Unknown;
            var fsPath = Path.IsPathRooted(filename) ? filename : Path.Combine(MyFileSystem.ContentPath, "Audio", filename);
            var exists = MyFileSystem.FileExists(fsPath);
            if (exists)
            {
                try
                {
                    MyInMemoryWave wave;
                    if (!LoadedStreamedWaves.TryGetValue(fsPath, out wave))
                        wave = LoadedStreamedWaves[fsPath] = new MyInMemoryWave(cue, fsPath, this, true);
                    else
                        wave.Reference();

                    // check the formats
                    if (encoding == SharpDX.Multimedia.WaveFormatEncoding.Unknown)
                    {
                        encoding = wave.WaveFormat.Encoding;
                    }

                    // check the formats
                    if (wave.WaveFormat.Encoding == SharpDX.Multimedia.WaveFormatEncoding.Unknown)
                    {
                        if (MyAudio.OnSoundError != null)
                        {
                            var msg = string.Format("Unknown audio encoding '{0}', '{1}'", cue.SubtypeId.ToString(), filename);
                            MyAudio.OnSoundError(cue, msg);
                        }
                        return null;
                    }

                    // 3D sounds must be mono
                    if (dim == MySoundDimensions.D3 && wave.WaveFormat.Channels != 1)
                    {
                        if (MyAudio.OnSoundError != null)
                        {
                            var msg = string.Format("3D sound '{0}', '{1}' must be in mono, got {2} channels", cue.SubtypeId.ToString(), filename, wave.WaveFormat.Channels);
                            MyAudio.OnSoundError(cue, msg);
                        }
                        return null;
                    }

                    // all parts of the sound must have the same encoding
                    if (wave.WaveFormat.Encoding != encoding)
                    {
                        if (MyAudio.OnSoundError != null)
                        {
                            var msg = string.Format("Inconsistent sound encoding in '{0}', '{1}', got '{2}', expected '{3}'", cue.SubtypeId.ToString(), filename, wave.WaveFormat.Encoding, encoding);
                            MyAudio.OnSoundError(cue, msg);
                        }
                        return null;
                    }

                    return wave;
                }
                catch (Exception e)
                {
                    if (MyAudio.OnSoundError != null)
                    {
                        var msg = string.Format("Unable to load audio file: '{0}', '{1}': {2}", cue.SubtypeId.ToString(), filename, e.ToString());
                        MyAudio.OnSoundError(cue, msg);
                    }
                    return null;
                }
            }
            else
            {
                if (MyAudio.OnSoundError != null)
                {
                    var msg = string.Format("Unable to find audio file: '{0}', '{1}'", cue.SubtypeId.ToString(), filename);
                    MyAudio.OnSoundError(cue, msg);
                }
            }
            return null;
        }
예제 #15
0
        internal MySourceVoice GetVoice(MyStringId hashedCue, MySoundDimensions type = MySoundDimensions.D2)
        {
            MySoundData cue = GetCue(hashedCue);

            if ((cue == null) || (cue.Waves == null) || (cue.Waves.Count == 0))
            {
                return(null);
            }

            int            waveNumber;
            CuePart        part;
            MyInMemoryWave wave = GetRandomWave(cue, type, out waveNumber, out part);

            if (wave == null && type == MySoundDimensions.D2)
            {
                type = MySoundDimensions.D3;
                wave = GetRandomWave(cue, type, out waveNumber, out part);
            }
            if (wave == null)
            {
                return(null);
            }

            MySourceVoice voice = GetVoice(hashedCue, wave, part);

            if (voice == null)
            {
                return(null);
            }

            if (cue.Loopable)
            {
                wave = GetWave(cue, type, waveNumber, CuePart.Loop);
                if (wave != null)
                {
                    Debug.Assert(voice.Owner.WaveFormat.Encoding == wave.WaveFormat.Encoding);
                    if (voice.Owner.WaveFormat.Encoding == wave.WaveFormat.Encoding)
                    {
                        voice.SubmitSourceBuffer(hashedCue, wave, CuePart.Loop);
                    }
                    else
                    {
                        MyLog.Default.WriteLine(string.Format("Inconsistent encodings: '{0}', got '{1}', expected '{2}', part = '{3}'", hashedCue, wave.WaveFormat.Encoding, voice.Owner.WaveFormat.Encoding, CuePart.Loop));
                    }
                }
                wave = GetWave(cue, type, waveNumber, CuePart.End);
                if (wave != null)
                {
                    Debug.Assert(voice.Owner.WaveFormat.Encoding == wave.WaveFormat.Encoding);
                    if (voice.Owner.WaveFormat.Encoding == wave.WaveFormat.Encoding)
                    {
                        voice.SubmitSourceBuffer(hashedCue, wave, CuePart.End);
                    }
                    else
                    {
                        MyLog.Default.WriteLine(string.Format("Inconsistent encodings: '{0}', got '{1}', expected '{2}', part = '{3}'", hashedCue, wave.WaveFormat.Encoding, voice.Owner.WaveFormat.Encoding, CuePart.End));
                    }
                }
            }
            return(voice);
        }
예제 #16
0
        IMySourceVoice IMyAudio.GetSound(MyCueId cueId, IMy3DSoundEmitter source, MySoundDimensions type)
        {
			int waveNumber;
            return GetSound(cueId, out waveNumber, source, type);
        }
        private void PlayVoice(byte[] uncompressedBuffer, int uncompressedSize, ulong playerId, MySoundDimensions dimension, float maxDistance)
        {
            if (!m_voices.ContainsKey(playerId))
            {
                var player = Sync.Players.GetPlayerById(new MyPlayer.PlayerId(playerId));
                m_voices[playerId] = new MyEntity3DSoundEmitter(player.Character);
            }

            //Debug.Assert(uncompressedSize != 0, "Playing empty buffer");
            var emitter = m_voices[playerId];
            emitter.PlaySound(uncompressedBuffer, (int)uncompressedSize, m_VoIP.SampleRate, volume: MyAudio.Static.VolumeVoiceChat, maxDistance: maxDistance, dimension: dimension);
        }
예제 #18
0
 public bool ShouldPlayVoice(MyPlayer player, MyTimeSpan timestamp, out MySoundDimensions dimension, out float maxDistance)
 {
     dimension   = MySoundDimensions.D2;
     maxDistance = 0;
     return(false);
 }
 public void PlaySound(byte[] buffer, int size, int sampleRate, float volume = 1, float maxDistance = 0, MySoundDimensions dimension = MySoundDimensions.D3)
 {
     CustomMaxDistance = maxDistance;
     CustomVolume = volume;
     if (Sound == null)
         Sound = MyAudio.Static.GetSound(this, sampleRate, 1, dimension);
     if (Sound != null)
     {
         Sound.SubmitBuffer(buffer, size);
         if (!Sound.IsPlaying)
             Sound.StartBuffered();
     }
 }
예제 #20
0
 IMySourceVoice IMyAudio.GetSound(IMy3DSoundEmitter source, int sampleRate, int channels, MySoundDimensions dimension) { return null; }
예제 #21
0
        public MyInMemoryWave GetStreamedWave(string filename, MySoundData cue, MySoundDimensions dim = MySoundDimensions.D2)
        {
            if (string.IsNullOrEmpty(filename))
            {
                return(null);
            }

            SharpDX.Multimedia.WaveFormatEncoding encoding = SharpDX.Multimedia.WaveFormatEncoding.Unknown;
            var fsPath = Path.IsPathRooted(filename) ? filename : Path.Combine(MyFileSystem.ContentPath, "Audio", filename);
            var exists = MyFileSystem.FileExists(fsPath);

            if (exists)
            {
                try
                {
                    MyInMemoryWave wave;
                    if (!LoadedStreamedWaves.TryGetValue(fsPath, out wave))
                    {
                        wave = LoadedStreamedWaves[fsPath] = new MyInMemoryWave(cue, fsPath, this, true);
                    }
                    else
                    {
                        wave.Reference();
                    }

                    // check the formats
                    if (encoding == SharpDX.Multimedia.WaveFormatEncoding.Unknown)
                    {
                        encoding = wave.WaveFormat.Encoding;
                    }

                    // check the formats
                    if (wave.WaveFormat.Encoding == SharpDX.Multimedia.WaveFormatEncoding.Unknown)
                    {
                        if (MyAudio.OnSoundError != null)
                        {
                            var msg = string.Format("Unknown audio encoding '{0}', '{1}'", cue.SubtypeId.ToString(), filename);
                            MyAudio.OnSoundError(cue, msg);
                        }
                        return(null);
                    }

                    // 3D sounds must be mono
                    if (dim == MySoundDimensions.D3 && wave.WaveFormat.Channels != 1)
                    {
                        if (MyAudio.OnSoundError != null)
                        {
                            var msg = string.Format("3D sound '{0}', '{1}' must be in mono, got {2} channels", cue.SubtypeId.ToString(), filename, wave.WaveFormat.Channels);
                            MyAudio.OnSoundError(cue, msg);
                        }
                        return(null);
                    }

                    // all parts of the sound must have the same encoding
                    if (wave.WaveFormat.Encoding != encoding)
                    {
                        if (MyAudio.OnSoundError != null)
                        {
                            var msg = string.Format("Inconsistent sound encoding in '{0}', '{1}', got '{2}', expected '{3}'", cue.SubtypeId.ToString(), filename, wave.WaveFormat.Encoding, encoding);
                            MyAudio.OnSoundError(cue, msg);
                        }
                        return(null);
                    }

                    return(wave);
                }
                catch (Exception e)
                {
                    if (MyAudio.OnSoundError != null)
                    {
                        var msg = string.Format("Unable to load audio file: '{0}', '{1}': {2}", cue.SubtypeId.ToString(), filename, e.ToString());
                        MyAudio.OnSoundError(cue, msg);
                    }
                    return(null);
                }
            }
            else
            {
                if (MyAudio.OnSoundError != null)
                {
                    var msg = string.Format("Unable to find audio file: '{0}', '{1}'", cue.SubtypeId.ToString(), filename);
                    MyAudio.OnSoundError(cue, msg);
                }
            }
            return(null);
        }
예제 #22
0
 IMySourceVoice IMyAudio.GetSound(MyCueId cue, IMy3DSoundEmitter source, MySoundDimensions type)
 {
     return(null);
 }
예제 #23
0
        internal MySourceVoice PlaySound(MyStringId cueId, IMy3DSoundEmitter source = null, MySoundDimensions type = MySoundDimensions.D2, bool skipIntro = false, bool skipToEnd = false)
        {
            var sound = GetSound(cueId, source, type);

            if (sound != null)
            {
                sound.Start(skipIntro, skipToEnd);
            }
            return(sound);
        }
        private void PlayVoice(byte[] uncompressedBuffer, int uncompressedSize, ulong playerId, MySoundDimensions dimension, float maxDistance)
        {
            if (!m_voices.ContainsKey(playerId))
            {
                var player = Sync.Players.GetPlayerById(new MyPlayer.PlayerId(playerId));
                m_voices[playerId] = new MyEntity3DSoundEmitter(player.Character);
            }

            //Debug.Assert(uncompressedSize != 0, "Playing empty buffer");
            var emitter = m_voices[playerId];

            emitter.PlaySound(uncompressedBuffer, (int)uncompressedSize, m_VoIP.SampleRate, volume: MyAudio.Static.VolumeVoiceChat, maxDistance: maxDistance, dimension: dimension);
        }
예제 #25
0
 IMySourceVoice IMyAudio.PlaySound(MyStringId cueId, IMy3DSoundEmitter source, MySoundDimensions type, bool skipIntro, bool skipToEnd)
 {
     return(PlaySound(cueId, source, type, skipIntro, skipToEnd));
 }
예제 #26
0
 public void PlaySound(byte[] buffer, int size, int sampleRate, float volume = 1, float maxDistance = 0, MySoundDimensions dimension = MySoundDimensions.D3)
 {
     CustomMaxDistance = maxDistance;
     CustomVolume      = volume;
     if (Sound == null)
     {
         Sound = MyAudio.Static.GetSound(this, sampleRate, 1, dimension);
     }
     if (Sound != null)
     {
         Sound.SubmitBuffer(buffer, size);
         if (!Sound.IsPlaying)
         {
             Sound.StartBuffered();
         }
     }
 }
예제 #27
0
 internal MySourceVoice PlaySound(MyStringId cueId, IMy3DSoundEmitter source = null, MySoundDimensions type = MySoundDimensions.D2, bool skipIntro = false, bool skipToEnd = false)
 {
     var sound = GetSound(cueId, source, type);
     if(sound != null)
         sound.Start(skipIntro, skipToEnd);
     return sound;
 }
예제 #28
0
        internal MySourceVoice GetSound(MyStringId cueId, IMy3DSoundEmitter source = null, MySoundDimensions type = MySoundDimensions.D2)
        {
            //  If this computer can't play sound, we don't create cues
            if (cueId == MyStringId.NullOrEmpty || !m_canPlay || m_cueBank == null)
            {
                return(null);
            }

            //  If this is one-time cue, we check if it is close enough to hear it and if not, we don't even play - this is for optimization only.
            //  We must add loopable cues always, because if source of cue comes near the camera, we need to update the position, but of course we can do that only if we have reference to it.
            MySoundData cue = m_cueBank.GetCue(cueId);

            if ((SoloCue != null) && (SoloCue != cue))
            {
                return(null);
            }

            var sound        = m_cueBank.GetVoice(cueId, type);
            var originalType = type;

            if (sound == null && source != null && source.Force3D)
            {
                originalType = type == MySoundDimensions.D3 ? MySoundDimensions.D2 : MySoundDimensions.D3;
                sound        = m_cueBank.GetVoice(cueId, originalType);
            }
            if (sound == null)
            {
                return(null);
            }

            float volume = cue.Volume;

            if (source != null && source.CustomVolume.HasValue)
            {
                volume = source.CustomVolume.Value;
            }
            if (cue.VolumeVariation != 0f)
            {
                float variation = VolumeVariation(cue);
                volume = MathHelper.Clamp(volume + variation, 0f, 1f);
            }
            sound.SetVolume(volume);
            var wave = m_cueBank.GetWave(m_sounds.ItemAt(0), MySoundDimensions.D2, 0, MyCueBank.CuePart.Start);

            if (cue.PitchVariation != 0f)
            {
                float semitones = PitchVariation(cue);
                sound.FrequencyRatio = SemitonesToFrequencyRatio(semitones);
            }
            else
            {
                sound.FrequencyRatio = 1f;
            }

            if (cue.IsHudCue)
            {
                sound.Voice.SetOutputVoices(m_hudAudioVoiceDesc);
            }
            else
            {
                sound.Voice.SetOutputVoices(m_gameAudioVoiceDesc);
            }

            if (type == MySoundDimensions.D3)
            {
                m_helperEmitter.UpdateValuesOmni(source.SourcePosition, source.Velocity, cue, m_deviceDetails.OutputFormat.Channels, source.CustomMaxDistance);
                float maxDistance = source.CustomMaxDistance.HasValue ? source.CustomMaxDistance.Value : cue.MaxDistance;

                source.SourceChannels = 1;
                if (originalType == MySoundDimensions.D2)
                {
                    source.SourceChannels = 2;
                }
                m_x3dAudio.Apply3D(sound.Voice, m_listener, m_helperEmitter, source.SourceChannels, m_deviceDetails.OutputFormat.Channels, m_calculateFlags, maxDistance, sound.FrequencyRatio);

                Update3DCuesState();

                // why was this only for loops?
                //if (sound.IsLoopable)
                Add3DCueToUpdateList(source);

                ++m_soundInstancesTotal3D;
            }
            else
            {
                if (m_3Dsounds.Contains(source))
                {
                    StopUpdating3DCue(source);
                }
                ++m_soundInstancesTotal2D;
            }
            return(sound);
        }
예제 #29
0
        internal MySourceVoice GetVoice(MyCueId cueId, out int waveNumber, MySoundDimensions type = MySoundDimensions.D2, int tryIgnoreWaveNumber = -1)
        {
            waveNumber = -1;
            MySoundData cue = GetCue(cueId);

            if ((cue == null) || (cue.Waves == null) || (cue.Waves.Count == 0))
            {
                return(null);
            }

            CuePart        part;
            MyInMemoryWave wave = GetRandomWave(cue, type, out waveNumber, out part, tryIgnoreWaveNumber);

            if (wave == null && type == MySoundDimensions.D2)
            {
                type = MySoundDimensions.D3;
                wave = GetRandomWave(cue, type, out waveNumber, out part, tryIgnoreWaveNumber);
            }
            if (wave == null)
            {
                return(null);
            }

            MySourceVoice voice = GetVoice(cueId, wave, part);

            if (voice == null)
            {
                return(null);
            }

            if (cue.Loopable)
            {
                wave = GetWave(cue, type, waveNumber, CuePart.Loop);
                if (wave != null)
                {
                    Debug.Assert(voice.Owner.WaveFormat.Encoding == wave.WaveFormat.Encoding);
                    if (voice.Owner.WaveFormat.Encoding == wave.WaveFormat.Encoding)
                    {
                        voice.SubmitSourceBuffer(cueId, wave, CuePart.Loop);
                    }
                    else
                    {
                        MyLog.Default.WriteLine(string.Format("Inconsistent encodings: '{0}', got '{1}', expected '{2}', part = '{3}'", cueId, wave.WaveFormat.Encoding, voice.Owner.WaveFormat.Encoding, CuePart.Loop));
                    }
                }
                wave = GetWave(cue, type, waveNumber, CuePart.End);
                if (wave != null)
                {
                    Debug.Assert(voice.Owner.WaveFormat.Encoding == wave.WaveFormat.Encoding);
                    if (voice.Owner.WaveFormat.Encoding == wave.WaveFormat.Encoding)
                    {
                        voice.SubmitSourceBuffer(cueId, wave, CuePart.End);
                    }
                    else
                    {
                        MyLog.Default.WriteLine(string.Format("Inconsistent encodings: '{0}', got '{1}', expected '{2}', part = '{3}'", cueId, wave.WaveFormat.Encoding, voice.Owner.WaveFormat.Encoding, CuePart.End));
                    }
                }
            }

#if DEBUG
            if (voice.CueEnum.IsNull == false)
            {
                AddVoiceForDebug(voice);
            }
#endif

            return(voice);
        }
예제 #30
0
 IMySourceVoice IMyAudio.GetSound(MyStringId cueId, IMy3DSoundEmitter source, MySoundDimensions type)
 {
     return(GetSound(cueId, source, type));
 }
예제 #31
0
 IMySourceVoice IMyAudio.PlaySound(MyStringId cue, IMy3DSoundEmitter source, MySoundDimensions type, bool skipIntro, bool skipToEnd) { return null; }
예제 #32
0
        internal MySourceVoice PlaySound(MyCueId cueId, IMy3DSoundEmitter source = null, MySoundDimensions type = MySoundDimensions.D2, bool skipIntro = false, bool skipToEnd = false)
        {
			int waveNumber = -1;
			var sound = GetSound(cueId, out waveNumber, source, type);
			if(source != null)
				source.LastPlayedWaveNumber = -1;
			if (sound != null)
			{
                sound.Start(skipIntro, skipToEnd);
				if (source != null)
					source.LastPlayedWaveNumber = waveNumber;
			}
            return sound;
        }
예제 #33
0
        internal MySourceVoice PlaySound(MyCueId cueId, IMy3DSoundEmitter source = null, MySoundDimensions type = MySoundDimensions.D2, bool skipIntro = false, bool skipToEnd = false)
        {
            int waveNumber = -1;
            var sound      = GetSound(cueId, out waveNumber, source, type);

            if (source != null)
            {
                source.LastPlayedWaveNumber = -1;
            }
            if (sound != null)
            {
                sound.Start(skipIntro, skipToEnd);
                if (source != null)
                {
                    source.LastPlayedWaveNumber = waveNumber;
                }
            }
            return(sound);
        }
예제 #34
0
 IMySourceVoice IMyAudio.PlaySound(MyCueId cueId, IMy3DSoundEmitter source, MySoundDimensions type, bool skipIntro, bool skipToEnd)
 {
     return PlaySound(cueId, source, type, skipIntro, skipToEnd);
 }
예제 #35
0
        IMySourceVoice IMyAudio.GetSound(MyCueId cueId, IMy3DSoundEmitter source, MySoundDimensions type)
        {
            int waveNumber;

            return(GetSound(cueId, out waveNumber, source, type));
        }
예제 #36
0
        IMySourceVoice IMyAudio.GetSound(IMy3DSoundEmitter source, int sampleRate, int channels, MySoundDimensions dimension)
        {
            if (!m_canPlay)
                return null;

            var waveFormat = new WaveFormat(sampleRate, channels);
            source.SourceChannels = channels;
            var sourceVoice = new MySourceVoice(m_audioEngine, waveFormat);

            float volume = source.CustomVolume.HasValue ? source.CustomVolume.Value : 1;
            float maxDistance = source.CustomMaxDistance.HasValue ? source.CustomMaxDistance.Value : 0;

            sourceVoice.SetVolume(volume);

            if (dimension == MySoundDimensions.D3)
            {
                m_helperEmitter.UpdateValuesOmni(source.SourcePosition, source.Velocity, maxDistance, m_deviceDetails.OutputFormat.Channels, MyCurveType.Linear);
                sourceVoice.distanceToListener = m_x3dAudio.Apply3D(sourceVoice.Voice, m_listener, m_helperEmitter, source.SourceChannels, m_deviceDetails.OutputFormat.Channels, m_calculateFlags, maxDistance, sourceVoice.FrequencyRatio, sourceVoice.Silent, source.Realistic);
                Update3DCuesState();
                Add3DCueToUpdateList(source);

                ++m_soundInstancesTotal3D;
            }

            return sourceVoice;
        }
예제 #37
0
 public void PlaySound(byte[] buffer, int size, int sampleRate, float volume = 1f, float maxDistance = 0f, MySoundDimensions dimension = 1)
 {
     this.CustomMaxDistance = new float?(maxDistance);
     this.CustomVolume      = new float?(volume);
     if (this.Sound == null)
     {
         this.Sound = MyAudio.Static.GetSound(this, sampleRate, 1, dimension);
     }
     if (this.Sound != null)
     {
         this.Sound.SubmitBuffer(buffer, size);
         if (!this.Sound.IsPlaying)
         {
             this.Sound.StartBuffered();
         }
     }
 }