using System; using System.Collections; namespace Wavelet_Tracker { public class NineOhNineMachine : MachineParameterisedBase { private const string type = "909a"; private const string author = "Internal"; private const int version = 1; private ArrayList playingDrums = new ArrayList(); public NineOhNineMachine(string name) : base(type, author, version, name) { machineLimitations = MachineLimitations.EmitsPCM; } protected override void endProductionImpl(long interval) { PCMEvent evt = new PCMEvent(playTime, playTime + interval, 1); evt.clearData(); for (int x = 0; x < playingDrums.Count; x++) { PlayingDrum drum = (PlayingDrum)playingDrums[x]; bool hasFinished = drum.play(evt); if (hasFinished) { playingDrums.RemoveAt(x); x--; } } outputs[0].buffer.addEvent(evt); } protected override void endSeekImpl(long seekTime) { playingDrums.Clear(); } protected override void endSetupParametersImpl() { parameters = new MachineParameter[1]; MachineParameterSwitch bassdrum = new MachineParameterSwitch("Bassdrum", 1, false); parameters[0] = bassdrum; } protected override void endSetupInputOutputImpl() { outputs = new MachineConnection[1]; outputs[0] = new MachineConnection("Sound Output"); inputs = new MachineConnection[0]; } protected override void endTickImpl(ArrayList parameterChanges) { for (int x = 0; x < parameterChanges.Count; x++) { MachineParameterChange mpc = (MachineParameterChange) parameterChanges[x]; // This is what the programmer will do for each parameter that they want to watch // for changes. Any parameters that are just read from during production can be // ignored. if (mpc.parameter.parameterName.Equals("Bassdrum")) { PlayingDrum drum = new PlayingDrum(playTime); playingDrums.Add(drum); } } } } public class PlayingDrum { public long startTime; public long currTime; public const long duration = (long) (App.TIME_RES * 0.4); public PlayingDrum(long playTime) { currTime = startTime = playTime; } public unsafe bool play(PCMEvent evt) { double sampAdvance = (evt.endTime - evt.startTime) / (double)evt.bufferLength; double workTime = currTime-startTime; //onsole.WriteLine(workTime); //onsole.WriteLine("Calling for production"); for (int x = 0; x < evt.bufferLength && workTime < duration; x++) { float f = (float) (Math.Sin(Math.Pow(workTime * 0.000001, 0.85)) * (1.0 - (workTime / duration)) * 0.9); *(evt.data[0] + x) += f; // evt.data[1, x] += f; // evt.data[2, x] += f; // evt.data[3, x] += f; // evt.data[4, x] += f; // evt.data[5, x] += f; // evt.data[6, x] += f; // evt.data[7, x] += f; workTime += sampAdvance; } currTime += (evt.endTime - evt.startTime); if (workTime > duration) return true; return false; } } }