/* 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();
            }
        }
Example #2
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();
            }
        }
Example #3
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();
            }
        }
        /**
         * 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();
            }
        }
        /* 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();
            }
        }
Example #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();
            }
        }
        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();

            }
        }
Example #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();
            }
        }
   /**
    * 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
            }
        }
Example #10
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
            }
        }