Short: Realtime effects for Delfina sound cards Author: lemming@assampler.com Uploader: lemming assampler com Type: mus/misc Version: 1.00 Requires: Delfina sound card, camd.library Architecture: m68k-amigaos Kurz: Echtzeiteffekte für die Soundkarte Delfina (mit Quelltexten) Recommended: MIDI interface for MIDI controlled effects Recommended: OctaMED Studio Aminet30:mus/edit/OctamedSS1.03c.lha You wonder why it is better to have a Delfina sound card with a freely programmable DSP instead of a card that is specialized to replay MP3 files and to encode Dolby surround sounds? The answer is that the possibilities the Delfina sound card provides are much more than these applications. E.g. it can act as a great effect processor for you. This is ideal for people with a great sound card but a poor music keyboard (like me :-). DelfLuxe is a collection of Delfina effects such as tone generators and filters. Most of them are already available in Assampler in a rather non-realtime manner. Installation: I did not include an install script, but installation is very simple. Extract the archive to somewhere you want. Then move libs/delfinacontrol.library to your Libs: directory. You may also want to assign DelfLuxe: to the delfluxe directory, then OctaMED can find the scripts for demo songs. Usage: In DelfLuxe a central library called delfinacontrol.library supports a common CLI argument template and an interface to several controling sources. (GUI? See below) The basic template for all DelfinaMidi(#?) programs is: NAME/K,ALGORITHM=ALGO/K, OMOD/K,OSOCKET/K/N,INTISOCKET/K/N,INTOSOCKET/K/N,IMOD/K,ISOCKET/K/N, CONTROLRATE=CR/K/N,PRIORITY=PRI/K/N,SIGNALTASK/K/N ALGORITHM, NAME Every effect can be associated with a group of effects called Algorithm. There is no structure, no handle that is allocated for an algorithm. It is only the same algorithm name which makes several effects belong together. Further it is possible to give every effect a name according to its function. E.g. if you have an oscillator that controls another oscillator, you could call the first oscillator a "Low Frequency Oscillator", short LFO. Then both modules are distinguishable. If you do not specify a NAME, the default name is derived from the effect name, e.g. DelfinaOscillator -> NAME=Oscillator DelfinaMoogFilter -> NAME="Moog Filter" The name of the internal Delfina modules that are created are concatenations of ALGORITHM, NAME and an internal name, if the effect is build of more than one Delfina module (e.g. DelfinaMidiReverb). Whenever a module is adressed by its name by DelfLuxe programs the module is searched first as part of the same algorithm before it is tried to find a module which owns this name as internal Delfina name. E.g. in case of DelfinaMidiEcho ALGORITHM=Forrest OMOD=Connectors ... a Delfina module with name "Forrest Echo" is setup (because an alternative name was left) and it is tried to connect its input to "Forrest Connectors" which will probably not exist, thus it is connected to the global "Connectors" module. OMOD, OSOCKET, INTISOCKET, INTOSOCKET, IMOD, ISOCKET A connection [OMOD] OSOCKET --- INTISOCKET [ThisModule] INTOSOCKET --- ISOCKET [IMOD] is setup. Socket options indicate where pipes are plugged in. This saves you some calls to SetPipe and let you benefit from the improved module search. (See options ALGORITHM, NAME) CONTROLRATE The frequency with which controling Delfina signals are checked. E.g. if you use an Oscillator as control signal for a filter sweep, the control rate should be the higher the faster the Oscillator moves, otherwise you get ugly quantifying effects. (Unfortunately, although I use microHz as timer unit, it sounds to be never faster than screen refresh. :-( ) PRIORITY Priority of the task that checks for incoming MIDI and Delfina controling events. If the priority is too low, the controling might be interrupted by moving windows, starting programs etc. SIGNALTASK For internal use with DelfinaRunModule. Controller Some parameters of every effect are controlable. E.g. the filter frequency can be controlled by the pitch bender wheel of your MIDI keyboard. DelfinaMidiMoogFilter FREQUENCY=midi.bender:exp(110,6) ... means that the filter frequency is controlled by any pitch bender event that comes from some MIDI device, where the lower limit of the wheel is mapped to 110 Hz (the unit Hz is the interpretation of the filter effect) and the upper limit is mapped to 110 Hz * 2^6 = 7040 Hz. Thus, in the center position of the pitch bender wheel a filter frequency of 880 Hz is set (exponential scaling). Now the full explaination. The controller description is divided into an incoming and an outgoing part. Both are separated by a colon. The ingoing part tells what source should be watched and which value range one have to expect from it. The outgoing part tells how to map the incoming values into effect parameters. ingoing part constant The controller does not change its value. It is fixed to the one specified on the outgoing part. This differs a little bit from the standard scheme. E.g. constant:100 means a constant value of 100. You can not abbreviate FREQUENCY=100 but you must write FREQUENCY=constant:100 instead, sorry! delfina delfina.LFO.0 addresses the output signal at socket 0 of the Delfina module LFO (either in the same algorithm or globally) midi midi.keyboard(min,max) - holds the key number of the currently pressed key. The range of keys from min to max is mapped to the outgoing range, but also keys outside this range are mapped. midi.keyboard(48,60):exp(523.25,1) maps the keys from a specific C to the next C (don't ask me for absolute octave numbers) to the corresponding frequency midi.keyboard(48,60):exp(523.25,-1) reverse the key order :-) midi.keyboard(48,101):exp(523.25,1) enables you to play Steinberg's 53-tone music B-) midi.velocity - the force with which you have pressed the key midi.aftertouch - pressure on a key when it is already down midi.bender - the pitch bender wheel midi.modulation - the modulation wheel midi.vectorx - x component of Vector Control joystick (Yamaha SY35) midi.vectory - y component of Vector Control joystick midi.volume - volume of the sound (never received this event) midi.sustain - state of the sustain pedal (never tested) midi.controller.$0A(0,$80) - the MIDI controller with number $0A (10 = pan due to the MIDI specifications) which can have values from 0 (inclusive) to $80 (exclusive), at least I assume so ;-) midichannel E.g. by replacing midi by midichannel.3 you can make the effect to listen to events on MIDI channel 3 instead of listening to all channels. outgoing part lin(0,1) means linear scaling from 0 to 1. Thus VOLUME=midi.velocity:lin(0,1) let you interpret the key press force of the MIDI keyboard as volume for some effect. exp(440,3) means exponential scaling from 440 to 3 octaves higher, i.e. 440*2^3 = 3520 E.g. it would sensible to map 12 keys from the keyboard to 1 octave. Effects Every of the following programs supports one effect and has additional CLI options for their controllers. I am a bit lazy to explain all controllers. I hope you can guess their meanings easily. DelfinaMidiAllpassCascade A cascade of ORDER all passes, which can be used to simulate phasing effects from analogue synthesizers. DelfinaMidiAmplifier A simple amplifier. DelfinaMidiBlockResample Blockwise resampling. Unfortunately the periodic clicking becomes faster the more you move away from 1:1 resampling. DelfinaMidiComplexFilter Band pass like filter where each stereo channel influences the other. DelfinaMidiEcho Repeated echo. To minimize the need for allocation of echo buffers (which would require a buffer flush at each reallocation) you have to specify a fix maximal possible delay and the real delay is measured as ratio of this and can be controlled. DelfinaMidiFilter1stOrder Simple filter with high pass and low pass output on different sockets. DelfinaMidiGetAmplitude Envelope follower. DelfinaMidiLimit Limits each elongation (sample). Creates the fuzz distortion effect. DelfinaMidiMoogFilter A cascade of ORDER low passes which are fed back to obtain band pass characteristic. This is a filter of Moog's synthesizers. DelfinaMidiMultiplier An amplifier where the second input signal is the volume control. Can be used as ring modulator. DelfinaMidiNoise Noise generator with built-in quantification. DelfinaMidiOscillator Tone generator with optional linear interpolation. There are some waveforms in 32-bit signed words format in the waves directory which are ready to be loaded into the oscillator. Feel free to create new forms! DelfinaMidiReverb A reverb made of some short echos. Very memory and time consuming. Will probably force the Delfina to switch back to lower sample rates. DelfinaMidiUniFilter The universal filter provides high pass, band pass, low pass and band limit at its four output sockets. DelfinaMidiVocoder A multi-channel vocoder. Don't work. The analysis filters don't seem to work the way they should. I chose the ComplexFilter because it is the fastest. Every other filter will slow down the process to unacceptable sample rates or number of channels :-( DelfinaRunModule Runs another DelfinaMidi(#?) effect program in the background, but waits until the effect is completely set up. This is necessary for batch scripts where every module assumes that the module already exists where it wants to connect to. Attention! Improper use of DelfinaRunModule will crash your machine! I did not found a way to make the whole thing really safe. Because the user may accidentally start a program that is not an effect program, DelfinaRunModule may wait infinitely. To avoid this you can break DelfinaRunModule with CTRL-C. But make sure that the started program will never try to tell DelfinaRunModule about its successful setup after you quit DelfinaRunModule, or the machine will crash as soon as it try so. DelfinaQuitAlgorithm Sends a CTRL-C to all programs that are associated with the algorithm name. DelfinaListContexts Similar to Delfina:ListMod, but lists all effects that run with delfinacontrol.library currently. DelfinaCreateWaves The program which generated the files in the waves directory. Additional tools To be able to manage situations you got by accidentally starting programs with wrong options etc. you should be familar with AmigaDOS commands Status and Break, or alternatively with the system monitors Scout, ARTM (AmigaRealTimeMonitor). Examples: To get the effect examples running you should plug a sound source, e.g. microphone, synthesizer line output, radio etc. into your Delfina card. (I assume that the Delfina card is all the time plugged into a HIFI amplifier on the other side. Thus we skip this step. :-) For the MIDI controlled effects, you should additionally connect the MIDI output of some keyboard with the MIDI interface in your Amiga. Then run some of the scripts in the "s" directory or play one of the OctaMED modules which will start some of the (#?)NoCtrl scripts by themselves. These scripts will fail to run without OctaMED, because they will open an requester on the OctaMED screen. Technical background: Streaming As Assampler the delfinacontrol.library and DelfLuxe are developed with Cluster (= Modula II deluxe). The delfina code is written with a56, the standard DSP 56000 assembler for Delfina cards. The delfinacontrol.library is a temporary solution until this or the next Amiga system will have a very sophisticated streaming engine build into. This would enable us to process several signals coming from MIDI (wheels, keys), sampled sounds (from hard disk, memory, microphone), user input (mouse move, joy stick), synthetic sources (noise, oscillator from delfina, Assampler). delfinacontrol.library is quite limitted in this aspect, e.g. it is not possible to mix the two control signals "pitch bender" and "key pitch" to create a tone controlled by MIDI keyboard and the pitch bender wheel. GUI A GUI is not supported, unless you consider mus/misc/DelfSetPipeMui as that. A nice GUI for the Delfina effects would be Assampler, but integrating DelfLuxe into it would mean to blow up Assampler or to completely restructure and modularize it. The latter is preferred way, but may not come reality on the classic Amigas. Exceptions Exceptions are simply written to standard output (your CLI in most cases). It's one of the things I feel to be limitting more and more in the classic AmigaOS that it do not support an exception throwing and catching system. Thus all languages that support exceptions have to take care not to skip OS cleanup code when throwing an exception. That's why one do better if one writes code in a level of plain C. :-( Support site: http://www.assampler.de (german) http://www.assampler.com (english) This is the support site for Assampler, another sound synthesis project of mine, but its site is also used for the Delfina effects now. Mailing list: http://www.yahoogroups.com/subscribe/assampler http://www.yahoogroups.com/group/assampler Again this mailing list is mainly addressed to people interested in Assampler, but because of very low traffic and the similar topic, you are welcome to join it, if you are interested in Delfina effects.