static void Main(string[] args) { // TODO: Main runs in a different thread than the audio streams. Deal with thread safety. // if a future hihat closed sound is not muted, calculate its position in byte time, var hhc. // (number of cycles * cycle size + value of old byteInterval at start of present cycle + new byteInterval) // in the hihat open sound thread, determine how many bytes until hhc is reached. Metronome metronome = Metronome.GetInstance(); metronome.Tempo = 75f; //new Layer("[.25,.25@C4,.25@A2,.25@A3,.25@Bb2,1.75@Bb3]2,[.25@F2,.25@F3,.25@D2,.25@D3,.25@Eb2,1.75@Eb3](2)-.5,1/6@Eb3,1/6@D3,1/6@Db3,.5@C3,.5@Eb3,.5@D3,.5@Ab2,.5@G2,.5@Db3,1/6@C3,1/6@F#3,1/6@F3,1/6@E3,1/6@Bb3,1/6@A3,1/3@Ab3,1/3@Eb3,1/3@B2,1/3@Bb2,1/3@A2,1/3+3@Ab2,{$s}2/3", "C3", "", 0, .7f); //new Layer("[.5,.5+.75,.5,.75]4,.5,.25,.5,.25,.75,.25,.5,!1!.5,.5+.75,.5,.75!2!,.5,.75,.5,1,.25,{$s}2/3", WavFileStream.GetFileByName("Kick Drum V2")); //new Layer("[[1@0,1.5|.5]2,.25(2)]2,1@0,2,!1!1@0,.5,1.25!2.75!,.5,.75,1.5,.25(2),{$s}2/3", WavFileStream.GetFileByName("Snare Rim V3")); //new Layer("[.5(6)]7,{$s}2/3", WavFileStream.GetFileByName("HiHat Half Center V1")); //new Layer("1", "A6"); new Layer(".5@0,[.5(3),.5@47,.25,.5,1.25]2,!3!.75,1,.75,.5@47,.25,1.5,!4!.5@47,1.5,.5,.25,{$s}2/3,{$s}4/5", WavFileStream.GetFileByName("Snare Center V2")); new Layer("[.75,3.25]3,.75,1.25,.75,1.25,{$s}2/3,{$s}4/5", WavFileStream.GetFileByName("Kick Drum V3")); new Layer("3*4+.25@0,.25@28,3.5,{$s}2/3,{$s}4/5", WavFileStream.GetFileByName("FloorTom V2")); new Layer(".25@0,[1,.5,.25@20,.25@22,.25@20,.5@22,.5,.25,.5]2,!3!.75,.5,1/6,1/6@12(2),.5,.25,.5,.75+1,!4!.5,.75,.25,.5(2),.5,{$s}2/3,{$s}4/5", WavFileStream.GetFileByName("HiHat Half Center V2")); new Layer("1", "A7"); //new Layer("[.75@0,.75,.5,2]3,.75@0,.75,.5+.75,.75,.5", "A4"); //new Layer("1", "D3"); //metronome.SetSilentInterval(4, 4); //Metronome.Save("Slinky"); //todo: why does @0 on first of pitch layer get played? //var layer1 = new Layer("[1,2/3,1/3]4,{$s}2/3", "A4"); //new Layer("1", "A5"); //var layer2 = new Layer("1,2/3,1/3", WavFileStream.GetFileByName("Ride Center V3")); //new Layer("1,1,1/3@19", WavFileStream.GetFileByName("HiHat Pedal V2")); //Metronome.Load("metronome"); //var metronome = Metronome.GetInstance(); //metronome.SetRandomMute(50); //Thread.Sleep(500); metronome.Play(); //Console.ReadKey(); //metronome.Tempo = 20f; //metronome.Record("test"); //metronome.ExportAsWav(0, "test.wav"); Console.ReadKey(); metronome.Stop(); //metronome.ChangeTempo(50f); //Console.ReadKey(); //metronome.ChangeTempo(38f); //Console.ReadKey(); //metronome.Stop(); //metronome.Play(); //Console.ReadKey(); //metronome.Stop(); metronome.Dispose(); //Console.ReadKey(); }
/** <summary>Add array of beat cells and create all audio sources.</summary> * <param name="beat">Array of beat cells.</param> */ public void SetBeat(BeatCell[] beat) { //float tempo = Metronome.GetInstance().Tempo; List <string> sources = new List <string>(); for (int i = 0; i < beat.Count(); i++) { beat[i].Layer = this; if (beat[i].SourceName != string.Empty && beat[i].SourceName.Count() > 5) { // should cells of the same source use the same audiosource instead of creating new source each time? Yes if (!AudioSources.ContainsKey(beat[i].SourceName)) { var wavStream = new WavFileStream(beat[i].SourceName) { Layer = this }; AudioSources.Add(beat[i].SourceName, wavStream); } beat[i].AudioSource = AudioSources[beat[i].SourceName]; if (BeatCell.HiHatOpenFileNames.Contains(beat[i].SourceName)) { HasHiHatOpen = true; } else if (BeatCell.HiHatClosedFileNames.Contains(beat[i].SourceName)) { HasHiHatClosed = true; } } else { if (beat[i].SourceName != string.Empty && beat[i].SourceName.Count() <= 5) { // beat has a defined pitch // check if basepitch source exists if (BasePitchSource == default(PitchStream)) { BasePitchSource = new PitchStream(); BasePitchSource.SetFrequency(beat[i].SourceName, beat[i]); BasePitchSource.BaseFrequency = PitchStream.ConvertFromSymbol(beat[i].SourceName); // make the base freq BasePitchSource.Layer = this; } else { BasePitchSource.SetFrequency(beat[i].SourceName, beat[i]); } beat[i].AudioSource = BasePitchSource; } else { if (IsPitch) { // no pitch defined, use base pitch BasePitchSource.SetFrequency(BasePitchSource.BaseFrequency.ToString(), beat[i]); } beat[i].AudioSource = BaseAudioSource; // is hihat sound? if (BeatCell.HiHatClosedFileNames.Contains(BaseSourceName)) { beat[i].IsHiHatClosed = true; } else if (BeatCell.HiHatOpenFileNames.Contains(BaseSourceName)) { beat[i].IsHiHatOpen = true; } } } // set beat's value based on tempo and bytes/sec beat[i].SetBeatValue(); } Beat = beat.ToList(); SetBeatCollectionOnSources(Beat); }