From 60da9e6838b36ad4c5100aad06bca357ab1b1251 Mon Sep 17 00:00:00 2001 From: dzamkov Date: Sun, 13 Nov 2011 19:57:41 -0500 Subject: [PATCH] Fixed subtraction bug, moved generators into their own file, rearranged some parser functions --- BitOrchestra.csproj | 1 + Evaluator.cs | 115 ----------------------------------------- Expression.cs | 2 +- Generator.cs | 123 ++++++++++++++++++++++++++++++++++++++++++++ Parser.cs | 120 +++++++++++++++++++++++++++++------------- Samples/droid.bos | 3 ++ 6 files changed, 211 insertions(+), 153 deletions(-) create mode 100644 Generator.cs create mode 100644 Samples/droid.bos diff --git a/BitOrchestra.csproj b/BitOrchestra.csproj index 7dfa3af..f37b709 100644 --- a/BitOrchestra.csproj +++ b/BitOrchestra.csproj @@ -72,6 +72,7 @@ + Form diff --git a/Evaluator.cs b/Evaluator.cs index 22db73e..33f8c00 100644 --- a/Evaluator.cs +++ b/Evaluator.cs @@ -640,121 +640,6 @@ public override void Generate(Value Start, Value[] Buffer) } } - /// - /// An evaluator for a generator function. - /// - public abstract class GeneratorEvaluator : UnaryEvaluator - { - public GeneratorEvaluator(Evaluator Source, double Period, double Scale) - : base(Source) - { - this.Period = Period; - this.Scale = Scale; - } - - /// - /// The length of a period for this generator. - /// - public readonly double Period; - - /// - /// The amount the output value is scaled by. - /// - public readonly double Scale; - } - - /// - /// An evaluator for a saw generator. - /// - public sealed class SawEvaluator : GeneratorEvaluator - { - public SawEvaluator(Evaluator Source, double Period, double Scale) - : base(Source, Period, Scale) - { - - } - - public override void Generate(Value Start, Value[] Buffer) - { - this.Source.Generate(Start, Buffer); - for (int t = 0; t < Buffer.Length; t++) - { - double input = ((Buffer[t] / this.Period) % 1.0 + 1.0) % 1.0; - double output = input * 2.0 - 1.0; - Buffer[t] = (Value)(output * Scale); - } - } - } - - /// - /// An evaluator for a sine generator. - /// - public sealed class SineEvaluator : GeneratorEvaluator - { - public SineEvaluator(Evaluator Source, double Period, double Scale) - : base(Source, Period, Scale) - { - - } - - public override void Generate(Value Start, Value[] Buffer) - { - this.Source.Generate(Start, Buffer); - for (int t = 0; t < Buffer.Length; t++) - { - double input = Buffer[t] / this.Period; - double output = Math.Sin(input * 2.0 * Math.PI); - Buffer[t] = (Value)(output * Scale); - } - } - } - - /// - /// An evaluator for a square generator. - /// - public sealed class SquareEvaluator : GeneratorEvaluator - { - public SquareEvaluator(Evaluator Source, double Period, double Scale) - : base(Source, Period, Scale) - { - - } - - public override void Generate(Value Start, Value[] Buffer) - { - this.Source.Generate(Start, Buffer); - for (int t = 0; t < Buffer.Length; t++) - { - double input = ((Buffer[t] / this.Period) % 1.0 + 1.0) % 1.0; - double output = input > 0.5 ? 1.0 : -1.0; - Buffer[t] = (Value)(output * Scale); - } - } - } - - /// - /// An evaluator for a triangle generator. - /// - public sealed class TriangleEvaluator : GeneratorEvaluator - { - public TriangleEvaluator(Evaluator Source, double Period, double Scale) - : base(Source, Period, Scale) - { - - } - - public override void Generate(Value Start, Value[] Buffer) - { - this.Source.Generate(Start, Buffer); - for (int t = 0; t < Buffer.Length; t++) - { - double input = ((Buffer[t] / this.Period) % 1.0 + 1.0) % 1.0; - double output = input < 0.5 ? input * 4.0 - 1.0 : input * -4.0 + 3.0; - Buffer[t] = (Value)(output * Scale); - } - } - } - /// /// An evaluator for a sequencer. /// diff --git a/Expression.cs b/Expression.cs index eb05ab9..c665010 100644 --- a/Expression.cs +++ b/Expression.cs @@ -235,7 +235,7 @@ protected override Evaluator CreateEvaluator(Dictionary Ca if (constleft && constright) return new ConstantEvaluator(leftval - rightval); if (constleft) - return new AddConstantEvaluator(righteval, -leftval); + return new SubtractEvaluator(lefteval, righteval.GetBuffered(BufferSize)); if (constright) return new AddConstantEvaluator(lefteval, -rightval); return new SubtractEvaluator(lefteval, righteval.GetBuffered(BufferSize)); diff --git a/Generator.cs b/Generator.cs new file mode 100644 index 0000000..0bdfbe0 --- /dev/null +++ b/Generator.cs @@ -0,0 +1,123 @@ +using System; +using System.Collections.Generic; +using System.Linq; + +using Value = System.Int32; + +namespace BitOrchestra +{ + /// + /// An evaluator for a generator function. + /// + public abstract class GeneratorEvaluator : UnaryEvaluator + { + public GeneratorEvaluator(Evaluator Source, double Period, double Scale) + : base(Source) + { + this.Period = Period; + this.Scale = Scale; + } + + /// + /// The length of a period for this generator. + /// + public readonly double Period; + + /// + /// The amount the output value is scaled by. + /// + public readonly double Scale; + } + + /// + /// An evaluator for a saw generator. + /// + public sealed class SawEvaluator : GeneratorEvaluator + { + public SawEvaluator(Evaluator Source, double Period, double Scale) + : base(Source, Period, Scale) + { + + } + + public override void Generate(Value Start, Value[] Buffer) + { + this.Source.Generate(Start, Buffer); + for (int t = 0; t < Buffer.Length; t++) + { + double input = ((Buffer[t] / this.Period) % 1.0 + 1.0) % 1.0; + double output = input * 2.0 - 1.0; + Buffer[t] = (Value)(output * Scale); + } + } + } + + /// + /// An evaluator for a sine generator. + /// + public sealed class SineEvaluator : GeneratorEvaluator + { + public SineEvaluator(Evaluator Source, double Period, double Scale) + : base(Source, Period, Scale) + { + + } + + public override void Generate(Value Start, Value[] Buffer) + { + this.Source.Generate(Start, Buffer); + for (int t = 0; t < Buffer.Length; t++) + { + double input = Buffer[t] / this.Period; + double output = Math.Sin(input * 2.0 * Math.PI); + Buffer[t] = (Value)(output * Scale); + } + } + } + + /// + /// An evaluator for a square generator. + /// + public sealed class SquareEvaluator : GeneratorEvaluator + { + public SquareEvaluator(Evaluator Source, double Period, double Scale) + : base(Source, Period, Scale) + { + + } + + public override void Generate(Value Start, Value[] Buffer) + { + this.Source.Generate(Start, Buffer); + for (int t = 0; t < Buffer.Length; t++) + { + double input = ((Buffer[t] / this.Period) % 1.0 + 1.0) % 1.0; + double output = input > 0.5 ? 1.0 : -1.0; + Buffer[t] = (Value)(output * Scale); + } + } + } + + /// + /// An evaluator for a triangle generator. + /// + public sealed class TriangleEvaluator : GeneratorEvaluator + { + public TriangleEvaluator(Evaluator Source, double Period, double Scale) + : base(Source, Period, Scale) + { + + } + + public override void Generate(Value Start, Value[] Buffer) + { + this.Source.Generate(Start, Buffer); + for (int t = 0; t < Buffer.Length; t++) + { + double input = ((Buffer[t] / this.Period) % 1.0 + 1.0) % 1.0; + double output = input < 0.5 ? input * 4.0 - 1.0 : input * -4.0 + 3.0; + Buffer[t] = (Value)(output * Scale); + } + } + } +} \ No newline at end of file diff --git a/Parser.cs b/Parser.cs index 146f220..1f0051b 100644 --- a/Parser.cs +++ b/Parser.cs @@ -17,64 +17,79 @@ public static bool Parse(string Text, out Expression Expression, out SoundOption { Expression = null; Options = new SoundOptions(); + Dictionary variables = null; + int index = 0; + AcceptProgram(Text, ref index, ref variables, ref Options, out ErrorIndex); + if (index == Text.Length) + { + variables.TryGetValue(Result, out Expression); + return true; + } + return false; + } - Dictionary variables = new Dictionary(); - variables[Parameter] = IdentityExpression.Instance; - variables[Resolution] = ResolutionExpression.Instance; - + /// + /// Parses the given text (or as much as possible of it) and returns the expression for the specified target string, or false with an error index. + /// + public static bool Parse(string Text, int TargetIndex, int TargetLength, out Expression Expression, out SoundOptions Options, out int ErrorIndex) + { + Expression = null; + Options = new SoundOptions(); + Dictionary variables = null; int index = 0; - while (true) + AcceptProgram(Text, ref index, ref variables, ref Options, out ErrorIndex); + if (index >= TargetIndex) { + index = 0; + string target = Text.Substring(TargetIndex, TargetLength); AcceptExtendedWhitespace(Text, ref index); - int sindex = index; - - string optname = null; - int optvalue = 0; - if (AcceptOption(Text, ref sindex, ref optname, ref optvalue, out ErrorIndex)) + if (AcceptExpression(variables, target, ref index, ref Expression, out ErrorIndex)) { - switch (optname) + AcceptExtendedWhitespace(Text, ref index); + if (index == TargetLength) { - case "rate": - Options.Rate = optvalue; - break; - case "offset": - Options.Offset = optvalue; - break; - case "length": - Options.Length = optvalue; - break; - case "resolution": - Options.Resolution = optvalue; - break; - default: - break; + return true; } - index = sindex; + } + ErrorIndex += TargetIndex; + return false; + } + return false; + } + + /// + /// Parses a program in the given text. + /// + public static void AcceptProgram(string Text, ref int Index, ref Dictionary Variables, ref SoundOptions Options, out int ErrorIndex) + { + Variables = new Dictionary(); + Variables[Parameter] = IdentityExpression.Instance; + Variables[Resolution] = ResolutionExpression.Instance; + + while (true) + { + AcceptExtendedWhitespace(Text, ref Index); + + if (AcceptOption(Text, ref Index, Options, out ErrorIndex)) + { continue; } string varname = null; Expression varvalue = null; - if (AcceptAssignment(variables, Text, ref sindex, ref varname, ref varvalue, out ErrorIndex)) + if (AcceptAssignment(Variables, Text, ref Index, ref varname, ref varvalue, out ErrorIndex)) { - variables[varname] = varvalue; - index = sindex; + Variables[varname] = varvalue; continue; } break; } - AcceptExtendedWhitespace(Text, ref index); - if (index == Text.Length) - { - variables.TryGetValue(Result, out Expression); - return true; - } - - return false; + AcceptExtendedWhitespace(Text, ref Index); } + /// /// Tries parsing the target string in the given text. /// @@ -134,6 +149,37 @@ public static bool AcceptWhitespace(string Text, ref int Index) return found; } + /// + /// Tries parsing an option and applying it to the given sound options structure. + /// + public static bool AcceptOption(string Text, ref int Index, SoundOptions Options, out int ErrorIndex) + { + string optname = null; + int optvalue = 0; + if (AcceptOption(Text, ref Index, ref optname, ref optvalue, out ErrorIndex)) + { + switch (optname) + { + case "rate": + Options.Rate = optvalue; + break; + case "offset": + Options.Offset = optvalue; + break; + case "length": + Options.Length = optvalue; + break; + case "resolution": + Options.Resolution = optvalue; + break; + default: + break; + } + return true; + } + return false; + } + /// /// Tries parsing an option. /// diff --git a/Samples/droid.bos b/Samples/droid.bos new file mode 100644 index 0000000..24c15e8 --- /dev/null +++ b/Samples/droid.bos @@ -0,0 +1,3 @@ +#rate 8000 + +u = t >> 4 | t & (t >> 5) / (t >> 7 - (t >> 15) & -t >> 7 - (t >> 15)); \ No newline at end of file