Merge 1.0 in.
[dcpomatic.git] / src / lib / audio_mapping.cc
1 /*
2     Copyright (C) 2013 Carl Hetherington <cth@carlh.net>
3
4     This program is free software; you can redistribute it and/or modify
5     it under the terms of the GNU General Public License as published by
6     the Free Software Foundation; either version 2 of the License, or
7     (at your option) any later version.
8
9     This program is distributed in the hope that it will be useful,
10     but WITHOUT ANY WARRANTY; without even the implied warranty of
11     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12     GNU General Public License for more details.
13
14     You should have received a copy of the GNU General Public License
15     along with this program; if not, write to the Free Software
16     Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
17
18 */
19
20 #include <boost/lexical_cast.hpp>
21 #include <libxml++/libxml++.h>
22 #include <libcxml/cxml.h>
23 #include "audio_mapping.h"
24
25 using std::list;
26 using std::cout;
27 using std::make_pair;
28 using std::pair;
29 using std::string;
30 using boost::shared_ptr;
31 using boost::lexical_cast;
32 using boost::dynamic_pointer_cast;
33
34 AudioMapping::AudioMapping ()
35         : _content_channels (0)
36 {
37
38 }
39
40 /** Create a default AudioMapping for a given channel count.
41  *  @param c Number of channels.
42  */
43 AudioMapping::AudioMapping (int c)
44         : _content_channels (c)
45 {
46
47 }
48
49 void
50 AudioMapping::make_default ()
51 {
52         if (_content_channels == 1) {
53                 /* Mono -> Centre */
54                 add (0, libdcp::CENTRE);
55         } else {
56                 /* 1:1 mapping */
57                 for (int i = 0; i < _content_channels; ++i) {
58                         add (i, static_cast<libdcp::Channel> (i));
59                 }
60         }
61 }
62
63 AudioMapping::AudioMapping (shared_ptr<const cxml::Node> node)
64 {
65         _content_channels = node->number_child<int> ("ContentChannels");
66         
67         list<shared_ptr<cxml::Node> > const c = node->node_children ("Map");
68         for (list<shared_ptr<cxml::Node> >::const_iterator i = c.begin(); i != c.end(); ++i) {
69                 add ((*i)->number_child<int> ("ContentIndex"), static_cast<libdcp::Channel> ((*i)->number_child<int> ("DCP")));
70         }
71 }
72
73 void
74 AudioMapping::add (int c, libdcp::Channel d)
75 {
76         _content_to_dcp.push_back (make_pair (c, d));
77 }
78
79 list<int>
80 AudioMapping::dcp_to_content (libdcp::Channel d) const
81 {
82         list<int> c;
83         for (list<pair<int, libdcp::Channel> >::const_iterator i = _content_to_dcp.begin(); i != _content_to_dcp.end(); ++i) {
84                 if (i->second == d) {
85                         c.push_back (i->first);
86                 }
87         }
88
89         return c;
90 }
91
92 list<libdcp::Channel>
93 AudioMapping::content_to_dcp (int c) const
94 {
95         assert (c < _content_channels);
96         
97         list<libdcp::Channel> d;
98         for (list<pair<int, libdcp::Channel> >::const_iterator i = _content_to_dcp.begin(); i != _content_to_dcp.end(); ++i) {
99                 if (i->first == c) {
100                         d.push_back (i->second);
101                 }
102         }
103
104         return d;
105 }
106
107 void
108 AudioMapping::as_xml (xmlpp::Node* node) const
109 {
110         node->add_child ("ContentChannels")->add_child_text (lexical_cast<string> (_content_channels));
111         
112         for (list<pair<int, libdcp::Channel> >::const_iterator i = _content_to_dcp.begin(); i != _content_to_dcp.end(); ++i) {
113                 xmlpp::Node* t = node->add_child ("Map");
114                 t->add_child ("ContentIndex")->add_child_text (lexical_cast<string> (i->first));
115                 t->add_child ("DCP")->add_child_text (lexical_cast<string> (i->second));
116         }
117 }