// Copyright (C) 2006 David Griffiths // // This program is free software; you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation; either version 2 of the License, or // (at your option) any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. #include #include #include "Sample.h" using namespace std; using namespace spiralcore; ///////////////////////////////////////////////// ///////////////////////////////////////////////// class Node; class Synth { public: Synth(double samplerate) : m_Samplerate(samplerate), m_Root(NULL) {} void Build(const string &desc); Node *BuildNode(unsigned int &i, const string &desc); void Run(Sample &sample); void Delete(Node *node); private: Node *NewNode(const string &name); double m_Time; double m_Samplerate; Node *m_Root; }; ///////////////////////////////////////////////// class Node { public: Node() {} virtual ~Node() {} virtual double Run()=0; virtual char Type() { return 'n'; } private: }; class TerminalNode : public Node { public: TerminalNode() {} virtual ~TerminalNode() {} virtual double Run()=0; virtual char Type() { return 't'; } private: }; class NumTerminalNode : public TerminalNode { public: NumTerminalNode(double n) { m_Num=n; } virtual double Run() { return m_Num; } private: double m_Num; }; class TimeTerminalNode : public TerminalNode { public: virtual double Run() { return m_Time; } static void UpdateTime(double t) { m_Time=t; } private: static double m_Time; }; ///////////////////////////////////////////////// class OpNode : public Node { public: OpNode() {} virtual ~OpNode() {} virtual double Run()=0; virtual void AddArg(Node *a) { m_Children.push_back(a); } virtual char Type() { return 'o'; } virtual double RunArg(unsigned int i); vector m_Children; }; class PlusOpNode : public OpNode { public: virtual double Run() { return RunArg(0)+RunArg(1); } }; class MinusOpNode : public OpNode { public: virtual double Run() { return RunArg(0)-RunArg(1); } }; class MultiplyOpNode : public OpNode { public: virtual double Run() { return RunArg(0)*RunArg(1); } }; class ModOpNode : public OpNode { public: virtual double Run() { return fmod(RunArg(0),RunArg(1)); } }; class DivideOpNode : public OpNode { public: virtual double Run() { double b = RunArg(1); if (b!=0) return RunArg(0)/b; else return 0; } }; class SinOpNode : public OpNode { public: virtual double Run() { return sin(RunArg(0)); } }; class CosOpNode : public OpNode { public: virtual double Run() { return cos(RunArg(0)); } };