public void TestMidiFileUse() { using (var cs = new Csound6Net()) { FileInfo fi = new FileInfo("pgmassign_advanced.wav"); if (fi.Exists) { fi.Delete(); } fi.Refresh(); Assert.IsFalse(fi.Exists); FileInfo csf = new FileInfo(@"csdFiles\pgmassign_advanced.csd"); var parms = cs.GetParameters(); Assert.IsFalse(parms.IsDoneWhenMidiDone); parms.SetOption("-T"); parms = cs.GetParameters(); Assert.IsTrue(parms.IsDoneWhenMidiDone); cs.SetMidiFileInput("midiFiles/pgmassign_advanced.mid"); cs.SetOutputFileName(fi.Name, SoundFileType.TypWav, SampleFormat.AeShort); CsoundStatus result = cs.Compile(new string[] { csf.FullName }); Assert.AreEqual(CsoundStatus.Success, result); Assert.AreEqual(0.0, cs.ScoreTime); cs.Perform(); var time = cs.ScoreTime; Assert.IsTrue(cs.ScoreTime > 0.0); Assert.IsTrue(cs.ScoreTime > 3.50); fi.Refresh(); Assert.IsTrue(fi.Exists); Assert.IsTrue(fi.Length > 0); Assert.IsTrue(fi.Length > 1000); } }
static int Main(string[] args) { Console.Out.WriteLine(); var channels = new UserData(); //empty constructor creates its own Csound instance. CsoundStatus result = channels.Csound.Compile(args); //args include the csd file to perform (example plays for one minute) if (result == CsoundStatus.Success) { var t = new Csound6NetThread(channels); //This sets the thread in motion until Hz not a positive integer or score completes. // Now we can communicate with it from here via channels or callbacks double hz = 1; // So, we'll send whatever frequency is typed in from the keyboard via "pitch" channel while (hz > 0) { Console.Out.Write("\nEnter a pitch in Hz (or 0 to exit) and press enter:"); string s = Console.In.ReadLine(); if (Double.TryParse(s, out hz) && (hz > 0)) { channels["pitch"] = hz;// channel implementations use new csound 6 thread-safe signatures for channel access. } } channels.Done = true; //aborts performance loop (could use mutexes for airtight concurrent access) t.Join(); //good practice for orderly shutdown, but destructor of thread would pretty much do this anyway. while (t.IsRunning) { ; //normally not running when Join returns } t.Dispose(); } return((((int)result) >= 0) ? 0 : (int)result); }
public async Task TestPlayAsync() { using (Csound6Net cs = new Csound6Net()) { var parms = cs.GetParameters(); parms.MaximumThreadCount = 1;//tried cranking up to 4 cores, but this simple case actually slows down when > 1 parms.IsRealtimeMode = true; var progress = new ProgressCounter(); m_timenow = 0.0f; //should increase as progress is reported var cancel = new CancellationTokenSource(); cancel.CancelAfter(500); //force a cancelation after 2 seconds of processing (full xanadu takes 7 seconds to render) try { CsoundStatus result = await cs.PlayAsync(new FileInfo("csdFiles\\xanadu.csd"), progress, cancel.Token); Assert.Fail("Reached unexpected completion in TestPlayAsync: expected cancellation not executed."); //shouldn't execute } catch (OperationCanceledException e) { var token = e.CancellationToken; Assert.AreEqual(cancel.Token, token); Assert.IsTrue(token.IsCancellationRequested); } catch (Exception se) { Assert.Fail("System Exception: {0}", se.Message); } Assert.IsTrue(cancel.IsCancellationRequested); Assert.IsTrue(m_timenow > 0.0f); //confirm that there was progress bar activity Assert.IsTrue(m_timenow > 2.0f); //confirm that we got at least the first 2 seconds processed. Assert.IsTrue(m_timenow < 40.0f); //xanadu lasts just under 60 seconds verify that final value well under that. } }
/* * Main loop for processing messages from client to performance thread. * Processes all queued messages before each call to PerformKsmps. * When Stop() message received or if an error or completion state occurs, * this method exits causing the performance thread to complete. */ private CsoundStatus Perform() { bool done = false; while (!done) { done = DrainQueue(); if (!done) { var handle = ProcessCallback; if (handle != null) { handle(this, new Csound6ThreadedProcessEventArgs(m_csound)); } done = m_csound.PerformKsmps(); } } ; if (Status == CsoundStatus.Success) { Status = CsoundStatus.Completed; } m_csound.Cleanup(); m_queueLock.Lock(); m_queue.Clear(); m_flushLock.Notify(); m_queueLock.Unlock(); IsRunning = false; return(Status); }
public void TestTableAccess() { Csound6Net cs = new Csound6Net(); FileInfo csf = new FileInfo(@"csdFiles\xanadu.csd"); CsoundStatus result = cs.CompileArgs(new string[] { csf.FullName }); Assert.IsTrue(((int)result) >= 0); Assert.AreEqual(CsoundStatus.Success, cs.Start()); //CompileArgs doesn't call start(); bool done = cs.PerformKsmps(); //enough to get f1 to be created Assert.IsFalse(done); Csound6Table f1 = new Csound6Table(1, cs); Assert.IsTrue(f1.IsDefined); int len = f1.Length; Assert.AreEqual(8192, len); //xanadu tables are 8192 cells long. double[] f1dat = f1.Copy(); //fetch f1 the legacy way Assert.IsNotNull(f1dat); Assert.AreEqual(len, f1dat.Length); Assert.AreEqual(f1dat[25], f1[25]); double[] f1safe = f1.CopyOut(); //fetch f1 the new threadsafe way f1[50] = .5; Assert.AreEqual(.5, f1[50]); f1[50] = f1dat[50];//swap out a few cells via this[index] Assert.AreEqual(f1dat[50], f1[50]); Assert.AreEqual(f1dat[25], f1[25]); for (int i = 0; i < f1.Length; i++) { Assert.AreEqual(f1dat[i], f1safe[i]); } //try out some of the other tables, test CopyIn. var f2 = new Csound6Table(2, cs); double[] f2dat = f2.CopyOut(); Assert.AreEqual(f1dat.Length, f2dat.Length); for (int i = 0; i < 2048; i++) { Assert.AreEqual((int)(f1[i + 2048] * 100000000), (int)(f2[i] * 100000000));//f1 is sine, f2 is cosine } f1.CopyIn(f2dat); for (int i = 0; i < f1.Length; i++) { Assert.AreEqual(f1[i], f2[i]); //did CopyIn work? } f1.CopyIn(f1dat); //restore for (int i = 0; i < f1.Length; i++) { Assert.AreEqual(f1[i], f1safe[i]); } cs.Stop(); //shut csound down. (stop not relevant in single thread but call anyway to test. result = cs.Cleanup(); Assert.IsTrue(result == CsoundStatus.Success); cs.Dispose(); }
public void TestRuntimeProperties() { bool set = Csound6Net.SetGlobalEnv("RGHMUSIC", "Henninger"); Assert.IsTrue(set); object o = new Object(); using (Csound6Net cs = new Csound6Net(o, CsoundInitFlag.NoFlags, null)) { try { m_messageText = new StringBuilder(); m_count = 0; cs.MessageCallback += TestMessageEvent; m_fileopened = false; cs.FileOpenCallback += TestFileOpenEvent; FileInfo csdFile = new FileInfo("csdFiles\\Simple.csd"); string path = csdFile.FullName; string shortpath = BridgeToCpInvoke.wGetShortPathName(csdFile.FullName); //test long strings CsoundStatus result = cs.Compile(new string[] { shortpath }); Assert.AreEqual(CsoundStatus.Success, result); object o1 = cs.HostData; //test marshalling of host data. Assert.AreEqual(o, o1); cs.HostData = "abc"; Assert.IsTrue("abc".Equals(cs.HostData)); string sfdir = cs.GetEnv("SFDIR"); Assert.IsNotNull(sfdir); Assert.IsTrue(sfdir.Length > 0); string garbage = cs.GetEnv("garbage"); Assert.IsTrue(string.IsNullOrWhiteSpace(garbage)); string rgh = cs.GetEnv("RGHMUSIC"); Assert.AreEqual("Henninger", rgh); //test for sample rate, control rate, ksamps, filename from simple.csd... Assert.AreEqual(44100.0, cs.Sr); Assert.AreEqual(441.0, cs.Kr); Assert.AreEqual(100, cs.Ksmps); Assert.AreEqual(1.0, cs.OdBFS); Assert.AreEqual(1, cs.Nchnls); Assert.AreNotEqual(0, m_count); Assert.AreEqual("simple.wav", cs.OutputFileName); //confirm that all stdout text went here: for Simple.csd, chatter ends "SECTION 1:\n" string text = m_messageText.ToString(); Assert.IsTrue(text.EndsWith("SECTION 1:\n")); Assert.IsTrue(m_fileopened); //make sure we enterred the tests in TestFileOpenEvent } catch (Exception e) { string x = e.Message; Assert.Fail(x); } } }
/// <summary> /// Prepares an instance of Csound for Cscore processing outside of running an orchestra (i.e. "standalone Cscore"). /// It is an alternative to csoundPreCompile(), csoundCompile(), and csoundPerform*() /// and should not be used with these functions. /// You must call this function before using the interface in "cscore.h" when you do not wish /// to compile an orchestra. /// Pass it the already open FILE* pointers to the input and output score files. /// </summary> /// <param name="ifile"></param> /// <param name="ofile"></param> /// <returns>CsoundStatus.Success on success and CsoundStaus.InitializationError or other error code if it fails.</returns> /// <returns></returns> public CsoundStatus InitializeCscore(FileInfo inFile, FileInfo outFile) { IntPtr pInFile = BridgeToCpInvoke.cfopen(inFile.FullName, "r"); IntPtr pOutFile = BridgeToCpInvoke.cfopen(outFile.FullName, "w"); CsoundStatus result = Int2StatusEnum(NativeMethods.csoundInitializeCscore(Engine, pInFile, pOutFile)); if ((int)result < 0) { throw new Csound6NetException(Csound6NetException.CscoreFailed, "Init", result); } return(result); }
public async Task TestOpcodeAccess() { using (Csound6Net cs = new Csound6Net()) { FileInfo csdFile = new FileInfo("csdFiles\\Simple.csd"); CsoundStatus result = await cs.CompileAsync(new string[] { csdFile.FullName }); //tests raw long strings for fopen Assert.AreEqual(CsoundStatus.Success, result); IDictionary <string, IList <OpcodeArgumentTypes> > opcodes = await cs.GetOpcodeListAsync(); Assert.IsTrue(opcodes.Count > 1000); Assert.IsTrue(opcodes.ContainsKey("oscil")); Assert.IsTrue(opcodes["oscil"].Count > 2); Assert.AreEqual(5, opcodes["oscil"].Count);//there should be five oscil opcode instances foreach (OpcodeArgumentTypes op in opcodes["oscil"]) { Assert.IsFalse(string.IsNullOrWhiteSpace(op.outypes)); Assert.IsFalse(string.IsNullOrWhiteSpace(op.intypes)); char otype = op.outypes[0]; Assert.IsTrue((otype == 'a') || (otype == 's')); Assert.AreEqual(4, op.intypes.Length); Assert.IsTrue(op.intypes.EndsWith("jo")); if (otype == 's') { Assert.IsTrue(op.intypes.StartsWith("kk")); } else if (otype == 'a') { string start = op.intypes.Substring(0, 2); Assert.IsTrue(start.Contains("a") || start.Contains("k")); } else { Assert.Fail("opcode test: output type for oscil - expected a|s got {0}", otype); } } //test that modules loaded: Assert.IsNotNull(opcodes["pan2"]); Assert.AreEqual(1, opcodes["pan2"].Count); Assert.AreEqual("aa", opcodes["pan2"][0].outypes); Assert.AreEqual("axo", opcodes["pan2"][0].intypes); Assert.IsTrue(opcodes.Keys.Contains("granule")); IDictionary <string, int> namedGens = cs.GetNamedGens(); Assert.IsTrue(namedGens.Count > 0); foreach (string name in namedGens.Keys) { Assert.IsTrue(name.Length > 0); Assert.IsTrue(namedGens[name] > 0); } } }
/// <summary> /// Legacy channel access method. Should be avoided in favor of csound 6's new thread-safe /// access methods as used in subclasses. /// Used internally by Get/SetValueDirect methods in subclasses ideally called from /// within the same thread between calls to PerformKsmps or PerformBuffer. /// If used between different threads (not recommended - use threadsafe property "Value" instead), /// you should acquire and use a lock (see GetLock method) to arbitrate potential race conditions. /// </summary> /// <returns>a pointer to unmanaged memory where the channel's data begins</returns> internal IntPtr GetChannelPointer() { if (m_pChannel == IntPtr.Zero) { int flags = ((int)Type) + (int)(((uint)Direction) << 4); CsoundStatus result = Csound6Net.Int2StatusEnum(NativeMethods.csoundGetChannelPtr(m_csound.Engine, out m_pChannel, Name, flags)); if (((int)result) < 0) { throw new Csound6NetException(Csound6NetException.ChannelAccessFailed, Name, result); } } return(m_pChannel); }
public async Task TestPerformAsync() { using (var cs = new Csound6Net()) { var cancel = new CancellationTokenSource(); try { FileInfo csf = new FileInfo(@"csdFiles\xanadu.csd"); CsoundStatus result = await cs.CompileAsync(new string[] { csf.FullName }); cs.SetOutputFileName("f:\\PerfXanadu.wav", SoundFileType.TypWav, SampleFormat.AeShort); string s = cs.OutputFileName; Assert.AreEqual(CsoundStatus.Success, result); cancel.CancelAfter(1500);//cancel timeout avter 1.5 seconds of computation Assert.IsFalse(cancel.Token.IsCancellationRequested); result = await cs.PerformAsync(null, cancel.Token); Assert.Fail("Reached unexpected completion in TestPlayAsync: expected cancellation not executed."); //shouldn't execute } catch (OperationCanceledException ce) {//Verify that cancelation timeout occurred in a timely way. var token = ce.CancellationToken; Assert.AreEqual(cancel.Token, token); Assert.IsTrue(token.IsCancellationRequested); Assert.IsTrue(cs.ScoreTime < 50.0); } catch (Csound6NetException e) { Assert.Fail("TestSimplePerform Error: {0}", e.Message); } catch (Exception se) { Assert.Fail("System Exception: {0}", se.Message); } var time = cs.ScoreTime;//Confirm that cancelation worked: goes 60 sec - time at cancel... Assert.IsTrue(cancel.Token.IsCancellationRequested); Assert.IsTrue(time < 50.0); } }
public Csound6PerformanceException(string msg, CsoundStatus _status) : base(msg, _status) { }
public Csound6ScoreException(string msg, CsoundStatus _status) : base(msg, _status) { }
public Csound6CompilerException(string msg, CsoundStatus _status) : base(msg, _status) { }
public Csound6NetException(string msg, string value, CsoundStatus _status) : base(string.Format(((msg.IndexOf(" ") < 0) ? Csound6Net.c_rm.GetString(msg) : msg), value, _status)) { Status = _status; }
public void TestChannelDefinition() { m_messageText = new StringBuilder(); m_count = 0; using (var cs = new Csound6NetRealtime()) { cs.MessageCallback += TestMessageEvent; FileInfo csf = new FileInfo("csdFiles\\SimpleRuntime.csd"); CsoundStatus result = cs.CompileArgs(new string[] { csf.FullName }); Assert.AreEqual(CsoundStatus.Success, result); result = cs.Start(); Assert.AreEqual(CsoundStatus.Success, result); var cch = new Csound6ControlChannel("chan1", ChannelDirection.Input, cs); Assert.AreEqual(ChannelDirection.Input, cch.Direction); Assert.AreEqual(ChannelBehavior.Exponential, cch.Behavior); Assert.AreEqual(ChannelType.Control, cch.Type); Assert.AreEqual(1000.0, cch.Default); Assert.AreEqual(500.0, cch.Minimum); Assert.AreEqual(2000.0, cch.Maximum); cch.Behavior = ChannelBehavior.Integer; cch.Maximum = 2500.0; cch.Minimum = 400.0; var cch1 = new Csound6ControlChannel("chan1", ChannelDirection.Input, cs); Assert.AreEqual(cch.Name, cch1.Name); Assert.AreEqual(cch.Minimum, cch1.Minimum); Assert.AreEqual(400.0, cch1.Minimum); Assert.AreEqual(2500.0, cch.Maximum); Assert.AreEqual(cch.Maximum, cch1.Maximum); Assert.AreEqual(ChannelBehavior.Integer, cch1.Behavior); var bus = new Csound6SoftwareBus(cs); IDictionary <string, ChannelInfo> chans = cs.GetChannelList(); Assert.IsNotNull(chans); Assert.IsTrue(chans.Count > 0); foreach (string key in chans.Keys)//now in test for software bus. remove this part? { ChannelInfo info = chans[key]; var chan = bus.AddChannel(info); switch (chan.Type) { case ChannelType.String: Assert.IsInstanceOfType(chan, typeof(Csound6StringChannel)); Assert.AreEqual(256, chan.DataSize); break; case ChannelType.Audio: Assert.IsInstanceOfType(chan, typeof(Csound6AudioChannel)); Assert.AreEqual(35280, chan.DataSize); //ksmps = 4410 * sizeof(MYFLT) break; case ChannelType.Control: Assert.IsInstanceOfType(chan, typeof(Csound6ControlChannel)); Assert.AreEqual(8, chan.DataSize); if (chan.Name.Equals(cch1.Name)) { Assert.AreEqual(cch.Maximum, ((Csound6ControlChannel)chan).Maximum); Assert.AreEqual(cch.Minimum, ((Csound6ControlChannel)chan).Minimum); Assert.AreEqual(cch.Default, ((Csound6ControlChannel)chan).Default); } break; case ChannelType.Pvs: case ChannelType.Var: default: Assert.IsFalse(false, string.Format("Unsupported Channel type:{0}", chan.GetType())); break; } //end switch } //end foreach key } //end using csound string text = m_messageText.ToString(); //if need to analyze output... }
public void TestCsound6Compiles() { string orc; string sco; string[] opts = "-R -W -d".Split(new char[] { ' ', '\t' }); using (var orcReader = new StreamReader("classicFiles\\Simple.orc")) { orc = orcReader.ReadToEnd(); } using (var scoReader = new StreamReader("classicFiles\\Simple.sco")) { sco = scoReader.ReadToEnd(); } using (var cs = new Csound6Net()) { var parms = new Csound6Parameters(cs); Assert.IsTrue(parms.IsDisplayingGraphs); foreach (string opt in opts) { Assert.IsTrue(parms.SetOption(opt) == CsoundStatus.Success); //try with object } parms.RefreshParams(); Assert.IsFalse(parms.IsDisplayingGraphs); cs.SetOutputFileName("simple1.wav", SoundFileType.TypWav, SampleFormat.AeFloat); Assert.AreEqual("simple1.wav", cs.OutputFileName); CsoundStatus result = cs.CompileOrc(orc); Assert.IsTrue(result == CsoundStatus.Success); int kcycles = 0; long lastSamp = 0; if (result == CsoundStatus.Success) { result = cs.ReadScore(sco); Assert.AreEqual(CsoundStatus.Success, result); if (result == CsoundStatus.Success) { result = cs.Start(); while (!cs.PerformKsmps()) { kcycles++; } Assert.IsTrue(kcycles > 0); lastSamp = cs.CurrentTimeSamples; Assert.IsTrue(lastSamp > 0L); result = cs.Cleanup(); Assert.IsTrue(result == CsoundStatus.Success); } } result = cs.Cleanup(); Assert.AreEqual(CsoundStatus.Success, result); //Reset and try again with TREE-based signatures cs.Reset(); //try parms via static method foreach (string opt in opts) { Assert.IsTrue(Csound6Parameters.SetOption(cs, opt) == CsoundStatus.Success); } cs.SetOutputFileName("simple2.wav", SoundFileType.TypWav, SampleFormat.AeFloat); IntPtr tree = cs.ParseOrc(orc); Assert.IsNotNull(tree); Assert.AreNotEqual(IntPtr.Zero, tree); result = cs.CompileTree(tree); Assert.AreEqual("simple2.wav", cs.OutputFileName); Assert.AreEqual(CsoundStatus.Success, result); cs.DeleteTree(tree); result = cs.ReadScore(sco); Assert.AreEqual(CsoundStatus.Success, cs.Start()); long crntSamp = 0L; while (!cs.PerformBuffer()) { Assert.IsTrue(cs.CurrentTimeSamples > crntSamp); crntSamp = cs.CurrentTimeSamples; } Assert.AreEqual(lastSamp, cs.CurrentTimeSamples);//same file should yield same number of samples Assert.AreEqual(CsoundStatus.Success, cs.Cleanup()); }//end using Csound6Net }