DISSCO DISSCO, a Digital Instrument for Sound Synthesis and Composition, offers a unified approach to music composition and sound synthesis, bringing both disciplines together in a seamless process. Presently, DISSCO has three main modules: LASS, a Library for Additive Sound Synthesis; CMOD, a Composition Module; and LASSIE, a Graphic User Interface (GUI). Two more modules are currently under consideration: one for the production of visual events, the other for sonification experiments. Although DISSCO can be used to generate music in any desired style, it exhibits a strong bias towards the use of controlled randomness and encourages the user to plan the composition ahead of time and in detail (pre-composition work). DISSCO is a “black box:” once the data is fed in, the user does not intervene during the computations, and the output does not require post-processing. All three components (CMOD, LASS, and LASSIE) are written in C++; the Bison/lexyacc parser used to read and interpret input files for the DISSCO-1.0 version has been replaced in the DISSCO-2.0 version by Xerces-C++ XML parser and muParser, a math parser. Older files can be updated using the UpgradeProjectFormat command. LASS LASS, the Library for Additive Sound Synthesis, is based on theoretical contributions by Hans G. Kaper, Senior Mathematician Emeritus at Argonne National Laboratory, and Sever Tipei, Professor of Music at the University of Illinois at Urbana-Champaign and Manager of the Computer Music Project of the UIUC Experimental Music Studios. LASS has also benefited from their experience with two earlier additive synthesis systems, DIASS_M4C and DISCO. Unlike its predecessors, LASS uses function evaluations instead of table look-ups and does not require a "score." For this reason, LASS is not a program of the MusicN type. LASS can generate an arbitrary number of sounds, each of them containing an arbitrary number of partials, and provides the user with detailed control over each partial. LASS is also unique in the way it allows musicians to specify the loudness of a sound. Loudness is a nonlinear function of amplitude; to achieve an assigned perceived loudness, the amplitude of the sound is adjusted using the ISO equalloudness curves and a number of critical bands. Three design goals have guided this project: expandability, ease of use, and efficiency. The architecture of LASS is very modular. No doubt, new features will need to be added, and future developers must be able to easily expand the system. The library was also designed to be user-friendly. The interfaces to classes were made as clear as possible and kept consistent across objects. Extensive use of references instead of pointers helps insure good memory management. Finally, LASS must also be efficient since sound synthesis is computationally intensive. The general framework of the library and many of its features were written by Braden Kowitz. A number of students enrolled in the "Advanced Computer Music" seminar at UIUC have also contributed to the project and Mert Bay wrote the BiQuad Filter. CMOD The central component of the composition module, CMOD, is the Event class. An event can have children events that, in turn, can become parent events and have their own children, in an arrangement reminiscent of Russian dolls (matryoshkas). There is only one Top Event (the entire piece), but there can be an arbitrary number of High, Medium, Low, and Bottom Events corresponding to various structural levels (eg. sections, themes, chords or any other subdivisions of the piece) and individual sounds or notes generated by the Bottom level. This framework reflects the realization that similar tools are used at different time scales to select values for parameters of various events types. Not all types of events need to be present, new categories can be added, and the hierarchy of events is flexible: a Low event may have a Medium event as a parent while, at the same time, it can have High or Medium events as its own children. Events are defined by start time, type, and duration; they can also be assigned environmental attributes such as spatialization and reverberation as well as other parameters such as frequency, loudness, vibrato, etc. These features are inherited by the event's children, insuring uniformity of the offspring, unless overridden by the child event. The Top Event and the Bottom Event are different from the other events: the Top Event is unique, while the Bottom Event creates synthesized sounds, notes in a score, or both, and actually assigns to them various attributes such as vibrato, tremolo, glissando, location in space, and reverberation or user-defined score symbols. An initial version of the composition module was written by Sever Tipei, modified by students of the “Advanced Computer Music” seminar, and greatly improved by Ryan Cavis, Andrew Burnson and Ming-Ching Chiu. In 2012-2013, CMOD underwent intensive refactoring and improving. The newest version was launched in May 2013. The improvements include: Integrating LASS in a tighter manner. Adopting XML as its input format. Adopting muparser as its math parser. LASSIE A graphic user interface, LASSIE provides easy access to DISSCO on Linux machines. Without changing the format of the original text-based (XML) CMOD input files, LASSIE offers the users an alternative way of managing and editing the files in an integrated graphic environment. LASSIE is implemented using gtkmm, the official C++ interface for the popular GUI library GTK+. The main window of LASSIE contains three parts. The first part is the drop down menu and the tool bar on the top of the window. The left half of the main window is the Objects List, which groups the objects, including events, spectrums, notes, envelopes, etc., in separate folders. The right side of the window shows the attributes of the object selected in the Objects List. Users can inspect and edit the attributes of any object by double clicking the object in the Objects List. Besides the main window, Envelope Library Window is also part of LASSIE. Users can click the “Envelope Library” button at the bottom of the Objects List to open Envelope Library Window. This window provides the visualized representation of the original text-based envelope specification. Users can directly modify the envelopes in this window. LASSIE also provides some instructions in real-time when the users edit the attributes of objects. Besides, LASSIE checks the syntax of the information input by the users and shows warnings if the input files contain illegal syntax. LASSIE was written by Ming-ching Chiu. ******* Event objects There are a number of event categories corresponding to various structural levels: Top, High, Medium, Low, and Bottom. An event object may have a number of layers and each layer may have a number of types. In an analogy with traditional music, a layer could be seen as an acoustic instrument (eg. Violin) able to produce various types of sound (eg. arco, pizzicato, col legno, etc.). Each event object has a start time, duration, and type as well as a specific method of producing all its children events. The Continuous method distributes children events within the duration of the parent according to a stochastic distribution, in an unordered time sequence. Sweep also uses a stochastic distribution but insures that the start time of the first child object is the same as the start time of the parent and that the rest of children events' start times are in an ordered time sequence. Discrete uses a three-dimensional matrix (start time/type/duration) to distribute children events that do not collide with each other within the same layer. CMOD Files Each event has a text file associated with it which contains basic information about the event as well as directions on how to create children of the event. While the start time, type, and duration have been already determined by the parent event, the text file specifies the number of children events, the names of their associated text files, and the method used to determine their start times, types and durations. The Bottom events have a more complex text file associated with them, since information about the frequency, loudness, etc. of synthesized sounds or printed notes is needed. Different category of event files are stored in separate directories, which are named after the first letter of the event category: T (Top), H (High), M (Medium), L (Low), and B (Bottom). Bottom files used to generate synthesized sounds must start with “s” (ex. B/sfilename), while those used to generate printed notes must start with “n” (ex. B/nfilename). The letters THMLBsn are used as flags identifying different categories of text files. Various auxiliary text files are used to build envelopes (ENV), sieves (SIEV), and patterns (PAT), or to control the spectrum (S), the spatialization (SPA), and the reverberation (REV). A file (projectname.dat) defines the main properties of the project and precedes the creation of the Top event from the T/file. Project Properties (project.dat): Title of the project; a directory with that name needs to be created before accessing this window. File Flags: the default values are THMLBsn (see above) and need to be preserved -in this particular order, no spaces between letters- even if not all structural levels are present in the project. The user may introduce more levels only by modifying the code. Duration of the project in seconds may be a number or the output of a function (see Functions). For sound synthesis only: ◦ Number Of Channels may vary between two and an arbitrary number (see Spatialization) ◦ Sampling Rate /second ◦ Sample Size in bits Number Of Threads should be left at 1 unless more than one processor is used. Top Event: the name of the file associated with it the needs to start with T. Event file: All categories of events inherit from the Event class. Event Name maxChildDur the longest duration a child event may have in seconds, as a fraction of the parent's total duration (percentage) or in EDUs; needs to be expressed in the same units as the Duration Type. EDU (Elementary Displacement Unit) Per Beat is given by the smallest common multiple (LCM) of the different tuplets used. If eight note triplets, sixteenths, and quintuplets are present, then: 1/4 * 1/3 * 1/5 = 1/60 and the beat will have 60 EDUs in order to accommodate divisions by 4, 3, and 5 of the quarter note, the beat. (Note that, in this case, sextuplets or 1/6 of the beat=quarter note will also be allowed). Time Signature: any fraction whose denominator is a power of 2 is allowed (2/4, 7/8, 5/16, etc). Tempo may be expressed as a note value (e.g. quarter note = 60) a fraction where the denominator is the number of beats in the section * EDU and the nominator is the length of the fragment in seconds. Ex: If the section is 50 beats long, the EDU = 60, and the length of the section is 28 seconds, then 50 * 60 /28 = 3000/28 =750/7 (the reduction of the fraction will be done automatically). Number of Children can be determined from a given Density, denotes the number of sounds/second desired (see SoundsPerSec) entered as a Fixed number corresponding to the total number of children events entered as individual numbers for each Layer. Add New Layer allows the user to add new children names by Creating a New Object and dragging it in the window. The type, class, and name are displayed. Children Events Definition: a choice between the three available methods of producing children events: Continuum, Sweep, or Discrete. Children of the same parent are produced with the same method. If Discrete is chosen: Attack Sieve: sieve defining all possible discrete start times for children events within the duration of the parent. Duration Sieve: sieve defining all possible discrete durations for children objects (have to be ≤ maxChildDur). (NOTE: When specifying children attributes in layers [see below] make sure you click outside the line, in the window, after each entry to secure it.) If Continuum is chosen: Start Time could be a floating point number or a function. If Sweep is chosen: use PREVIOUS_CHILD_DURATION for an uninterrupted sequence of sounds for various intervals between sounds, a list and PREVIOUS_CHILD_DURATION Value Type for Start Time and Duration: Percentage: a floating point number between 0 and 1 (not available for Discrete) – refers to the duration of the parent event EDUs (Elementary Displacement Units): an integer; EDU = 1/LCM (Least Common Multiple) of all beat subdivisions Seconds: a float (not available for Discrete) Type of the child/event: an integer starting with 0 Duration could be a floating point number or a function. Value Type for Duration: see above Layers: Independent streams of events containing types of sound. Ex. a layer representing “violin” contains a type “arco” and a type “pizz.”; inside a layer, sounds of different types will not overlap, sounds in different layers may overlap. Bottom file: More information is required by a Bottom object in order to create sounds or notes. A Bottom file is the same as the generic Event file but, since more information is required by a Bottom, also includes: Frequency, a floating point number, can be defined using: Equal tempered: an integer, number of semitones from C0 = 0 (eg. C4 = 48). Fundamental: Fundamental Frequency in Hertz, chosen by the user (min. fundamental frequency = 1, not 0). Partial number: of the specified Fundamental Frequency above Continuum: frequency in Hertz Power of Two: value that controls the exponential of 2, to be multiplied with 20 Hz, lowest frequency and not to exceed 15,000 Hz, the highest frequency listed by ISO. 0 < value < 1. 20 * 2**(log2((15000 – 20) * value)), where 15000 is the max. frequency allowed Loudness: values are expressed in sone units, on a logarithmic scale of 0 – 256, where a two-fold increase corresponds to a step in the traditional scale: pp, p, mf, f, ff, etc. Modifiers Alterations of the fundamental parameters of sound: frequency and amplitude (and phase). May apply to the SOUND as a whole or to each PARTIAL individually. TREMOLO: amplitude modulation Probability Envelope: probability that the modifier will be applied. Amp Value Envelope: size (magnitude) of the distortion; 0 → no modulation; 1 → 0.1 of amplitude Rate Value Envelope: rate of the modulation; 6Hz considered “normal”. VIBRATO: frequency modulation Probability Envelope: probability that the modifier will be applied. Amp Value Envelope: size (magnitude) of the distortion; 0 → no modulation; 1 → 0.1 of amplitude; however, to create a FM type of sound, larger numbers are useful: 2, 4, 25, etc. - see Dodge or Chowning's writings) Rate Value Envelope: rate of the modulation; 6Hz considered “normal”. A frequency envelope is used at the sound level to create glissandi, sound bends, and when applied to individual partials, to GLISSANDO: frequency is multiplied by the value of the envelope at tn. Frequency * 2 → octave above, frequency * 0.5 → octave bellow; a 0 value will produce segmentation fault. BEND: small, irregular modification of the frequency, use an envelope There are default values for DETUNE_SPREAD DETUNE_DIRECTION DETUNE_VELOCITY DETUNE_FUNDAMENTAL Transients are narrow spikes/distortions in the amplitude domain or in the frequency domain. In the case of acoustic instruments, they occur briefly at the onset of the vibration. AMPTRANS: Probability Envelope: probability that the modifier will be applied. Amp Value Envelope: size (magnitude) of the distortion; 0 → no modulation; 1 → 0.1 of amplitude Rate Value Envelope: probability of occurrence of a spike Width Envelope: width of the spike, default value is 1103. FREQTRANS: Probability Envelope: probability that the modifier will be applied. Amp Value Envelope: size (magnitude) of the distortion; 0 → no modulation; 1 → 0.1 of amplitude Rate Value Envelope: probability of occurrence of a spike Width Envelope: width of the spike, default value is 1103. WAVE_TYPE: a choice between sine wave (0) or white noise (1). More wave types to be added later. Filters can be used to select various frequency bands for white noise. Environment Spatialization: can be applied to the entire sound or to individual partials SPA: Stereo: a float representing the amount of sound produced by the left speaker ReadSPAFile: name of the file stored in the directory SPA. The following can be used for multi channel playback, an arbitrary number of channels Multi_Pan: amount of sound played by each speaker Polar: using polar coordinates to specify the location in space; assumes an arbitrary number of channels arranged in a circle, on a plane Theta: the angle measured clockwise 0 (straight ahead) to ± π (behind) going through negative values on the right side and positive values on the left side. 0 0.25 π -0.25 π 0.50 π -0.50 π 0.75 π -0.75 π ±π Radius: distance from the center of the circle Two examples of using a choice between multiple files: ===================================================================== <Fun><Name>ReadSPAFile</Name> <File><Fun><Name>Select</Name> <List> polAshriek0c, polAshriek0e </List> <Index><Fun><Name>RandomInt</Name> <LowBound>0</LowBound> <HighBound>1</HighBound> </Fun></Index> </Fun></File> </Fun> =================================================================== <Fun><Name>ReadSPAFile</Name> <File><Fun><Name>Select</Name> <List>polApercText2.0, polApercText2.1, polApercText2.2, polApercText2.3 </List> <Index><Fun><Name>RandomInt</Name> <LowBound>0</LowBound> <HighBound>3</HighBound> </Fun></Index> </Fun></File> </Fun> ===================================================================== Reverberation: The Reverb class implements an artificial reverberator, built on the model in Moore's "Elements of Computer Music" book. That model, in turn, is based on Schroder's and Moorer's work. More about reverberation in a special section bellow. There are three ways in which reverberation may be applied; all three apply only to the entire sound. SIMPLE: Room Size: only the size of the room is considered, all other parameters have default values. MEDIUM: Reverb Percentage: the amount of reverberated vs. direct sound, an envelope. Hilow Spread: ratio between the decay of high frequencies vs. the decay of low frequencies. Gain All Pass: see special section. Delay: see special section. ADVANCED: Reverb Percentage: the amount of reverberated vs. direct sound, an envelope Comb Gain List: see special section. LP Gain List: see special section. Gain All Pass: see special section. Delay: see special section. Filter This is a BiQuadFilter(int type, m_sample_type dbGain, m_sample_type freq, m_sample_type srate, m_sample_type bandwidth); MAKFILTER: Filter type: Low Pass Filter High Pass Filter Band Pass Filter Notch Filter Peaking Band EQ filter Low Shelf Filter High Shelf Filter Frequency - Cutoff Frequency (Hz) Bandwidth (in octaves) db Gain - Filters gain (dB) for peaking and shelving filters only READFILE: File Name SELECT: see Select. Sound - S file (Spectrum): Defines the internal structure of a sound. Number of Partials: set to 0. Add Partials one by one and the number will automatically change. Deviation: when deviation = 0, all partials are integer multiples of the fundamental (i.e. partial 1); when deviation = 1.00, partials 2 and higher may have frequencies as high as ½ the distance to the upper or lower neighbors. The process is random and the distortion is proportional to the deviation number (between 0 and 1.00). If a deterministic outcome is desired, use a Frequency envelope for each partial or the special DETUNE parameters. Spectrum: envelopes describing the evolution of each partial's amplitude in time scaled to the desired strength (amplitude) of each partial. Add Partials: and assign an envelope number and a scaling factor for each partial. It can be done using a (normalized) envelope from the Envelope Library (EnvLib), an envelope stored in a file, or calling the function MakeEnvelope which will create a reusable envelope file. Auxiliary files Envelopes: Used mostly as functions of time but not exclusively. The format is: 2 Envelope 1 2 0.00 1.00 LINEAR FLEXIBLE 1.00 1.00 //number of envelopes in the library //number of segments (lines) in the envelope // x value; y value; type of path; length of segment is flexible // x value; y value; no other information on the last line The x value marks the starting point of a segment with the y value at that point; the path followed by a segment can be LINEAR, EXPONENTIAL, or CUBIC_SPLINE; a segment can be FIXED (its length can not be modified) or FLEXIBLE (it may be stretched or compressed). When used to control the amplitude of partials, the first and last y values need to be 0 to avoid pops and clicks. Envelope Library: Pre-existing envelopes that are reusable. See above. Make Envelope ENV file: Envelopes generated “on-the-fly”, useful especially when some coordinates are random and the envelope can be re-used with slightly different coordinates. X Value: a list of possible values if an amount of randomness is desired; a possible function to use: Stochos. Y Value: a list of possible values if an amount of randomness is desired; a possible function to use: Stochos. Scaling Factor: if the envelope will be normalized, a value of 1 is required. That way the envelope could be easily scaled further when it is used in a particular context. Sieve - SIEV file: Logical filters; discrete elements are selected using modulo m and boolean operations. Sieve Builder: chooses between methods MakeSieve: generates a sieve Low Bound: smallest element in the sieve High Bound: largest element in the sieve Elements: chooses between methods for generating the elements of the sieve Meaningful: lists pre-selected elements (in order) Values: an ordered list, the increment does not have to be constant Mods: modulo numbers (equivalence classes) and their multiples generate the elements of the sieve Values: an unordered list of mod numbers, the result is an ordered list of sieve elements Offset(s): modulo indice(s) displacing the starting value of a mod element Fake: all elements between Low Bound and High Bound are allowed Values: all elements between those limits Fibonacci: not available yet. Overtones: not available yet. Multiple_Params: not available yet Weights: chooses between methods of assigning an weight to each element Periodic: assigns weights to the elements of a sieve by cycling through a given ordered list of weights. Values: a list of weights corresponding to the first elements of the sieve that will be repeated. Hierarchic: assigns weights to the elements of a sieve by adding for each element the probabilities associated with each equivalence class Values: a list of integers corresponding to the probabilities of each modulo of the elements list (works only with the Mods method of selecting sieve elements). Include: reads weights corresponding to a list of elements. Used frequently as a companion to the Meaningful function. Values: a list of arbitrary weights, same length as the companion list of elements. (A type: choice between Constant and Variable is needed see ValuePick) ReadSIVFile: reads in a preëxisting file Name of the SIV File: enter the name of a file from the SIV directory Patterns - PAT file: A pattern of values is generated using a pre-defined origin and a sequence of intervals; it delivers one value at a time. Same input may be used to generate various related patterns produced through mod m equivalences, symmetrical set forms (R, I, RI), and distortions. Pattern Builder: chooses between methods MakePattern: creates a new pattern Origin: user defined first element of a pattern. Intervals: discrete values measuring the distance between adjacent pattern elements ExpandPattern: coordinates various methos of expanding and/or modifying the pattern: equivalence classes, transpositions, symmetric forms (I, R, RI), distortions (augmentation, diminution, etc.). Equivalence: finds all intervals allowed within a given range which are equivalent mod m with the initial list. Modulo: interval of repeat. Low: lower limit. High: upper limit. Pattern: the resulting string of values. Symmetries: creates symmetrical patterns ( not available at the present time). Distort: distorts an existing pattern (not available at the present time). ReadPATFile: reads a sequence of values from an existing file. PAT File Name: Origin: user defined first element of the pattern. GetPattern: In Order: NB. Patterns of stimes (attacks) will work _only_ with the SWEEP option. Functions Auxiliary devices helping choose from a list of elements. Functions could be connected between themselves in various ways, in most instances in a cascading fashion. Stochos: user defined stochastic distributions Method: selects a method Range Distribution: uses a group of three envelopes to define a range and the distribution within the range; there could be an arbitrary number of such groups Offset: points to one of the groups of three envelopes Min: envelope defining the lower limit of the range Max: envelope defining the upper limit of the range Distribution: third envelope defining the probability curve within the range at a certain moment Functions: a set of stacked up envelopes defining successive areas. The sum of envelope values at any moment is ≤ 1. Can be used with only one envelope. Suggested by the orchestration chart for Xenakis' Achorripsis (see Formalized Music) Select: chooses from a list according to some criteria. List: a list of items to choose from. MakeList: builds a list (see below). Choice index: variable whose current value determines the choice (see examples below). ValuePick: establishes a dynamic range and a distribution within that range; builds a sieve with elements within the range and assigns them weights. Similar to both Stochos and Sieve but only for discrete values. Absolute Range: the highest value allowed. Low: envelope defining the lower boundry of the range; (% of the absolute range). High: envelope defining the upper bound of the range ; (% of the absolute range). Distribution: third envelope defining the probability within the range. Elements: see Sieve. (for Meaningful and Fake there is no Offset; for Fake there are no Values either) Weights: see Sieve. Type: chooses between the following two options. (Should also be an option in Sieve) Variable: uses the PreferedValueDistribution method from the Random class (see special section). Constant: using the probability given by the third envelope. Random: Returns a random number in the range [low, high]. Lower Bound: Higher Bound: RandomInt: Returns a random integer in the range [low, high] based on a flat distribution. Lower Bound: Higher Bound: Randomizer: randomly increases or decreases a given base value within the limits of a given deviation. Base: the original value Deviation: how much the base value may be increased or decreased. Decay:used in connection with a sieve Base: Rate: Index: Exponential: Linear: ChooseL: used in connection with a sieve from ValuePick MakeList: ************* SoundsPerSec (DENSITY): Maps an "abstract" density of 0 - 1 onto a number of sounds per second by defining a total number of regions (areas) and the number of such areas with less than 1 sound/sec. (underOne). A common example: areas 0 1 2 3 4 5 6 7 dens. 0.00 0.125 0.250 0.375 0.500 0.625 0.750 0.875 1.00 s/sec 1/16 1/8 1/4 1/2 1 2 4 8 16 Here, there are 8 areas (0-7) and 4 of them (0-3) include values of less than 1 sound/sec. By subtracting underOne, a dens = 0 is mapped onto a value of 1 sound every 16 sec. and not onto 0. In most cases areas = 8 and underOne = 4 as in the above example. Finding the density of a section/box when its duration is known and when the number of desired objects is known: log10(numObjects / duration) / (area * log10 2) + underOne/area for areas = 8 and underOne = 4: log10(numObjects / duration) / (8 * log10 2) + 0.5 = log10(numObjects / duration) / 2.408239965 + 0.5 To find the number of objects given the density: soundsPsec = pow(2, dens * area - underOne) and numObjects = duration * soundsPsec =============================================================================== To calculate densities for different layers of the same object: If all objects have the same duration: 1. Find out the total number of objects in that event. 2. Find out the % of time each layer is active 3. Normalize these % (divide each by their sum) 4. Find out how many objects in each layer 5. Determine the density of each layer according to the above ************* Prefered Value Distribution: Finds a probability through a comparison of an average situation with a desired or "prefered" situation. Borrowed from MP1, NT expression. probability = exp(FIRST_CONST + SECOND_CONST * pow(2, (value - 0.5)) * pow(2, checkPoint)) FIRST_CONST = -5.54 SECOND_CONST = -1.84 checkPoint: the moment in time (x axis) of the testing. ************* Inverse Function: How to design a function correlating probabilities (segments on the x axis) with values on a continuum (e.g. attacks in time) given another probability function defining the chance of such values (e.g. discrete time values) to be selected. Useful when more than one x of the original function can have the same y value. 1. take original function 2. find the average values between probability values (Y axis) 3. normalize - divide each probability by the sum 4. plot the new weights on the x axis of a new function adding each of them to the preceding ones. 5. plot the original function's x values on the new function's y 6. map each new function x to the corresponding new y Example: Original function x y 0.00 0.00 average % Inverse function x y 0.00 0.00 0.50 0.25 0.20 1.00 0.25 0.20 0.50 0.25 0.35 0.00 0.50 0.35 0.02 0.01 0.60 0.02 0.51 0.60 0.48 0.24 0.70 1.00 0.75 0.70 0.50 0.25 0.85 0.00 1.00 0.00 1.00 0.85 0.00 0.00 ____ 2.00 ************* Reverberation: There are a few different constructors to choose from, depending on how much control you want to have (and thus, how much you want to be burdened with details). SIMPLE constructor. Room_size this is constructed to give some reasonable results when you input room_size values between 0.0 and 1.0. I found some parameter sets that I felt approximated various familiar rooms (lincoln hall, MB 1201, great hall, a large stadium, etc), and mapped these into a room_size space of 0.0 to 1.0. Then I used gnumeric (spreadsheet for linux, like excel) to find a linear regression to get all the parameters simply in terms of room_size. Thus a value of 0.0 will have virtually no reverb. A value of 1.0 will have a very high degree of reverb. MEDIUM (next-most-advanced constructor). param reverbPercent this determines the mix (in the resultant sound) between the direct sound (the input sound) and the reverberated sound. 0.0 is no reverb, all direct sound. 1.0 is all reverb, no direct sound. param hilow_spread in most rooms the low frequency response will be higher than the high frequency response. If we hold other parameters constant, the math gives a range of possible ratios between low frequency to high frequency response. A value of 1.0 will choose the maximum low-frequency response, holding the high-frequency response at a given. A value of 0.0 will mean an even response across all frequencies. param gainAllPass Moore's reverberator has only one all-pass filter, and this is its gain. The default value is 0.7. Higher values (up to 1.0) cause more ringing at certain frequencies. Lower values (down to 0.0) cause less ringing. param delay this is the length (in seconds) of the first echo response. ADVANCED constructor. param reverbPercent this determines the mix (in the resultant sound) between the direct sound (the input sound) and the reverbed sound. 0.0 is no reverb, all direct sound. 1.0 is all reverb, no direct sound. param combGainList this is the address of an array of 6 floats that are the comb filter gains. param lpGainList this is the address of an array of 6 floats that are the low-pass filter gains param gainAllPass Moore's reverberator has only one all-pass filter, and this is its gain. The default value is 0.7. Higher values (up to 1.0) cause more ringing at certain frequencies. Lower values (down to 0.0) cause less ringing. param delay the length (in seconds) of the first echo response. Common code used by all constructors. param percentReverb this determines the mix (in the resultant sound) between the direct sound (the input sound) and the reverbed sound. 0.0 is no reverb, all direct sound. 1.0 is all reverb, no direct sound. param combGainList this is the address of an array of 6 floats that are the comb filter gains. param lpGainList this is the address of an array of 6 floats that are the low-pass filter gains param gainAllPass Moore's reverberator has only one all-pass filter, and this is its gain. The default value is 0.7. Higher values (up to 1.0) cause more ringing at certain frequencies. Lower values (down to 0.0) cause less ringing. param delay this is the length (in seconds) of the first echo response. written by Andrew Kurtz & Jim Lindstrom 2002 Event Offset Nesting The following graphic attempts to show the many possibilities of nested exact and inexact offsets. i = inexact start offset e = exact start offset T = tempo start time 0================================================ | EVENT 1-----------------------------------------------------. . . | | EVENT 2-----------------------------------------. . . | | | EVENT 3------------------------------. . . | | | | EVENT 4--------------------. . . | | | | | EVENT 5----------. . . | | | | | | EVENT 6--. . . | | | | | | | | + i1 + e2 + e3 + i4 + i5 + e6 | | | | | | | . . . . . . . . . . . . . . . . . . . . . | TEMPO | START | TIMES | | | | \\ \\ T1 (T1) (T1) T5 (T5) Inexact Start Times (~ means the exact value is truncated to floating point): Event 1 = i1 Event 2 = i1 + ~e2 Event 3 = i1 + ~e2 + ~e3 Event 4 = i1 + ~e2 + ~e3 + i4 Event 5 = i1 + ~e2 + ~e3 + i4 + i5 Event 6 = i1 + ~e2 + ~e3 + i4 + i5 + ~e6 Exact Start Times: Event 1 = (not applicable) Event 2 = T1 + e2 Event 3 = T1 + (e2 + e3) Event 4 = (not applicable) Event 5 = (not applicable) Event 6 = T5 + e6 Possible combinations: 1) Parent inexact, child inexact (Events 4-5) Since both are inexact, nothing further is to be done. They will both only have global inexact time offsets. 2) Parent exact, child inexact (Events 3-4) Since the child is inexact, nothing further is to be done. The child will simply have a global inexact time offset. The parent will already have calculated its tempo start time. 3) Parent exact, child exact (Events 2-3) Since the both are exact, the child inherits the tempo of the parent. Its exact offset is calculated by adding the exact parent start time offset. Important Note: If the child attempts to override the parent tempo, it will be ignored and the above calculation. This is to prevent implicitly nested tempos, which are better handled explicitly at the moment. For example it would be very difficult to properly render "4/4 for 3 1/4 beats, then change to 5/8 for 3 beats as a child tempo." If this nesting were allowed, it would be very ambiguous as to how to return back to 4/4. Even if the 5/8 were to trigger a new tempo start time, in the score this would be misleading making it appear that the two sections were not rhythmically related, even though they inherently are by virtue of them both being exact. 4) Parent inexact, child exact (Events 1-2, 5-6) In this case, since the parent did not have an exact offset from the grandparent, the exact child needs a new reference point. This triggers the creation of a new tempo start time *for the parent*. Since the child is offset an exact amount from the parent, the parent is the new tempo reference. This could easily be the source of confusion: when a parent offset is inexact, and a child offset is exact, it is the parent which takes on the new tempo. Note that this implies that the child's siblings will refer to the same new tempo start time. Written by Andrew Burnson ********* &&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& FOR THE PROGRAMMER Description of files, present code CMOD Bottom.h and Bottom.cpp – stores and manages Bottom type objects CMOD.h – include files and libraries used by CMOD Define.h – constants used throughout DISSCO Event.h and Event.cpp – defines a generic Event object and manages features common to various event types EventParser.h and EventParser.cpp – used only by DISSCO-1.0; deprecated in DISSCO-2.0 FileValue.h and FileValue.cpp – middlewear between data files and CMOD in DISSCO-1.0; deprecated in DISSCO-2.0 Libraries.h – includes STL and Xercesc methods, muParser, enums for EventType, Tempo, NoteValue, etc. Main.cpp - creates the Piece object which reads the .dissco file (in XML format) Modifier.h and Modifier.cpp – manages FM, AM, glissando and other modifiers of the basic sound/note muParser – directory containing files for the fast mathematical parser library *Note.h and Note.cpp – manages the duration, pitch, dynamics and modifiers of a note in a printed score Output.h and Output.cpp – prepares output for XML, particel, and FOMUS. parser – directory containing the Bison/Lex-Yacc parser used only by DISSCO-1.0; deprecated in DISSCO-2.0 Patter.h and Patter.cpp – generates a pattern of intervals using an origin Piece.h and Piece.cpp – sets up the environment for the current piece (directories,files, output, etc.) Random.h and Random.cpp – manages random numbers generation and selections base on random numbers *Rational.h – class managing rational numbers, adapted from Andrew Burnson's “Belle Bonne, Sage” *Sieve.h and Sieve.cpp – class creating and using sieves (logical filters) and their weights. *Tempo.h and Tempo.cpp - determines the tempo according to metronome beat value, EDUs. TimeSpan.h – structure, defines a span in time in seconds and EDUs Utilities.h and Utilities.cpp – evaluates XML strings; also an interface between CMOD Event and LASS Score replaces DISSCO-1.0 FileValue Abreviations: DOM = Document Object Model used by XML parser GFEC = Get First Element Child GNES = Get Next Element Sibling → used to traverse the DOM tree. mutex = mutual exclusive (protects data) XMLTranscode = converts ASCII to DOM XMLCh = typedef unsigned short (?) LASS: Up LASSIE Up UpgradeFileFormat.h and UpgradeFileFormat.cpp convert the DISSCO-1.0 files to DISSCO-2.0 XML format