Minc Tutorial
Paul Lansky
'Minc' (M Is Not C) is the data specification language for Cmix. It was written as a student project by Lars Graf in 1985.
Communication between Minc and Cmix is usually made in the form
of function calls, such as
flange_a_note(5,1,99.2,8,3,4)
which results in some Cmix routine, perhaps called flange_a_note
(but not necessarily) being called and passed the arguments, 5,1,99.2,8,3,4.
In otherwords, you would have some data file, called flangedata, for example, containing one or more lines such as the above, which you would then read into a Cmix application, called flange, for example, designed to recognize it, by saying
Or you could simply say
which would get you the Cmix banner
-----------> Cmix <------------
after which you could type in the data interactively. This is not the preferred procedure however.
Minc is a very powerful language since it allows you to specify data with program-like syntax. It is almost like C, but not quite.
You could say the following, for example:
float start,dur,ratio,rise,decay
flange_a_note(start=2, dur=4.3, ratio=.44, rise=.1*dur, decay=(dur-rise)*.99)
flange_a_note(start=start+dur+1, dur, ratio, rise, decay)
These values would be computed before being passed to the function flange_a_note. The values are computed from left to right, so that the variable 'dur' in the above example is available for the 5th argument since it has been defined in the second argument. Everything in Minc is defined as type float. If you do not declare a variable you will get a warning statement telling you that it has been auto-declared. This protects you against typos and misspellings.
Some cmix functions return values which can then be used as arguments.
For example:
float amp
amp = ampdb(50) /* return the amplitude value for 50 decibels */
playnote(1,2,amp) /* use this as the amplitude argument for something
called "playnote()" */
or you could say
Minc also allows conditional statements such as
if(ampdb(50) > 100) playnote(1,2,ampdb(50))
It uses the C-style comparisons, ==, >, <, >=, <=, !=,
and loops such as:
float i,val
for(i=0; i<10; i=i+1) {
playnote(i,2,ampdb(50))
playnote(i+2,4,val=ampdb(22))
}
Unlike C, however, Minc does not allow multiple conditions in the for() loop. It also doesn't allow i++ constructions.
The following are functions which every Cmix application recognizes.
If you call for a function which is not in the Cmix application you
are using Minc will simply parse the arguments and print out the values.
open("filename",cmix_number,protection) /* open file "filename" with cmix number 'cmix_number' (in the range 0 - 3), and protection 'protection (0=read only, 1=write only, 2=read/write) */
input("filename") /* open file "filename" for reading only, opened as Cmix file number 0 */
output("filename") /* open file "filename" for reading and writing, opened as Cmix file number 1 */
makegen() /* see the manual page on makegen */
peakoff(file_num, flag) /* turn peak amplitude checking for file number file_num off if flag==1, or on if flag==0, default is on, I suggest you leave it alone */
punch() /* punch normalization cards, see manual page */
sfclean() /* erase all or part of a file, see manual page */
sfprint() /* print file stats, see manual page */
system("some system call") /* perform some non-cmix function */
pch = cpcpch(8ve.pch) /* return cps from 8ve.pch form */
oct = octpch(8ve.pch) /* return linear octaves from 8ve.pch form */
cps = cpsoct(8ve.oct) /* return cps from linear octaves */
num = random() /* return random number between 0 and 1 */
num = rand() /* return random number between -1 and +1 */
srand(val) /* seed random number generator */
fplot(num) /* draw crt plot of gen function -- see manual page */
time = tb(beat) /* return time from beat, according to current tempo */
beat = bt(time) /* return beat from time, according to current tempo */
tbase(val) /* set basis for tempo, normally 60 */
tempo(time,tempo, time, tempo, etc) /* draw tempo curve, see man page */
trunc(num) /* truncate a number to its integer value */
amp = ampdb(db) /* return amplitude from decibels */
amp = boost(sloc) /* boost amplitude according to speaker loc, see man page */
resetamp(file) /* reset header amplitude for file 'file' to 0 */
sampling_rate = sr(filenum) /* return sampling rate of file 'filenum' */
channels = chans(filenum) /* return number of channels for file 'filenum' */
format = class(filenum) /* return type of file 'filenum', either 2, short integers, or 4, floating point numbers */
duration = dur(filenum) /* return duration in seconds for file 'filenum' */
peakamp = peak(filenum) /* return peak amplitude of file, 'filenum' */
left = left_peak(filenum) /* returns peak amp of left channel for file , 'filenum' */
right = right_peak(filenum) /* returns peak amp of right channel for file, 'filenum' */
numvals = load_array(arraynum, val1,val2,val3....val256) /* loads array number 'arraynum', with values, val1 ...valn */
val = get_array(arraynum, valn) /* fetches value n from array 'arraynum' */
sum = get_sum(arraynum) /* returns the sum of the values in array 'arraynum' */
val = mod(oldval,modulus) /* returns the value of 'oldval', mod 'modulus' */
returnval = put_array(arraynum,loc,val) /* puts value 'val' in location 'loc' in array 'arraynum. Returns loc on success, -1 on failure */
size = get_size(arraynum) /* returns the size of array 'arraynum'*/
maxval = max(val1,val2,....val256) /* returns the maximum value of the listed numbers */
exit() /* exits cmix application */
val = pow(num, exponent) /* return 'num' to the 'exponent' power */
val = abs(val) /* returns the absolute value of 'val' */
val = f_arg(argnum) /* reads a floating point value from the cmix command line. e.g. if you say cmixapp 123.321 f_arg(0) will return 123.321 */
val = i_arg(argnum) /* returns an integer argument from the command line */
val = s_arg(argnum) /* returns a string argument from the command line. e.g if you say cmixapp somefilename, then you could refer to a file in the manner, 'input(s_arg(0))' which would open file 'somefilename' as an input file.*/
Here is an example of an actual Minc file
-------------------------------------------------------------------------
words = load_array(11, 4,24,4,24,4,24,4,24,4,24,4,24)
pitches = load_array(13,6.10,7.05,7.10,8.03,8.06,8.11)
rhythm = load_array(12,1)
revtime=13
sndlist = load_array(14,"fs/src/take26mono.sndl","fs/src/take29mono.sndl","fs/src/take30mono.sndl","fs/src/take31mono.sndl","fs/src/take32mono.sndl","fs/src2/page1.mix.snd","fs/src2/page2.mix.snd","fs/src2/page3.mix.snd","fs/src2/page4.mix.snd","fs/src2/page5.mix.snd","fs/src2/story.mix.snd")
expenv(0)
count = 0
output("fs/nchords22")
punch(1,32767)
dur=revtime+1
time=0 track=1 beat=0 beatpoint=-1 beatpoint2=-1
for(count=0; count < words/2; count=count+1) {
pch = get_array(13,count)
snd = get_array(11,x=count*2)
input(get_array(14,snd))
num = get_array(11,x+1)
skip = getstarttime(snd,num)
end = getendtime(snd,num)
setcombs(x=1/cpspch(pch),revtime,1,
y=1/cpspch(pch+.001),revtime,1,
y=1/cpspch(pch+.002),revtime,1)
xsetreson(z=cpspch(pch),1*z ,z=1*cpspch(pch+.001),2*z,
z=1*cpspch(pch+.002),3*z)
beat = trunc(count/rhythm)*dur
multicombd(beat,end-skip,skip,12,0,.0005,.2,.4)
}
}
When building your own Cmix application, any function will return a value to Minc, as long as the function is declared as type double.
E.g.
double
myfunction(p,n_args)
float *p;
{
This will create a function which will return the sum of two arguments. So in Minc, if you were to say
val would be equal to 3. Or you could say
someotherfunction(myfunction(3,4))
which would pass the number 7 as an argument to someotherfunction().
COMMENTS
Minc recognizes standard C syntax for comments
Minc will also politely ignore any function it doesn't recognize. You can therefore comment out commands you want it to ignore by making them unrecognizable to Minc. e.g.
becomes
and will be ignored.
see also:
Minc manual page
Advanced MINC Features from What is Cmix
CMIX Home Page
Music Dept. Main Menu