Skip to content

Commit

Permalink
v.1.0.0.0, 2013-07-28, 19:52:36
Browse files Browse the repository at this point in the history
= GUI only breaks if other windows move over it
+ Reconnect on drop
~ Renamed project
  • Loading branch information
9001 committed Oct 12, 2015
1 parent 8c63acf commit 22ab775
Show file tree
Hide file tree
Showing 30 changed files with 475 additions and 260 deletions.
2 changes: 1 addition & 1 deletion Loopstream.sln
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio 2012
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "LoopStream", "LoopStream\LoopStream.csproj", "{B9218FDB-D5A1-422F-BA2E-5B5326DDCEEC}"
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Loopstream", "Loopstream\Loopstream.csproj", "{B9218FDB-D5A1-422F-BA2E-5B5326DDCEEC}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Expand Down
4 changes: 2 additions & 2 deletions Loopstream/DFC.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
using System.Text;
using System.Windows.Forms;

namespace LoopStream
namespace Loopstream
{
class DFC
{
Expand Down Expand Up @@ -37,7 +37,7 @@ public void extract(Label pb)
bool extracting = false;
void exthread()
{
using (Stream stream = System.Reflection.Assembly.GetExecutingAssembly().GetManifestResourceStream("LoopStream.res.tools.dfc"))
using (Stream stream = System.Reflection.Assembly.GetExecutingAssembly().GetManifestResourceStream("Loopstream.res.tools.dfc"))
{
if (stream == null)
{
Expand Down
2 changes: 1 addition & 1 deletion Loopstream/LSDevice.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
using System.Linq;
using System.Text;

namespace LoopStream
namespace Loopstream
{
public class LSDevice
{
Expand Down
140 changes: 105 additions & 35 deletions Loopstream/LSEncoder.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,61 +6,103 @@
using System.Text;
using System.Windows.Forms;

namespace LoopStream
namespace Loopstream
{
public class LSEncoder
{
protected bool dump;
protected Process proc;
protected LSPcmFeed pimp;
protected LSSettings settings;
protected LSSettings.LSParams enc;
public LSSettings.LSParams enc;

public virtual Stream stdin { get; set; }
public virtual Stream stdout { get; set; }
public void Kill() { }
public Stream stdin { get; set; }
public Stream stdout { get; set; }
protected Stream pstdin { get; set; }
protected Stream pstdout { get; set; }
public bool crashed { get; private set; }

System.Net.Sockets.TcpClient tc;
System.Net.Sockets.NetworkStream s;

public LSEncoder()
{
stdin = stdout = pstdin = pstdout = null;
s = null;
tc = null;
enc = null;
proc = null;
pimp = null;
dump = false;
settings = null;
crashed = false;
}

protected void makeShouter()
{
System.Net.Sockets.NetworkStream prepS;
string ver = Application.ProductVersion;
string auth = "source:" + settings.pass;
auth = Convert.ToBase64String(System.Text.Encoding.UTF8.GetBytes(auth));
byte[] header = System.Text.Encoding.UTF8.GetBytes(string.Format(
"SOURCE /{1}.{2} HTTP/1.0{0}" +
"Authorization: Basic {3}{0}" +
"User-Agent: loopstream/{4}{0}" +
"Content-Type: {5}{0}" +
"ice-name: LoopStream{0}" +
"ice-public: 0{0}" +
"ice-url: https://github.com/9001/loopstream{0}" +
"ice-genre: Post-Avant Jazzcore{0}" +
"ice-audio-info: channels={6};samplerate={7};{8}={9}{0}" +
"ice-description: Wasapi Capture{0}{0}",

"\r\n",
settings.mount,
enc.ext,
auth,
ver,
enc.ext == "mp3" ? "audio/mpeg" :
enc.ext == "ogg" ? "application/ogg" :
"idk/wtf",
enc.channels == LSSettings.LSChannels.stereo ? 2 : 1,
settings.samplerate,
enc.compression == LSSettings.LSCompression.cbr ? "bitrate" : "quality",
enc.compression == LSSettings.LSCompression.cbr ? "" + enc.bitrate : enc.quality + ".0"));
byte[] header;
if (enc.ext == "mp3")
{
header = System.Text.Encoding.UTF8.GetBytes(string.Format(
"SOURCE /{1}.{2} HTTP/1.0{0}" +
"Authorization: Basic {3}{0}" +
"User-Agent: loopstream/{4}{0}" +
"Content-Type: audio/mpeg{0}" +
"ice-name: Loopstream{0}" +
"ice-public: 0{0}" +
"ice-url: https://github.com/9001/loopstream{0}" +
"ice-genre: Post-Avant Jazzcore{0}" +
"ice-audio-info: channels={5};samplerate={6};{7}={8}{0}" +
"ice-description: Wasapi Capture{0}{0}",

"\r\n",
settings.mount,
enc.ext,
auth,
ver,
enc.channels == LSSettings.LSChannels.stereo ? 2 : 1,
settings.samplerate,
enc.compression == LSSettings.LSCompression.cbr ? "bitrate" : "quality",
enc.compression == LSSettings.LSCompression.cbr ? "" + enc.bitrate : enc.quality + ".0"));
}
else
{
header = System.Text.Encoding.UTF8.GetBytes(string.Format(
"SOURCE /{1}.{2} ICE/1.0{0}" +
"Content-Type: application/ogg{0}" +
"Authorization: Basic {3}{0}" +
"User-Agent: loopstream/{4}{0}" +
"ice-name: Loopstream{0}" +
"ice-url: https://github.com/9001/loopstream{0}" +
"ice-genre: Post-Avant Jazzcore{0}" +
"ice-bitrate: {5}{0}" +
"ice-private: 0{0}" +
"ice-public: 0{0}" +
"ice-description: Wasapi Capture{0}" +
"ice-audio-info: ice-samplerate={6};ice-channels={5};ice-bitrate={5}{0}{0}",

"\r\n",
settings.mount,
enc.ext,
auth,
ver,
enc.compression == LSSettings.LSCompression.cbr ? enc.bitrate + "" : "Quality " + enc.quality,
settings.samplerate,
enc.channels == LSSettings.LSChannels.stereo ? 2 : 1));
}

string str = "(no reply)";
try
{
tc = new System.Net.Sockets.TcpClient();
tc.Connect(settings.host, settings.port);
s = tc.GetStream();
s.Write(header, 0, header.Length);
int i = s.Read(header, 0, header.Length);
prepS = tc.GetStream();
prepS.Write(header, 0, header.Length);
int i = prepS.Read(header, 0, header.Length);
str = System.Text.Encoding.UTF8.GetString(header, 0, i);
}
catch (Exception e)
Expand All @@ -76,7 +118,11 @@ protected void makeShouter()
}
else if (str.StartsWith("HTTP/1.0 200 OK"))
{
Program.ni.ShowBalloonTip(1000, "LoopStream Connected", "Streaming to " + settings.mount + "." + enc.ext, ToolTipIcon.Info);
s = prepS;
stdin = pstdin;
stdout = pstdout;
stamps = new List<long>();
Program.ni.ShowBalloonTip(1000, "Loopstream Connected", "Streaming to " + settings.mount + "." + enc.ext, ToolTipIcon.Info);
new System.Threading.Thread(new System.Threading.ThreadStart(reader)).Start();
}
else
Expand All @@ -86,12 +132,13 @@ protected void makeShouter()
}
}

public List<long> stamps;
protected void reader()
{
System.IO.FileStream m = null;
if (dump)
{
m = new System.IO.FileStream(string.Format("LoopStream-{0}.{1}",
m = new System.IO.FileStream(string.Format("Loopstream-{0}.{1}",
DateTime.Now.ToString("yyyy-MM-dd_HH.mm.ss"), enc.ext),
System.IO.FileMode.Create);
}
Expand All @@ -106,12 +153,35 @@ protected void reader()
{
m.Write(buffer, 0, i);
}
s.Write(buffer, 0, i);
try
{
s.Write(buffer, 0, i);
}
catch
{
crashed = true;
break;
}
}
string fn = proc.StartInfo.FileName;
fn = fn.Substring(fn.Replace('\\', '/').LastIndexOf('/') + 1).Split('.')[0];
Console.WriteLine("shutting down " + fn);
if (m != null) m.Close();
}

public void Dispose()
{
stdin = stdout = null;
crashed = true;
proc.Kill();
try
{
tc.Close();
}
catch
{
// you took a nuke to the head and you're worrying about a socket?
}
}
}
}
9 changes: 3 additions & 6 deletions Loopstream/LSLame.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,10 @@
using System.Linq;
using System.Text;

namespace LoopStream
namespace Loopstream
{
public class LSLame : LSEncoder
{
public override Stream stdin { get; set; }
public override Stream stdout { get; set; }

public LSLame(LSSettings settings, LSPcmFeed pimp)
{
this.pimp = pimp;
Expand Down Expand Up @@ -41,8 +38,8 @@ public LSLame(LSSettings settings, LSPcmFeed pimp)
}
catch { }
}
stdin = proc.StandardInput.BaseStream;
stdout = proc.StandardOutput.BaseStream;
pstdin = proc.StandardInput.BaseStream;
pstdout = proc.StandardOutput.BaseStream;
dump = settings.recMp3;
enc = settings.mp3;
makeShouter();
Expand Down
2 changes: 1 addition & 1 deletion Loopstream/LSMixer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
using System.Text;
using System.Threading.Tasks;

namespace LoopStream
namespace Loopstream
{
class LSMixer
{
Expand Down
65 changes: 58 additions & 7 deletions Loopstream/LSPcmFeed.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
using System.Linq;
using System.Text;

namespace LoopStream
namespace Loopstream
{
public class LSPcmFeed
{
Expand All @@ -27,7 +27,7 @@ public void Dispose()
{
lock (locker)
{
quitting = 1 + encoders.Count;
quitting = 2 + encoders.Count;
}
for (int a = 0; a < 100; a++)
{
Expand All @@ -39,7 +39,7 @@ public void Dispose()
}
foreach (LSEncoder enc in encoders)
{
enc.Kill();
enc.Dispose();
}
}
void dicks()
Expand All @@ -49,14 +49,17 @@ void dicks()
System.IO.FileStream w = null;
if (settings.recPCM)
{
w = new System.IO.FileStream(string.Format("LoopStream-{0}.pcm", DateTime.Now.ToString("yyyy-MM-dd_HH.mm.ss")), System.IO.FileMode.Create);
w = new System.IO.FileStream(string.Format("Loopstream-{0}.pcm", DateTime.Now.ToString("yyyy-MM-dd_HH.mm.ss")), System.IO.FileMode.Create);
}

// Create encoders first, but do not feed data
if (settings.mp3.enabled) encoders.Add(new LSLame(settings, this));
if (settings.ogg.enabled) encoders.Add(new LSVorbis(settings, this));
// Note that encoders handle creation of and connecting to shouters

// start the thread watching encoders/shouters and restarting the crashed ones
new System.Threading.Thread(new System.Threading.ThreadStart(medic)).Start();

// Finally, reposition PCM pointer to minimize latency
// (and chance of lost packets because icecast a bitch)
outlet.setReadPtr(0.2);
Expand All @@ -70,10 +73,17 @@ void dicks()
{
//Console.Write('.');
int i = wp16.Read(buffer, 0, (outlet.avail() / 4) * 4);
foreach (LSEncoder enc in encoders)
lock (locker)
{
enc.stdin.Write(buffer, 0, i);
enc.stdin.Flush();
for (int a = 0; a < encoders.Count; a++)
{
LSEncoder enc = encoders[a];
if (!enc.crashed && enc.stdin != null)
{
enc.stdin.Write(buffer, 0, i);
enc.stdin.Flush();
}
}
}
if (w != null)
{
Expand All @@ -86,6 +96,47 @@ void dicks()
if (w != null) w.Close();
}

void medic()
{
while (true)
{
if (qt()) break;
for (int a = 0; a < encoders.Count; a++)
{
LSEncoder enc = encoders[a];
if (enc.crashed)
{
enc.Dispose();
try
{
if (enc.enc.ext == "mp3")
{
enc = new LSLame(settings, this);
}
else if (enc.enc.ext == "ogg")
{
enc = new LSVorbis(settings, this);
}
else
{
System.Windows.Forms.MessageBox.Show("this shouldn't happen");
Program.kill();
}
lock (locker)
{
encoders[a] = enc;
}
}
catch
{
Program.ni.ShowBalloonTip(1000, "Connection error", "Failed to restart " + enc.enc.ext, System.Windows.Forms.ToolTipIcon.Error);
}
}
}
System.Threading.Thread.Sleep(10);
}
}

public bool qt()
{
lock (locker)
Expand Down
Loading

0 comments on commit 22ab775

Please sign in to comment.