Ejemplo n.º 1
0
    // Supposed to be called once at voice initialization.
    // Otherwise recreate native object (instead of adding 'set callback' method to java interface)
    public void SetCallback(Action <short[]> callback, Voice.LocalVoice localVoice)
    {
        if (audioIn != null)
        {
            Dispose();
        }
        var voiceFrameSize = ((Voice.LocalVoiceFramed)localVoice).FrameSize;

        // setting to voice FrameSize lets to avoid framing procedure
        javaBuf = AndroidJNI.NewGlobalRef(AndroidJNI.NewShortArray(voiceFrameSize));

        this.callback = new DataCallback(callback, javaBuf);
        audioIn       = new AndroidJavaObject("com.exitgames.photon.audioinaec.AudioInAEC");
        bool aecAvailable = audioIn.Call <bool>("AECIsAvailable");
        int  minBufSize   = audioIn.Call <int>("GetMinBufferSize", SamplingRate, Channels);

        Debug.LogFormat("AndroidAudioInAEC: AndroidJavaObject created: aecAvailable: {0}, minBufSize: {1}", aecAvailable, minBufSize);

        AndroidJavaClass  app      = new AndroidJavaClass("com.unity3d.player.UnityPlayer");
        AndroidJavaObject activity = app.GetStatic <AndroidJavaObject>("currentActivity");
        // Set buffer IntPtr reference separately via pure jni call, pass other values and start capture via AndroidJavaObject helper

        var  meth = AndroidJNI.GetMethodID(audioIn.GetRawClass(), "SetBuffer", "([S)Z");
        bool ok   = AndroidJNI.CallBooleanMethod(audioIn.GetRawObject(), meth, new jvalue[] { new jvalue()
                                                                                              {
                                                                                                  l = javaBuf
                                                                                              } });

        if (ok)
        {
            ok = audioIn.Call <bool>("Start", activity, this.callback, SamplingRate, Channels, minBufSize * 4, aecAvailable);
        }

        Debug.LogFormat("AndroidAudioInAEC: AndroidJavaObject started: {0}, buffer size: {1}, sampling rate: {2}, channels: {3}, record buffer size: {4}, aec: {5}", ok, voiceFrameSize, SamplingRate, Channels, minBufSize * 4, aecAvailable);
    }
Ejemplo n.º 2
0
 internal object[] buildVoiceRemoveMessage(LocalVoice v)
 {
     byte[]   ids     = new byte[] { v.id };
     object[] content = new object[] { (byte)0, EventSubcode.VoiceRemove, ids };
     this.frontend.LogInfo(v.LogPrefix + " remove sent");
     return(content);
 }
Ejemplo n.º 3
0
    private void updateAudioSource()
    {
        // update local voice's mic audio source
        if (this.voice != Voice.LocalVoiceAudio.Dummy && (Source == AudioSource.Microphone))
        {
            // first remove voice and stop mic, then create new mic wrapper
            this.audioSource.Dispose();
            this.voice.RemoveSelf();
            gameObject.SendMessage("PhotonVoiceRemoved", SendMessageOptions.DontRequireReceiver);

            var debugEchoMode = this.DebugEchoMode;
            this.DebugEchoMode = false;
            var prevVoice = this.voice;

            this.voice = createLocalVoiceAudioAndSource();

            this.voice.Group    = prevVoice.Group;
            this.voice.Transmit = prevVoice.Transmit;
            this.voiceAudio.VoiceDetector.On        = voiceAudio.VoiceDetector.On;
            this.voiceAudio.VoiceDetector.Threshold = voiceAudio.VoiceDetector.Threshold;
            sendPhotonVoiceCreatedMessage();

            this.DebugEchoMode = debugEchoMode;
        }
    }
 private void Start()
 {
     if (photonView.isMine)
     {
         switch (this.TypeConvert)
         {
         case SampleTypeConv.Short:
             forceShort = true;
             if (PhotonVoiceSettings.Instance.DebugInfo)
             {
                 Debug.LogFormat(
                     "PUNVoice: Type Conversion set to Short. Audio samples will be converted if source samples type differs.");
             }
             break;
         }
         this.voice                   = createLocalVoiceAudioAndSource();
         this.VoiceDetector.On        = PhotonVoiceSettings.Instance.VoiceDetection;
         this.VoiceDetector.Threshold = PhotonVoiceSettings.Instance.VoiceDetectionThreshold;
         if (this.voice != Voice.LocalVoiceAudio.Dummy)
         {
             this.voice.Transmit = PhotonVoiceSettings.Instance.AutoTransmit;
         }
         else if (PhotonVoiceSettings.Instance.AutoTransmit)
         {
             Debug.LogWarning("PUNVoice: Cannot Transmit.");
         }
         sendPhotonVoiceCreatedMessage();
     }
 }
Ejemplo n.º 5
0
 public override void Service(LocalVoice localVoice)
 {
     while (this.reader.Read(this.buffer))
     {
         ((LocalVoiceFramed <T>)localVoice).PushData(this.buffer);
     }
 }
        /// <summary>
        /// Creates new local voice (outgoing audio stream).
        /// </summary>
        /// <param name="audioStream">Object providing audio data for the outgoing stream.</param>
        /// <param name="voiceInfo">Outgoing audio stream parameters (should be set according to Opus encoder restrictions).</param>
        /// <returns>Outgoing stream handler.</returns>
        /// <remarks>
        /// audioStream.SamplingRate and voiceInfo.SamplingRate may do not match. Automatic resampling will occur in this case.
        /// </remarks>
        public LocalVoice CreateLocalVoice(IAudioStream audioStream, VoiceInfo voiceInfo, int channelId)
        {
            // id assigned starting from 1 and up to 255

            byte newId = 0; // non-zero if successfully assigned

            if (voiceIdCnt == 255)
            {
                // try to reuse id
                var ids = new bool[256];
                foreach (var v in localVoices)
                {
                    ids[v.Value.id] = true;
                }
                // ids[0] is not used
                for (byte id = 1; id != 0 /* < 256 */; id++)
                {
                    if (!ids[id])
                    {
                        newId = id;
                        break;
                    }
                }
            }
            else
            {
                voiceIdCnt++;
                newId = voiceIdCnt;
            }

            if (newId != 0)
            {
                var v = new LocalVoice(this.frontend, newId, audioStream, voiceInfo, channelId);
                localVoices[newId] = v;

                List <LocalVoice> voiceList;
                if (!localVoicesPerChannel.TryGetValue(channelId, out voiceList))
                {
                    voiceList = new List <LocalVoice>();
                    localVoicesPerChannel[channelId] = voiceList;
                }
                voiceList.Add(v);

                this.frontend.DebugReturn(DebugLevel.INFO, "[PV] Local voice #" + v.id + " at channel " + this.channelStr(channelId) + " added: src_f=" + audioStream.SamplingRate + " enc_f=" + v.info.SamplingRate + " ch=" + v.info.Channels + " d=" + v.info.FrameDurationUs + " s=" + v.info.FrameSize + " b=" + v.info.Bitrate + " ud=" + voiceInfo.UserData);
                if (this.frontend.IsChannelJoined(channelId))
                {
                    this.frontend.SendVoicesInfo(this.buildVoicesInfo(new List <LocalVoice>()
                    {
                        v
                    }, true), channelId, 0);                                                                              // broadcast if joined
                }
                v.AudioGroup = this.GlobalAudioGroup;
                return(v);
            }
            else
            {
                return(null);
            }
        }
Ejemplo n.º 7
0
 /// <summary>
 /// Removes local voice (outgoing audio stream).
 /// <param name="voice">Handler of outgoing stream to be removed.</param>
 /// </summary>
 public static void RemoveLocalVoice(Voice.LocalVoice voice)
 {
     // can be called from OnDestroy, check if still exists
     if (!destroyed)
     {
         instance.client.RemoveLocalVoice(voice);
     }
 }
Ejemplo n.º 8
0
 public override void Service(LocalVoice localVoice)
 {
     while (this.reader.Read(buffer))
     {
         var v   = ((LocalVoiceFramed <T>)localVoice);
         var buf = v.PushDataBufferPool.AcquireOrCreate();
         Array.Copy(buffer, buf, buffer.Length);
         v.PushDataAsync(buf);
     }
 }
Ejemplo n.º 9
0
    // give user a chance to change MicrophoneDevice in Awake()
    void Start()
    {
        if (photonView.isMine)
        {
            var pvs = PhotonVoiceSettings.Instance;

            Application.RequestUserAuthorization(UserAuthorization.Microphone);
            // put required sample rate into audio source and encoder - both adjust it if needed
            Voice.IBufferReader <float> audioStream;
            int channels           = 0;
            int sourceSamplingRate = 0;
            if (AudioClip == null)
            {
                if (Microphone.devices.Length < 1)
                {
                    // Error already logged in PhotonVoiceNetwork.Awake()
                    return;
                }

                var micDev = this.MicrophoneDevice != null ? this.MicrophoneDevice : PhotonVoiceNetwork.MicrophoneDevice;
                if (PhotonVoiceSettings.Instance.DebugInfo)
                {
                    Debug.LogFormat("PUNVoice: Setting recorder's microphone device to {0}", micDev);
                }
                var mic = new MicWrapper(micDev, (int)pvs.SamplingRate);
                sourceSamplingRate = mic.SourceSamplingRate;
                channels           = mic.Channels;
                audioStream        = mic;
            }
            else
            {
                audioStream        = new AudioClipWrapper(AudioClip);
                sourceSamplingRate = AudioClip.frequency;
                channels           = AudioClip.channels;
                if (this.LoopAudioClip)
                {
                    ((AudioClipWrapper)audioStream).Loop = true;
                }
            }

            Voice.VoiceInfo voiceInfo = Voice.VoiceInfo.CreateAudioOpus(pvs.SamplingRate, sourceSamplingRate, channels, pvs.FrameDuration, pvs.Bitrate, photonView.viewID);
            this.voice                   = createLocalVoice(voiceInfo, audioStream);
            this.VoiceDetector.On        = PhotonVoiceSettings.Instance.VoiceDetection;
            this.VoiceDetector.Threshold = PhotonVoiceSettings.Instance.VoiceDetectionThreshold;
            if (this.voice != Voice.LocalVoiceAudio.Dummy)
            {
                this.voice.Transmit = PhotonVoiceSettings.Instance.AutoTransmit;
            }
            else if (PhotonVoiceSettings.Instance.AutoTransmit)
            {
                Debug.LogWarning("PUNVoice: Cannot Transmit.");
            }
            sendVoiceCreatedMessage(voiceInfo);
        }
    }
Ejemplo n.º 10
0
 /// <summary>
 /// Removes local voice (outgoing audio stream).
 /// <param name="voice">Handler of outgoing stream to be removed.</param>
 /// </summary>
 public void RemoveLocalVoice(LocalVoice v)
 {
     localVoices.Remove(v);
     if (this.State == LoadBalancing.ClientState.Joined)
     {
         this.sendVoiceRemove(new List <LocalVoice> {
             v
         });
     }
     this.DebugReturn(DebugLevel.INFO, "[PV] Local voice #" + v.id + " removed");
 }
Ejemplo n.º 11
0
 /// <summary>
 /// Removes local voice (outgoing data stream).
 /// <param name="voice">Handler of outgoing stream to be removed.</param>
 /// </summary>
 internal void RemoveLocalVoice(LocalVoice voice)
 {
     this.localVoices.Remove(voice.id);
     this.localVoicesPerChannel[voice.channelId].Remove(voice);
     if (this.frontend.IsChannelJoined(voice.channelId))
     {
         this.frontend.SendVoiceRemove(voice, voice.channelId, 0);
     }
     voice.Dispose();
     this.frontend.LogInfo(voice.LogPrefix + " removed");
 }
Ejemplo n.º 12
0
    // Supposed to be called once at voice initialization.
    // Otherwise recreate native object (instead of adding 'set callback' method to native interface)
    public void SetCallback(Action <float[]> callback, Voice.LocalVoice localVoice)
    {
        if (handle != IntPtr.Zero)
        {
            Dispose();
        }

        this.pushCallback = callback;
        this.localVoice   = (Voice.LocalVoiceFramed <float>)localVoice;
        handle            = Photon_Audio_In_CreatePusher(instanceCnt, deviceID, nativePushCallback);
        instancePerHandle.Add(instanceCnt++, this);
    }
Ejemplo n.º 13
0
        public override void Service(LocalVoice localVoice)
        {
            var v = ((LocalVoiceFramed <T>)localVoice);

            T[] buf = v.PushDataBufferPool.AcquireOrCreate();
            while (this.reader.Read(buf))
            {
                v.PushDataAsync(buf);
                buf = v.PushDataBufferPool.AcquireOrCreate();
            }
            // release unused buffer
            v.PushDataBufferPool.Release(buf, buf.Length);
        }
Ejemplo n.º 14
0
    // Supposed to be called once at voice initialization.
    // Otherwise recreate native object (instead of adding 'set callback' method to native interface)
    public void SetCallback(Action <short[]> callback, Voice.LocalVoice localVoice)
    {
        if (handle != IntPtr.Zero)
        {
            Dispose();
        }

        this.pushCallback = callback;
        this.localVoice   = (Voice.LocalVoiceFramed <short>)localVoice;
        pushRef           = push;
        // use default playback device
        handle = Photon_Audio_In_Create(SystemMode.SINGLE_CHANNEL_AEC, deviceID, -1, pushRef, true, true, true, true); // defaults in original ms sample: false, true, false, false
    }
Ejemplo n.º 15
0
        /// <summary>
        /// Creates new local voice (outgoing audio stream).
        /// </summary>
        /// <param name="audioStream">Object providing audio data for the outgoing stream.</param>
        /// <param name="voiceInfo">Outgoing audio stream parameters (should be set according to Opus encoder restrictions).</param>
        /// <returns>Outgoing stream handler.</returns>
        /// <remarks>
        /// audioStream.SamplingRate and voiceInfo.SamplingRate may do not match. Automatic resampling will occur in this case.
        /// </remarks>
        public LocalVoice CreateLocalVoice(IAudioStream audioStream, VoiceInfo voiceInfo)
        {
            // id assigned starting from 1 and up to 255

            byte newId = 0; // non-zero if successfully assigned

            if (voiceIdCnt == 255)
            {
                // try to reuse id
                var ids = new bool[256];
                foreach (var v in localVoices)
                {
                    ids[v.id] = true;
                }
                // ids[0] is not used
                for (byte id = 1; id != 0 /* < 256 */; id++)
                {
                    if (!ids[id])
                    {
                        newId = id;
                        break;
                    }
                }
            }
            else
            {
                voiceIdCnt++;
                newId = voiceIdCnt;
            }

            if (newId != 0)
            {
                var v = new LocalVoice(this, newId, audioStream, voiceInfo.UserData, voiceInfo.SamplingRate, voiceInfo.Channels, voiceInfo.Bitrate, voiceInfo.EncoderDelay);
                localVoices.Add(v);

                this.DebugReturn(DebugLevel.INFO, "[PV] Local voice #" + v.id + " added: src_f=" + audioStream.SamplingRate + " enc_f=" + v.InputSamplingRate + " ch=" + v.InputChannels + " d=" + v.EncoderDelay + " s=" + v.frameSize + " b=" + v.Bitrate + " ud=" + voiceInfo.UserData);
                if (this.State == LoadBalancing.ClientState.Joined)
                {
                    this.sendVoicesInfo(0, new List <LocalVoice>()
                    {
                        v
                    });                                                   // broadcast if joined
                }
                v.AudioGroup = this.globalAudioGroup;
                return(v);
            }
            else
            {
                return(null);
            }
        }
        /// <summary>
        /// Removes local voice (outgoing audio stream).
        /// <param name="voice">Handler of outgoing stream to be removed.</param>
        /// </summary>
        public void RemoveLocalVoice(LocalVoice voice)
        {
            this.localVoices.Remove(voice.id);

            this.localVoicesPerChannel[voice.channelId].Remove(voice);
            if (this.frontend.IsChannelJoined(voice.channelId))
            {
                var content = this.buildVoiceRemoveMessage(new List <LocalVoice>()
                {
                    voice
                });
                this.frontend.SendVoiceRemove(content, voice.channelId);
            }
            this.frontend.DebugReturn(DebugLevel.INFO, "[PV] Local voice #" + voice.id + " at channel " + this.channelStr(voice.channelId) + " removed");
        }
Ejemplo n.º 17
0
 public static IEncoder Create(VoiceInfo i, LocalVoice localVoice)
 {
     if (localVoice.GetType() == typeof(LocalVoiceAudioFloat))
     {
         return(new EncoderFloat(i));
     }
     else if (localVoice.GetType() == typeof(LocalVoiceAudioShort))
     {
         return(new EncoderShort(i));
     }
     else
     {
         throw new UnsupportedCodecException(i.Codec, localVoice);
     }
 }
Ejemplo n.º 18
0
        internal static IEncoder CreateDefaultEncoder(VoiceInfo info, LocalVoice localVoice)
        {
            switch (info.Codec)
            {
            case Codec.AudioOpus:
                return(OpusCodec.EncoderFactory.Create(info, localVoice));

#if PHOTON_VOICE_VIDEO_ENABLE
            case Codec.VideoVP8:
                return(new VPxCodec.Encoder(info));
#endif
            default:
                throw new UnsupportedCodecException(info.Codec, localVoice);
            }
        }
        public void SendVoiceRemove(LocalVoice voice, int channelId, int targetPlayerId)
        {
            object content = voiceClient.buildVoiceRemoveMessage(voice);
            var    opt     = new LoadBalancing.RaiseEventOptions();

            opt.SequenceChannel = (byte)channelId;
            if (targetPlayerId != 0)
            {
                opt.TargetActors = new int[] { targetPlayerId };
            }
            lock (sendLock)
            {
                this.OpRaiseEvent(VoiceEventCode.GetCode(opt.SequenceChannel), content, true, opt);
            }
        }
Ejemplo n.º 20
0
        /// <summary>Iterates through copy of all local voices list of given channel.</summary>
        public IEnumerable <LocalVoice> LocalVoicesInChannel(int channelId)
        {
            List <LocalVoice> channelVoices;

            if (this.localVoicesPerChannel.TryGetValue(channelId, out channelVoices))
            {
                var res = new LocalVoice[channelVoices.Count];
                channelVoices.CopyTo(res, 0);
                return(res);
            }
            else
            {
                return(new LocalVoice[0]);
            }
        }
        public void SendFrame(object content, int channelId, LocalVoice localVoice)
        {
            var opt = new LoadBalancing.RaiseEventOptions();

            opt.SequenceChannel = (byte)channelId;
            if (localVoice.DebugEchoMode)
            {
                opt.Receivers = LoadBalancing.ReceiverGroup.All;
            }
            opt.InterestGroup = localVoice.Group;
            lock (sendLock)
            {
                this.OpRaiseEvent((byte)VoiceEventCode.GetCode(opt.SequenceChannel), content, localVoice.Reliable, opt);
            }
            this.loadBalancingPeer.SendOutgoingCommands();
        }
Ejemplo n.º 22
0
 public void SetDebugEchoMode(LocalVoice v)
 {
     if (this.State == LoadBalancing.ClientState.Joined)
     {
         if (v.DebugEchoMode)
         {
             SendVoicesInfo(new List <LocalVoice>()
             {
                 v
             }, v.channelId, this.LocalPlayer.ID);
         }
         else
         {
             SendVoiceRemove(v, v.channelId, this.LocalPlayer.ID);
         }
     }
 }
Ejemplo n.º 23
0
        public override void Service(Voice.LocalVoice localVoice)
        {
            var v = ((Voice.LocalVoiceFramed <short>)localVoice);

            short[] buf = v.PushDataBufferPool.AcquireOrCreate();
            while (this.reader.Read(buffer))
            {
                for (int i = 0; i < buf.Length; i++)
                {
                    buf[i] = (short)(buffer[i] * (float)short.MaxValue);
                }
                v.PushDataAsync(buf);
                buf = v.PushDataBufferPool.AcquireOrCreate();
            }
            // release unused buffer
            v.PushDataBufferPool.Release(buf, buf.Length);
        }
Ejemplo n.º 24
0
    IEnumerator Start()
    {
        yield return(Application.RequestUserAuthorization(UserAuthorization.Microphone));

        if (!Application.HasUserAuthorization(UserAuthorization.Microphone))
        {
            yield break;
        }

        if (photonView.isMine)
        {
            switch (this.TypeConvert)
            {
            case SampleTypeConv.Short:
                forceShort = true;
                Debug.LogFormat("PUNVoice: Type Convertion set to Short. Audio samples will be converted if source samples type differs.");
                break;

            case SampleTypeConv.ShortAuto:
                var speex = gameObject.GetComponent <SpeexDSP>();
                if (speex != null && speex.Active)
                {
                    if (PhotonVoiceSettings.Instance.DebugInfo)
                    {
                        Debug.LogFormat("PUNVoice: Type Convertion set to ShortAuto. SpeexDSP found. Audio samples will be converted if source samples type differs.");
                    }
                    forceShort = true;
                }
                break;
            }
            this.voice                   = createLocalVoiceAudioAndSource();
            this.VoiceDetector.On        = PhotonVoiceSettings.Instance.VoiceDetection;
            this.VoiceDetector.Threshold = PhotonVoiceSettings.Instance.VoiceDetectionThreshold;
            if (this.voice != Voice.LocalVoiceAudio.Dummy)
            {
                this.voice.Transmit = PhotonVoiceSettings.Instance.AutoTransmit;
            }
            else if (PhotonVoiceSettings.Instance.AutoTransmit)
            {
                Debug.LogWarning("PUNVoice: Cannot Transmit.");
            }
            sendPhotonVoiceCreatedMessage();
        }
    }
Ejemplo n.º 25
0
    // give user a chance to change MicrophoneDevice in Awake()
    void Start()
    {
        if (photonView.isMine)
        {
            var pvs = PhotonVoiceSettings.Instance;

            if (!this.microphoneDeviceSet)
            {
                this.MicrophoneDevice = PhotonVoiceNetwork.MicrophoneDevice;
            }

            Application.RequestUserAuthorization(UserAuthorization.Microphone);
            // put required sample rate into audio source and encoder - both adjust it if needed
            Voice.IAudioStream audioStream;
            int channels = 0;
            if (AudioClip == null)
            {
                if (PhotonVoiceSettings.Instance.DebugInfo)
                {
                    Debug.Log("PUNVoice: Setting recorder's microphone device to " + this.MicrophoneDevice);
                }
                var mic = new MicWrapper(this.MicrophoneDevice, (int)pvs.SamplingRate);
                this.microphoneDeviceUsed = true;
                channels    = mic.Channels;
                audioStream = mic;
            }
            else
            {
                audioStream = new AudioClipWrapper(AudioClip);
                channels    = AudioClip.channels;
                if (this.LoopAudioClip)
                {
                    ((AudioClipWrapper)audioStream).Loop = true;
                }
            }

            Voice.VoiceInfo voiceInfo = new Voice.VoiceInfo((int)pvs.SamplingRate, channels, (int)pvs.Delay, pvs.Bitrate, photonView.viewID);
            this.voice = PhotonVoiceNetwork.CreateLocalVoice(audioStream, voiceInfo);

            this.VoiceDetector.On        = PhotonVoiceSettings.Instance.VoiceDetection;
            this.VoiceDetector.Threshold = PhotonVoiceSettings.Instance.VoiceDetectionThreshold;
        }
    }
Ejemplo n.º 26
0
        void addVoice(byte newId, int channelId, LocalVoice v)
        {
            localVoices[newId] = v;
            List <LocalVoice> voiceList;

            if (!localVoicesPerChannel.TryGetValue(channelId, out voiceList))
            {
                voiceList = new List <LocalVoice>();
                localVoicesPerChannel[channelId] = voiceList;
            }
            voiceList.Add(v);
            if (this.frontend.IsChannelJoined(channelId))
            {
                this.frontend.SendVoicesInfo(new List <LocalVoice>()
                {
                    v
                }, channelId, 0);                                                         // broadcast if joined
            }
            v.Group = this.GlobalGroup;
        }
Ejemplo n.º 27
0
        private LocalVoice createLocalVoice(VoiceInfo voiceInfo, int channelId, IEncoder encoder, Func <byte, int, LocalVoice> voiceFactory)
        {
            if (channelId == ChannelAuto)
            {
                channelId = this.frontend.AssignChannel(voiceInfo);
            }
            var newId = getNewVoiceId();

            if (newId != 0)
            {
                LocalVoice v = voiceFactory(newId, channelId);
                if (v != null)
                {
                    addVoice(newId, channelId, v);
                    this.frontend.LogInfo(v.LogPrefix + " added enc: " + v.info.ToString());
                    return(v);
                }
            }
            return(null);
        }
Ejemplo n.º 28
0
    private void InitialVoiceSetUp()
    {
        var pvs = PhotonVoiceSettings.Instance;

        Application.RequestUserAuthorization(UserAuthorization.Microphone);
        // put required sample rate into audio source and encoder - both adjust it if needed
        Voice.IAudioStream audioStream;
        int channels = 0;

        if (AudioClip == null)
        {
            var micDev = microphoneDevice ?? PhotonVoiceNetwork.MicrophoneDevice ?? (Microphone.devices.Any() ? Microphone.devices.First() : null);
            microphoneDevice = micDev;
            if (PhotonVoiceSettings.Instance.DebugInfo)
            {
                Debug.LogFormat("PUNVoice: Setting recorder's microphone device to {0}", micDev);
            }
            var mic = new MicWrapper(micDev, (int)pvs.SamplingRate);
            channels    = mic.Channels;
            audioStream = mic;
        }
        else
        {
            audioStream = new AudioClipWrapper(AudioClip);
            channels    = AudioClip.channels;
            if (LoopAudioClip)
            {
                ((AudioClipWrapper)audioStream).Loop = true;
            }
        }

        Voice.VoiceInfo voiceInfo = new Voice.VoiceInfo((int)pvs.SamplingRate, channels, (int)pvs.Delay, pvs.Bitrate, photonView.viewID);
        voice                   = PhotonVoiceNetwork.CreateLocalVoice(audioStream, voiceInfo);
        VoiceDetector.On        = PhotonVoiceSettings.Instance.VoiceDetection;
        VoiceDetector.Threshold = PhotonVoiceSettings.Instance.VoiceDetectionThreshold;
        MicrophoneDevice        = microphoneDevice;
    }
Ejemplo n.º 29
0
    // Message sent by PhotonVoiceRecorder
    void PhotonVoiceCreated(Voice.LocalVoice localVoice)
    {
        if (!Active)
        {
            return;
        }
        if (localVoice.Info.Channels != 1)
        {
            throw new Exception("SpeexProcessor: only mono audio signals supported.");
        }
        if (!(localVoice is Voice.LocalVoiceAudioShort))
        {
            throw new Exception("SpeexProcessor: only short audio voice supported (Set PhotonVoiceRecorder.TypeConvert option).");
        }
        var v = (Voice.LocalVoiceAudioShort)localVoice;

        // can't access the AudioSettings properties in InitAEC if it's called from not main thread
        var playChannelCount = new Dictionary <AudioSpeakerMode, int>()
        {
            { AudioSpeakerMode.Raw, 0 },
            { AudioSpeakerMode.Mono, 1 },
            { AudioSpeakerMode.Stereo, 2 },
            { AudioSpeakerMode.Quad, 4 },
            { AudioSpeakerMode.Surround, 5 },
            { AudioSpeakerMode.Mode5point1, 6 },
            { AudioSpeakerMode.Mode7point1, 8 },
            { AudioSpeakerMode.Prologic, 0 },
        }[AudioSettings.speakerMode];
        int playBufSize;
        int playBufNum;

        AudioSettings.GetDSPBufferSize(out playBufSize, out playBufNum);
        proc = new Voice.SpeexProcessor(new Logger(), () => (long)(AudioSettings.dspTime * 1000), v.FrameSize, localVoice.Info.SourceSamplingRate, localVoice.Info.Channels, AudioSettings.outputSampleRate, playChannelCount, playBufSize);
        v.AddPreProcessor(proc);
        UpdateProcProps();
        Debug.Log("SpeexDSP initialized.");
    }
Ejemplo n.º 30
0
        public void SendVoiceRemove(LocalVoice voice, int channelId, int targetPlayerId)
        {
            object content = voiceClient.buildVoiceRemoveMessage(voice);
            var    sendOpt = new SendOptions()
            {
                Reliability = true,
                Channel     = (byte)channelId
            };

            var opt = new LoadBalancing.RaiseEventOptions();

            if (targetPlayerId != 0)
            {
                opt.TargetActors = new int[] { targetPlayerId };
            }
            lock (sendLock)
            {
                if (voice.DebugEchoMode)
                {
                    opt.Receivers = ReceiverGroup.All;
                }
                this.OpRaiseEvent(VoiceEventCode.GetCode(channelId), content, opt, sendOpt);
            }
        }