Exemplo n.º 1
0
        /* Example 7 - Communicating continuous values with Csound's Channel System
        *
        * This example introduces using Csound's Channel System to communicate
        * continuous control data (k-rate) from a host program to Csound. The
        * first thing to note is the RandomLine class. It takes in a base value
        * and a range in which to vary randomly.  The reset functions calculates
        * a new random target value (self.end), a random duration in which to
        * run (self.dur, expressed as # of audio blocks to last in duration), and
        * calculates the increment value to apply to the current value per audio-block.
        * When the target is met, the Randomline will reset itself to a new target
        * value and duration.
        *
        * In this example, we use two RandomLine objects, one for amplitude and
        * another for frequency.  We start a Csound instrument instance that reads
        * from two channels using the chnget opcode. In turn, we update the values
        * to the channel from the host program.  In this case, because we want to
        * keep our values generating in sync with the audio engine, we use a
        * while-loop instead of a CsoundPerformanceThread. To update the channel,
        * we call the SetChannel method on the Csound object, passing a channel name
        * and value.  Note: The getValue method on the RandomLine not only gets
        * us the current value, but also advances the internal state by the increment
        * and by decrementing the duration.
        *
        * In the C# object wrappers, channels are objects which are most easily used
        * via a software bus object as this implemetation demonstrates.
        */
        public void Example7()
        {
            using (var c = new Csound6NetRealtime())
            {
                c.SetOption("-odac");   // Set option for Csound
                c.SetOption("-m7");     // Set option for Csound
                c.CompileOrc(orc3);     // Compile Orchestra from String
                c.ReadScore("i1 0 10\n");//Read in a score to run for 10 seconds
                c.Start();              //Must call Start() explicitly when compiling from a string

                var amp = new RandomLine(.4, .2);   // create RandomLine for use with Amplitude
                var freq = new RandomLine(400, 80); // create RandomLine for use with Frequency

                var bus = c.GetSoftwareBus();
                //The bus's channels can be accessed by name like a dictionary.
                //If they don't yet exist, they will be defined (input/output as default)
                bus["amp"] = amp.Value;  //Create and provide and initial value for an amplitude channel
                bus["freq"] = freq.Value;//Create and provide and initial value for a frequency channel

                while (!c.PerformKsmps())
                {
                    bus["amp"] = amp.Value;
                    bus["freq"] = freq.Value;
                }
                c.Stop();
            }
        }
Exemplo n.º 2
0
        /**
         * Example 8 - More efficient Channel Communications (in a single threaded host)
         *
         * This example builds on Example 7 by replacing the calls to SetChannel
         * with using GetChannelPtr. In the Csound API, using SetChannel and GetChannel
         * is great for quick work, but ultimately it is slower than pre-fetching the
         * actual channel pointer.  This is because Set/GetChannel operates by doing a
         * lookup of the Channel Pointer, then setting or getting the value.  This
         * happens on each call. The alternative is to use GetChannelPtr, which fetches
         * the Channel Pointer and lets you directly set and get the value on the pointer.
         * The approach shown here is only safe if you remain in a single thread
         * such as managing channel values in between calls to PerformKsmps.
         *
         * The thread-safe method shown in Example6 is preferred when using events in
         * a multithreaded environment such as was hinted at in Example4.
         * You can use the Channel Pointer technique when using threads but you must use
         * a channel lock to take care in not to creating a race condition while using
         * memory shared between host and csound itself thereby causing potential glitches
         * in your music.  Further, since you write directly into unmanaged memory when
         * using this technique, getting even one byte of data wrong can crash your program.
         *
         * Like other managed hosts (like python), C# provides mechanisms that attempt
         * to contain your ability to do this.
         * The C# version supplies Get/SetValueDirect methods for channels which use
         * the channel objects declared name and direction and limits memory access to the
         * actual size defined for the channel's type.
         * The call to the memory pointer (GetChannelPtr) is internal and the returned pointer
         * is used whenever GetValueDirect or SetValueDirect is called thereby preserving
         * the speed advantage mentioned in the python example.
         *
         * Managing thread locks in host code is beyond the scope of this tutorial.
         * Use the method shown in Example6 when using more than one thread.
         *
         * The code below shows how to make indirect use of the .net Csound6Channel
         * object's GetChannelPtr function to touch channel memory directly.
         *
         */
        public void Example8()
        {
            using (var c = new Csound6NetRealtime())
            {
                c.SetOutputDac(0);
                c.SetOption("-m7");
                c.CompileOrc(orc3);     // Compile Orchestra from String
                c.ReadScore("i1 0 10\n");//Read in a score to run for 10 seconds
                c.Start();              //Must call Start() explicitly when compiling from a string

                var amps = new RandomLine(.4, .2);   // create RandomLine for use with Amplitude
                var freqs = new RandomLine(400, 80); // create RandomLine for use with Frequency

                var bus = c.GetSoftwareBus();//Get bus and define the "amp" and "freq" channels of orc3
                //Since orc3 instrument doesn't declare channels directly, define them here
                var ampChannel = bus.AddControlChannel("amp", ChannelDirection.Input);
                var freqChannel = bus.AddControlChannel("freq", ChannelDirection.Input);

                //Prime with initial values accessing channel memory directly
                ampChannel.SetValueDirect(amps.Value); //Use
                freqChannel.SetValueDirect(freqs.Value);

                while (!c.PerformKsmps())
                {
                    //continue to update memory for the two channels directly
                    ampChannel.SetValueDirect(amps.Value);
                    freqChannel.SetValueDirect(freqs.Value);
                }

                c.Stop();
            }
        }
Exemplo n.º 3
0
        /* Example 7 - Communicating continuous values with Csound's Channel System
         *
         * This example introduces using Csound's Channel System to communicate
         * continuous control data (k-rate) from a host program to Csound. The
         * first thing to note is the RandomLine class. It takes in a base value
         * and a range in which to vary randomly.  The reset functions calculates
         * a new random target value (self.end), a random duration in which to
         * run (self.dur, expressed as # of audio blocks to last in duration), and
         * calculates the increment value to apply to the current value per audio-block.
         * When the target is met, the Randomline will reset itself to a new target
         * value and duration.
         *
         * In this example, we use two RandomLine objects, one for amplitude and
         * another for frequency.  We start a Csound instrument instance that reads
         * from two channels using the chnget opcode. In turn, we update the values
         * to the channel from the host program.  In this case, because we want to
         * keep our values generating in sync with the audio engine, we use a
         * while-loop instead of a CsoundPerformanceThread. To update the channel,
         * we call the SetChannel method on the Csound object, passing a channel name
         * and value.  Note: The getValue method on the RandomLine not only gets
         * us the current value, but also advances the internal state by the increment
         * and by decrementing the duration.
         *
         * In the C# object wrappers, channels are objects which are most easily used
         * via a software bus object as this implemetation demonstrates.
         */
        public void Example7()
        {
            using (var c = new Csound6NetRealtime())
            {
                c.SetOption("-odac");               // Set option for Csound
                c.SetOption("-m7");                 // Set option for Csound
                c.CompileOrc(orc3);                 // Compile Orchestra from String
                c.ReadScore("i1 0 10\n");           //Read in a score to run for 10 seconds
                c.Start();                          //Must call Start() explicitly when compiling from a string

                var amp  = new RandomLine(.4, .2);  // create RandomLine for use with Amplitude
                var freq = new RandomLine(400, 80); // create RandomLine for use with Frequency

                var bus = c.GetSoftwareBus();
                //The bus's channels can be accessed by name like a dictionary.
                //If they don't yet exist, they will be defined (input/output as default)
                bus["amp"]  = amp.Value;  //Create and provide and initial value for an amplitude channel
                bus["freq"] = freq.Value; //Create and provide and initial value for a frequency channel

                while (!c.PerformKsmps())
                {
                    bus["amp"]  = amp.Value;
                    bus["freq"] = freq.Value;
                }
                c.Stop();
            }
        }
Exemplo n.º 4
0
        /**
         * Example 8 - More efficient Channel Communications (in a single threaded host)
         *
         * This example builds on Example 7 by replacing the calls to SetChannel
         * with using GetChannelPtr. In the Csound API, using SetChannel and GetChannel
         * is great for quick work, but ultimately it is slower than pre-fetching the
         * actual channel pointer.  This is because Set/GetChannel operates by doing a
         * lookup of the Channel Pointer, then setting or getting the value.  This
         * happens on each call. The alternative is to use GetChannelPtr, which fetches
         * the Channel Pointer and lets you directly set and get the value on the pointer.
         * The approach shown here is only safe if you remain in a single thread
         * such as managing channel values in between calls to PerformKsmps.
         *
         * The thread-safe method shown in Example6 is preferred when using events in
         * a multithreaded environment such as was hinted at in Example4.
         * You can use the Channel Pointer technique when using threads but you must use
         * a channel lock to take care in not to creating a race condition while using
         * memory shared between host and csound itself thereby causing potential glitches
         * in your music.  Further, since you write directly into unmanaged memory when
         * using this technique, getting even one byte of data wrong can crash your program.
         *
         * Like other managed hosts (like python), C# provides mechanisms that attempt
         * to contain your ability to do this.
         * The C# version supplies Get/SetValueDirect methods for channels which use
         * the channel objects declared name and direction and limits memory access to the
         * actual size defined for the channel's type.
         * The call to the memory pointer (GetChannelPtr) is internal and the returned pointer
         * is used whenever GetValueDirect or SetValueDirect is called thereby preserving
         * the speed advantage mentioned in the python example.
         *
         * Managing thread locks in host code is beyond the scope of this tutorial.
         * Use the method shown in Example6 when using more than one thread.
         *
         * The code below shows how to make indirect use of the .net Csound6Channel
         * object's GetChannelPtr function to touch channel memory directly.
         *
         */

        public void Example8()
        {
            using (var c = new Csound6NetRealtime())
            {
                c.SetOutputDac(0);
                c.SetOption("-m7");
                c.CompileOrc(orc3);                  // Compile Orchestra from String
                c.ReadScore("i1 0 10\n");            //Read in a score to run for 10 seconds
                c.Start();                           //Must call Start() explicitly when compiling from a string

                var amps  = new RandomLine(.4, .2);  // create RandomLine for use with Amplitude
                var freqs = new RandomLine(400, 80); // create RandomLine for use with Frequency

                var bus = c.GetSoftwareBus();        //Get bus and define the "amp" and "freq" channels of orc3
                //Since orc3 instrument doesn't declare channels directly, define them here
                var ampChannel  = bus.AddControlChannel("amp", ChannelDirection.Input);
                var freqChannel = bus.AddControlChannel("freq", ChannelDirection.Input);

                //Prime with initial values accessing channel memory directly
                ampChannel.SetValueDirect(amps.Value); //Use
                freqChannel.SetValueDirect(freqs.Value);

                while (!c.PerformKsmps())
                {
                    //continue to update memory for the two channels directly
                    ampChannel.SetValueDirect(amps.Value);
                    freqChannel.SetValueDirect(freqs.Value);
                }

                c.Stop();
            }
        }
Exemplo n.º 5
0
        /* Example 7 - Communicating continuous values with Csound's Channel System
         *
         * This example introduces using Csound's Channel System to communicate
         * continuous control data (k-rate) from a host program to Csound. The
         * first thing to note is the RandomLine class. It takes in a base value
         * and a range in which to vary randomly.  The reset functions calculates
         * a new random target value (this.End), a random duration in which to
         * run (this.Dur, expressed as # of audio blocks to last in duration), and
         * calculates the increment value to apply to the current value per audio-block.
         * When the target is met, the Randomline will reset itself to a new target
         * value and duration.
         *
         * In this example, we use two RandomLine objects, one for amplitude and
         * another for frequency.  We start a Csound instrument instance that reads
         * from two channels using the chnget opcode. In turn, we update the values
         * to the channel from the host program.  In this case, because we want to
         * keep our values generating in sync with the audio engine, we use a
         * while-loop instead of a CsoundPerformanceThread. To update the channel,
         * we call the SoftwareBus's channel indexer methods with new values.
         *
         * Note: The Value property on the RandomLine objects not only gets
         * us the current value, but also advances the internal state by the increment
         * and by decrementing the duration.
         *
         * In the C# object wrappers, channels are objects which are most easily used
         * via a software bus object as this implemetation demonstrates.
         */
        public void Example7()
        {
            using (var c = new Csound6NetRealtime())
            {
                c.SetOption("-odac");               // Set option for Csound
                c.SetOption("-m7");                 // Set option for Csound
                c.CompileOrc(orc3);                 // Compile Orchestra from String
                c.ReadScore("i1 0 10\n");           //Read in a score to run for 10 seconds
                c.Start();                          //Must call Start() explicitly when compiling from a string

                var amp  = new RandomLine(.4, .2);  // create RandomLine for use with Amplitude
                var freq = new RandomLine(400, 80); // create RandomLine for use with Frequency

                var bus = c.GetSoftwareBus();
                //Channels can be created explicitly:
                bus.AddControlChannel("amp", ChannelDirection.Input);
                bus["amp"] = amp.Value;  //Add an initial value: Value property changes after each use

                //Or channels can be created implicitly just by using it:
                //The bus's channels can be accessed by name like a dictionary.
                //If they don't yet exist, they will be defined (input/output as default)
                bus["freq"] = freq.Value;//Create and provide and initial value in one call

                //Now we have our channels: update them with new RandomLine values after each ksmps cycle:
                while (!c.PerformKsmps())
                {
                    bus["amp"]  = amp.Value;
                    bus["freq"] = freq.Value;
                }
                c.Stop();
            }
        }
Exemplo n.º 6
0
        /* Example 7 - Communicating continuous values with Csound's Channel System
        *
        * This example introduces using Csound's Channel System to communicate
        * continuous control data (k-rate) from a host program to Csound. The
        * first thing to note is the RandomLine class. It takes in a base value
        * and a range in which to vary randomly.  The reset functions calculates
        * a new random target value (this.End), a random duration in which to
        * run (this.Dur, expressed as # of audio blocks to last in duration), and
        * calculates the increment value to apply to the current value per audio-block.
        * When the target is met, the Randomline will reset itself to a new target
        * value and duration.
        *
        * In this example, we use two RandomLine objects, one for amplitude and
        * another for frequency.  We start a Csound instrument instance that reads
        * from two channels using the chnget opcode. In turn, we update the values
        * to the channel from the host program.  In this case, because we want to
        * keep our values generating in sync with the audio engine, we use a
        * while-loop instead of a CsoundPerformanceThread. To update the channel,
        * we call the SoftwareBus's channel indexer methods with new values.
        *
        * Note: The Value property on the RandomLine objects not only gets
        * us the current value, but also advances the internal state by the increment
        * and by decrementing the duration.
        *
        * In the C# object wrappers, channels are objects which are most easily used
        * via a software bus object as this implemetation demonstrates.
        */
        public void Example7()
        {
            using (var c = new Csound6NetRealtime())
            {
                c.SetOption("-odac");   // Set option for Csound
                c.SetOption("-m7");     // Set option for Csound
                c.CompileOrc(orc3);     // Compile Orchestra from String
                c.ReadScore("i1 0 10\n");//Read in a score to run for 10 seconds
                c.Start();              //Must call Start() explicitly when compiling from a string

                var amp = new RandomLine(.4, .2);   // create RandomLine for use with Amplitude
                var freq = new RandomLine(400, 80); // create RandomLine for use with Frequency

                var bus = c.GetSoftwareBus();
                //Channels can be created explicitly:
                bus.AddControlChannel("amp", ChannelDirection.Input);
                bus["amp"] = amp.Value;  //Add an initial value: Value property changes after each use

                //Or channels can be created implicitly just by using it:
                //The bus's channels can be accessed by name like a dictionary.
                //If they don't yet exist, they will be defined (input/output as default)
                bus["freq"] = freq.Value;//Create and provide and initial value in one call

                //Now we have our channels: update them with new RandomLine values after each ksmps cycle:
                while (!c.PerformKsmps())
                {
                    bus["amp"] = amp.Value;
                    bus["freq"] = freq.Value;
                }
                c.Stop();
            }
        }
Exemplo n.º 7
0
        public void Example9()
        {
            using (var c = new Csound6NetRealtime())
            {
                c.SetOutputDac(0);  //direct sample output to sound card

                //SetOptions requires the knowing and using the command line flags and their arguments.
                //The csound API (and C# bridge) expose another way to set csounds
                //parameters as properties.  This would suit a GUI dialog better than SetOption.
                var options = c.GetParameters(); //also var options = new Csound6Parameters(c);

                //You can read their current value: Console.Write(options.Tempo);
                Console.WriteLine(string.Format("Current Message Level = {0}", options.MessageLevel));

                //Instead of SetOptions("-m7"), you can use:
                options.MessageLevel = MessageLevel.Amps | MessageLevel.Range | MessageLevel.Warnings; //=7

                //Using IntelliSense, you can explore the various settings csound exposes (various command line flags).
                options.IsDebugMode = false;
                options.Tempo = 120; //will cause 10 in score to be 5 (tempo defaults to 60)

                c.CompileOrc(orc3);     // Compile Orchestra from String
                c.ReadScore("i1 0 10\n");//Read in a score to run for 10 seconds
                c.Start();              //Must call Start() explicitly when compiling from a string

                var amps = new RandomLine(.4, .2);   // create RandomLine for use with Amplitude
                var freqs = new RandomLine(400, 80); // create RandomLine for use with Frequency

                var bus = c.GetSoftwareBus();//Get bus and define the "amp" and "freq" channels of orc3
                //Since orc3 instrument doesn't declare channels directly, define them here
                var ampChannel = bus.AddControlChannel("amp", ChannelDirection.Input);
                var freqChannel = bus.AddControlChannel("freq", ChannelDirection.Input);

                //Prime with initial values accessing channel memory directly
                //That is, it contains a call to csoundGetChannelPtr internally.
                ampChannel.SetValueDirect(amps.Value); //Use
                freqChannel.SetValueDirect(freqs.Value);

                while (!c.PerformKsmps())
                {
                    //continue to update memory for the two channels directly
                    ampChannel.SetValueDirect(amps.Value);
                    freqChannel.SetValueDirect(freqs.Value);
                }

                c.Stop();

            }
        }
Exemplo n.º 8
0
        public void Example9()
        {
            using (var c = new Csound6NetRealtime())
            {
                c.SetOutputDac(0);  //direct sample output to sound card

                //SetOptions requires the knowing and using the command line flags and their arguments.
                //The csound API (and C# bridge) expose another way to set csounds
                //parameters as properties.  This would suit a GUI dialog better than SetOption.
                var options = c.GetParameters(); //also var options = new Csound6Parameters(c);

                //You can read their current value: Console.Write(options.Tempo);
                Console.WriteLine(string.Format("Current Message Level = {0}", options.MessageLevel));

                //Instead of SetOptions("-m7"), you can use:
                options.MessageLevel = MessageLevel.Amps | MessageLevel.Range | MessageLevel.Warnings; //=7

                //Using IntelliSense, you can explore the various settings csound exposes (various command line flags).
                options.IsDebugMode = false;
                options.Tempo       = 120;           //will cause 10 in score to be 5 (tempo defaults to 60)

                c.CompileOrc(orc3);                  // Compile Orchestra from String
                c.ReadScore("i1 0 10\n");            //Read in a score to run for 10 seconds
                c.Start();                           //Must call Start() explicitly when compiling from a string

                var amps  = new RandomLine(.4, .2);  // create RandomLine for use with Amplitude
                var freqs = new RandomLine(400, 80); // create RandomLine for use with Frequency

                var bus = c.GetSoftwareBus();        //Get bus and define the "amp" and "freq" channels of orc3
                //Since orc3 instrument doesn't declare channels directly, define them here
                var ampChannel  = bus.AddControlChannel("amp", ChannelDirection.Input);
                var freqChannel = bus.AddControlChannel("freq", ChannelDirection.Input);

                //Prime with initial values accessing channel memory directly
                //That is, it contains a call to csoundGetChannelPtr internally.
                ampChannel.SetValueDirect(amps.Value); //Use
                freqChannel.SetValueDirect(freqs.Value);

                while (!c.PerformKsmps())
                {
                    //continue to update memory for the two channels directly
                    ampChannel.SetValueDirect(amps.Value);
                    freqChannel.SetValueDirect(freqs.Value);
                }

                c.Stop();
            }
        }
Exemplo n.º 9
0
        public void TestSoftwareBus()
        {
            using (var cs = new Csound6NetRealtime())
            {
                var result = cs.Compile(new string[] { "csdFiles\\SimpleRuntime.csd" });
                Assert.AreEqual(CsoundStatus.Success, result);

                var bus = cs.GetSoftwareBus();
                Assert.IsNotNull(bus);
                Assert.IsTrue(bus.Count > 0);
                Assert.AreEqual(8, bus.Count);
                foreach (var channel in bus.Channels)
                {
                    switch (channel.Type)
                    {
                    case ChannelType.Control:
                        Assert.IsTrue(channel.Name.StartsWith("chan"));
                        Assert.IsInstanceOfType(channel, typeof(Csound6ControlChannel));
                        Assert.IsInstanceOfType(channel.Value, typeof(double));
                        Assert.AreEqual(channel.Value, bus[channel.Name]);
                        break;

                    case ChannelType.String:
                        Assert.IsInstanceOfType(channel, typeof(Csound6StringChannel));
                        Assert.IsInstanceOfType(channel.Value, typeof(string));
                        Assert.IsTrue(channel.Name.StartsWith("schan"));
                        Assert.AreEqual(channel.Value, bus[channel.Name]);
                        break;

                    case ChannelType.Audio:
                        Assert.IsInstanceOfType(channel, typeof(Csound6AudioChannel));
                        Assert.IsTrue(channel.Name.StartsWith("achan"));
                        Assert.IsInstanceOfType(channel.Value, typeof(double[]));
                        var values = channel.Value as double[];
                        Assert.AreEqual(cs.Ksmps, values.Length);
                        break;

                    case ChannelType.Pvs:
                        Assert.Fail("PVS data type not yet supported in .net");
                        break;

                    default:
                        Assert.Fail(string.Format("Software bus has unsupported channel {0} of type: {1}", channel.Name, channel.Type));
                        break;
                    }
                }
            }
        }
Exemplo n.º 10
0
 public void TestOutInCallbacks()
 {
     m_messageText = new StringBuilder();
     m_count       = 0;
     m_outval      = -1;
     using (var cs = new Csound6NetRealtime())
     {
         cs.OutputChannelCallback += TestOutputCallback;
         cs.InputChannelCallback  += TestInputCallback;
         var result = cs.Compile(new string[] { "csdFiles\\SimpleRuntime.csd" });
         Assert.AreEqual(CsoundStatus.Success, result);
         if (result == CsoundStatus.Success)
         {
             while (!cs.PerformKsmps())
             {
                 ;
             }
         }
         cs.Cleanup();
     }
 }
Exemplo n.º 11
0
 public void TestPerformanceThread()
 {
     using (var cs = new Csound6NetRealtime())
     {
         var result = cs.Compile(new string[] { "-odac0", "csdFiles\\xanadu.csd" });
         Assert.AreEqual(CsoundStatus.Success, result);
         m_perfTheadCalledBack = false;
         using (var pt = new Csound6PerformanceThread(cs))
         {
             pt.ProcessCallback += TestPerfThreadCallback;
             Assert.IsFalse(pt.IsRunning);//test initial state
             Assert.IsTrue(pt.IsPaused);
             Assert.IsTrue(pt.Status == CsoundStatus.Success);
             pt.Play();
             pt.SendScoreEvent(false, ScoreEventType.Note, new double[] { 3, 0, 15, 0, 5.10, 1.4, 0.8 });
             Thread.Sleep(1000);
             Assert.IsTrue(pt.IsRunning);
             Assert.IsFalse(pt.IsPaused);
             Assert.IsTrue(pt.Status == CsoundStatus.Success);
             Thread.Sleep(3000);
             pt.Pause();
             Thread.Sleep(1000);
             Assert.IsTrue(pt.IsRunning);
             Assert.IsTrue(pt.IsPaused);
             pt.SetScoreOffset(44.00);
             pt.TogglePause();
             Thread.Sleep(1000);
             pt.SendInputMessage("i3 0 20 0 5.10 1.4 0.8");
             Thread.Sleep(18000);
             Assert.IsTrue(pt.IsRunning);
             Assert.IsFalse(pt.IsPaused);
             pt.Stop();
             Thread.Sleep(1500);                                 //wait for threads do settle
             Assert.IsTrue(m_perfTheadCalledBack);               //insure that we executed the callback beyound the first ksmps
             Assert.IsFalse(pt.IsRunning);                       //flags eventually got set
             Assert.IsTrue(pt.Status == CsoundStatus.Completed); //finished all events
             Assert.IsTrue(cs.ScoreTime > 60.0);                 //last input message should extend past 60 seconds.
         }
     }
 }
Exemplo n.º 12
0
        /**
         * Example 4 - Using Csound's Performance Thread
         * Example 4.1 - Using Csound in a C# async/await Task for threaded execution
         *
         * In this example, we use a CsoundPerformanceThread to run Csound in
         * a native thread.  Using a native thread is important to get the best
         * runtime performance for the audio engine.
         * CsoundPerformanceThread has some convenient methods for handling events,
         * but does not have features for doing regular processing at block boundaries.
         * In general, use CsoundPerformanceThread when the only kinds of communication you
         * are doing with Csound are through events, and not using channels.
         *
         * Since VS2012, C# programmers have become comfortable with the async/await Task-based
         * paradigm for running background processes.
         * Example 4.1 shows an alternative to running csound in a separate thread (really Task)
         * to achieve the same result as example 4.
         * This approach is very useful in a GUI where a cancel event and a progress dialog
         * would be desireable.
         * This example bypasses these features; later examples will use them.
         */

        public void Example4()
        {
            using (var c = new Csound6NetRealtime())
            {
                c.SetOutputDac(0);      // Set realtime output for Csound
                c.CompileOrc(orc);      // Compile Orchestra from String
                c.ReadScore("i1 0 1");  // Read in Score from String

                c.Start();              // When compiling from strings, this call needed before performing

                // Create a new CsoundPerformanceThread, passing in the Csound object
                var t = new Csound6PerformanceThread(c);
                t.Play();   // starts the thread, which is now running separately from the main thread. This
                // call is asynchronous and will immediately return back here to continue code
                // execution.
                t.Join();   // Join will wait for the other thread to complete. If we did not call Join(),
                // after t.Play() returns we would immediate move to the next line, c.Stop().
                // That would stop Csound without really giving it time to run.
                c.Stop();    // stops Csound
                c.Cleanup(); // clean up Csound; this is useful if you're going to reuse a Csound instance
            }
        }
Exemplo n.º 13
0
   /**
    * Example 4 - Using Csound's Performance Thread
    * Example 4.1 - Using Csound in a C# async/await Task for threaded execution
    * 
    * In this example, we use a CsoundPerformanceThread to run Csound in 
    * a native thread.  Using a native thread is important to get the best
    * runtime performance for the audio engine.
    * CsoundPerformanceThread has some convenient methods for handling events,
    * but does not have features for doing regular processing at block boundaries.
    * In general, use CsoundPerformanceThread when the only kinds of communication you
    * are doing with Csound are through events, and not using channels.
    * 
    * Since VS2012, C# programmers have become comfortable with the async/await Task-based
    * paradigm for running background processes.
    * Example 4.1 shows an alternative to running csound in a separate thread (really Task)
    * to achieve the same result as example 4.
    * This approach is very useful in a GUI where a cancel event and a progress dialog
    * would be desireable.
    * This example bypasses these features; later examples will use them.
    */

        public void Example4()
        {
            using (var c = new Csound6NetRealtime())
            {
                c.SetOutputDac(0);      // Set realtime output for Csound
                c.CompileOrc(orc);      // Compile Orchestra from String
                c.ReadScore("i1 0 1");  // Read in Score from String

                c.Start();              // When compiling from strings, this call needed before performing

                // Create a new CsoundPerformanceThread, passing in the Csound object
                var t = new Csound6PerformanceThread(c);
                t.Play();   // starts the thread, which is now running separately from the main thread. This 
                // call is asynchronous and will immediately return back here to continue code
                // execution.
                t.Join();   // Join will wait for the other thread to complete. If we did not call Join(),
                // after t.Play() returns we would immediate move to the next line, c.Stop(). 
                // That would stop Csound without really giving it time to run. 
                c.Stop();   // stops Csound
                c.Cleanup();// clean up Csound; this is useful if you're going to reuse a Csound instance
            }
        }
Exemplo n.º 14
0
        public void TestChannelDirectAccess()
        {
            using (var cs = new Csound6NetRealtime())
            {
                var result = cs.Compile(new string[] { "csdFiles\\SimpleRuntime.csd" });
                Assert.AreEqual(CsoundStatus.Success, result);
                if (result == CsoundStatus.Success)
                {
                    var bus   = cs.GetSoftwareBus();
                    var chan2 = bus.GetChannel("chan2") as Csound6ControlChannel;
                    chan2.SetValueDirect(chan2.Default);
                    double val = chan2.GetValueDirect();
                    Assert.AreEqual(chan2.Default, val);

                    while (!cs.PerformKsmps())
                    {
                        Assert.AreEqual(val, chan2.GetValueDirect());
                        chan2.SetValueDirect(++val);
                    }
                }
            }
        }
Exemplo n.º 15
0
 /// <summary>
 /// Creates a threadable userdata class using the provided csound instance
 /// </summary>
 /// <param name="_csound"></param>
 public UserData(Csound6NetRealtime _csound)
 {
     Csound = _csound;
     Done   = false;
 }
Exemplo n.º 16
0
        public void TestChannelDefinition()
        {
            m_messageText = new StringBuilder();
            m_count       = 0;
            using (var cs = new Csound6NetRealtime())
            {
                cs.MessageCallback += TestMessageEvent;
                FileInfo     csf    = new FileInfo("csdFiles\\SimpleRuntime.csd");
                CsoundStatus result = cs.CompileArgs(new string[] { csf.FullName });
                Assert.AreEqual(CsoundStatus.Success, result);
                result = cs.Start();
                Assert.AreEqual(CsoundStatus.Success, result);
                var cch = new Csound6ControlChannel("chan1", ChannelDirection.Input, cs);
                Assert.AreEqual(ChannelDirection.Input, cch.Direction);
                Assert.AreEqual(ChannelBehavior.Exponential, cch.Behavior);
                Assert.AreEqual(ChannelType.Control, cch.Type);
                Assert.AreEqual(1000.0, cch.Default);
                Assert.AreEqual(500.0, cch.Minimum);
                Assert.AreEqual(2000.0, cch.Maximum);

                cch.Behavior = ChannelBehavior.Integer;
                cch.Maximum  = 2500.0;
                cch.Minimum  = 400.0;

                var cch1 = new Csound6ControlChannel("chan1", ChannelDirection.Input, cs);
                Assert.AreEqual(cch.Name, cch1.Name);
                Assert.AreEqual(cch.Minimum, cch1.Minimum);
                Assert.AreEqual(400.0, cch1.Minimum);
                Assert.AreEqual(2500.0, cch.Maximum);
                Assert.AreEqual(cch.Maximum, cch1.Maximum);
                Assert.AreEqual(ChannelBehavior.Integer, cch1.Behavior);

                var bus = new Csound6SoftwareBus(cs);
                IDictionary <string, ChannelInfo> chans = cs.GetChannelList();
                Assert.IsNotNull(chans);
                Assert.IsTrue(chans.Count > 0);
                foreach (string key in chans.Keys)//now in test for software bus. remove this part?
                {
                    ChannelInfo info = chans[key];
                    var         chan = bus.AddChannel(info);
                    switch (chan.Type)
                    {
                    case ChannelType.String:
                        Assert.IsInstanceOfType(chan, typeof(Csound6StringChannel));
                        Assert.AreEqual(256, chan.DataSize);
                        break;

                    case ChannelType.Audio:
                        Assert.IsInstanceOfType(chan, typeof(Csound6AudioChannel));
                        Assert.AreEqual(35280, chan.DataSize);      //ksmps = 4410 * sizeof(MYFLT)
                        break;

                    case ChannelType.Control:
                        Assert.IsInstanceOfType(chan, typeof(Csound6ControlChannel));
                        Assert.AreEqual(8, chan.DataSize);
                        if (chan.Name.Equals(cch1.Name))
                        {
                            Assert.AreEqual(cch.Maximum, ((Csound6ControlChannel)chan).Maximum);
                            Assert.AreEqual(cch.Minimum, ((Csound6ControlChannel)chan).Minimum);
                            Assert.AreEqual(cch.Default, ((Csound6ControlChannel)chan).Default);
                        }
                        break;

                    case ChannelType.Pvs:
                    case ChannelType.Var:
                    default:
                        Assert.IsFalse(false, string.Format("Unsupported Channel type:{0}", chan.GetType()));
                        break;
                    } //end switch
                }     //end foreach key
            }         //end using csound
            string text = m_messageText.ToString(); //if need to analyze output...
        }
Exemplo n.º 17
0
 public void TestPerfTimeChannels()
 {
     m_messageText = new StringBuilder();
     m_count       = 0;
     m_outval      = -1;
     using (var cs = new Csound6NetRealtime())
     {
         var result = cs.Compile(new string[] { "csdFiles\\SimpleRuntime.csd" });
         Assert.AreEqual(CsoundStatus.Success, result);
         if (result == CsoundStatus.Success)
         {
             var bus = cs.GetSoftwareBus();
             while (!cs.PerformKsmps())
             {
                 double[] samps   = bus["achan1"] as double[];
                 double[] sampInv = new double[samps.Length];
                 if (cs.ScoreTime <= 0.1)
                 {
                     foreach (double samp in samps)
                     {
                         Assert.IsTrue(samp == 0.0);
                     }
                     bool hasPvs = bus.HasChannel("0");
                     if (hasPvs)
                     {
                         object o = bus["0"];
                     }
                 }
                 else if (cs.ScoreTime == 0.2)
                 {
                     double prev = -1.0;
                     for (int i = 0; i < 26; i++)
                     {
                         Assert.IsTrue(samps[i] > prev);
                         prev = samps[i];
                     }
                     for (int i = 26; i < 75; i++)
                     {
                         Assert.IsTrue(prev > samps[i]);
                         prev = samps[i];
                     }
                     for (int i = 0; i < sampInv.Length; i++)
                     {
                         sampInv[i] = -samps[i];
                     }
                     bus["achan2"] = sampInv;
                 }
                 else if (cs.ScoreTime == 0.3)
                 {
                     double[] samp2 = bus["achan2"] as double[];
                     double[] samp3 = bus["achan3"] as double[]; //instrument will have put samp2 into achan3 during 0.2 second; now available in 0.3 sec
                     for (int i = 0; i < samp3.Length; i++)
                     {
                         Assert.AreEqual(samp2[i], samp3[i]);
                     }
                 }
             }
         }
         cs.Cleanup();
     }
 }