Here is the full code of client #2.
Code:
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using TeamSpeak.Sdk;
using TeamSpeak.Sdk.Client;
namespace simdjinni_voiceserver
{
class Server
{
static Connection Connection;
const string IdentityFile = "identity.txt";
private CustomDevice VirtualDevice;
Dictionary<ushort, MemoryStream> VoiceStreams = new Dictionary<ushort, MemoryStream>();
int counter = 0;
public Server()
{
// Initialise TS3
InitialiseTS3();
// Register custom devices
VirtualDevice = new CustomDevice(
"VirtualDevice",
SamplingRate.Hz16000,
1,
SamplingRate.Hz16000,
1);
Connection.OpenPlayback(VirtualDevice);
Connection.OpenCapture(VirtualDevice);
string identity = ReadIdentity() ?? Library.CreateIdentity();
Console.WriteLine($"Client Identity: {identity}");
Task starting = Connection.Start(identity, "192.168.0.10", 9987, "Watson", serverPassword: "secret");
Console.WriteLine("Client lib initialized and running");
Console.WriteLine($"Client lib version: {Library.Version}({Library.VersionNumber})");
try
{
starting.Wait();
}
catch (AggregateException e)
{
if (e.InnerException is TeamSpeakException)
{
Error errorCode = ((TeamSpeakException)e.InnerException).ErrorCode;
Console.WriteLine("Failed to connect to server: {0}", errorCode);
return;
}
else
{
throw;
}
}
Console.WriteLine();
Console.WriteLine("TeamSpeak 3 client initialised");
Connection.Preprocessor.Vad = false;
var samples = (int)(16000 * 0.02);
var buffer = new short[samples];
Task.Run(() =>
{
while (true)
{
// Drain the virtual playback buffer 20ms at a time
while (VirtualDevice.AcquireData(buffer, samples)) { }
Thread.Sleep(20);
}
});
// Main loop
while (true);
}
private void InitialiseTS3()
{
// Pass in location of native SDK
var parameters = new LibraryParameters("../../../ts3_sdk_3.0.4/bin/");
parameters.UsedLogTypes = LogTypes.File | LogTypes.Console | LogTypes.Userlogging;
Library.Initialize(parameters);
Connection = Library.SpawnNewConnection();
Connection.Self.IsInputDeactivated = true;
// Configure event handlers
Connection.TalkStatusChanged += Connection_TalkStatusChanged;
Connection.EditPlaybackVoiceData += Connection_EditPlaybackVoiceData;
}
private void Connection_TalkStatusChanged(Client client, TalkStatus status, bool isReceivedWhisper)
{
counter++;
Trace.WriteLine($"Status changed message #{counter}");
switch (status)
{
case TalkStatus.Talking:
Trace.WriteLine($"Client {client.ID} Started Talking");
// If we have a previous Voice Stream, delete it
if (this.VoiceStreams.ContainsKey(client.ID))
{
this.VoiceStreams.Remove(client.ID);
}
// Create a new VoiceStream
this.VoiceStreams.Add(client.ID, new MemoryStream());
break;
case TalkStatus.NotTalking:
Trace.WriteLine($"Client {client.ID} Stopped Talking");
// Create a task to process
break;
}
}
private string ReadIdentity()
{
try
{
return File.ReadAllText(IdentityFile);
}
catch
{
Console.WriteLine($"Could not read file '{IdentityFile}'.");
return null;
}
}
}
}