/* 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 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 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 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();

            }
        }
Beispiel #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();
            }
        }