com.adrenak.univoice 2.0.2 → 4.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (87) hide show
  1. package/LICENSE +21 -21
  2. package/LICENSE.meta +7 -7
  3. package/README.md +32 -54
  4. package/README.md.meta +7 -7
  5. package/Runtime/Adrenak.UniVoice.Runtime.asmdef +19 -3
  6. package/Runtime/Adrenak.UniVoice.Runtime.asmdef.meta +7 -7
  7. package/Runtime/ClientSession.cs +137 -0
  8. package/Runtime/{Types/ChatroomAgentMode.cs.meta → ClientSession.cs.meta} +11 -11
  9. package/Runtime/Common/Utils.cs +55 -0
  10. package/Runtime/{Interfaces/IChatroomNetwork.cs.meta → Common/Utils.cs.meta} +11 -11
  11. package/Runtime/Common.meta +8 -0
  12. package/Runtime/Impl/Filters/GaussianAudioBlur.cs +90 -0
  13. package/Runtime/{ChatroomAgent.cs.meta → Impl/Filters/GaussianAudioBlur.cs.meta} +11 -11
  14. package/Runtime/Impl/Filters/OpusFilter.cs +85 -0
  15. package/Runtime/Impl/Filters/OpusFilter.cs.meta +11 -0
  16. package/Runtime/Impl/Filters.meta +8 -0
  17. package/Runtime/Impl/Inputs/UniMicInput.cs +39 -0
  18. package/Runtime/Impl/Inputs/UniMicInput.cs.meta +11 -0
  19. package/Runtime/Impl/Inputs.meta +8 -0
  20. package/Runtime/Impl/Networks/Mirror/MirrorClient.cs +161 -0
  21. package/Runtime/Impl/Networks/Mirror/MirrorClient.cs.meta +11 -0
  22. package/Runtime/Impl/Networks/Mirror/MirrorMessage.cs +21 -0
  23. package/Runtime/Impl/Networks/Mirror/MirrorMessage.cs.meta +11 -0
  24. package/Runtime/Impl/Networks/Mirror/MirrorMessageTags.cs +16 -0
  25. package/Runtime/Impl/Networks/Mirror/MirrorMessageTags.cs.meta +11 -0
  26. package/Runtime/Impl/Networks/Mirror/MirrorModeObserver.cs +43 -0
  27. package/Runtime/Impl/Networks/Mirror/MirrorModeObserver.cs.meta +11 -0
  28. package/Runtime/Impl/Networks/Mirror/MirrorServer.cs +234 -0
  29. package/Runtime/Impl/Networks/Mirror/MirrorServer.cs.meta +11 -0
  30. package/Runtime/Impl/Networks/Mirror.meta +8 -0
  31. package/Runtime/Impl/Networks.meta +8 -0
  32. package/Runtime/Impl/Outputs/StreamedAudioSourceOutput.cs +56 -0
  33. package/Runtime/Impl/Outputs/StreamedAudioSourceOutput.cs.meta +11 -0
  34. package/Runtime/Impl/Outputs.meta +8 -0
  35. package/Runtime/Impl.meta +8 -0
  36. package/Runtime/Interfaces/IAudioClient.cs +77 -0
  37. package/Runtime/Interfaces/IAudioClient.cs.meta +11 -0
  38. package/Runtime/Interfaces/IAudioFilter.cs +10 -0
  39. package/Runtime/Interfaces/IAudioFilter.cs.meta +11 -0
  40. package/Runtime/Interfaces/IAudioInput.cs +1 -24
  41. package/Runtime/Interfaces/IAudioInput.cs.meta +11 -11
  42. package/Runtime/Interfaces/IAudioOutput.cs +6 -30
  43. package/Runtime/Interfaces/IAudioOutput.cs.meta +11 -11
  44. package/Runtime/Interfaces/IAudioOutputFactory.cs +2 -7
  45. package/Runtime/Interfaces/IAudioOutputFactory.cs.meta +11 -11
  46. package/Runtime/Interfaces/IAudioServer.cs +41 -0
  47. package/Runtime/Interfaces/IAudioServer.cs.meta +11 -0
  48. package/Runtime/Interfaces.meta +8 -8
  49. package/Runtime/Types/{ChatroomAudioSegment.cs → AudioFrame.cs} +27 -26
  50. package/Runtime/Types/{ChatroomAudioSegment.cs.meta → AudioFrame.cs.meta} +11 -11
  51. package/Runtime/Types/VoiceSettings.cs +53 -0
  52. package/Runtime/Types/VoiceSettings.cs.meta +11 -0
  53. package/Runtime/Types.meta +8 -8
  54. package/Runtime.meta +9 -9
  55. package/Samples~/Group Chat Sample/Prefabs/Mic Toggle.prefab +235 -0
  56. package/{CHANGELOG.md.meta → Samples~/Group Chat Sample/Prefabs/Mic Toggle.prefab.meta } +7 -7
  57. package/Samples~/Group Chat Sample/Prefabs/Peer View.prefab +851 -0
  58. package/Samples~/Group Chat Sample/Prefabs/Peer View.prefab.meta +7 -0
  59. package/Samples~/Group Chat Sample/Prefabs.meta +8 -0
  60. package/Samples~/Group Chat Sample/Scenes/GroupVoiceCallSample-Mirror.unity +2160 -0
  61. package/Samples~/Group Chat Sample/Scenes/GroupVoiceCallSample-Mirror.unity.meta +7 -0
  62. package/Samples~/Group Chat Sample/Scenes.meta +8 -0
  63. package/Samples~/Group Chat Sample/Scripts/GroupVoiceCallMirrorSample.cs +217 -0
  64. package/Samples~/Group Chat Sample/Scripts/GroupVoiceCallMirrorSample.cs.meta +11 -0
  65. package/Samples~/Group Chat Sample/Scripts/PeerView.cs +74 -0
  66. package/Samples~/Group Chat Sample/Scripts/PeerView.cs.meta +11 -0
  67. package/Samples~/Group Chat Sample/Scripts.meta +8 -0
  68. package/Samples~/Group Chat Sample/Sprites/mic.png +0 -0
  69. package/Samples~/Group Chat Sample/Sprites/mic.png.meta +88 -0
  70. package/Samples~/Group Chat Sample/Sprites/off.png +0 -0
  71. package/Samples~/Group Chat Sample/Sprites/off.png.meta +88 -0
  72. package/Samples~/Group Chat Sample/Sprites/on.png +0 -0
  73. package/Samples~/Group Chat Sample/Sprites/on.png.meta +88 -0
  74. package/Samples~/Group Chat Sample/Sprites/speaker.png +0 -0
  75. package/Samples~/Group Chat Sample/Sprites/speaker.png.meta +88 -0
  76. package/Samples~/Group Chat Sample/Sprites.meta +8 -0
  77. package/Samples~/Group Chat Sample.meta +8 -0
  78. package/package.json +39 -20
  79. package/package.json.meta +7 -7
  80. package/CHANGELOG.md +0 -67
  81. package/Runtime/ChatroomAgent.cs +0 -215
  82. package/Runtime/Extensions.cs +0 -39
  83. package/Runtime/Extensions.cs.meta +0 -12
  84. package/Runtime/Interfaces/IChatroomNetwork.cs +0 -121
  85. package/Runtime/Types/ChatroomAgentMode.cs +0 -22
  86. package/Runtime/Types/ChatroomPeerSettings.cs +0 -18
  87. package/Runtime/Types/ChatroomPeerSettings.cs.meta +0 -11
package/LICENSE CHANGED
@@ -1,21 +1,21 @@
1
- MIT License
2
-
3
- Copyright (c) 2018 Vatsal Ambastha
4
-
5
- Permission is hereby granted, free of charge, to any person obtaining a copy
6
- of this software and associated documentation files (the "Software"), to deal
7
- in the Software without restriction, including without limitation the rights
8
- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
- copies of the Software, and to permit persons to whom the Software is
10
- furnished to do so, subject to the following conditions:
11
-
12
- The above copyright notice and this permission notice shall be included in all
13
- copies or substantial portions of the Software.
14
-
15
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
- SOFTWARE.
1
+ MIT License
2
+
3
+ Copyright (c) 2018 Vatsal Ambastha
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/LICENSE.meta CHANGED
@@ -1,7 +1,7 @@
1
- fileFormatVersion: 2
2
- guid: 789be013ec943714a826e42a9d7db452
3
- DefaultImporter:
4
- externalObjects: {}
5
- userData:
6
- assetBundleName:
7
- assetBundleVariant:
1
+ fileFormatVersion: 2
2
+ guid: 789be013ec943714a826e42a9d7db452
3
+ DefaultImporter:
4
+ externalObjects: {}
5
+ userData:
6
+ assetBundleName:
7
+ assetBundleVariant:
package/README.md CHANGED
@@ -1,5 +1,3 @@
1
- Note: Inbuilt implementations and samples have been removed from this repository. They'll be added to separate repositories soon.
2
-
3
1
  # UniVoice
4
2
  UniVoice is a voice chat/VoIP solution for Unity.
5
3
 
@@ -9,73 +7,53 @@ Some features of UniVoice:
9
7
  - ⚙ Peer specific settings. Don't want to listen to a peer? Mute them. Don't want someone listening to you? Mute yourself against them.
10
8
 
11
9
  - 🎨 Customize your audio input, output and networking layer.
12
- * 🎤 __Configurable Audio Input__: Decide what the input of your outgoing audio is. Let it be from [Unity's Microphone](https://docs.unity3d.com/ScriptReference/Microphone.html) class, or a live streaming audio, or an MP4 file on the disk.
10
+ * 🎤 __Configurable Audio Input__: UniVoice is audio input agnostic. It supports mic audio input out of the box and you can change the source of outgoing audio by implementing the `IAudioInput` interrace.
13
11
 
14
- * 🔊 __Configurable Audio Output__: Decide where the incoming peer audio goes. Let the output of incoming audio be [Unity AudioSource](https://docs.unity3d.com/ScriptReference/AudioSource.html) to play the audio in-game, or write it into an MP4 on the disk, or stream it to an online service.
12
+ * 🔊 __Configurable Audio Output__: UniVoice is audio output agnostic. Out of the box is supports playing peer audio using Unity AudioSource. You can divert incoming audio to anywhere you want by implementing the `IAudioOutput` interface.
15
13
 
16
- * 🌐 __Configurable Network__: Want to use UniVoice in a WLAN project using [Telepathy?](https://github.com/vis2k/Telepathy) Just adapt its API for UniVoice with a simple the `IChatroomNetwork` interface. Using your own backend for multiplayer? Create and expose your audio API and write a UniVoice implementation, again with the same interface.
17
-
18
- # Docs
19
- Manuals and sample projects are not available yet. For the API reference, please visit http://www.vatsalambastha.com/univoice
20
-
21
- # Usage
22
- ## Creating a chatroom agent
23
- - To be able to host and join voice chatrooms, you need a `ChatroomAgent` instance.
14
+ * 🌐 __Configurable Network__: UniVoice is network agnostic and supports Mirror out of the box. You can implement the `IAudioClient` and `IAudioServer` interfaces using the networking plugin of your choice to make it compatible with it.
24
15
 
16
+ ## Installation
17
+ ⚠️ [OpenUPM](https://openupm.com/packages/com.adrenak.univoice/?subPage=versions) may not have up to date releases. Install using NPM registry instead 👇
18
+
19
+ Ensure you have the NPM registry in the `packages.json` file of your Unity project with the following scopes:
25
20
  ```
26
- var agent = new ChatroomAgent(IChatroomNetwork network, IAudioInput audioInput, IAudioOutput audioOutput);
21
+ "scopedRegistries": [
22
+ {
23
+ "name": "npmjs",
24
+ "url": "https://registry.npmjs.org",
25
+ "scopes": [
26
+ "com.npmjs",
27
+ "com.adrenak.univoice",
28
+ "com.adrenak.brw",
29
+ "com.adrenak.unimic",
30
+ "com.adrenak.unityopus"
31
+ ]
32
+ }
33
+ }
27
34
  ```
28
35
 
29
- ## Hosting and joining chatrooms
30
-
31
- Every peer in the chatroom is assigned an ID by the host. And every peer has a peer list, representing the other peers in the chatroom.
36
+ ## Docs
37
+ Am API reference is available: http://www.vatsalambastha.com/univoice
32
38
 
33
- - To get your ID
34
- `agent.Network.OwnID;`
39
+ ## Samples
40
+ This repository contains a sample scene for the Mirror network, which is the best place to see how UniVoice can be integrated into your project.
35
41
 
36
- - To get a list of the other peers in the chatroom, use this:
37
- `agent.Network.PeersIDs`
38
-
39
- `agent.Network` also provides methods to host or join a chatroom. Here is how you use them:
42
+ To try the sample, import Mirror and add the `UNIVOICE_MIRROR_NETWORK` compilation symbol to your project.
40
43
 
41
- ```
42
- // Host a chatroom using a name
43
- agent.Network.HostChatroom(optional_data);
44
+ ## Dependencies
45
+ [com.adrenak.brw](https://www.github.com/adrenak/brw)`@1.0.1` for reading and writing messages for communication. See `MirrorServer.cs` and `MirrorClient.cs` where they're used.
44
46
 
45
- // Join an existing chatroom using a name
46
- agent.Network.JoinChatroom(optional_data);
47
+ [com.adrenak.unimic](https://www.github.com/adrenak/unimic)`@3.2.1` for easily capturing audio from any connected mic devices. See `UniMicInput.cs` for usage.
47
48
 
48
- // Leave the chatroom, if connected to one
49
- agent.Network.LeaveChatroom(optional_data);
49
+ [com.adrenak.unityopus](https://www.github.com/adrenak/unityopus)`@1.0.0` for Opus encoding and decoding. See `OpusFilter.cs` for usage
50
50
 
51
- // Closes a chatroom, if is hosting one
52
- agent.Network.CloseChatroom(optional_data);
53
-
54
- ```
55
- ## Muting Audio
56
- To mute everyone in the chatroom, use `agent.MuteOthers = true;` or set it to `false` to unmute them all.
57
-
58
- To mute yourself use `agent.MuteSelf = true;` or set it to `false` to unmute yourself. This will stop sending your audio to all the peers in the chatroom.
59
-
60
- For muting a specific peer, first get the peers settings object using this:
61
- ```
62
- agent.PeerSettings[id].muteThem = true; // where id belongs to the peer in question
63
- ```
64
-
65
- If you want to mute yourself towards a specific peer, use this:
66
- `agent.PeerSettings[id].muteSelf = true; // where id belongs to the peer in question`
67
-
68
- ## Events
69
- `agent.Network` provides several network related events. Refer to the [API reference](http://www.vatsalambastha.com/univoice/api/Adrenak.UniVoice.ChatroomAgent.html) for them.
70
-
71
- # License and Support
51
+ ## License and Support
72
52
  This project is under the [MIT license](https://github.com/adrenak/univoice/blob/master/LICENSE).
73
53
 
74
- Updates and maintenance are not guaranteed and the project is maintained by the original developer in his free time. Community contributions are welcome.
75
-
76
- __Commercial consultation and development can be arranged__ but is subject to schedule and availability.
54
+ Community contributions are welcome.
77
55
 
78
- # Contact
56
+ ## Contact
79
57
  The developer can be reached at the following links:
80
58
 
81
59
  [Website](http://www.vatsalambastha.com)
package/README.md.meta CHANGED
@@ -1,7 +1,7 @@
1
- fileFormatVersion: 2
2
- guid: b497ccbc9f4029f4593611f820e24235
3
- TextScriptImporter:
4
- externalObjects: {}
5
- userData:
6
- assetBundleName:
7
- assetBundleVariant:
1
+ fileFormatVersion: 2
2
+ guid: b497ccbc9f4029f4593611f820e24235
3
+ TextScriptImporter:
4
+ externalObjects: {}
5
+ userData:
6
+ assetBundleName:
7
+ assetBundleVariant:
@@ -1,3 +1,19 @@
1
- {
2
- "name": "Adrenak.UniVoice.Runtime"
3
- }
1
+ {
2
+ "name": "Adrenak.UniVoice.Runtime",
3
+ "references": [
4
+ "GUID:f87ecb857e752164ab814a3de8eb0262",
5
+ "GUID:1f776cd02c03a7b4280b6b649d7758e2",
6
+ "GUID:30817c1a0e6d646d99c048fc403f5979",
7
+ "GUID:725ee7191c021de4dbf9269590ded755",
8
+ "GUID:34d15e3fb5fa4b541b5a93a6dc182cc5"
9
+ ],
10
+ "includePlatforms": [],
11
+ "excludePlatforms": [],
12
+ "allowUnsafeCode": false,
13
+ "overrideReferences": false,
14
+ "precompiledReferences": [],
15
+ "autoReferenced": true,
16
+ "defineConstraints": [],
17
+ "versionDefines": [],
18
+ "noEngineReferences": false
19
+ }
@@ -1,7 +1,7 @@
1
- fileFormatVersion: 2
2
- guid: 6b289bb677194eb40b60db3a566aab7b
3
- AssemblyDefinitionImporter:
4
- externalObjects: {}
5
- userData:
6
- assetBundleName:
7
- assetBundleVariant:
1
+ fileFormatVersion: 2
2
+ guid: 6b289bb677194eb40b60db3a566aab7b
3
+ AssemblyDefinitionImporter:
4
+ externalObjects: {}
5
+ userData:
6
+ assetBundleName:
7
+ assetBundleVariant:
@@ -0,0 +1,137 @@
1
+ using System;
2
+ using System.Collections.Generic;
3
+
4
+ using UnityEngine;
5
+
6
+ namespace Adrenak.UniVoice {
7
+ /// <summary>
8
+ /// Handles a client session.
9
+ /// Requires an implementation of <see cref="IAudioClient{T}"/>, <see cref="IAudioInput"/> and <see cref="IAudioOutputFactory"/> each.
10
+ /// Allows adding input and output filters and handles their execution.
11
+ /// </summary>
12
+ /// <typeparam name="T"></typeparam>
13
+ public class ClientSession<T> : IDisposable {
14
+ /// <summary>
15
+ /// The <see cref="IAudioOutput"/> instances of each peer in the session
16
+ /// </summary>
17
+ public Dictionary<T, IAudioOutput> PeerOutputs { get; private set; } = new Dictionary<T, IAudioOutput>();
18
+
19
+ /// <summary>
20
+ /// The input <see cref="IAudioFilter"/> that will be applied to the outgoing audio for all the peers.
21
+ /// Note that filters are executed in the order they are present in this list
22
+ /// </summary>
23
+ public List<IAudioFilter> InputFilters { get; set; } = new List<IAudioFilter>();
24
+
25
+ /// <summary>
26
+ /// The output <see cref="IAudioFilter"/> that will be applied to the incoming audio for all the peers.
27
+ /// Note that filters are executed in the order they are present in this list.
28
+ /// </summary>
29
+ public List<IAudioFilter> OutputFilters { get; set; } = new List<IAudioFilter>();
30
+
31
+ public ClientSession(IAudioClient<T> client, IAudioInput input, IAudioOutputFactory outputFactory) {
32
+ Client = client;
33
+ Input = input;
34
+ OutputFactory = outputFactory;
35
+ }
36
+
37
+ /// <summary>
38
+ /// The <see cref="IAudioClient{T}"/> that's used for networking
39
+ /// </summary>
40
+ IAudioClient<T> client;
41
+ public IAudioClient<T> Client {
42
+ get => client;
43
+ set {
44
+ if(client != null)
45
+ client.Dispose();
46
+ client = value;
47
+
48
+ Client.OnLeft += () => {
49
+ foreach (var output in PeerOutputs)
50
+ output.Value.Dispose();
51
+ PeerOutputs.Clear();
52
+ };
53
+
54
+ Client.OnPeerJoined += id => {
55
+ try {
56
+ var output = outputFactory.Create();
57
+ PeerOutputs.Add(id, output);
58
+ }
59
+ catch (Exception e) {
60
+ Debug.LogException(e);
61
+ }
62
+ };
63
+
64
+ Client.OnPeerLeft += id => {
65
+ if (!PeerOutputs.ContainsKey(id))
66
+ return;
67
+
68
+ PeerOutputs[id].Dispose();
69
+ PeerOutputs.Remove(id);
70
+ };
71
+
72
+ client.OnReceivedPeerAudioFrame += (id, audioFrame) => {
73
+ if (!PeerOutputs.ContainsKey(id))
74
+ return;
75
+
76
+ if (OutputFilters != null) {
77
+ foreach (var filter in OutputFilters)
78
+ audioFrame = filter.Run(audioFrame);
79
+ }
80
+
81
+ PeerOutputs[id].Feed(audioFrame);
82
+ };
83
+ }
84
+ }
85
+
86
+ IAudioInput input;
87
+ /// <summary>
88
+ /// The <see cref="IAudioInput"/> that's used for sourcing outgoing audio
89
+ /// </summary>
90
+ public IAudioInput Input {
91
+ get => input;
92
+ set {
93
+ if(input != null)
94
+ input.Dispose();
95
+ input = value;
96
+ input.OnFrameReady += frame => {
97
+ if (InputFilters != null) {
98
+ foreach (var filter in InputFilters)
99
+ frame = filter.Run(frame);
100
+ }
101
+
102
+ Client.SendAudioFrame(frame);
103
+ };
104
+ }
105
+ }
106
+
107
+ IAudioOutputFactory outputFactory;
108
+ /// <summary>
109
+ /// The <see cref="IAudioOutputFactory"/> that creates the <see cref="IAudioOutput"/> of peers
110
+ /// </summary>
111
+ public IAudioOutputFactory OutputFactory {
112
+ get => outputFactory;
113
+ set {
114
+ outputFactory = value;
115
+
116
+ foreach (var output in PeerOutputs)
117
+ output.Value.Dispose();
118
+ PeerOutputs.Clear();
119
+
120
+ foreach (var id in Client.PeerIDs) {
121
+ try {
122
+ var output = outputFactory.Create();
123
+ PeerOutputs.Add(id, output);
124
+ }
125
+ catch (Exception e) {
126
+ Debug.LogException(e);
127
+ }
128
+ }
129
+ }
130
+ }
131
+
132
+ public void Dispose() {
133
+ Client.Dispose();
134
+ Input.Dispose();
135
+ }
136
+ }
137
+ }
@@ -1,11 +1,11 @@
1
- fileFormatVersion: 2
2
- guid: 95ab24cb9f03b8c4c8f22f567259def4
3
- MonoImporter:
4
- externalObjects: {}
5
- serializedVersion: 2
6
- defaultReferences: []
7
- executionOrder: 0
8
- icon: {instanceID: 0}
9
- userData:
10
- assetBundleName:
11
- assetBundleVariant:
1
+ fileFormatVersion: 2
2
+ guid: 923d8509d2c05f2479d6af7331dabe58
3
+ MonoImporter:
4
+ externalObjects: {}
5
+ serializedVersion: 2
6
+ defaultReferences: []
7
+ executionOrder: 0
8
+ icon: {instanceID: 0}
9
+ userData:
10
+ assetBundleName:
11
+ assetBundleVariant:
@@ -0,0 +1,55 @@
1
+ using System.IO;
2
+ using System.IO.Compression;
3
+ using System.Net.Sockets;
4
+ using System.Net;
5
+ using System.Runtime.Serialization.Formatters.Binary;
6
+ using System;
7
+ using UnityEngine;
8
+
9
+ namespace Adrenak.UniVoice {
10
+ public class Utils {
11
+ public class Bytes {
12
+ public static byte[] FloatsToBytes(float[] floats) {
13
+ int byteCount = sizeof(float) * floats.Length;
14
+ byte[] byteArray = new byte[byteCount];
15
+
16
+ Buffer.BlockCopy(floats, 0, byteArray, 0, byteCount);
17
+
18
+ return byteArray;
19
+ }
20
+
21
+ public static float[] BytesToFloats(byte[] bytes) {
22
+ int floatCount = bytes.Length / sizeof(float);
23
+ float[] floatArray = new float[floatCount];
24
+
25
+ Buffer.BlockCopy(bytes, 0, floatArray, 0, bytes.Length);
26
+
27
+ return floatArray;
28
+ }
29
+ }
30
+
31
+ public static class Audio {
32
+ static float[] audioF;
33
+ static float sumOfSquares;
34
+ public static float CalculateRMS(byte[] audio) {
35
+ audioF = Bytes.BytesToFloats(audio);
36
+
37
+ foreach(var x in audioF)
38
+ sumOfSquares += x * x;
39
+ return Mathf.Sqrt(sumOfSquares / audioF.Length);
40
+ }
41
+ }
42
+
43
+ public static class Network {
44
+ public static string LocalIPv4Address {
45
+ get {
46
+ using (Socket socket = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, 0)) {
47
+ socket.Connect("8.8.8.8", 65530);
48
+ IPEndPoint endPoint = socket.LocalEndPoint as IPEndPoint;
49
+ return endPoint.Address.ToString();
50
+ }
51
+ }
52
+ }
53
+ }
54
+ }
55
+ }
@@ -1,11 +1,11 @@
1
- fileFormatVersion: 2
2
- guid: 11ba8951ad10dc84a963ca3c32cda48a
3
- MonoImporter:
4
- externalObjects: {}
5
- serializedVersion: 2
6
- defaultReferences: []
7
- executionOrder: 0
8
- icon: {instanceID: 0}
9
- userData:
10
- assetBundleName:
11
- assetBundleVariant:
1
+ fileFormatVersion: 2
2
+ guid: a3530a416ca433448ab4c50826faefb4
3
+ MonoImporter:
4
+ externalObjects: {}
5
+ serializedVersion: 2
6
+ defaultReferences: []
7
+ executionOrder: 0
8
+ icon: {instanceID: 0}
9
+ userData:
10
+ assetBundleName:
11
+ assetBundleVariant:
@@ -0,0 +1,8 @@
1
+ fileFormatVersion: 2
2
+ guid: 7e8f97d020fcd2740b34e8d69e4f882d
3
+ folderAsset: yes
4
+ DefaultImporter:
5
+ externalObjects: {}
6
+ userData:
7
+ assetBundleName:
8
+ assetBundleVariant:
@@ -0,0 +1,90 @@
1
+ using System;
2
+
3
+ using UnityEngine;
4
+
5
+ namespace Adrenak.UniVoice.Filters {
6
+ /// <summary>
7
+ /// A filter that applies Gaussian blur over audio data to smoothen it.
8
+ /// This is somewhat effective in removing noise from the audio.
9
+ /// </summary>
10
+ public class GaussianAudioBlur : IAudioFilter {
11
+ readonly float sigma;
12
+ readonly int range;
13
+ byte[] lastInput;
14
+
15
+ public GaussianAudioBlur(float sigma = 2, int range = 2) {
16
+ this.sigma = sigma;
17
+ this.range = range;
18
+ }
19
+
20
+ public AudioFrame Run(AudioFrame frame) {
21
+ var input = frame.samples;
22
+ if (input == null || input.Length == 0) {
23
+ frame.samples = null;
24
+ return frame;
25
+ }
26
+
27
+ // If this is the first audio input we've received, we simply apply the gaussian filter
28
+ // and return the result.
29
+ if (lastInput == null) {
30
+ lastInput = input;
31
+ frame.samples = Utils.Bytes.FloatsToBytes(
32
+ ApplyGaussianFilter(Utils.Bytes.BytesToFloats(input))
33
+ );
34
+ return frame;
35
+ }
36
+
37
+ // Else, if we've had some input before, we also consider the previously processed
38
+ // audio. We make an array that has both the previous and the current input, smoothen
39
+ // it, and then return the second half of the array. This reducing jittering by making
40
+ // the smoothing a little more seamless.
41
+ else {
42
+ // Create an all input, that also has the input from the last time this filter ran.
43
+ byte[] allInput = new byte[lastInput.Length + input.Length];
44
+ Buffer.BlockCopy(lastInput, 0, allInput, 0, lastInput.Length);
45
+ Buffer.BlockCopy(input, 0, allInput, lastInput.Length, input.Length);
46
+
47
+ // smoothen all input
48
+ byte[] allInputSmooth = Utils.Bytes.FloatsToBytes(
49
+ ApplyGaussianFilter(Utils.Bytes.BytesToFloats(allInput))
50
+ );
51
+
52
+ // get the second half of the smoothened values
53
+ byte[] result = new byte[input.Length];
54
+ Buffer.BlockCopy(allInputSmooth, lastInput.Length, result, 0, input.Length);
55
+
56
+ lastInput = input;
57
+ frame.samples = result;
58
+ return frame;
59
+ }
60
+ }
61
+
62
+ float[] ApplyGaussianFilter(float[] inputArray) {
63
+ int length = inputArray.Length;
64
+ float[] smoothedArray = new float[length];
65
+
66
+ for (int i = 0; i < length; i++) {
67
+ float sum = 0.0f;
68
+ float weightSum = 0.0f;
69
+
70
+ for (int j = -range; j <= range; j++) {
71
+ int index = i + j;
72
+ if (index >= 0 && index < length) {
73
+ float weight = Gaussian(j, sigma);
74
+ sum += inputArray[index] * weight;
75
+ weightSum += weight;
76
+ }
77
+ }
78
+
79
+ smoothedArray[i] = sum / weightSum;
80
+ }
81
+
82
+ return smoothedArray;
83
+ }
84
+
85
+ float Gaussian(int x, float sigma) {
86
+ return (float)Mathf.Exp(-(x * x) / (2 * sigma * sigma))
87
+ / ((float)Mathf.Sqrt(2 * Mathf.PI) * sigma);
88
+ }
89
+ }
90
+ }
@@ -1,11 +1,11 @@
1
- fileFormatVersion: 2
2
- guid: 76706adfc97ef7d44823aa51d618267d
3
- MonoImporter:
4
- externalObjects: {}
5
- serializedVersion: 2
6
- defaultReferences: []
7
- executionOrder: 0
8
- icon: {instanceID: 0}
9
- userData:
10
- assetBundleName:
11
- assetBundleVariant:
1
+ fileFormatVersion: 2
2
+ guid: 5992899a0c52b09498191b477927699d
3
+ MonoImporter:
4
+ externalObjects: {}
5
+ serializedVersion: 2
6
+ defaultReferences: []
7
+ executionOrder: 0
8
+ icon: {instanceID: 0}
9
+ userData:
10
+ assetBundleName:
11
+ assetBundleVariant: