+void
+AudioLibrary::compact_vector(vector<string>& vec)
+{
+ sort(vec.begin(), vec.end());
+ unique(vec.begin(), vec.end());
+}
+
+void
+AudioLibrary::set_paths (vector<string> paths)
+{
+ sfdb_paths = paths;
+
+ scan_paths ();
+}
+
+vector<string>
+AudioLibrary::get_paths ()
+{
+ return sfdb_paths;
+}
+
+void
+AudioLibrary::scan_paths ()
+{
+ if (sfdb_paths.size() < 1) {
+ return;
+ }
+
+ vector<char *> pathv(sfdb_paths.size());
+ unsigned int i;
+ for (i = 0; i < sfdb_paths.size(); ++i) {
+ pathv[i] = new char[sfdb_paths[i].length() +1];
+ sfdb_paths[i].copy(pathv[i], string::npos);
+ pathv[i][sfdb_paths[i].length()] = 0;
+ }
+ pathv[i] = 0;
+
+ FTS* ft = fts_open(&pathv[0], FTS_LOGICAL|FTS_NOSTAT|FTS_PHYSICAL|FTS_XDEV, 0);
+ if (errno) {
+ error << strerror(errno) << endmsg;
+ return;
+ }
+
+ lrdf_statement s;
+ s.predicate = RDF_TYPE;
+ s.object = SOUNDFILE;
+ s.object_type = lrdf_uri;
+ string filename;
+ while (FTSENT* file = fts_read(ft)) {
+ if ((file->fts_info & FTS_F) && (safe_file_extension(file->fts_name))) {
+ filename = "file:";
+ filename.append(file->fts_accpath);
+ s.subject = strdup(filename.c_str());
+ if (lrdf_exists_match(&s)) {
+ continue;
+ } else {
+ add_member(file->fts_accpath);
+ cout << file->fts_accpath << endl;
+ }
+ free(s.subject);
+ }
+ }
+ fts_close(ft);
+
+ for (i = 0; i < pathv.size(); ++i) {
+ delete[] pathv[i];
+ }
+
+ save_changes();
+}
+
+bool
+AudioLibrary::safe_file_extension(string file)
+{
+ return !(file.rfind(".wav") == string::npos &&
+ file.rfind(".aiff")== string::npos &&
+ file.rfind(".aif") == string::npos &&
+ file.rfind(".snd") == string::npos &&
+ file.rfind(".au") == string::npos &&
+ file.rfind(".raw") == string::npos &&
+ file.rfind(".sf") == string::npos &&
+ file.rfind(".cdr") == string::npos &&
+ file.rfind(".smp") == string::npos &&
+ file.rfind(".maud")== string::npos &&
+ file.rfind(".vwe") == string::npos &&
+ file.rfind(".paf") == string::npos &&
+#ifdef HAVE_COREAUDIO
+ file.rfind(".mp3") == string::npos &&
+ file.rfind(".aac") == string::npos &&
+ file.rfind(".mp4") == string::npos &&
+#endif // HAVE_COREAUDIO
+ file.rfind(".voc") == string::npos);
+}
+
+XMLNode&
+AudioLibrary::get_state ()
+{
+ XMLNode* root = new XMLNode(X_("AudioLibrary"));
+
+ for (vector<string>::iterator i = sfdb_paths.begin(); i != sfdb_paths.end(); ++i) {
+ XMLNode* node = new XMLNode(X_("Path"));
+ node->add_property("value", *i);
+ root->add_child_nocopy(*node);
+ }
+
+ return *root;
+}
+
+int
+AudioLibrary::set_state (const XMLNode& node)
+{
+ if (node.name() != X_("AudioLibrary")) {
+ fatal << "programming error: AudioLibrary: incorrect XML node sent to set_state()" << endmsg;
+ return -1;
+ }
+
+ XMLNodeList nodes = node.children(X_("Path"));
+
+ vector<string> paths;
+ XMLProperty* prop;
+ XMLNode* child;
+ for (XMLNodeConstIterator iter = nodes.begin(); iter != nodes.end(); ++iter) {
+ child = *iter;
+
+ if ((prop = child->property(X_("value"))) != 0) {
+ paths.push_back(prop->value());
+ }
+ }
+
+ set_paths (paths);
+
+ return 0;
+}