public void VolumeFieldIsUpdated()
        {
            Context c = new Context();

            c.ConnectAndWait();

            helper.SpawnAplaySinkInput();

            SinkInput aplay = null;

            using (Operation opn = c.EnumerateSinkInputs((SinkInput input, int eol) => {
                if (eol == 0)
                {
                    if (input.Properties[Properties.ApplicationProcessBinary] == "aplay")
                    {
                        aplay = input;
                    }
                }
            })) {
                opn.Wait();
            }

            Volume vol = aplay.Volume;

            vol.Modify(0.1);
            Assert.AreNotEqual(vol, aplay.Volume);
            using (Operation opn = aplay.SetVolume(vol, (_) => {; })) {
                opn.Wait();
            }

            Helper.DrainEventLoop();
            // Wait for volume change events to percolate
            Thread.Sleep(200);
            Helper.DrainEventLoop();
            Thread.Sleep(10);
            Helper.DrainEventLoop();

            try {
                Assert.AreEqual(vol, aplay.Volume);
            } finally {
                //Reset the volume to 100%
                vol.Reset();
                using (Operation opn = aplay.SetVolume(vol, (_) => {; })) {
                    opn.Wait();
                }
            }
        }
        public void VolumeChangedEventFires()
        {
            Context c = new Context();

            c.ConnectAndWait();

            helper.SpawnAplaySinkInput();

            SinkInput aplay = null;

            using (Operation opn = c.EnumerateSinkInputs((SinkInput input, int eol) => {
                if (eol == 0)
                {
                    if (input.Properties[Properties.ApplicationProcessBinary] == "aplay")
                    {
                        aplay = input;
                    }
                }
            })) {
                opn.Wait();
            }
            Assert.IsNotNull(aplay, "Testing error: aplay SinkInput not found");

            var volumeChangedEventTriggered = new ManualResetEvent(false);

            aplay.VolumeChanged += delegate(object sender, SinkInput.VolumeChangedEventArgs e) {
                volumeChangedEventTriggered.Set();
            };
            // Ensure the volume changed callback is hooked up.
            Helper.DrainEventLoop();

            Volume vol = aplay.Volume;

            vol.Modify(0.1);

            using (Operation o = aplay.SetVolume(vol, (_) => {; })) {
                o.Wait();
            }

            Helper.RunUntilEventSignal(() => {; }, volumeChangedEventTriggered, "Timeout waiting for VolumeChanged signal");
        }
        public void TestAplaySinkInputHasCorrectApplicationBinaryProperty()
        {
            Context c = new Context();

            c.ConnectAndWait();

            helper.SpawnAplaySinkInput();

            List <SinkInput> inputs = new List <SinkInput> ();

            using (Operation opn = c.EnumerateSinkInputs((SinkInput input, int eol) => { if (eol == 0)
                                                                                         {
                                                                                             inputs.Add(input);
                                                                                         }
                                                         })) {
                opn.Wait();
            }
            SinkInput aplayInput = inputs.FirstOrDefault((SinkInput input) => input.Properties[Properties.ApplicationProcessBinary] == "aplay");

            Assert.IsNotNull(aplayInput);
        }
        public void MoveToSinkChangesSink()
        {
            string sinkNameA = "TestSinkDestinationA";
            string sinkNameB = "TestSinkDestinationB";

            helper.AddSink(sinkNameA);
            helper.AddSink(sinkNameB);

            Context c = new Context();

            c.ConnectAndWait();

            Sink destinationA = null;
            Sink destinationB = null;

            using (Operation o = c.EnumerateSinks((Sink s) => {
                if (s.Name == sinkNameA)
                {
                    destinationA = s;
                }
                else if (s.Name == sinkNameB)
                {
                    destinationB = s;
                }
            })) {
                o.Wait();
            }
            Assert.IsNotNull(destinationA);
            Assert.IsNotNull(destinationB);

            helper.SpawnAplaySinkInput();

            SinkInput aplay = null;

            using (Operation opn = c.EnumerateSinkInputs((SinkInput input, int eol) => {
                if (eol == 0)
                {
                    if (input.Properties[Properties.ApplicationProcessBinary] == "aplay")
                    {
                        aplay = input;
                    }
                }
            })) {
                opn.Wait();
            }
            Assert.IsNotNull(aplay, "Testing error: aplay SinkInput not found");

            AutoResetEvent propertiesChanged = new AutoResetEvent(false);

            aplay.PropertiesChanged += delegate(object sender, SinkInput.PropertyChangedEventArgs e) {
                propertiesChanged.Set();
            };

            using (Operation o = aplay.MoveTo(destinationA, (_) => {; })) {
                o.Wait();
            }
            Helper.RunUntilEventSignal(() => {; }, propertiesChanged, "Timeout waiting for first sink change");
            Assert.AreEqual(destinationA.Index, aplay.Sink, "Failed to move stream to first sink");

            using (Operation o = aplay.MoveTo(destinationB, (_) => {; })) {
                o.Wait();
            }
            Helper.RunUntilEventSignal(() => {; }, propertiesChanged, "Timeout waiting for second sink change");
            Assert.AreEqual(destinationB.Index, aplay.Sink, "Failed to move stream to second sink");
        }