25c0abec68f48e984963ed4acfc822dd2fd0deae
[ardour.git] / libs / surfaces / mackie / surface.cc
1 #include "surface.h"
2
3 #include <sstream>
4 #include <iomanip>
5 #include <iostream>
6
7 using namespace std;
8 using namespace Mackie;
9
10 Surface::Surface( uint32_t max_strips )
11 : _max_strips( max_strips )
12 {
13 }
14
15 void Surface::init()
16 {
17         init_controls();
18         // TODO fix this hard coding
19         init_strips( _max_strips, 8 );
20 }
21
22 Surface::~Surface()
23 {
24         // delete groups
25         for( Groups::iterator it = groups.begin(); it != groups.end(); ++it )
26         {
27                 delete it->second;
28         }
29         
30         // delete controls
31         for( Controls::iterator it = controls.begin(); it != controls.end(); ++it )
32         {
33                 delete *it;
34         }
35 }
36
37 // Possibly Mackie-specific, because of multiple devices on separate ports
38 // add the strips from 9..max_strips
39 // unit_strips is the number of strips for additional units.
40 // TODO would be better to pass the MackiePorts in here, cos
41 // each might have a different number of strips
42 void Surface::init_strips( uint32_t max_strips, uint32_t unit_strips )
43 {
44         if ( strips.size() < max_strips )
45         {
46                 strips.resize( max_strips );
47                 for ( uint32_t i = strips.size(); i < max_strips; ++i )
48                 {
49                         // because I can't find itoa
50                         ostringstream os;
51                         os << "strip_" << i + 1;
52                         string name = os.str();
53                         
54                         // shallow copy existing strip
55                         // which works because the controls
56                         // have the same ids across units
57                         Strip * strip = new Strip( *strips[i % unit_strips] );
58                         
59                         // update the relevant values
60                         strip->index( i );
61                         strip->name( name );
62                         
63                         // add to data structures
64                         groups[name] = strip;
65                         strips[i] = strip;
66                 }
67         }
68 }
69
70 ostream & Mackie::operator << ( ostream & os, const Mackie::Control & control )
71 {
72         os << typeid( control ).name();
73         os << " { ";
74         os << "name: " << control.name();
75         os << ", ";
76         os << "id: " << "0x" << setw(2) << setfill('0') << hex << control.id() << setfill(' ');
77         os << ", ";
78         os << "ordinal: " << dec << control.ordinal();
79         os << ", ";
80         os << "group: " << control.group().name();
81         os << " }";
82         
83         return os;
84 }
85
86 /**
87         TODO could optimise this to use enum, but it's only
88         called during the protocol class instantiation.
89
90         generated using
91
92         irb -r controls.rb
93         sf=Surface.new
94         sf.parse
95         controls = sf.groups.find{|x| x[0] =~ /strip/}.each{|x| puts x[1]}
96         controls[1].each {|x| puts "\telse if ( control.name() == \"#{x.name}\" )\n\t{\n\t\t_#{x.name} = reinterpret_cast<#{x.class.name}*>(&control);\n\t}\n"}
97 */
98 void Strip::add( Control & control )
99 {
100         Group::add( control );
101         if ( control.name() == "gain" )
102         {
103                 _gain = reinterpret_cast<Fader*>(&control);
104         }
105         else if ( control.name() == "vpot" )
106         {
107                 _vpot = reinterpret_cast<Pot*>(&control);
108         }
109         else if ( control.name() == "recenable" )
110         {
111                 _recenable = reinterpret_cast<Button*>(&control);
112         }
113         else if ( control.name() == "solo" )
114         {
115                 _solo = reinterpret_cast<Button*>(&control);
116         }
117         else if ( control.name() == "mute" )
118         {
119                 _mute = reinterpret_cast<Button*>(&control);
120         }
121         else if ( control.name() == "select" )
122         {
123                 _select = reinterpret_cast<Button*>(&control);
124         }
125         else if ( control.name() == "vselect" )
126         {
127                 _vselect = reinterpret_cast<Button*>(&control);
128         }
129         else if ( control.name() == "fader_touch" )
130         {
131                 _fader_touch = reinterpret_cast<Button*>(&control);
132         }
133         else if ( control.type() == Control::type_led || control.type() == Control::type_led_ring )
134         {
135                 // do nothing
136                 cout << "Strip::add not adding " << control << endl;
137         }
138         else
139         {
140                 ostringstream os;
141                 os << "Strip::add: unknown control type " << control;
142                 throw MackieControlException( os.str() );
143         }
144 }
145