soundbeam – Rev 2
?pathlinks?
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Net.Sockets;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms;
using CSCore;
using CSCore.Codecs.WAV;
using CSCore.SoundIn;
using CSCore.SoundOut;
using Mono.Zeroconf;
namespace SoundBeam
{
/*using (WasapiCapture capture = new WasapiLoopbackCapture())
{
//if nessesary, you can choose a device here
//to do so, simply set the device property of the capture to any MMDevice
//to choose a device, take a look at the sample here: http://cscore.codeplex.com/
//initialize the selected device for recording
capture.Initialize();
capture.DataAvailable += OnCaptureDataAvailable;
//create a wavewriter to write the data to
using (WaveWriter w = new WaveWriter("dump.wav", capture.WaveFormat))
{
//setup an eventhandler to receive the recorded data
capture.DataAvailable += (s, a) =>
{
//save the recorded audio
w.Write(a.Data, a.Offset, a.ByteCount);
};
//start recording
capture.Start();
Console.ReadKey();
//stop recording
capture.Stop();
}
}*/
public partial class Form1 : Form
{
private static readonly CancellationTokenSource CancellationTokenSource = new CancellationTokenSource();
private static readonly TcpServer TcpServer = new TcpServer("0.0.0.0", 9000);
private static readonly WasapiCapture WasapiCapture = new WasapiCapture();
private static readonly RegisterService SoundBeamRegisterService = new RegisterService();
private static readonly ServiceBrowser SoundBeamServiceBrowser = new ServiceBrowser();
private static readonly Dictionary<TcpClient, WasapiOut> WasapiOut = new Dictionary<TcpClient, WasapiOut>();
private static readonly BindingList<DiscoveredServer> DiscoveredServersBindingList = new BindingList<DiscoveredServer>();
private static readonly BindingSource DiscoveredServersBindingSource =
new BindingSource(DiscoveredServersBindingList, null);
public Form1()
{
InitializeComponent();
// Set the tool strip combo box binding.
sendToolStripComboBox.ComboBox.DisplayMember = "Hostname";
sendToolStripComboBox.ComboBox.ValueMember = "Hostname";
sendToolStripComboBox.ComboBox.DataSource = DiscoveredServersBindingSource;
sendToolStripComboBox.ComboBox.BindingContext = this.BindingContext;
// Register local service.
SoundBeamRegisterService.Name = "SoundBeam Audio Sink";
SoundBeamRegisterService.RegType = "_soundbeam._tcp";
SoundBeamRegisterService.Port = 9000;
SoundBeamRegisterService.UPort = 9000;
SoundBeamRegisterService.ReplyDomain = "local.";
SoundBeamRegisterService.Response += OnRegisterServiceResponse;
SoundBeamRegisterService.Register();
// Browse for services.
SoundBeamServiceBrowser.ServiceAdded += OnSoundBeamServiceBrowserServiceAdded;
SoundBeamServiceBrowser.Browse(0, AddressProtocol.Any, "_soundbeam._tcp", "local.");
}
/// <summary>
/// Clean up any resources being used.
/// </summary>
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
TcpServer.Dispose();
WasapiCapture.Dispose();
SoundBeamRegisterService.Dispose();
SoundBeamServiceBrowser.Dispose();
components.Dispose();
}
base.Dispose(disposing);
}
private void OnTcpServerClientConnected(object sender, TcpClientConnectedEventArgs args)
{
WasapiOut.Add(args.TcpClient, new WasapiOut());
using (var waveReader = new WaveFileReader(args.TcpClient.GetStream()))
{
WasapiOut[args.TcpClient].Initialize(waveReader);
WasapiOut[args.TcpClient].Play();
}
}
private void OnSoundBeamServiceBrowserServiceAdded(object o, ServiceBrowseEventArgs args)
{
if (args?.Service == null)
return;
args.Service.Resolved += OnSoundBeamServiceResolved;
args.Service.Resolve();
}
private void OnSoundBeamServiceResolved(object o, ServiceResolvedEventArgs args)
{
if (args?.Service == null)
return;
args.Service.Resolved -= OnSoundBeamServiceResolved;
// Do not add already added servers.
if (DiscoveredServersBindingList.Any(server =>
string.Equals(server.Hostname, args.Service.HostTarget, StringComparison.OrdinalIgnoreCase) &&
server.Port == args.Service.Port))
return;
Invoke((Action) (() =>
{
DiscoveredServersBindingList.Add(new DiscoveredServer(args.Service.HostTarget, args.Service.Port));
}));
}
private void OnRegisterServiceResponse(object o, RegisterServiceEventArgs args)
{
if (args.IsRegistered)
{
notifyIcon1.ShowBalloonTip(250, "SoundBeam Audio Sink Registered", "Bonjour service registered successfully.", ToolTipIcon.Info);
return;
}
notifyIcon1.ShowBalloonTip(250, "SoundBeam Sink Failed to Register", "Failed to register SoundBeam sink with bonjour.", ToolTipIcon.Error);
}
private void OnCaptureDataAvailable(object sender, DataAvailableEventArgs args)
{
// Send data to destination.
}
private void OnReceiveToolStripMenuItemCheckedChanged(object sender, EventArgs e)
{
switch (((ToolStripMenuItem) sender).Checked)
{
case true:
// Listen for TCP connections.
TcpServer.ClientConnected += OnTcpServerClientConnected;
TcpServer.Start();
break;
default:
TcpServer.ClientConnected -= OnTcpServerClientConnected;
TcpServer.Stop();
break;
}
}
private void OnSendToolStripMenuItemCheckedChanged(object sender, EventArgs e)
{
}
private void OnQuitToolStripMenuItemClick(object sender, EventArgs e)
{
Dispose(true);
Application.Exit();
}
private void OnFormLoad(object sender, EventArgs e)
{
}
}
}