Merge branch 'master' of https://scm.cri.ensmp.fr/git/Faustine
[Faustine.git] / interpretor / preprocessor / faust-0.9.47mr3 / architecture / osclib / faust / src / OSCControler.cpp
1 /*
2
3 Faust Project
4
5 Copyright (C) 2011 Grame
6
7 This library is free software; you can redistribute it and/or
8 modify it under the terms of the GNU Lesser General Public
9 License as published by the Free Software Foundation; either
10 version 2.1 of the License, or (at your option) any later version.
11
12 This library is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 Lesser General Public License for more details.
16
17 You should have received a copy of the GNU Lesser General Public
18 License along with this library; if not, write to the Free Software
19 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
20
21 Grame Research Laboratory, 9 rue du Garet, 69001 Lyon - France
22 research@grame.fr
23
24 */
25
26 #include <stdlib.h>
27 #include <iostream>
28
29 #include "OSCControler.h"
30 #include "FaustFactory.h"
31 #include "OSCSetup.h"
32 #include "OSCFError.h"
33 #include "RootNode.h"
34 #include "OSCIO.h"
35
36 using namespace std;
37
38 namespace oscfaust
39 {
40
41 #define kVersion 0.91f
42 #define kVersionStr "0.91"
43
44 static const char* kUDPPortOpt = "-port";
45 static const char* kUDPOutOpt = "-outport";
46 static const char* kUDPErrOpt = "-errport";
47 static const char* kUDPDestOpt = "-dest";
48
49 //--------------------------------------------------------------------------
50 // utilities for command line arguments
51 //--------------------------------------------------------------------------
52 static int getPortOption (int argc, char *argv[], const std::string& option, int defaultValue)
53 {
54 for (int i=0; i < argc-1; i++) {
55 if (option == argv[i]) {
56 int val = strtol( argv[i+1], 0, 10);
57 if (val) return val;
58 }
59 }
60 return defaultValue;
61 }
62
63 static const char* getDestOption (int argc, char *argv[], const std::string& option, const char* defaultValue)
64 {
65 for (int i=0; i < argc-1; i++) {
66 if (option == argv[i])
67 return argv[i+1];
68 }
69 return defaultValue;
70 }
71
72
73 //--------------------------------------------------------------------------
74 OSCControler::OSCControler (int argc, char *argv[], OSCIO* io)
75 : fUDPPort(kUDPBasePort), fUDPOut(kUDPBasePort+1), fUPDErr(kUDPBasePort+2), fIO(io)
76 {
77 fUDPPort = getPortOption (argc, argv, kUDPPortOpt, fUDPPort);
78 fUDPOut = getPortOption (argc, argv, kUDPOutOpt, fUDPOut);
79 fUPDErr = getPortOption (argc, argv, kUDPErrOpt, fUPDErr);
80 fDestAddress = getDestOption (argc, argv, kUDPDestOpt, "localhost");
81
82 fFactory = new FaustFactory(io);
83 fOsc = new OSCSetup();
84 }
85
86 OSCControler::~OSCControler ()
87 {
88 quit();
89 delete fFactory;
90 delete fOsc;
91 }
92
93 //--------------------------------------------------------------------------
94 float OSCControler::version() { return kVersion; }
95 const char* OSCControler::versionstr() { return kVersionStr; }
96
97 //--------------------------------------------------------------------------
98 // Add a node in the current group (top of the group stack)
99 void OSCControler::addnode (const char* label, float* zone, float init, float min, float max)
100 {
101 fFactory->addnode (label, zone, init, min, max);
102 }
103
104 //--------------------------------------------------------------------------
105 // Add a node using its fullpath from the root instead of the current group
106 // This method is used for alias messages. The arguments imin and imax allow
107 // to map incomming values from the alias input range to the actual range
108 void OSCControler::addfullpathnode (const string& fullpath, float* zone, float imin, float imax, float init, float min, float max)
109 {
110 fFactory->addfullpathnode (fullpath, zone, imin, imax, init, min, max);
111 }
112
113
114 //--------------------------------------------------------------------------
115 void OSCControler::opengroup (const char* label)
116 {
117 fFactory->opengroup (label);
118 }
119
120 //--------------------------------------------------------------------------
121 void OSCControler::closegroup ()
122 {
123 fFactory->closegroup ();
124 }
125
126 //--------------------------------------------------------------------------
127 static std::string quote (const char* str) {
128 std::string outstr ( str );
129 outstr.insert (0, 1, '\'');
130 outstr += '\'';
131 return outstr;
132 }
133
134 //--------------------------------------------------------------------------
135 // start the network services
136 void OSCControler::run ()
137 {
138 SMessageDriven root = fFactory->root(); // first get the root node
139 if (root) {
140 // and cast it to a RootNode
141 RootNode * rootnode = dynamic_cast<RootNode*> ((MessageDriven*)root);
142 // informs the root node of the udp ports numbers (required to handle the 'hello' message
143 if (rootnode) rootnode->setPorts (&fUDPPort, &fUDPOut, &fUPDErr);
144 // starts the network services
145 fOsc->start (root, fUDPPort, fUDPOut, fUPDErr, getDesAddress());
146
147 // and outputs a message on the osc output port
148 oscout << OSCStart("Faust OSC version") << versionstr() << "-"
149 << quote(root->getName()).c_str() << "is running on UDP ports "
150 << fUDPPort << fUDPOut << fUPDErr;
151 if (fIO) oscout << " using OSC IO - in chans: " << fIO->numInputs() << " out chans: " << fIO->numOutputs();
152 oscout << OSCEnd();
153
154 // that should not occur unless a derivative changes the root node type
155 if (!rootnode) OSCFErr << root->getName() << ": is not a root node, 'hello' message won't be supported" << OSCFEndl;
156 }
157 }
158
159 //--------------------------------------------------------------------------
160 const char* OSCControler::getRootName() { return fFactory->root()->getName(); }
161
162 //--------------------------------------------------------------------------
163 void OSCControler::quit ()
164 {
165 fOsc->stop();
166 }
167
168 }