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