1 /*
2  *  music_manager.h
3  *
4  *  This file is part of NEST.
5  *
6  *  Copyright (C) 2004 The NEST Initiative
7  *
8  *  NEST is free software: you can redistribute it and/or modify
9  *  it under the terms of the GNU General Public License as published by
10  *  the Free Software Foundation, either version 2 of the License, or
11  *  (at your option) any later version.
12  *
13  *  NEST is distributed in the hope that it will be useful,
14  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
15  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16  *  GNU General Public License for more details.
17  *
18  *  You should have received a copy of the GNU General Public License
19  *  along with NEST.  If not, see <http://www.gnu.org/licenses/>.
20  *
21  */
22 
23 #ifndef MUSIC_MANAGER_H
24 #define MUSIC_MANAGER_H
25 
26 #include "config.h"
27 
28 #ifdef HAVE_MUSIC
29 #include <music.hh>
30 #endif
31 #include <string>
32 
33 // Includes from nestkernel:
34 #include "manager_interface.h"
35 #include "nest_types.h"
36 
37 // Includes from sli:
38 #include "dict.h"
39 
40 #ifdef HAVE_MUSIC
41 #include "music_event_handler.h"
42 #include "music_rate_in_handler.h"
43 #endif
44 
45 /*
46 Encapsulates all calls to MUSIC. We need to strip out all #ifdef
47 HAVE_MUSIC from other places and put them here. Look into those
48 functions:
49 
50 void nest::Communicator::finalize()
51 
52 Linked Functions:
53 
54 void set_status( index, const DictionaryDatum& );
55 DictionaryDatum get_status( index );
56 void register_music_in_port( std::string portname );
57 void unregister_music_in_port( std::string portname );
58 void register_music_event_in_proxy( std::string portname, int channel,
59 nest::Node* mp );
60 void set_music_in_port_acceptable_latency( std::string portname, double
61 latency );
62 void set_music_in_port_max_buffered( std::string portname, int maxbuffered );
63 void publish_music_in_ports_();
64 void update_music_event_handlers_( Time const&, const long, const long );
65 
66 Linked Data Structures:
67 
68 struct MusicPortData
69 std::map< std::string, MusicPortData > music_in_portlist_;
70 std::map< std::string, MusicEventHandler > music_event_in_portmap_;
71  */
72 
73 namespace nest
74 {
75 
76 class MUSICManager : public ManagerInterface
77 {
78 public:
79   virtual void initialize(); // called from meta-manager to construct
80   virtual void finalize();   // called from meta-manger to reinit
81 
82   virtual void set_status( const DictionaryDatum& );
83   virtual void get_status( DictionaryDatum& );
84 
85   MUSICManager();
86 
87   void init_music( int* argc, char** argv[] );
88 
89   /**
90    * Enter the runtime mode. This must be done before simulating. After having
91    * entered runtime mode ports cannot be published anymore.
92    * \param h_min_delay is the length of a time slice, after which
93    * communication should take place.
94    */
95   void enter_runtime( double h_min_delay );
96 
97   /**
98    * Advance the time of music by 1 simulation step.
99    */
100   void advance_music_time();
101 
102   void music_finalize(); // called from MPIManager::mpi_finalize
103 
104 #ifdef HAVE_MUSIC
105   MPI::Intracomm communicator();
106 
107   MUSIC::Setup* get_music_setup();
108   MUSIC::Runtime* get_music_runtime();
109 
110   /**
111    * Register a MUSIC input port (portname) with the port list.
112    * This will increment the counter of the respective entry in the
113    * music_in_portlist.
114    *
115    * The argument pristine should be set to true when a model
116    * registers the initial port name. This typically happens when the
117    * copy constructor of the model registers a port, as in
118    * models/music_event_in_proxy.cpp. Setting pristine = true causes
119    * the port to be also added to pristine_music_in_portlist.  See
120    * also comment above Network::pristine_music_in_portlist_.
121    */
122   void register_music_in_port( std::string portname, bool pristine = false );
123 
124   /**
125    * Unregister a MUSIC input port (portname) from the port list.
126    * This will decrement the counter of the respective entry in the
127    * music_in_portlist and remove the entry if the counter is 0
128    * after decrementing it.
129    */
130   void unregister_music_in_port( std::string portname );
131 
132   /**
133    * Register a node (of type music_input_proxy) with a given MUSIC
134    * port (portname) and a specific channel. The proxy will be
135    * notified, if a MUSIC event is being received on the respective
136    * channel and port.
137    */
138   void register_music_event_in_proxy( std::string portname, int channel, nest::Node* mp );
139 
140   /**
141    * Register a node (of type music_input_proxy) with a given MUSIC
142    * port (portname) and a specific channel. The proxy will be
143    * notified, if a MUSIC event is being received on the respective
144    * channel and port.
145    */
146   void register_music_rate_in_proxy( std::string portname, int channel, nest::Node* mp );
147 
148   /**
149    * Set the acceptable latency (latency) for a music input port (portname).
150    */
151   void set_music_in_port_acceptable_latency( std::string portname, double latency );
152   void set_music_in_port_max_buffered( std::string portname, int maxbuffered );
153   /**
154    * Data structure to hold variables and parameters associated with a port.
155    */
156   struct MusicPortData
157   {
MusicPortDataMusicPortData158     MusicPortData( size_t n, double latency, int m )
159       : n_input_proxies( n )
160       , acceptable_latency( latency )
161       , max_buffered( m )
162     {
163     }
MusicPortDataMusicPortData164     MusicPortData()
165     {
166     }
167     size_t n_input_proxies; // Counter for number of music_input proxies
168                             // connected to this port
169     double acceptable_latency;
170     int max_buffered;
171   };
172 
173   /**
174    * The mapping between MUSIC input ports identified by portname
175    * and the corresponding port variables and parameters.
176    * @see register_music_in_port()
177    * @see unregister_music_in_port()
178    */
179   std::map< std::string, MusicPortData > music_in_portlist_;
180 
181   /**
182    * A copy of music_in_portlist_ at the pristine state.
183    *
184    * This is used to reset music_in_portlist_ to its pristine state in
185    * initialize (a default state). Pristine here refers to the
186    * initial state of music_in_portlist_ after the loading of the
187    * pristine_models_.
188    */
189   std::map< std::string, MusicPortData > pristine_music_in_portlist_;
190 
191   /**
192    * The mapping between MUSIC input ports identified by portname
193    * and the corresponding MUSIC event handler.
194    */
195   std::map< std::string, MusicEventHandler > music_event_in_portmap_;
196   std::map< std::string, MusicRateInHandler > music_rate_in_portmap_;
197 
198   /**
199    * Publish all MUSIC input ports that were registered using
200    * Network::register_music_event_in_proxy().
201    */
202   void publish_music_in_ports_();
203 
204   /**
205    * Call update() for each of the registered MUSIC event handlers
206    * to deliver all queued events to the target music_in_proxies.
207    */
208   void update_music_event_handlers( Time const&, const long, const long );
209 #endif
210 
211 private:
212 #ifdef HAVE_MUSIC
213   MUSIC::Setup* music_setup;     //!< pointer to a MUSIC setup object
214   MUSIC::Runtime* music_runtime; //!< pointer to a MUSIC runtime object
215 #endif
216 };
217 }
218 
219 
220 #endif /* MUSIC_MANAGER_H */
221