diff options
Diffstat (limited to 'tests/examplefiles/test.orc')
-rw-r--r-- | tests/examplefiles/test.orc | 257 |
1 files changed, 257 insertions, 0 deletions
diff --git a/tests/examplefiles/test.orc b/tests/examplefiles/test.orc new file mode 100644 index 00000000..36725342 --- /dev/null +++ b/tests/examplefiles/test.orc @@ -0,0 +1,257 @@ +// This is a Csound orchestra file for testing a Pygments <http://pygments.org> +// lexer. Csound single-line comments can be preceded by a pair of forward +// slashes... +; ...or a semicolon. + +/* Block comments begin with /* and end with */ + +// Orchestras begin with a header of audio parameters. +nchnls = 1 +nchnls_i = 1 +sr = 44100 +0dbfs = 1 +ksmps = 10 + +// The control rate kr = sr / ksmps can be omitted when the number of audio +// samples in a control period (ksmps) is set, but kr may appear in older +// orchestras. +kr = 4410 + +// Orchestras contain instruments. These begin with the keyword instr followed +// by a comma-separated list of numbers or names of the instrument. Instruments +// end at the endin keyword and cannot be nested. +instr 1, N_a_M_e_, +Name + // Instruments contain statements. Here is a typical statement: + aSignal oscil 0dbfs, 440, 1 + // Statements are terminated with a newline (possibly preceded by a comment). + // To write a statement on several lines, precede the newline with a + // backslash. + prints \ + "hello, world\n";comment + + // Csound 6 introduced function syntax for opcodes with one or zero outputs. + // The oscil statement above is the same as + aSignal = oscil(0dbfs, 440, 1) + + // Instruments can contain control structures. + kNote = p3 + if (kNote == 0) then + kFrequency = 220 + elseif kNote == 1 then // Parentheses around binary expressions are optional. + kFrequency = 440 + endif + + // Csound 6 introduced looping structures. + iIndex = 0 + while iIndex < 5 do + print iIndex + iIndex += 1 + od + iIndex = 0 + until iIndex >= 5 do + print iIndex + iIndex += 1 + enduntil + // Both kinds of loops can be terminated by either od or enduntil. + + // Single-line strings are enclosed in double-quotes. + prints "string\\\r\n\t\"" + // Multi-line strings are enclosed in pairs of curly braces. + prints {{ + hello, + + world + }} + + // Instruments often end with a statement containing an output opcode. + outc aSignal +endin + +// Orchestras can also contain user-defined opcodes (UDOs). Here is an +// oscillator with one audio-rate output and two control-rate inputs: +opcode anOscillator, a, kk + kAmplitude, kFrequency xin + aSignal vco2 kAmplitude, kFrequency + xout aSignal +endop +instr TestOscillator + outc(anOscillator(0dbfs, 110)) +endin + +// Python can be executed in Csound +// <http://www.csounds.com/manual/html/pyrun.html>. So can Lua +// <http://www.csounds.com/manual/html/lua.html>. +pyruni {{ +import random + +pool = [(1 + i / 10.0) ** 1.2 for i in range(100)] + +def get_number_from_pool(n, p): + if random.random() < p: + i = int(random.random() * len(pool)) + pool[i] = n + return random.choice(pool) +}} + +// The Csound preprocessor supports conditional compilation and including files. +#ifdef DEBUG +#undef DEBUG +#include "filename.orc" +#endif + +// The preprocessor also supports object- and function-like macros. This is an +// object-like macro that defines a number: +#define A_HZ #440# + +// This is a function-like macro: +#define OSCIL_MACRO(VOLUME'FREQUENCY'TABLE) #oscil $VOLUME, $FREQUENCY, $TABLE# + +// Bodies of macros are enclosed in # and can contain newlines. The arguments of +// function-like macros are separated by single-quotes. Uses of macros are +// prefixed with a dollar sign. +instr TestMacro + aSignal $OSCIL_MACRO(1'$A_HZ'1) + // Not unlike PHP, macros expand in double-quoted strings. + prints "The frequency of the oscillator is $A_HZ Hz.\n" + out aSignal +endin + +// Here are other things to note about Csound. + +// There are two bitwise NOT operators, ~ and ¬ (U+00AC). The latter is common +// on keyboards in the United Kingdom +// <https://en.wikipedia.org/wiki/British_and_American_keyboards>. +instr TestBitwiseNOT + print ~42 + print ¬42 +endin + +// Csound uses # for bitwise XOR, which the Csound manual calls bitwise +// non-equivalence <http://www.csounds.com/manual/html/opnonequiv.html>. +instr TestBitwiseXOR + print 0 # 0 + print 0 # 1 + print 1 # 0 + print 1 # 1 +endin + +// Loops and if-then statements are relatively recent additions to Csound. There +// are many flow-control opcodes that involve goto and labels. +instr TestGoto + // This... + if p3 > 0 goto if_label + goto else_label +if_label: + prints "if branch\n" + goto endif_label +else_label: + prints "else branch\n" +endif_label: + + // ...is the same as this. + if p3 > 0 then + prints "if branch\n" + else + prints "else branch\n" + endif + + // This... + iIndex = 0 +loop_label: + print iIndex + iIndex += 1 + if iIndex < 10 goto loop_label + + // ...is the same as this... + iIndex = 0 +loop_lt_label: + print iIndex + loop_lt iIndex, 1, 10, loop_lt_label + + // ...and this. + iIndex = 0 + while iIndex < 10 do + print iIndex + iIndex += 1 + od +endin + +// The prints and printks opcodes +// <https://github.com/csound/csound/blob/develop/OOps/ugrw1.c#L831>, arguably +// the primary methods of logging output, treat certain sequences of characters +// different from printf in C. +instr TestPrints + // ^ prints an ESCAPE character (U+001B), not a CIRCUMFLEX ACCENT character + // (U+005E). ^^ prints a CIRCUMFLEX ACCENT. + prints "^^\n" + // ~ prints an ESCAPE character (U+001B) followed by a [, not a TILDE + // character (U+007E). ~~ prints a TILDE. + prints "~~\n" + // \A, \B, \N, \R, and \T correspond to the escaped lowercase characters (that + // is, BELL (U+0007), BACKSPACE (U+0008), new line (U+000A), CARRIAGE RETURN + // (U+000D), and tab (U+0009)). + prints "\T\R\N" + // %n, %r, and %t are the same as \n, \r, and \t, as are %N, %R, and %T. + prints "%t%r%n" + // %! prints a semicolon. This is a hold-over from old versions of Csound that + // allowed comments to begin in strings. + prints "; %!\n" +endin + +// The arguments of function-like macros can be separated by # instead of '. +// These two lines define the same macro. +#define OSCIL_MACRO(VOLUME'FREQUENCY'TABLE) #oscil $VOLUME, $FREQUENCY, $TABLE# +#define OSCIL_MACRO(VOLUME#FREQUENCY#TABLE) #oscil $VOLUME, $FREQUENCY, $TABLE# + +// Uses of macros can optionally be suffixed with a period. +instr TestMacroPeriodSuffix + aSignal $OSCIL_MACRO.(1'$A_HZ'1) + prints "The frequency of the oscillator is $A_HZ.Hz.\n" + out aSignal +endin + +// Csound has @ and @@ operator-like macros that, when followed by a literal +// non-negative integer, expand to the next power of 2 and the next power of 2 +// plus 1: +// @x = 2^(ceil(log2(x + 1))), x >= 0 +// @@0 = 2 +// @@x = 2^(ceil(log2(x))) + 1, x > 0 +// These macros are in +// <https://github.com/csound/csound/blob/develop/Engine/csound_orc.l#L542> (and +// <https://github.com/csound/csound/blob/develop/Engine/csound_sco.lex#L202>) +// and are described at <http://www.csounds.com/manual/html/ScoreEval.html>. +instr TestAt + prints "%d %2d %2d\n", 0, @0, @@0 + prints "%d %2d %2d\n", 1, @1, @@1 + prints "%d %2d %2d\n", 2, @2, @@2 + prints "%d %2d %2d\n", 3, @3, @@3 + prints "%d %2d %2d\n", 4, @4, @@4 + prints "%d %2d %2d\n", 5, @5, @@5 + prints "%d %2d %2d\n", 6, @6, @@6 + prints "%d %2d %2d\n", 7, @7, @@7 + prints "%d %2d %2d\n", 8, @8, @@8 + prints "%d %2d %2d\n", 9, @9, @@9 +endin + +// Including newlines in macros can lead to confusing code, but it tests the +// lexer. +instr MacroAbuse + if 1 == 1 then + prints "on\n" +#define FOO# +BAR +#endif // This ends the if statement. It is not a preprocessor directive. +endin + +scoreline_i {{ +f 1 0 16384 10 1 +i "N_a_M_e_" 0 2 +i "TestOscillator" 2 2 +i "TestBitwiseNOT" 0 1 +i "TestBitwiseXOR" 0 1 +i "TestGoto" 0 1 +i "TestMacroPeriodSuffix" 4 1 +i "TestAt" 0 1 +i "MacroAbuse" 0 1 +e +}} |