Release Notes for 4.22 ====================== Bug Fixes --------- pvsynth corrected regarding reuse of buffer Bitwise arithmetic parsing corrected Parsing of a() function fixed If was possible to close a file twice -- OK according to the standard but crashed Windows if/then/else fixed regarding internal label generation Language Changes ---------------- The FLTK widgets integrated into the source tree opcode/endop introducted to define top-level opcodes soundin can handle up to 24 inputs A new score event, q, added to mute/unmutre instruments Opcode Fixes ------------ Bitwise logic values are rounded when creating integers loopseg and lpsshold now wrap segments vcomb and valpass fixed diskin fixed for skip time beyond the file soundin has been reworked (but may still have bugs) New Opcodes ----------- oscilikt, oscilikt, osciliktp, oscilikts -- oscilators with variying tables vco2init, vco2ift, vco2ft, vco2 mute New Gens -------- Other Changes: ------------- On X systems, it is now possible to scroll through graphs and tables displayed. Some memory leaks fixed Code improvements, both for speed and style in many places. Known Bugs ========== The following bugs are known but not yet fixed (still!) 6: PVOC can glitch (mail of Mon, 19 Jun 2000 00:45:23 +0200) 8. Spaces in arguments to opcodes can be ignored, giving oddities 9. Mismatched closing bracket can give crash (mail of Fri, 19 Oct 2001 19:00:56 +0100) Windows GUI Changes ------------------- .csd files are given higher status in the interface. If selected the score section is greyed out ==John ff ======================================================================== _________________________________________________________________ Widgets and GUI controllers by Gabriel Maldonado http://csounds.com/maldonado _________________________________________________________________ Introduction Widgets allow to design a custom Grafic User Interface to control an orchestra in real-time. They are derived from the open-source library FLTK (Fast Light Tool Kit). Such library is one of the fastest graphic libraries available, supports OpenGL and should be source compatible with different platforms (Windows, Linux, Unix and Mac OS) The subset of FLTK implemented in Csound provides the following types of objects: * Containers * Valuators * Other widgets Containers are widgets that contain other widgets, such as panels, windows etc. Csound provides the following container objects: * Panels * Scroll areas * Pack * Tabs * Groups The most useful objects are named valuators. These objects allow the user to vary synthesis parameter values in realtime. Csound provides the following valuator objects: * Sliders * Knobs * Rollers * Text fields * Joysticks * Counters There are other widgets that are not valuators nor containers: * Buttons * Button banks * Labels Also there are some other opcodes useful to modify the widget apparence: * updating widget value * setting primary and selection colors of a widget * setting font type, size and color of widgets * resizing a widget * hiding and showing a widget At last, there are three important opcodes that allowing the following actions: * running the widget thread * saving and loading snapshots containing the status of all valuators of an orchestra Here is an example preview of Csound code for a window containing a valuator. Notice that all opcodes are init-rate and must be called only once per session. The best way to use them is to place them in the header section of an orchestra, externally to any instrument (even if placing them inside an instrument is not prohibited, unpredictable results can occur if that instrument is called more than once). Each container are made up of a couple of opcodes, the first indicating the start of the container block, the last indicating the end of that container block. Some container blocks can be nested, but they must not be crossed. After defining all containers, widget thread must be run, by using the special FLrun opcode, that takes no arguments.For example to create a window, the following Csound code is needed: ;******************** sr=48000 kr=480 ksmps=100 nchnls=1 ;*** It is recommended to put almost all GUI code in the ;*** header section of an orchestra FLpanel "Panel1",450,550 ;***** start of container ; some widgets should contained here FLpanelEnd ;***** end of container FLrun ;***** runs the widget thread, it is always required! instr 1 ;put some synthesis code here endin ;********************* The previous code simply creates a panel (an empty window because no widgets are defined inside the container). The following example creates two panels and inserts a slider inside each of them: ;****************************** sr=48000 kr=480 ksmps=100 nchnls=1 FLpanel "Panel1",450,550,100,100 ;***** start of container gk1,iha FLslider "FLslider 1", 500, 1000, 2 ,1, ih1, 300,15, 20,50 FLpanelEnd ;***** end of container FLpanel "Panel1",450,550,100,100 ;***** start of container gk2,ihb FLslider "FLslider 2", 100, 200, 2 ,1, ih2, 300,15, 20,50 FLpanelEnd ;***** end of container FLrun ;***** runs the widget thread, it is always required! instr 1 ;put some synthesis code here ; gk1 and gk2 variables that contain the output of valuator ; widgets previously defined, can be used inside any instrument endin ;******************************* All widget opcodes are init-rate opcodes, even if valuators output k-rate variables. This happens because an independent thread is run, based on a callback mechanism which consumes very few processing resources, since there is not need of polling (differently from other MIDI based controller opcodes). So you can use any number of windows and valuators without degrading the realtime performance. Since FLTK tookit is still in evolution process, opcode syntax provided in Csound could be modified in future version, causing some incompatibilities between orchestras of a determinate version. However it should not be hard to modify early orchestras in order to make them compatible with later versions. For more information see following sections. _________________________________________________________________ Containers FLpanel "label", iwidth, iheight[, ix, iy, iborder] FLpanelEnd FLscroll iwidth, iheight[, ix, iy] FLscrollEnd FLtabs iwidth, iheight, ix, iy FLtabsEnd FLgroup "label", iwidth, iheight, ix, iy [, iborder, image] FLgroupEnd FLpack iwidth, iheight, ix, iy, itype, ispace, iborder FLpackEnd INITIALIZATION label - a double-quoted string containing the title of the windows or a label iwidth - width of the widget in pixels iheight - heigth of the widget in pixels ix - horizontal position of the upper left corner of the widget (in pixels) iy - vertical position of the upper left corner of the widget (in pixels) iborder - border type of the container. It is expressed by means of an integer number choosen from the following: 0 - no border 1 - down box border 2 - up box border 3 - engraved border 4 - embossed border 5 - black line border 6 - thin down border 7 - thin up border if the integer number doesn't match any of the previous values, no border is provided as default. image - a handle referring to an eventual image opened with bmopen opcode. If it is set, it allows a skin for that widget PERFORMANCE There are no k-rate arguments in containers. Containers are useful to format the graphic apparence of the widgets. The most important container is FLpanel, that actually creates a window, that can be filled with other containers and/or valuators or other kinds of widgets. FLpanel creates a window. It must be followed by the opcode FLpanelEnd when all widgets internal to it are declared. For example: FLpanel "PanelPluto",450,550,100,100 ;***** start of container gk1,ih1 FLslider "FLslider 1", 500, 1000, 2 ,1, -1, 300,15, 20,50 gk2,ih2 FLslider "FLslider 2", 300, 5000, 2 ,3, -1, 300,15, 20,100 gk3,ih3 FLslider "FLslider 3", 350, 1000, 2 ,5, -1, 300,15, 20,150 gk4,ih4 FLslider "FLslider 4", 250, 5000, 1 ,11,-1, 300,30, 20,200 FLpanelEnd ;***** end of container will output the following result: [Image] FLscroll adds scroll bars to an area. Normally you must set arguments iwidth, iheight equal to that of the parent window or other parent container; ix, iy are optional since normally are set to zero. For example the following code: FLpanel "PanelPluto",400,300,100,100 FLscroll 400,300 gk1,ih1 FLslider "FLslider 1", 500, 1000, 2 ,1, -1, 300,15, 20,50 gk2,ih2 FLslider "FLslider 2", 300, 5000, 2 ,3, -1, 300,15, 20,100 gk3,ih3 FLslider "FLslider 3", 350, 1000, 2 ,5, -1, 300,15, 20,150 gk4,ih4 FLslider "FLslider 4", 250, 5000, 1 ,11,-1, 300,30, 20,200 FLscrollEnd FLpanelEnd will show scroll bars, when the main window size is reduced: [Image] FLtabs is the "file card tabs" interface that allows useful to display several areas containing widgets in the same windows, alternatively. [Image] It must be used together with FLgroup, another container that groups child widgets. The following example code: FLpanel "Panel1",450,550,100,100 FLscroll 450,550,0,0 FLtabs 400,550, 5,5 FLgroup "sliders",380,500, 10,40,1 gk1,ihs FLslider "FLslider 1", 500, 1000, 2 ,1, -1, 300,15, 20,50 gk2,ihs FLslider "FLslider 2", 300, 5000, 2 ,3, -1, 300,15, 20,100 gk3,ihs FLslider "FLslider 3", 350, 1000, 2 ,5, -1, 300,15, 20,150 gk4,ihs FLslider "FLslider 4", 250, 5000, 1 ,11, -1, 300,30, 20,200 gk5,ihs FLslider "FLslider 5", 220, 8000, 2 ,1, -1, 300,15, 20,250 gk6,ihs FLslider "FLslider 6", 1, 5000, 1 ,13, -1, 300,15, 20,300 gk7,ihs FLslider "FLslider 7", 870, 5000, 1 ,15, -1, 300,30, 20,350 gk8,ihs FLslider "FLslider 8", 20, 20000, 2 ,6, -1, 30,400, 350,50 FLgroupEnd FLgroup "rollers",380,500, 10,30,2 gk1,ihr FLroller "FLroller 1", 50, 1000,.1,2 ,1 ,-1, 200,22, 20,50 gk2,ihr FLroller "FLroller 2", 80, 5000,1,2 ,1 ,-1, 200,22, 20,100 gk3,ihr FLroller "FLroller 3", 50, 1000,.1,2 ,1 ,-1, 200,22, 20,150 gk4,ihr FLroller "FLroller 4", 80, 5000,1,2 ,1 ,-1, 200,22, 20,200 gk5,ihr FLroller "FLroller 5", 50, 1000,.1,2 ,1 ,-1, 200,22, 20,250 gk6,ihr FLroller "FLroller 6", 80, 5000,1,2 ,1 ,-1, 200,22, 20,300 gk7,ihr FLroller "FLroller 7",50, 5000,1,1 ,2 ,-1, 30,300, 280,50 FLgroupEnd FLgroup "joysticks",380,500, 10,40,3 gk1,gk2,ihj1,ihj2 FLjoy "FLjoy", 50, 18000, 50, 18000,2,2,-1,-1,300,300,30,60 FLgroupEnd FLtabsEnd FLscrollEnd FLpanelEnd ...will produce the following result: [Image] [Image] [Image] ...each picture shows a different tab selection of the same windows. FLpack provide the functionality of compressing and aligning widgets. itype argument expresses the type of packing: 0 - vertical 1 - horizontal ispace argument sets the space between the widgets contained in FLpack. iborder sets the border type. The following example: FLpanel "Panel1",450,300,100,100 FLpack 400,300, 10,40,0,15,3 gk1,ihs1 FLslider "FLslider 1", 500, 1000, 2 ,1, -1, 300,15, 20,50 gk2,ihs2 FLslider "FLslider 2", 300, 5000, 2 ,3, -1, 300,15, 20,100 gk3,ihs3 FLslider "FLslider 3", 350, 1000, 2 ,5, -1, 300,15, 20,150 gk4,ihs4 FLslider "FLslider 4", 250, 5000, 1 ,11, -1, 300,30, 20,200 gk5,ihs5 FLslider "FLslider 5", 220, 8000, 2 ,1, -1, 300,15, 20,250 gk6,ihs6 FLslider "FLslider 6", 1, 5000, 1 ,13, -1, 300,15, 20,300 gk7,ihs7 FLslider "FLslider 7", 870, 5000, 1 ,15, -1, 300,30, 20,350 FLpackEnd FLpanelEnd ...will produce this result, when resizing the window: [Image] _________________________________________________________________ Valuators kout, ihandle FLslider "label", imin, imax, iexp, itype, idisp, iwidth, iheight, ix, iy kout, ihandle FLknob "label", imin, imax, iexp, itype, idisp, iwidth, ix, iy [,icursorsize] kout, ihandle FLroller "label", imin, imax, istep, iexp, itype, idisp, iwidth, iheight, ix, iy kout, ihandle FLtext "label", imin, imax, istep, itype, iwidth, iheight, ix, iy koutx, kouty, ihandlex, ihandley FLjoy "label", iminx, imaxx, iminy, imaxy, iexpx, iexpy, idispx, idispy, iwidth, iheight, ix, iy kout, ihandle FLcount "label", imin, imax, istep1, istep2, itype, iwidth, iheight, ix, iy, iopcode [, kp1, kp2, kp3, ...., kpN] INITIALIZATION ihandle - handle value (an integer number) that univocally references to corresponding valuator, used by further opcodes that changes some valuator's properties. It is automatically set by the corresponding valuator. label - a double-quoted string containing some user-provided text, placed near corresponding valuator imin, iminx, iminy - minumum value of output range imax, imaxx, imaxy -maximum value of output range iexp - an integer numeber denoting the behaviuor of valuator: 0 -> valuator output is linear; -1 -> valuator output is exponential; all other positive numbers indicate the number of an existing table that is used for indexing. Linear interpolation is provided in table indexing. A negative table number suppresses interpolation. IMPORTANT! Notice that tables used by valuators must be created with ftgen opcode, placed in the orchestra before corresponding valuator, not placed in the score. In fact tables placed in the score are created later than the initialization of the opcodes placed in the header section of the orchestra. itype - an integer number denoting the apparence of the valuator. Its meaning is different for different types of valuator (see below for details) idisp, idispx, idispy - a handle value that was output from a previous instance of the FLvalue opcode (see later), to display current value of current valuator in FLvalue widget itself. Otherwise (i.e. if the user don't want to use this feature that displays current values), it must be set to a negative number by the user. iwidth - width of valuator iheght - height of valuator ix and iy - horizontal and vertical positions of upper left corner of the valuator, relative to the upper left corner of corresponding window, expressed in pixels istep - a floating-point number indicating the increment of valuator value corresponding to of each mouse click istep1, istep2 - similar to istep, correspond the coarse and fine increment, used in FLcount valuator iopcode - ascii code indicating the score opcode to be scheduled. At present time the only opcode to be scheduled is the score "i" statement. So only the ascii value of this opcode (105) is valid. A zero value set the defaut of "i" opcode (so at present you can set this argument either to 0 or to 105 ,achieving the same result). icursorsize - optional. If FLknob itype is set to 1 (3D knob) this parameter controls the size of knob cursor. PERFORMANCE kout - output value kp1, kp2, ..., kpN - arguments of the activated instruments (see below) All valuators ouput their current values in the kout variable, and ihandle that is used in some cases by further opcodes (such as FLsetVal, see in a later section). FLslider opcode puts a slider into the corresponding container. itype argument can be set to the following values: 1 - shows a horizontal fill slider [Image] 2 - a vertical fill slider 3 - a horizontal engraved slider [Image] 4 - a vertical engraved slider 5 - a horizontal nice slider [Image] 6 - a vertical nice slider 7 - a horizontal up-box nice slider 8 - a vertical up-box nice slider imin argument may be greater than imax argument. This has the effect of "reversing" the object so the larger values are in the opposite direction. This also switches which end of the filled sliders is filled. FLknob puts a knob in the corresponding container. itype argument can be set to the following values: 1 - a 3-D knob [Image] 2 - a pie-like knob [Image] 3 - a clock-like knob [Image] 4 - a flat knob [Image] FLroller is a sort of knob, but put trasversally: [Image] . istep argument allow the user to arbitrally slow roller's motion, enabling arbitrary precision. itype argument can be set to the following values: 1 - horizontal roller 2 - vertical roller FLtext allow the user to modify a parameter value by directly typing it into a text field: [Image] . Value can also be modified by clicking on it and dragging the mouse horizontally. istep argument allow the user to arbitrally set the response on mouse dragging. itype argument can be set to the following values: 1 - normal behaviour 2 - dragging operation is suppressed, instead it will appear two arrow buttons. A mouse click on one of these buttons can increase/decrease the output value 3 - text editing is suppressed, only mouse dragging modify output value. FLjoy is a squared area that allows the user to modify two output values at the same time, it acts like a joystick. FLcount allows to increase/decrease value with mouse clicks on corresponding arrow buttons: [Image] . There are two kind of arrow buttons, for larger and smaller steps. Notice that FLcount not only outputs a value and a handle, but can also activate (schedule) an instrument provided by the user each time a button is pressed. P-fields of the activated instrument are kp1 (instrument number), kp2 (action time), kp3 (duration) and so on with user p-fields. If iopcode argument is set to a negative number, no instrument is activated, so this feature is optional. _________________________________________________________________ Other Widgets kout, ihandle FLbutton "label", ion, ioff, itype, iwidth, iheight, ix, iy, iopcode [, kp1, kp2, kp3, kp4, kp5, ...., kpN] kout, ihandle FLbutBank itype, inumx, inumy, iwidth, iheight, ix, iy, iopcode [, kp1, kp2, kp3, kp4, kp5, ...., kpN] ihandle Flbox "label", itype, ifont, isize, iwidth, iheight, ix, iy [, image] ihandle FLvalue "label", iwidth, iheight, ix, iy FLprintk itime, kval, idisp FLprintk2 kval, idisp INTIALIZATION ihandle - handle value (an integer number) that univocally references to corresponding widget, used by further opcodes that modify some widget's properties (see next section). It is automatically output by the corresponding widget, and must not set by the user label - a double-quoted string containing some user-provided text, placed near corresponding widget ion - value output when the button is checked ioff - value output when the button is unchecked itype - an integer number denoting the apparence of the widget. Its meaning is different for different types of widget (see below for details) inumx - number of buttons in each row of the bank inmuy - numebr of buttons in each column of the bank iwidth - width of widget iheght - height of widget ix and iy - horizontal and vertical positions of upper left corner of the valuator, relative to the upper left corner of corresponding window, expressed in pixels ifont - an integer number denoting the font of FLbox isize - size of the font itime - How much time in seconds is to elapse between updating display. iopcode - score opcode type. You have to provide the ascii code of the letter corresponding to the score opcode. At present time only 'i' (ascii code 105) score statements are supported. A zero value refers to default opcode that is a "i". So both 0 and 105 activates 'i' opcode. a value of -1 disables opcode feature. image - a handle referring to an eventual image opened with bmopen opcode. If it is set, it allows a skin for that widget PERFORMANCE kout - output value kp1, kp2, ..., kpN - arguments of the activated instruments (see below) kval - k-rate signal to be displayed FLbutton opcode creates a button. Several kind of buttons are possible, according to the value of itype argument: 1 - normal button 2 - light button 3 - check button 4 - round button This is the apparence of the buttons: [Image] Buttons of type 2, 3 and 4 also output (kout argument) the value contained in ion argument when checked, and that contained in ioff arguement, when unchecked. By adding 10 to itype argument (i.e. by setting 11 for type 1, 12 for type 2, 13 for type 3 and 14 for type 4) it is possible to skip button value when getting/setting snapshots (see later section). FLbutton not only outputs a value, but can also activate (or schedule) an instrument provided by the user each time a button is pressed. If iopcode argument is set to a negative number, no instrument is activated, so this feature is optional. In order to activate an instrument, iopcode must be set to 0 or to 105 (the ascii code of character "i", referring to the i score opcode). P-fields of the activated instrument are kp1 (instrument number), kp2 (action time), kp3 (duration) and so on with user p-fields. Notice that, in dual state buttons (light button, check button and round button), the instrument is activated only when button state changes from unchecked to checked (not when passing from checked to unchecked). FLbutBank opcode creates a bank of buttons. For example, the following line: gkButton,ihb1 FLbutBank 12, 8,8, 380,180, 50,350, 0,7,0,0,5000,6000 will create the this bank: [Image] A click to a button checks that button, and eventually uncheck a previous checked button belonging to the same bank. So the behaviour is always that of radio-buttons. Notice that each button is labeled with a progressive number. kout argument is filled with that number when corresponding button is checked. FLbutBank not only outputs a value, but can also activate (or schedule) an instrument provided by the user each time a button is pressed. If iopcode argument is set to a negative number, no instrument is activated, so this feature is optional. In order to activate an instrument, iopcode must be set to 0 or to 105 (the ascii code of character "i", referring to the i score opcode). P-fields of the activated instrument are kp1 (instrument number), kp2 (action time), kp3 (duration) and so on with user p-fields. itype argument sets the type of buttons identically to FLbutton opcode (see above). By adding 10 to itype argument (i.e. by setting 11 for type 1, 12 for type 2, 13 for type 3 and 14 for type 4) it is possible to skip current FLbutBank value when getting/setting snapshots (see later section). FLbutBank is very useful to retreive snapshots. FLbox is useful to show some text in a window. The text is bounded by a box, whose aspect depends on itype argument. The following values are legal for itype: 1 - flat box 2 - up box 3 - down box 4 - thin up box 5 - thin down box 6 - engraved box 7 - embossed box 8 - border box 9 - shadow box 10 - rounded box 11 - rounded box with shadow 12 - rounded flat box 13 - rounded up box 14 - rounded down box 15 - diamond up box 16 - diamond down box 17 - oval box 18 - oval shadow box 19 - oval flat box ifont argument set the font type. The following values are legal for ifont: 1 - helvetica (same as arial under Windows) 2 - helvetica bold 3 - helvetica italic 4 - helvetica bold italic 5 - courier 6 - courier bold 7 - courier italic 8 - courier bold italic 9 - times 10 - times bold 11 - times italic 12 - times bold italic 13 - symbol 14 - screen 15 - screen bold 16 - dingbats FLvalue shows current values of a valuator in a text field. It outputs ihandle that can then be used as idisp argument of a valuator (see previous section). In such a way, the values of that valuator will diamically be shown in the text field. FLprintk is similar to printk, but shows values of a k-rate signal into a text field instead of showing that in the console. idisp argument must be filled with the ihandle return value of a previous FLvalue opcode. While FLvalue should be placed in the header section of an orchestra, inside an FLpanel/FLpanelEnd block, FLprintk must be placed inside an instrument to operate correctly. For this reason, it slows-down performance, and should be used for debugging purposes only. FLprintk2 is similar to FLprintk, but shows kvar value only each time it changes. Useful for monitoring MIDI control changes when using sliders. It should be used for debugging purposes only, since it slows-down performance. _________________________________________________________________ Modifying Widget Apparence FLcolor ired, igreen, iblue FLcolor2 ired, igreen, iblue FLlabel isize, ifont, ialign, ired, igreen, iblue FLsetVal_i ivalue, ihandle FLsetVal ktrig, kvalue, ihandle FLsetColor ired, igreen, iblue, ihandle FLsetColor2 ired, igreen, iblue, ihandle FLsetTextSize isize, ihandle FLsetTextColor ired, igreen, iblue, ihandle FLsetFont ifont, ihandle FLsetTextType itype, ihandle FLsetText "itext", ihandle FLsetSize iwidth, iheight, ihandle FLsetPosition ix, iy, ihandle FLhide ihandle FLshow ihandle FLsetBox itype, ihandle FLsetAlign ialign, ihandle FLsetImage imageHandle, ihandle [, iflag] FLsetOverlay ktrig, kx, ky, kwidth, kheight, ihandle FLtextSize isize INITIALIZATION ihandle - an integer number (used as unique identifier) taken from the output of a previusly located widget opcode (which corresponds to the target widget), in order to univocally identify its reference when modifying its apparence with this class of opcodes. User must not set ihandle value directly, otherwise a Csound crash will occur. ired, igreen, iblue - a color of the target widget. It can be the first color, second color or font color, according to the opcode. The range for each RGB component is 0-255 ialign - sets the alignment of the label text of widgets ifont - sets the the font type of the label of a widget ired1, igreen1, iblue1 - first color of the target widget. The range for each RGB component is 0-255 ired2, igreen2, iblue2 - second color (selection color) of the target widget. The range for each RGB component is 0-255 isize - size of the font of the target widget. Normal values are in the order of 15. Greater numbers enlarge font size, while smaller numbers reduce it. iwidth - width of the target widget iheght - height of the target widget ix and iy - horizontal and vertical positions of upper left corner of the target widget, relative to the upper left corner of corresponding window, expressed in pixels itype - an integer number that modify the apparence of the target widget. Its meaning is different for different opcodes (see below for details) itext - a double-quoted string denoting the text of the label of the widget. imageHandle - an integer number corresponding to an image opened with bmopen. image must be created in array of raw bytes format (iflag argument of bmopen set to 1, or 2 if you intend also access array of line pointers format) iflag - in FLsetImage, resizes the widget according to image size, when non-zero. PERFORMANCE ktrig, kvalue - not implemented yet These opcodes modify the apparence of other widgets. There are two types of such opcodes, those that don't contain ihandle argument, that affect all subsequently declared widgets, and those without ihandle, which affect only a target widget previously defined. FLcolor sets the primary colors to RGB values given by the user. This opcode affects the primary color of (almost) all widgets defined next its location. User can put several instances of FLcolor in front of each widget he intend to modify. However, to modify a single widget, it could be better to use the opcode belonging to the second type (i.e. those containing ihandle argument, see below). FLcolor is designed to modify the colors of a group of related widget, that assume the same colors. The influence of FLcolor on next widgets can be turned off by setting -1 as the only argument of the opcode. Also, setting -2 (or -3) as the only value of FLcolor makes all next widget colors to be randomly selected. The difference is that -2 selects a light random color, while -3 selects a dark random color. FLcolor2 is the same of FLcolor except it affects the secondary (selection) color. Setting it to -1 turns off the influence of FLcolor2 on next widgets. A value of -2 (or -3) makes all next widget secondary colors to be randomly selected. The difference is that -2 selects a light random color, while -3 selects a dark random color. FLlabel modifies a set of parameters related to the text label apparence of a widget, i.e. size, font, alignment and color of corresponding text. This opcode affects (almost) all widgets defined next its location. User can put several instances of FLlabel in front of each widget he intend to modify. However, to modify a particular widget, it is better to use the opcode belonging to the second type (i.e. those containing ihandle argument, see below). The influence of FLlabel on next widgets can be turned off by setting -1 as the only argument of the opcode itself. FLlabel is designed to modify text attributes of a group of related widget. Legal values for ifont argument are: 1 - helvetica (same as arial under Windows) 2 - helvetica bold 3 - helvetica italic 4 - helvetica bold italic 5 - courier 6 - courier bold 7 - courier italic 8 - courier bold italic 9 - times 10 - times bold 11 - times italic 12 - times bold italic 13 - symbol 14 - screen 15 - screen bold 16 - dingbats Legal values for ialign argument are: 1 - align center 2 - align top 3 - align bottom 4 - align left 5 - align right 6 - align top-left 7 - align top-right 8 - align bottom-left 9 - align bottom-right FLsetVal_i forces the value of a valuator to a number provided by the user. This can be useful to set the initial values or to reset/update widget values for some special task. If the valuator has some graphic apparence related to position of its pointer (for example in a slider), it affect also pointer position. This and all following opcodes belong to the second type of modifiers, since they contain ihandle argument. So they affect only a single widget. Notice that, when using FLsetVal_i to set the values of FLjoy, two adjacent instances of FLsetVal_i are always required, the first matching the X value and the second the Y value of FLjoy. FLsetVal is almost identical to FLsetVal_i, except it operates at k-rate, and it affects target valuator only when ktrig is set to a non-zero value. It is not possible to use FLsetVal to set the value of FLbutton, FLbutBank and FLjoy. If you attempt to do that, probably a Csound crash will occurr. FLsetColor sets the primary color of the target widget. FLsetColor2 sets the secondary (or selection) color of the target widget. FLsetTextSize sets the size of the text label of the target widget. FLsetTextColor sets the color of the text label of the target widget. FLsetFont sets the font type of the target widget. See above for legal ifont values. FLsetTextType sets some attributes related to the fonts of the text label of the target widget. In this case, legal values of itype are: 0 - normal label 1 - no label (hides the text) 2 - symbol label (see below) 3 - shadow label 4 - engraved label 5- embossed label 6- bitmap label (not implemented yet) 7- pixmap label (not implemented yet) 8- image label (not implemented yet) 9- multi label (not implemented yet) 10- free-type label (not implemented yet) When using itype=3 (symbol label), it is possible to assign a graphical symbol instead of the text label of the target widget. In this case, the string of the target label must always start with '@'; if it starts with something else (or the symbol is not found) the label is drawn normally. The following symbols are supported: [symbols.gif] The @ sign may be followed by the following optional "formatting" characters, in this order: * '#' forces square scaling, rather than distortion to the widget's shape. * +[1-9] or -[1-9] tweaks the scaling a little bigger or smaller. * [1-9] - rotates by a multiple of 45 degrees. '6' does nothing, the others point in the direction of that key on a numeric keypad. Notice that, with FLbox and FLbutton, it is not necessary to call FLsetTextType opcode at all in order to use a symbol. In this case is sufficient set a label starting with '@' followed by the proper formatting string. FLsetText sets the label of the target widget to the double-quoted text string provided with itext argument. FLsetSize resize the target widget (not the size of the text), according to iwidth and iheight arguments. FLsetPosition sets the position of the target widget according to ix and iy arguments. Their values corrspond to the upper left corner of the widget and are relative to the upper left corner of the window that contain the widget. FLhide hides target widget, making it invisible. FLshow restore the visibility of a previously hidden widget. FLsetBox set the apparence of a box surrounding the target widget. Legal values for itype argument are: 1 - flat box 2 - up box 3 - down box 4 - thin up box 5 - thin down box 6 - engraved box 7 - embossed box 8 - border box 9 - shadow box 10 - rounded box 11 - rounded box with shadow 12 - rounded flat box 13 - rounded up box 14 - rounded down box 15 - diamond up box 16 - diamond down box 17 - oval box 18 - oval shadow box 19 - oval flat box FLsetAlign sets the text alignment of the label of the target widget. See above for legal ialign values. FLsetImage shows a RGB image inside or near the corresponding widget. imageHandle argument is an integer number corresponding to an image already opened with bmopen opcode. iflag argument (optional) can assume the following integer values: 0 - places the image into the center of parent widget 1 - resizes the parent widget according to image size 2 - tiles the image inside parent widget FLsetOverlay draws a rectangle over a widget, that can be modified at performance time. This can be useful, for example to draw a moving cursor following an image playing with bmscan opcode. FLtextSize sets the size of all subsequent text fonts. _________________________________________________________________ General Widget-related Opcodes FLrun inumSnap, inumVal FLsetsnap index [, ifn] inumSnap FLgetsnap index FLsavesnap "filename" FLloadsnap "filename" INITIALIZATION inumSnap - current number of snapshots inumVal - number of valuators (whose value is stored in a snapshot) present in current orchestra ifn - optional argument referring to an already allocated table, to store values of a snapshot. index - a number referring univocally to a snapshot. Several snapshots can be stored in the same bank. filename - a double-quoted string corresponding to a file to store or load a bank of snapshots FLrun opcode must be located at the end of all widget declarations. It has no arguments, and its purpose is to start the thread related to widgets. Widgets would not operate if FLrun is missing. FLsetsnap opcode stores current status of all valuators present in the orchestra into a snapshot location (in memory). Any number of snapshots can be stored in current bank. Banks are structures that only exist in memory, there are no other reference to them other that they can be accessed by FLsetsnap, FLsavesnap, FLloadsnap and FLgetsnap opcodes. Only a single bank can be present in memory. If ifn argument (optional) refers to an already allocated and valid table, the snapshot will be stored in the table, instead of in the bank. So that table can be accessed from other Csound opcodes. index argument univocally refers to a determinate snapshot. If the value of index refers to a previously stored snapshot, all its old values will be replaced with current ones. If index refers to a snapshot that doesn't exist, a new snapshot will be created. If index value is not adjacent with that of a previously created snapshot, some empty snapshots will be created (for example, if location with index 0 contains the only and unique snapshot present in a bank, and the user stores a new snapshot using index 5, all locations between 1 and 4 will automatically contain empty snapshots). Empty snapshots don't contain any data and are neutral. FLsetsnap outputs current number of snapshots (inumSnap argument) and the total number of values stored in each snapshot (inumVal), that is equal to the number of valuators present in the orchestra. FLgetsnap retreives a previously stored snapshot (in memory), i.e. sets all valuator to the corresponding values stored in that snaphot. index argument univocally must refer to an already existent snapshot. If index argument refers to an empty snapshot or to a snapshot that doesn't exist, no action is done. FLsetsnap outputs current number of snapshots (inumSnap argument). FLsavesnap saves all snapshots currently created (i.e. the entire memory bank) into a file whose name is filename. Since the file is a text file, snapshot values can also be edited manually, by means of a text editor. The format of data stored in the file is the following (at present time, this could be changed in next Csound version): ----------- 0 ----------- FLvalue 0 0 1 0 "" FLvalue 0 0 1 0 "" FLvalue 0 0 1 0 "" FLslider 331.946 80 5000 -1 "frequency of the first oscillator" FLslider 385.923 80 5000 -1 "frequency of the second ocillator" FLslider 80 80 5000 -1 "frequency of the third ocillator" FLcount 0 0 10 0 "this index must point to the location number where snaphsot is stored" FLbutton 0 0 1 0 "Store snapshot to current index" FLbutton 0 0 1 0 "Save snapshot bank to disk" FLbutton 0 0 1 0 "Load snapshot bank from disk" FLbox 0 0 1 0 "" ----------- 1 ----------- FLvalue 0 0 1 0 "" FLvalue 0 0 1 0 "" FLvalue 0 0 1 0 "" FLslider 819.72 80 5000 -1 "frequency of the first oscillator" FLslider 385.923 80 5000 -1 "frequency of the second ocillator" FLslider 80 80 5000 -1 "frequency of the third ocillator" FLcount 1 0 10 0 "this index must point to the location number where snaphsot is stored" FLbutton 0 0 1 0 "Store snapshot to current index" FLbutton 0 0 1 0 "Save snapshot bank to disk" FLbutton 0 0 1 0 "Load snapshot bank from disk" FLbox 0 0 1 0 "" ----------- 2 ----------- ..... etc... ----------- 3 ----------- ..... etc... --------------------------- As you can see, each shapshot contain several lines. Each snapshot is separated from previous and next snapshot by a line of this kind: "----------- snapshot Num -----------". Then there are several line containing data. Each of these lines corresponds to a widget. The first field of each line is an unquoted string containing opcode name corresponding to that widget. Second field is a number that expresses current value of a snapshot. In current version this is the only field that can be modified manually. The third and fourth fields shows minimum and maximum values allowed for that valuator. Fifth field is a special number that indicates if the valuator is linear (value 0), exponential (value -1), or is indexed by a table interpolating values (negative table numbers) or non-interpolating (positive table numbers). Last field is a quoted string with the label of the widget. Last line of the file is always "---------------------------". Note that FLvalue and FLbox are not valuators, and their values are fixed, cannot be modified. FLloadsnap loads all snapshots contained in filename into the memory bank of current orchestra. _________________________________________________________________ Slider Bank FLslidBnk "names", inumsliders [, ioutable, iwidth, iheight, ix, iy, itypetable, iexptable, istart_index, iminmaxtable] INITIALIZATION names - a double-quoted string containing the names of each slider. Each slider can have a different name. Separate each name with '@' character, for example "frequency@amplitude@cutoff". It is possible to not provide any name by giving a single space " "; in this case the opcode will automatically assign a progressive number as a label for each slider. inumsliders - number of sliders ioutable - number of a previously-allocated table in which to store output values of each slider. User must be sure that table size is large enough to contain all output cells, otherwise a segfault will crash Csound. By assigning zero to this argument, the output will be directed to the zak space, in the k-rate zone. In this case hte zak space must be previously allocated with the zakinit opcode, and the user must be sure that the allocation size is big enough to cover all sliders. Default is zero (i.e. store output in zak space). istart_index - an integer number referring to a starting offset of output cell locations. It can be positive to allow multiple banks of sliders to output in the same table or in the zak space. Default is zero (no offset). iminmaxtable - number of a previously-defined table containing a list of min-max pairs, referred to each slider. A zero value defaults 0 to 1 range for all slider, without necessity to provide a table. Default is zero iexptable - number of a previously-defined table containing a list of identifiers (i.e. integer numbers) provided to modify the behaviour of each slider independently. Identifiers can assume the following values: -1 = exponential curve response 0 = linear response number > than 0 = follow the curve of a previously-defined table to shape response of corresponding slider. In this case the number corresponds to table number. you can assume that all sliders of the bank have the same response curve (exponential or linear), in this case you can assign -1 or 0 to iexptable, without worring to previously define any table.Default value is zero (all sliders have a linear response, without having to provide a table). itypetable - number of a previously-defined table containing a list of identifiers (i.e. integer numbers) provided to modify the aspect of each individual slider independently. Identifiers can assume the following values: 1 = Fill slider 3 = Normal slider 5 or 0 = Nice slider 7 = Nice slider with down-box you can assume that all sliders of the bank have the same aspect, in this case you can assign a negative number to itypetable without worring to previously define any table. Negative numbers have the same meaning of the corresponding positive identifiers, with the difference that the same aspect is assigned to all sliders. You can also assign a random aspect to each slider, by setting itypetable to a negative number lower than -7. Default value is zero (all sliders have the aspect of nice sliders, without having to provide a table). iwidth, iheight - width and height of the rectangular area containing all sliders of the bank , excluding text labels, that are placed at the left of that area. ix, iy - horizontal and vertical position of the upper left corner of the rectangular area containing all sliders belonging to the bank. You have to leave enough space, at the left of that rectangle, in order to make labels of sliders to be visible, since labels themselves are external to the rectangular area. PERFORMANCE there are no k-rate arguments, even if cells of the output table (or the zak space) are updated at k- rate. FLslidBnk is a widget containing a bank of horizontal sliders. Any number of sliders can be placed into the bank (inumsliders argument). The output of all sliders is stored into a previously allocated table or into the zak space (ioutable argument). It is possible to determine the first location of the table (or of the zak space) in which to store the output of the first slider by means of istart_index argument. Each slider can have an individual label, that is placed at the left of it. Labels are defined by the "names" argument (see above, in the parameter description section). The output range of each slider can be individually set, by means of an external table (iminmaxtable argument). Curve response of each slider can be set individually, by means of a list of identifiers placed in a table (iexptable argument). It is possible to define the aspect of each slider indendently or to make all sliders have the same aspect (itypetable argument). iwidth, iheight, ix and iy, determine width, height, horizontal and vertical position of the rectangular area containing sliders. Notice that the label of each slider is placed at the left of them, and is not included in the rectagular area containing sliders, so the user should leave enough space at the left of the bank, by assigning a proper ix value in order to leave labels visible. ======================================================================== ar oscilikt xamp, xcps, kfn[, iphs[, istor]] kr oscilikt kamp, kcps, kfn[, iphs[, istor]] ar osciliktp kcps, kfn, kphs[, istor] ar oscilikts xamp, xcps, kfn, async, kphs[, istor] DESCRIPTION ----------- oscilikt is very similar to oscili, but allows changing the table number at k-rate. It is slightly slower than oscili (especially with high control rate), although also more accurate as it uses a 31-bit phase accumulator, as opposed to the 24-bit one used by oscili. osciliktp allows phase modulation (which is actually implemented as k-rate frequency modulation, by differentiating phase input). The disadvantage is that there is no amplitude control, and frequency can be varied only at the control rate. This opcode can be faster or slower than oscilikt, depending on the control rate. oscilikts is the same as oscilikt, except there is a sync input, that can be used to re-initialize the oscillator to a k-rate phase value. It is slower than oscilikt and osciliktp. INITIALIZATION -------------- istor (optional, defaults to 0) - skip initialization. iphs (optional, defaults to 0) - initial phase for oscilikt, in the range 0 to 1. Other values are wrapped to the allowed range. PERFORMANCE ----------- kr, ar - the output signal. xamp, kamp - amplitude. xcps, kcps - frequency in Hz. Zero and negative values are allowed, however the absolute value must be less than sr (and recommended to be less than sr/2). kfn - function table number. Can be varied at control rate (useful to "morph" waveforms, or select from a set of band-limited tables generated by GEN30). kphs - phase (k-rate). Similarly to iphs, the expected range is 0 to 1. In osciliktp, the absolute value of the difference of the current and previous value of kphs must be less than ksmps. oscilikts uses kphs only to set the initial phase, and when it is re-initialized with async. async - any positive value resets the phase of oscilikts to kphs. Zero, or negative values have no effect. EXAMPLES -------- ; ---- oscilikt.orc ---- sr = 44100 ksmps = 10 nchnls = 1 instr 1 ; instr 1: osciliktp example kphs line 0, p3, 4 a1x osciliktp 220.5, 1, 0 a1y osciliktp 220.5, 1, -kphs a1 = a1x - a1y out a1 * 14000 endin instr 2 ; instr 2: oscilikts example kfrq expon 400, p3, 1200 ; frequency envelope kphs line 0.1, p3, 0.9 ; phase atmp1 phasor 100 ; sync 1 atmp2 phasor 150 ; sync 2 async diff 1 - (atmp1 + atmp2) a1 oscilikts 14000, kfrq, 1, async, 0 a2 oscilikts 14000, kfrq, 1, async, -kphs out a1 - a2 endin ; ---- oscilikt.sco ---- f 1 0 3 -2 1 0 -1 ; sawtooth wave i 1 0 4 i 2 5 4 e AUTHOR ------ Istvan Varga Aug 2002 ======================================================================== ifn vco2init iwave[, ibasfn[, ipmul[, iminsiz[, imaxsiz[, isrcft]]]]] DESCRIPTION ----------- vco2init calculates tables for use by vco2 opcode. It is optionally also possible to access these tables as standard Csound function tables (in this case, vco2ft can be used to find the correct table number for a given oscillator frequency). In most cases, this opcode is called from the orchestra header (using vco2init in instruments is possible, but not recommended, because replacing tables during performance can result in a Csound crash if other opcodes are accessing the tables at the same time). Note that vco2init is not required for vco2 to work (tables are automatically allocated by the first vco2 call, if not done yet), however it can be useful in some cases: - pre-calculate tables at orchestra load time (this is useful to avoid generating the tables during performance, which could interrupt real-time processing) - share the tables as Csound ftables (by default, the tables can be accessed only by vco2) - change the default parameters of tables (e.g. size), or use an user defined waveform specified in a function table INITIALIZATION -------------- ifn - the first free ftable number after the allocated tables. If ibasfn (see below) was not specified, -1 is returned. iwave - sum of the following values selecting which waveforms are to be calculated: 16: triangle 8: square wave 4: pulse (not normalized) 2: 4 * x * (1 - x) (integrated sawtooth) 1: sawtooth Alternatively, iwave can be set to a negative integer that selects an user defined waveform (this also requires isrcft to be specified); vco2 can access waveform number -1, however, other user defined waveforms are usable only with vco2ft, or vco2ift. WARNING: if the selected table set already exists, it is replaced; if any opcode is accessing the tables at the same time, it is very likely that a crash will occur - this is why it is recommended to use vco2init only in the orchestra header. ibasfn (optional, defaults to -1) - ftable number from which the table set(s) can be accessed by opcodes other than vco2 (required by user defined waveforms, with the exception of -1). If this value is less than 1, it is not possible to access the tables calclulated by vco2init as Csound function tables. Note: the number, and size of tables is not fixed, and orchestras should not depend on these parameters, as they are subject to changes between releases. WARNING: these tables should not be replaced / overwritten by GEN routines or ftgen opcode, otherwise unpredictable behavior or a Csound crash may occur if vco2 is used. The first free ftable after the table array(s) is returned in ifn. ipmul (optional, defaults to -1) - multiplier value for number of harmonic partials (i.e. if one table has n partials, the next one will have n * ipmul, but at least n + 1). The allowed range for this parameter is 1.01 to 2, and zero or negative values select the default (1.05). ipmul controls how many tables are generated; the number of tables is about 1 + (1 / (ipmul - 1)) + log(maxpnum * (ipmul - 1)) / log(ipmul) where "maxpnum" is the maximum number of partials (4096, or maximum table size (see below) / 2, depending on which one is less). Thus, with the default settings, about 130 tables are created. iminsiz (optional, defaults to -1), imaxsiz (optional, defaults to -1) - minimum and maximum table size. The actual table size is calculated by multiplying the square root of the number of harmonic partials by "iminsiz", rounding up the result to the next power of two, and limiting this not to be greater than "imaxsiz". Both parameters must be power of two, and the allowed range is 16 to 262144 for iminsiz, and "iminsiz" to 16777216 for imaxsiz. Zero, or negative values select the default settings: - minimum size is 128 for all waveforms except pulse (iwave=4), for which it is 256 - the default maximum size is the minimum size multiplied by 64, but not more than 16384 if possible, and always at least the minimum size isrcft (optional, defaults to -1) - source ftable number for user defined waveforms (iwave < 0). isrcft should point to a function table containing the waveform to be used for generating the table array (table size is recommended to be at least imaxsiz points). If iwave is not negative (built-in waveforms are used), isrcft is ignored. --------------------------------------------------------------------- ifn vco2ift icps, iwave[, inyx] kfn vco2ft kcps, iwave[, inyx] DESCRIPTION ----------- vco2ft returns the function table number to be used for generating the specified waveform at a given frequency, by any Csound opcode that generates a signal by reading function tables (e.g. oscilikt). The tables must be calculated by vco2init before vco2ft is called, and shared as Csound ftables (ibasfn). vco2ift is the same as vco2ft, but works at i-time, and is suitable for use with opcodes that expect an i-rate table number (for example, oscili). INITIALIZATION -------------- ifn - the ftable number returned by vco2ift. icps - frequency in Hz. Zero and negative values are allowed, however, if the absolute value exceeds sr/2 (or sr*inyx), the selected table will contain silence. iwave - the waveform for which table number is to be selected. Allowed values are: 0: sawtooth 1: 4 * x * (1 - x) (integrated sawtooth) 2: pulse (not normalized) 3: square wave 4: triangle Additionally, negative values select user defined waveforms (see also vco2init). inyx (optional, defaults to 0.5) - bandwidth of the generated waveform, as percentage (0 to 1) of the sample rate. The expected range is 0 to 0.5 (i.e. up to sr/2), other values are limited to the allowed range. Setting this parameter to 0.25 (sr/4), or 0.3333 (sr/3) can produce a "fatter" sound in some cases, although it is more likely to reduce quality. PERFORMANCE ----------- kfn - same as ifn, but k-rate. kcps - same as icps, but k-rate. --------------------------------------------------------------------- ar vco2 kamp, kcps[, imode[, kpw[, kphs[, inyx]]]] DESCRIPTION ----------- vco2 is similar to vco, but the implementation uses pre-calculated tables of band-limited waveforms (see also GEN30), rather than integrating impulses. This opcode can be faster than vco (espacially if a low control rate is used), and also allows better sound quality. Additionally, there are more waveforms, and oscillator phase can be modulated at k-rate. The disadvantage is increased memory usage. For more details about vco2 tables, see also vco2init and vco2ft. INITIALIZATION -------------- imode (optional, defaults to 0) - sum of any of the following values, 16: enable k-rate phase control (if set, kphs is a required k-rate parameter that allows phase modulation) 1: skip initialization and exactly one of these to select the waveform to be generated: 14: user defined waveform -1 (requires vco2init) 12: triangle (no ramp, faster) 10: square wave (no PWM, faster) 8: 4 * x * (1 - x) (i.e. integrated sawtooth) 6: pulse (not normalized) 4: sawtooth / triangle / ramp 2: square / PWM 0: sawtooth The default is zero, which means a sawtooth wave with no k-rate phase control. inyx (optional, defaults to 0.5) - bandwidth of the generated waveform, as percentage (0 to 1) of the sample rate. The expected range is 0 to 0.5 (i.e. up to sr/2), other values are limited to the allowed range. Setting this parameter to 0.25 (sr/4), or 0.3333 (sr/3) can produce a "fatter" sound in some cases, although it is more likely to reduce quality. PERFORMANCE ----------- ar - the output signal. kamp - amplitude scale (in the case of waveform 6 (pulse), the actual output level can be a lot higher than this value). kcps - frequency in Hz (should be in the range -sr/2 to sr/2). kpw - pulse width of the square wave (type 2), or ramp characteristics of the triangle wave (type 4); it is required only by these waveforms, and ignored in all other cases. The expected range is 0 to 1, any other value is wrapped to the allowed range. WARNING: kpw must not be an exact integer value (e.g. 0 or 1) if a sawtooth / triangle ramp (waveform 4) is generated (in this case, the recommended range is about 0.01 to 0.99); there is no such limitation for square / PWM. kphs - oscillator phase (depending on imode, this can be either an optional i-rate parameter that defaults to zero, or required k-rate). Similarly to kpw, the expected range is 0 to 1. (note: pulse width (kpw) and phase (kphs) modulation is internally converted to frequency modulation for faster processing, and reduced artifacts when a low control rate is used. However, in the case of very long notes, and continuous fast changes in kpw or kphs, the phase may drift away from the requested value; in most cases, the phase error is at most 0.037 per hour, assuming a sample rate of 44100 Hz) EXAMPLE ------- /* ---- orchestra ---- */ sr = 44100 ksmps = 10 nchnls = 1 ; user defined waveform -1: trapezoid wave with default parameters (can be ; accessed at ftables starting from 10000) itmp ftgen 1, 0, 16384, 7, 0, 2048, 1, 4096, 1, 4096, -1, 4096, -1, 2048, 0 ift vco2init -1, 10000, 0, 0, 0, 1 ; user defined waveform -2: fixed table size (4096), number of partials ; multiplier is 1.02 (~238 tables) itmp ftgen 2, 0, 16384, 7, 1, 4095, 1, 1, -1, 4095, -1, 1, 0, 8192, 0 ift vco2init -2, ift, 1.02, 4096, 4096, 2 instr 1 kcps expon p4, p3, p5 ; instr 1: basic vco2 example a1 vco2 12000, kcps ; (sawtooth wave with default out a1 ; parameters) endin instr 2 kcps expon p4, p3, p5 ; instr 2: kpw linseg 0.1, p3/2, 0.9, p3/2, 0.1 ; PWM example a1 vco2 10000, kcps, 2, kpw out a1 endin instr 3 kcps expon p4, p3, p5 ; instr 3: vco2 with user a1 vco2 14000, kcps, 14 ; defined waveform (-1) aenv linseg 1, p3 - 0.1, 1, 0.1, 0 ; de-click envelope out a1 * aenv endin instr 4 kcps expon p4, p3, p5 ; instr 4: vco2ft example, kfn vco2ft kcps, -2, 0.25 ; with user defined waveform a1 oscilikt 12000, kcps, kfn ; (-2), and sr/4 bandwidth out a1 endin /* ---- score ---- */ i 1 0 3 20 2000 i 2 4 2 200 400 i 3 7 3 400 20 i 4 11 2 100 200 f 0 14 e AUTHOR ------ Istvan Varga Sep 2002 ======================================================================== USER DEFINED OPCODES -------------------- This feature is based on Matt J. Ingalls' subinstruments, however there are some differences (see below). sub-instruments can be used independently with the original syntax. User defined opcodes have these differences as compared to subinstruments: - opcodes are declared by opcode..endop pairs (similarly to instr..endin) - there are more argument types both for input and output - more output arguments are allowed that do not depend on nchnls - all p-fields (including p1) are copied from the calling instrument, as well as the release flag, and MIDI parameters. Changing these from opcodes has no effect on the calling instrument, but does affect opcode or sub-instrument calls inside the opcode definition. - p-fields cannot be updated at k-rate from the caller instrument, and are also not affected by input arguments - recursion is possible and only limited by available memory (this may be possible with subinstruments too, but not tested) - a local ksmps value can be set (this must be an even divisor of the ksmps of the calling instrument/opcode) both from the caller, and in the opcode definition (setksmps) - input/output to the caller instrument is done with xin and xout (these are easier to use than out, outk, etc. in sub- instruments, but work only in opcode definitions, and not in normal instruments) - better memory management (memory leaks fixed) - cannot be used as stand-alone instruments The syntax of an opcode definition is as follows: opcode Name, outtypes, intypes x1[, x2[, x3[, ... ]]] xin [setksmps iksmps] [...] xout x1[, x2[, x3[, ... ]]] endop intypes: a: a-rate k: k- or i-rate (updated at k-rate) K: k- or i-rate (updated at k- and i-rate) i: i-rate o: optional i-rate, defaults to 0 p: optional i-rate, defaults to 1 j: optional i-rate, defaults to -1 outtypes: a: a-rate k: k-rate (updated at k-rate) K: k-rate (updated at k- and i-rate) i: i-rate The setksmps statement can be used to set the local ksmps value of the opcode definition. It has one i-rate parameter specifying the new ksmps value (which is left unchanged if zero is used). setksmps should be used before any other opcodes (but allowed after xin), otherwise unpredictable results may occur. The input parameters can be read with xin, and the output is written by xout opcode (only one instance of these units should be used, as xout overwrites, and does not accumulate the output). The number and type of arguments must be the same as in the declaration. The new opcode can be used with the usual syntax: [x1[, x2[, ... ]]] Name [x1[, x2[, ... ]]][, iksmps] The input and output arguments must agree with the definition both in number (except if optional i-rate input is used) and type. An optional i-rate input parameter (iksmps) is automatically added to the intypes list, and (similarly to setksmps) sets the local ksmps value.  -=- MIME -=-  ------------28BA19D2DFF96A2 Content-Type: text/plain; charset=us-ascii Content-Transfer-Encoding: 7bit Here is another Csound patch with the following new stuff: - fixed bug in jpff_glue.c that caused compile errors with MYFLT=double - several changes in various files (including parser code) for user defined opcodes (can be declared with opcode..endop pairs, similarly to instr..endin). This is actually based on my modified subinstruments, however, as it was not compatible with Matt J. Ingalls' original subinstruments (and had some features missing, but also new ones), I made it independent of subinstruments, which are now restored to the original version (see also below for details). - the user opcode implementation is basically finished, the only change that is planned for new versions is optimization for speed (and possibly bug fixes, although I hope there is nothing to fix) - new features in user defined opcodes: more input types, "p" type renamed to "K" to avoid conflict with "p" for optional i-rate that defaults to 1, new opcode: setksmps I post the source to the developers I think are interested, but everything (source, patch, binaries, VIM files etc.) is available at the usual place: http://csounds.com/istvan/cspatches.html http://csounds.com/istvan/archive.html P.S.: (Matt): is this version OK now (I do not want to rewrite it again) ? (John): did you receive these patches ? I did not get any answer, and the BETA sources are not changed, so I do not know if my changes were rejected for some reason that I do not know, or you did not have time. --------------------------------------------------------------------- This is the list of changes in 4.21.3 (in most cases, the modifications are marked with "IV - Sep 8 2002" in the sources): aops.c: * functions kink() and koutk(): (IV - Sep 8 2002) * restored ink and outk opcodes to original (4.21) version cs.h: * at top level: (IV - Sep 8 2002) * added macros for new reserved words (OPCODE and ENDOP) * this also changed numbers of some other macros * structure INSDS: (IV - Sep 8 2002) * renamed *sub_iobufs to *opcod_iobufs disprep.c: * function printv(): (IV - Sep 8 2002) * print (int) p1 instead of insno (works better with user defined * opcodes) entry1.c: * added entries for new reserved words "opcode" (IV - Sep 8 2002) * and "endop" (see also cs.h) entry2.c: * declared new functions: (IV - Sep 8 2002) * useropcdset(), useropcd(), and setksmpsset() * restored old functions kink() and koutk() (IV - Sep 8 2002) * restored old entries for "subinstr", "ink", (IV - Sep 8 2002) * and "outk" * new entries added/modified: (IV - Sep 8 2002) * "userOpcode_#", "xin", "xout", and "setksmps" insert.c: * at top level: (IV - Sep 8 2002) * defined new global variables (all starting with global_) * these allow accessing the "real" ksmps (and other related) * value even while it is modified by user opcodes * function insert(): (IV - Sep 8 2002) * renamed sub_iobufs to opcod_iobufs * function MIDIinsert(): (IV - Sep 8 2002) * same as above, but also set p-fields p1, p2, and p3 * (this was missing from the code) * function deact(): (IV - Sep 8 2002) * recursively de-activate both subinstrument and user opcode * instances (this also needed declaring functions) * function kperf(): (IV - Sep 8 2002) * update global_kcounter along with kcounter (this occurs * in two places) * functions subinstrset(), and subinstr(): (IV - Sep 8 2002) * restored to original version by Matt J. Ingalls * functions useropcdset(), useropcd(), xinset(), (IV - Sep 8 2002) * xin(), xoutset(), xout(), and setksmpsset(): * new functions / replaced old ones for user defined opcodes * (not to be confused with Matt's subinstruments). There is * also a new opcode (setksmps). I did not mark changes in * these functions, as the whole functions should be replaced. insert.h: * restored Matt's subinstruments (macro SUBINSTNUMOUTS, * and structure SUBINST) (IV - Sep 8 2002) * new structures and macros for user defined opcodes: * OPCODENUMOUTS, OPCOD_IOBUFS, UOPCODE, XIN, * XOUT, and SETKSMPS (IV - Sep 8 2002) jpff_glue.c: * fixed definition of function MakeXYin() (IV - Sep 8 2002) * (should use MYFLT and not float) linevent.c: * declare external variables global_kcounter, and (IV - Sep 8 2002) * global_ekr * replaced all occurences of these variables: * ekr -> global_ekr * kcounter -> global_kcounter * this allows using "event" with a local ksmps oload.c: * at top level: (IV - Sep 8 2002) * declare all the global_* variables defined in insert.c * function oloadRESET(): (IV - Sep 8 2002) * reset global_ksmps and other similar variables too * function oload(): (IV - Sep 8 2002) * ENDOP is also recognized as end of instr blk (additionally * to ENDIN) * function oload(): (IV - Sep 8 2002) * set global_ksmps and related variables * function instance(): (IV - Sep 8 2002) * check for ENDOP as end of instr blk (additionally to ENDIN) otran.c: * function otran(): * check for OPCODE case (IV - Sep 8 2002) * syntax error for missing opcode/instr name (IV - Sep 8 2002) * syntax error for number as opcode name (IV - Sep 8 2002) * do error checking (number of args etc.) both * for user opcodes and named instruments (IV - Sep 8 2002) * use entry "userOpcode_#" for OPCODE, and * "subinstr" for INSTR (IV - Sep 8 2002) * checking for output and input types: * restored Matt's version for subinstruments, * new code for user defined opcodes (supports * more types) (IV - Sep 8 2002) * recognize both ENDIN and ENDOP as end of * instr blk (IV - Sep 8 2002) rdorch.c: * function getoptxt(): * define variable opcodblk (and init to 0) (IV - Sep 8 2002) * RESET code for obcodblk (IV - Sep 8 2002) * check for OPCODE as 1st real instr blk (IV - Sep 8 2002) * at label spctst: * modified checking for INSTR/ENDIN to also * deal with OPCODE/ENDOP (several changes) (IV - Sep 8 2002) schedule.c: * at top level, similarly to linevent.c, declare external vars: * global_kcounter, global_ekr, global_onedkr (IV - Sep 8 2002) * search/replace for these variables (but *NOT* in "lfo" opcode, * only in the various "schedule" units): * ekr -> global_ekr * onedkr -> global_onedkr * kcounter -> global_kcounter * this affects functions queue_event(), schedule(), schedwatch(), * kschedule(), sensOrcEvent(), triginset(), ktriginstr(), * seqtim_set(), and seqtim() widgets.cpp: * declare external global_* variables (IV - Sep 8 2002) * use originally Linux-specific stubs on all * platforms (IV - Sep 8 2002) * function ButtonSched(): * variables replaced: (IV - Sep 8 2002) * ekr -> global_ekr * onedkr -> global_onedkr * kcounter -> global_kcounter --------------------------------------------------------------------- USER DEFINED OPCODES -------------------- This feature is based on Matt J. Ingalls' subinstruments, however there are some differences (see below). sub-instruments can be used independently with the original syntax. User defined opcodes have these differences as compared to subinstruments: - opcodes are declared by opcode..endop pairs (similarly to instr..endin) - there are more argument types both for input and output - more output arguments are allowed that do not depend on nchnls - all p-fields (including p1) are copied from the calling instrument, as well as the release flag, and MIDI parameters. Changing these from opcodes has no effect on the calling instrument, but does affect opcode or sub-instrument calls inside the opcode definition. - p-fields cannot be updated at k-rate from the caller instrument, and are also not affected by input arguments - recursion is possible and only limited by available memory (this may be possible with subinstruments too, but not tested) - a local ksmps value can be set (this must be an even divisor of the ksmps of the calling instrument/opcode) both from the caller, and in the opcode definition (setksmps) - input/output to the caller instrument is done with xin and xout (these are easier to use than out, outk, etc. in sub- instruments, but work only in opcode definitions, and not in normal instruments) - better memory management (memory leaks fixed) - cannot be used as stand-alone instruments The syntax of an opcode definition is as follows: opcode Name, outtypes, intypes x1[, x2[, x3[, ... ]]] xin [setksmps iksmps] [...] xout x1[, x2[, x3[, ... ]]] endop intypes: a: a-rate k: k- or i-rate (updated at k-rate) K: k- or i-rate (updated at k- and i-rate) i: i-rate o: optional i-rate, defaults to 0 p: optional i-rate, defaults to 1 j: optional i-rate, defaults to -1 outtypes: a: a-rate k: k-rate (updated at k-rate) K: k-rate (updated at k- and i-rate) i: i-rate The setksmps statement can be used to set the local ksmps value of the opcode definition. It has one i-rate parameter specifying the new ksmps value (which is left unchanged if zero is used). setksmps should be used before any other opcodes (but allowed after xin), otherwise unpredictable results may occur. The input parameters can be read with xin, and the output is written by xout opcode (only one instance of these units should be used, as xout overwrites, and does not accumulate the output). The number and type of arguments must be the same as in the declaration. The new opcode can be used with the usual syntax: [x1[, x2[, ... ]]] Name [x1[, x2[, ... ]]][, iksmps] The input and output arguments must agree with the definition both in number (except if optional i-rate input is used) and type. An optional i-rate input parameter (iksmps) is automatically added to the intypes list, and (similarly to setksmps) sets the local ksmps value. ------------28BA19D2DFF96A2-- ========================================================================