NOOP, remove trailing whitespace, replace tabs in python scripts
[ardour.git] / libs / midi++2 / test / MidnamTest.cpp
1 #include "MidnamTest.hpp"
2
3 #include <glibmm/fileutils.h>
4 #include <glibmm/miscutils.h>
5
6 #include "pbd/xml++.h"
7 #include "pbd/file_utils.h"
8 #include "pbd/compose.h"
9 #include "midi++/midnam_patch.h"
10
11 using namespace std;
12 using namespace PBD;
13 using namespace MIDI::Name;
14
15 CPPUNIT_TEST_SUITE_REGISTRATION( MidnamTest );
16
17 PBD::Searchpath
18 test_search_path ()
19 {
20 #ifdef PLATFORM_WINDOWS
21         if (!getenv("MIDIPP_TEST_PATH")) {
22                 std::vector<std::string> path_tok;
23                 path_tok.push_back (g_win32_get_package_installation_directory_of_module(NULL));
24                 path_tok.push_back ("share");
25                 path_tok.push_back ("ardour3");
26                 path_tok.push_back ("patchfiles");
27                 return Glib::build_filename (path_tok);
28         }
29 #endif
30         return Glib::getenv("MIDIPP_TEST_PATH");
31 }
32
33 void
34 MidnamTest::protools_patchfile_test()
35 {
36     std::string test_file_path;
37
38     CPPUNIT_ASSERT(find_file (test_search_path (), "Roland_SC-88_Pro.midnam", test_file_path));
39     XMLTree xmldoc(test_file_path);
40     boost::shared_ptr<XMLSharedNodeList> result = xmldoc.find(
41             "//MIDINameDocument");
42     CPPUNIT_ASSERT(result->size() == 1);
43
44     result = xmldoc.find("//ChannelNameSet");
45     CPPUNIT_ASSERT(result->size() == 2);
46
47     MIDINameDocument doc(test_file_path);
48     CPPUNIT_ASSERT(doc.all_models().size() == 1);
49     CPPUNIT_ASSERT(doc.author().find("Mark of the Unicorn") == 0);
50
51     const string model = *doc.all_models().begin();
52     CPPUNIT_ASSERT_EQUAL(string("SC-88 Pro"), model);
53     boost::shared_ptr<MasterDeviceNames> masterDeviceNames =
54             doc.master_device_names_by_model().find(model)->second;
55     CPPUNIT_ASSERT_EQUAL(string("Roland"), masterDeviceNames->manufacturer());
56
57     string modename = masterDeviceNames->custom_device_mode_names().front();
58     CPPUNIT_ASSERT_EQUAL(string("Default"), modename);
59
60     boost::shared_ptr<CustomDeviceMode> mode =
61             masterDeviceNames->custom_device_mode_by_name(modename);
62
63     CPPUNIT_ASSERT_EQUAL(modename, mode->name());
64
65     string ns1 = string("Name Set 1");
66     string ns2 = string("Name Set 2");
67
68     for (uint8_t i = 0; i <= 15; i++) {
69         if (i != 9)
70             CPPUNIT_ASSERT_EQUAL(ns1,
71                     mode->channel_name_set_name_by_channel(i));
72         else
73             CPPUNIT_ASSERT_EQUAL(ns2,
74                     mode->channel_name_set_name_by_channel(i));
75     }
76
77     boost::shared_ptr<ChannelNameSet> nameSet1 =
78             masterDeviceNames->channel_name_set_by_channel(modename, 0);
79     boost::shared_ptr<ChannelNameSet> nameSet2 =
80             masterDeviceNames->channel_name_set_by_channel(modename, 9);
81
82     CPPUNIT_ASSERT_EQUAL(ns1, nameSet1->name());
83     CPPUNIT_ASSERT_EQUAL(ns2, nameSet2->name());
84
85     const ChannelNameSet::PatchBanks& banks1 = nameSet1->patch_banks();
86     const ChannelNameSet::PatchBanks& banks2 = nameSet2->patch_banks();
87     CPPUNIT_ASSERT(banks1.size() == 16);
88     CPPUNIT_ASSERT(banks2.size() == 1);
89
90     boost::shared_ptr<PatchBank> bank = banks1.front();
91     CPPUNIT_ASSERT_EQUAL(string("Piano"), bank->name());
92     const PatchNameList& plist1 = bank->patch_name_list();
93     CPPUNIT_ASSERT(plist1.size() == 110);
94
95     bank = banks2.front();
96     CPPUNIT_ASSERT_EQUAL(string("Drum sets"), bank->name());
97     const PatchNameList& plist2 = bank->patch_name_list();
98     CPPUNIT_ASSERT(plist2.size() == 49);
99 }
100
101 void
102 MidnamTest::yamaha_PSRS900_patchfile_test()
103 {
104     std::string test_file_path;
105
106     CPPUNIT_ASSERT(find_file (test_search_path (), "Yamaha_PSR-S900.midnam", test_file_path));
107     XMLTree xmldoc(test_file_path);
108     boost::shared_ptr<XMLSharedNodeList> result = xmldoc.find(
109             "//MIDINameDocument");
110     CPPUNIT_ASSERT(result->size() == 1);
111
112     result = xmldoc.find("//ChannelNameSet");
113     CPPUNIT_ASSERT(result->size() == 3);
114
115     MIDINameDocument doc(test_file_path);
116     CPPUNIT_ASSERT(doc.all_models().size() == 1);
117     CPPUNIT_ASSERT(doc.author().find("Hans Baier") == 0);
118
119     const string model = *doc.all_models().begin();
120     CPPUNIT_ASSERT_EQUAL(string("PSR-S900"), model);
121     boost::shared_ptr<MasterDeviceNames> masterDeviceNames =
122             doc.master_device_names_by_model().find(model)->second;
123     CPPUNIT_ASSERT_EQUAL(string("Yamaha"), masterDeviceNames->manufacturer());
124
125     const MasterDeviceNames::CustomDeviceModeNames& modes = masterDeviceNames->custom_device_mode_names();
126     CPPUNIT_ASSERT(masterDeviceNames->custom_device_mode_names().size() == 3);
127
128     string modename = modes.front();
129     CPPUNIT_ASSERT_EQUAL(string("Standard"), modename);
130
131     modename = (*(++modes.begin()));
132     CPPUNIT_ASSERT_EQUAL(string("GM+XG"), modename);
133
134     modename = modes.back();
135     CPPUNIT_ASSERT_EQUAL(string("GM2"), modename);
136
137     for (list<string>::const_iterator modename = modes.begin(); modename != modes.end(); ++modename) {
138         boost::shared_ptr<CustomDeviceMode> mode =
139                 masterDeviceNames->custom_device_mode_by_name(*modename);
140
141         CPPUNIT_ASSERT_EQUAL(*modename, mode->name());
142
143         string ns = mode->name();
144
145         if (ns != string("Standard"))
146         for (uint8_t i = 0; i <= 15; i++) {
147                 CPPUNIT_ASSERT_EQUAL(ns,
148                         mode->channel_name_set_name_by_channel(i));
149                 boost::shared_ptr<ChannelNameSet> nameSet =
150                         masterDeviceNames->channel_name_set_by_channel(ns, 1);
151
152                 CPPUNIT_ASSERT_EQUAL(ns, nameSet->name());
153
154                 const ChannelNameSet::PatchBanks& banks1 = nameSet->patch_banks();
155                 CPPUNIT_ASSERT(banks1.size() > 1);
156
157                 boost::shared_ptr<PatchBank> bank = banks1.front();
158                 const PatchNameList& list = bank->patch_name_list();
159
160                 for(PatchNameList::const_iterator p = list.begin(); p != list.end(); ++p) {
161
162                 if (ns == string("GM+XG")) {
163                     uint8_t msb = (((*p)->bank_number()) >> 7) & 0x7f;
164                     CPPUNIT_ASSERT( msb == 0 || msb == 64);
165                 }
166
167                 if (ns == string("GM2")) {
168                     CPPUNIT_ASSERT((*p)->bank_number() >= (uint16_t(120) << 7));
169                 }
170                 }
171         }
172     }
173 }
174
175 void
176 MidnamTest::load_all_midnams_test ()
177 {
178     vector<std::string> result;
179
180     PBD::find_files_matching_pattern (result, test_search_path (), "*.midnam");
181
182     CPPUNIT_ASSERT(!result.empty());
183
184     cout << "Loading " << result.size() << " MIDI patches from " << test_search_path ().to_string () << endl;
185
186     for (vector<std::string>::iterator i = result.begin(); i != result.end(); ++i) {
187         cout << "Processing file " << Glib::path_get_basename(*i) << endl;
188         boost::shared_ptr<MIDINameDocument> document(new MIDINameDocument(*i));
189
190         XMLTree xmldoc(*i);
191         boost::shared_ptr<XMLSharedNodeList> result = xmldoc.find("//MIDINameDocument");
192         CPPUNIT_ASSERT(result->size() == 1);
193
194         result = xmldoc.find("//MasterDeviceNames");
195         CPPUNIT_ASSERT(result->size() == 1);
196
197         result = xmldoc.find("//PatchBank");
198         //int banks = result->size();
199
200
201         result = xmldoc.find("//CustomDeviceMode[1]");
202         string deviceModeName = result->front()->property("Name")->value();
203
204         MIDINameDocument::MasterDeviceNamesList::const_iterator device =
205                     document->master_device_names_by_model().begin();
206
207         string modename = device->second->custom_device_mode_names().front();
208         boost::shared_ptr<CustomDeviceMode> mode = device->second->custom_device_mode_by_name(modename);
209         CPPUNIT_ASSERT_EQUAL(deviceModeName, mode->name());
210
211         boost::shared_ptr<ChannelNameSet> nameSet = device->second->channel_name_set_by_channel(modename, 0);
212     }
213 }
214