using System; using System.Collections; using System.Collections.Generic; namespace Wavelet_Tracker { public class WaveletSourceMachine : MachineParameterisedBase { private const string type = "Wavelet Source"; private const string author = "Internal"; private const int version = 1; private ArrayList playingNotes; private float[] harmonics = new float[] { 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f }; private EnvelopeSample envelope = null; public WaveletSourceMachine(string name) : base(type, author, version, name) { playingNotes = new ArrayList(); machineLimitations = MachineLimitations.EmitsWavelets; } protected override void endProductionImpl(long interval) { long endTime = playTime + interval; List incomingNotes = inputs[0].buffer.getForProcessing(playTime, interval, true); for (int x = 0; x < incomingNotes.Count; x++) { // TODO: This will crash if it receives events that are not notes. if (incomingNotes[x] is NoteEvent) { NoteEvent note = (NoteEvent)incomingNotes[x]; float volume = 1.0f; try { volume = ((float)(note.metadata.getAttribute("Volume"))); } catch (Exception) { } double notePitch = ScaleDefinition.getNotePitch(note.scale, note.note, note.fineTune); playingNotes.Add(new WaveletOscillator((float) notePitch, volume, harmonics, envelope, note.startTime)); } } for (int x = 0; x < playingNotes.Count; x++) { List events = ((WaveletOscillator)(playingNotes[x])).getEvents(interval); if (events != null) { outputs[0].buffer.addAllEvents(events); } else { playingNotes.RemoveAt(x); x--; } } } protected override void endSeekImpl(long seekTime) { // Since we do not get events for initialisation of parameters, we // must copy the initial values into our run-time structure during // the seek operation. for (int x = 1; x < 10; x++) { MachineParameterContinuous cparam = (MachineParameterContinuous) parameters[x]; harmonics[x - 1] = (float) cparam.parameterValue; } playingNotes.Clear(); } protected override void endSetupParametersImpl() { parameters = new MachineParameter[10]; MachineParameterDiscrete param = new MachineParameterDiscrete("Envelope", 0, 0, 999); parameters[0] = param; for (int x = 1; x < 10; x++) { MachineParameterContinuous cparam; if (x == 1) cparam = new MachineParameterContinuous("Fundamental", 0, 1.0f); else cparam = new MachineParameterContinuous("Harmonic x" + x, 0, 0.0f); parameters[x] = cparam; } } protected override void endSetupInputOutputImpl() { outputs = new MachineConnection[1]; outputs[0] = new MachineConnection("Sound Output"); inputs = new MachineConnection[1]; inputs[0] = new MachineConnection("Note Input"); } protected override void endTickImpl(ArrayList parameterChanges) { foreach (MachineParameterChange change in parameterChanges) { for (int x = 1; x < 10; x++) { if (change.parameter == parameters[x]) { // We swap our pointer so that any notes already playing won't change. harmonics = (float[])harmonics.Clone(); // Now we make the change to the new structure. harmonics[x - 1] = (float)change.newValue; return; } } if (change.parameter == parameters[0]) { Sample s = App.samples.getSample((int) change.newValue); if (s is EnvelopeSample) { envelope = (EnvelopeSample)s; } } } } } }