using System; using System.Collections; using System.Collections.Generic; // This is where you write your machine. Scroll down through the code and fill in all the places where it says 'TODO'. // Instructions are provided for each section you will come across. With this you can build a basic effect machine. // For more examples on how to write this and other types of machines, see the machines that ship with VioLet Composer. // TODO (Developer): Clean up the machines and comment them so they are a clear demonstration of the principles. // This is the very first layer in the machine writing API. This interface is still not frozen, but once it is we can // build more advanced APIs on top. namespace Wavelet_Tracker { public class SimpleEchoMachine : MachineParameterisedBase { ////////////////////////////////////////////////////////////////////////// // TODO: Fill in these values. ////////////////////////////////////////////////////////////////////////// private const string type = "Simple Echo"; private const string author = "Demonstration"; private const int version = 1; ////////////////////////////////////////////////////////////////////////// // TODO: Add any internal variables you want to use here. ////////////////////////////////////////////////////////////////////////// private const int numEchoes = 5; // You must not alter the signature of the machine. public SimpleEchoMachine(string name) : base(type, author, version, name) { } protected override void endSetupInputOutputImpl() { // We have one output called 'Wet' and one called 'Dry'. All outputs are the // same except for their name. Each output must have a unique name. outputs = new MachineConnection[2]; outputs[0] = new MachineConnection("Wet"); outputs[1] = new MachineConnection("Dry"); // This is how we tell the system we have no inputs. (If you remove the // lines below and don't uncomment this one, the machine will crash.) // The same applies if we (for some strange reason) have no outputs. // inputs = new MachineConnection[0]; inputs = new MachineConnection[1]; inputs[0] = new MachineConnection("Input"); } protected override void endSetupParametersImpl() { parameters = new MachineParameter[2]; MachineParameterContinuous delay = new MachineParameterContinuous("Delay", 0, 0.02); delay.multiplier = 10000; delay.label = "ms"; parameters[0] = delay; MachineParameterContinuous decay = new MachineParameterContinuous("Decay", 0, 0.2); decay.multiplier = 100; decay.label = "%"; parameters[1] = decay; } protected override void endProductionImpl(long interval) { ////////////////////////////////////////////////////////////////////////// // TODO: Generate sound as demonstrated below. ////////////////////////////////////////////////////////////////////////// List list = inputs[0].buffer.getForProcessing(playTime, interval, true); long etime = (long) (((double) parameters[0].parameterValue)*App.TIME_RES*10); float edecay = (float) (1.0 - (double)parameters[1].parameterValue); for (int x = 0; x < list.Count; x++) { SoundEvent e = list[x]; if (e.eventType == EventType.AUDIO_WAVELETS) { WaveletEvent w = (WaveletEvent) e; float wamp = w.amplitude; long wtime = w.startTime; for (int y = 0; y < numEchoes; y++) { wamp *= edecay; wtime += etime; WaveletEvent v = new WaveletEvent(w.frequency, wamp, w.length, w.phase, wtime); outputs[0].buffer.addEvent(v); } outputs[1].buffer.addEvent(w); } } } protected override void endSeekImpl(long seekTime) { ////////////////////////////////////////////////////////////////////////// // TODO: Anything you might need to do before each time play is pressed. ////////////////////////////////////////////////////////////////////////// } protected override void endTickImpl(ArrayList parameterChanges) { ////////////////////////////////////////////////////////////////////////// // TODO: Explicitly handle pattern events if you so desire. ////////////////////////////////////////////////////////////////////////// } } }