Example #1
0
        void dicks()
        {
            Logger.pcm.a("prism thread");
            long bufSize = settings.samplerate * 10;

            byte[] buffer          = new byte[bufSize * 4];
            System.IO.FileStream w = null;
            if (settings.recPCM)
            {
                Logger.pcm.a("open dump target");
                w = new System.IO.FileStream(string.Format("Loopstream-{0}.pcm", DateTime.UtcNow.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));
            }
            if (settings.opus.enabled)
            {
                encoders.Add(new LSOpus(settings, this));
            }
            // Note that encoders handle creation of and connecting to shouters

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

            // Finally, reposition PCM pointer to minimize latency
            // (and chance of lost packets because icecast a bitch)
            outlet.setReadPtr(0.2);

            // PCM reader loop, passing on to encoders/shouters
            //List<string> toclip = new List<string>();
            int align = (wp16.WaveFormat.BitsPerSample / 8) * wp16.WaveFormat.Channels;

            try
            {
                while (true)
                {
                    Logger.pcm.a("awaiting pcm");
                    int avail = 0;
                    while (!qt("dicks"))
                    {
                        avail = outlet.avail();
                        if (avail >= 2048)
                        {
                            break;
                        }

                        System.Threading.Thread.Sleep(20);
                    }

                    if (avail <= 0)
                    {
                        break;
                    }

                    //Console.Write('.');
                    int toRead = (outlet.avail() / align) * align;
                    Logger.pcm.a("reading pcm data " + buffer.Length + ", " + toRead);
                    int i = wp16.Read(buffer, 0, toRead);
                    //toclip.Add((DateTime.UtcNow.Ticks / 10000) + ", " + i);
                    Logger.pcm.a("locking for write " + i);
                    lock (locker)
                    {
                        int _soffMono   = soffMono;
                        int _soffStereo = soffStereo;
                        for (int a = 0; a < encoders.Count; a++)
                        {
                            LSEncoder enc = encoders[a];
                            if (!enc.crashed && enc.stdin != null)
                            {
                                bool silence = false;
                                if (enc.GetType() == typeof(LSVorbis))
                                {
                                    silence = true;
                                    for (int ofs = 1; ofs < i; ofs += 16)
                                    {
                                        int v = buffer[ofs];
                                        if (v > 0x80)
                                        {
                                            v = 255 - v;
                                        }
                                        if (v > 1)
                                        {
                                            silence = false;
                                            break;
                                        }
                                    }
                                    if (silence)
                                    {
                                        Logger.pcm.a("SILENCE to " + enc.enc.ext + " " + i);
                                        soffMono   = _soffMono;
                                        soffStereo = _soffStereo;
                                        bool stereo = enc.enc.channels == LSSettings.LSChannels.stereo;
                                        enc.enqueue(barf(i, stereo), i);
                                    }
                                }
                                if (!silence)
                                {
                                    //Logger.pcm.a("writing to " + enc.enc.ext + " " + i);
                                    enc.enqueue(buffer, i);
                                }
                            }
                        }
                    }
                    if (w != null)
                    {
                        //Logger.pcm.a("writing to dump " + i);
                        w.Write(buffer, 0, i);
                    }
                }
            }
            catch (Exception ex)
            {
                System.Windows.Forms.MessageBox.Show("pcm reader / enc prism just died\n\nthought you might want to know\n\n===========================\n" + ex.Message + "\n" + ex.StackTrace);
            }

            Console.WriteLine("shutting down encoder prism");
            if (w != null)
            {
                w.Close();
            }
        }
Example #2
0
        void medic()
        {
            Logger.med.a("active");
            while (!qt("medic"))
            {
                for (int a = 0; a < encoders.Count; a++)
                {
                    LSEncoder enc = encoders[a];
                    if (enc.crashed)
                    {
                        if (res_cd == 0)
                        {
                            Logger.pcm.a("pending resurrect " + enc.enc.ext);
                        }
                        if (++res_cd < 50)
                        {
                            continue;
                        }
                        res_cd = 0;

                        Logger.pcm.a("resurrecting " + enc.enc.ext);
                        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 if (enc.enc.ext == "opus")
                            {
                                enc = new LSOpus(settings, this);
                            }
                            else
                            {
                                System.Windows.Forms.MessageBox.Show("this shouldn't happen");
                                Program.kill();
                            }
                            lock (locker)
                            {
                                encoders[a] = enc;
                            }
                            Logger.pcm.a("resurrected " + enc.enc.ext);
                        }
                        catch
                        {
                            Logger.pcm.a("resurrect failure: " + enc.enc.ext);
                            if (Program.BALLOONS)
                            {
                                Program.ni.ShowBalloonTip(1000, "Connection error", "Failed to restart " + enc.enc.ext, System.Windows.Forms.ToolTipIcon.Error);
                            }
                        }
                    }
                    else if (enc.aborted)
                    {
                        string msg = "Removing " + enc.enc.ext + " encoder";

                        Logger.pcm.a(msg);
                        encoders.RemoveAt(a--);
                        if (Program.BALLOONS)
                        {
                            Program.ni.ShowBalloonTip(1000, "Connection error", msg, System.Windows.Forms.ToolTipIcon.Error);
                        }
                    }
                }
                System.Threading.Thread.Sleep(10);
            }
            Logger.med.a("disposed");
        }