*/
#include <sstream>
+#include <fstream>
#include <errno.h>
#include <string.h>
#include <math.h>
#include "pbd/xml++.h"
#include "pbd/convert.h"
#include "pbd/whitespace.h"
-#include "pbd/pathscanner.h"
+#include "pbd/file_utils.h"
#include "pbd/locale_guard.h"
#include <glibmm/threads.h>
#include <glibmm/fileutils.h>
#include <glibmm/miscutils.h>
+#include <glib/gstdio.h>
#include "ardour/ardour.h"
#include "ardour/audioengine.h"
using namespace PBD;
using namespace ARDOUR;
-#ifndef AU_STATE_SUPPORT
-static bool seen_get_state_message = false;
-static bool seen_set_state_message = false;
-static bool seen_loading_message = false;
-static bool seen_saving_message = false;
-#endif
-
AUPluginInfo::CachedInfoMap AUPluginInfo::cached_info;
static string preset_search_path = "/Library/Audio/Presets:/Network/Library/Audio/Presets";
static string preset_suffix = ".aupreset";
static bool preset_search_path_initialized = false;
+FILE * AUPluginInfo::_crashlog_fd = NULL;
static OSStatus
_render_callback(void *userData,
d.logarithmic = (info.flags & kAudioUnitParameterFlag_DisplayLogarithmic);
d.unit = info.unit;
- d.step = 1.0;
- d.smallstep = 0.1;
- d.largestep = 10.0;
d.min_unbound = 0; // lower is bound
d.max_unbound = 0; // upper is bound
+ d.update_steps();
descriptors.push_back (d);
}
bool
-AUPlugin::can_support_io_configuration (const ChanCount& in, ChanCount& out) const
+AUPlugin::can_support_io_configuration (const ChanCount& in, ChanCount& out)
{
// Note: We never attempt to multiply-instantiate plugins to meet io configurations.
AUPlugin::add_state (XMLNode* root) const
{
LocaleGuard lg (X_("POSIX"));
-
-#ifdef AU_STATE_SUPPORT
CFDataRef xmlData;
CFPropertyListRef propertyList;
CFRelease (xmlData);
CFRelease (propertyList);
-#else
- if (!seen_get_state_message) {
- info << string_compose (_("Saving AudioUnit settings is not supported in this build of %1. Consider paying for a newer version"),
- PROGRAM_NAME)
- << endmsg;
- seen_get_state_message = true;
- }
-#endif
}
int
AUPlugin::set_state(const XMLNode& node, int version)
{
-#ifdef AU_STATE_SUPPORT
int ret = -1;
CFPropertyListRef propertyList;
LocaleGuard lg (X_("POSIX"));
return -1;
}
+#ifndef NO_PLUGIN_STATE
if (node.children().empty()) {
return -1;
}
}
CFRelease (propertyList);
}
+#endif
Plugin::set_state (node, version);
return ret;
-#else
- if (!seen_set_state_message) {
- info << string_compose (_("Restoring AudioUnit settings is not supported in this build of %1. Consider paying for a newer version"),
- PROGRAM_NAME)
- << endmsg;
- }
- return Plugin::set_state (node, version);
-#endif
}
bool
{
Plugin::load_preset (r);
-#ifdef AU_STATE_SUPPORT
bool ret = false;
CFPropertyListRef propertyList;
Glib::ustring path;
}
return ret;
-#else
- if (!seen_loading_message) {
- info << string_compose (_("Loading AudioUnit presets is not supported in this build of %1. Consider paying for a newer version"),
- PROGRAM_NAME)
- << endmsg;
- seen_loading_message = true;
- }
- return true;
-#endif
}
void
string
AUPlugin::do_save_preset (string preset_name)
{
-#ifdef AU_STATE_SUPPORT
CFPropertyListRef propertyList;
vector<Glib::ustring> v;
Glib::ustring user_preset_path;
- bool ret = true;
std::string m = maker();
std::string n = name();
if (g_mkdir_with_parents (user_preset_path.c_str(), 0775) < 0) {
error << string_compose (_("Cannot create user plugin presets folder (%1)"), user_preset_path) << endmsg;
- return false;
+ return string();
}
DEBUG_TRACE (DEBUG::AudioUnits, "get current preset\n");
if (unit->GetAUPreset (propertyList) != noErr) {
- return false;
+ return string();
}
// add the actual preset name */
if (save_property_list (propertyList, user_preset_path)) {
error << string_compose (_("Saving plugin state to %1 failed"), user_preset_path) << endmsg;
- ret = false;
+ return string();
}
CFRelease(propertyList);
return string ("file:///") + user_preset_path;
-#else
- if (!seen_saving_message) {
- info << string_compose (_("Saving AudioUnit presets is not supported in this build of %1. Consider paying for a newer version"),
- PROGRAM_NAME)
- << endmsg;
- seen_saving_message = true;
- }
- return string();
-#endif
}
//-----------------------------------------------------------------------------
{
string preset_name;
-#ifdef AU_STATE_SUPPORT
CFPropertyListRef propertyList;
DEBUG_TRACE (DEBUG::AudioUnits, "get current preset for current_preset()\n");
preset_name = get_preset_name_in_plist (propertyList);
CFRelease(propertyList);
}
-#endif
+
return preset_name;
}
void
AUPlugin::find_presets ()
{
-#ifdef AU_STATE_SUPPORT
- vector<string*>* preset_files;
- PathScanner scanner;
+ vector<string> preset_files;
user_preset_map.clear ();
- preset_files = scanner (preset_search_path, au_preset_filter, this, true, true, -1, true);
+ find_files_matching_filter (preset_files, preset_search_path, au_preset_filter, this, true, true, true);
- if (!preset_files) {
+ if (preset_files.empty()) {
return;
}
- for (vector<string*>::iterator x = preset_files->begin(); x != preset_files->end(); ++x) {
+ for (vector<string>::iterator x = preset_files.begin(); x != preset_files.end(); ++x) {
- string path = *(*x);
+ string path = *x;
string preset_name;
/* make an initial guess at the preset name using the path */
user_preset_map[preset_name] = path;
}
- delete *x;
}
- delete preset_files;
-
/* now fill the vector<string> with the names we have */
for (UserPresetMap::iterator i = user_preset_map.begin(); i != user_preset_map.end(); ++i) {
string const uri = string_compose ("%1", _presets.size ());
_presets.insert (make_pair (uri, Plugin::PresetRecord (uri, i->first, i->second)));
}
-
-#endif
}
bool
if (!Glib::file_test (au_cache_path(), Glib::FILE_TEST_EXISTS)) {
ARDOUR::BootMessage (_("Discovering AudioUnit plugins (could take some time ...)"));
}
+ // create crash log file
+ au_start_crashlog ();
PluginInfoList* plugs = new PluginInfoList;
discover_generators (*plugs);
discover_instruments (*plugs);
+ // all fine if we get here
+ au_remove_crashlog ();
+
DEBUG_TRACE (DEBUG::PluginManager, string_compose ("AU: discovered %1 plugins\n", plugs->size()));
return plugs;
discover_by_description (plugs, desc);
}
+
+bool
+AUPluginInfo::au_get_crashlog (std::string &msg)
+{
+ string fn = Glib::build_filename (ARDOUR::user_cache_directory(), "au_crashlog.txt");
+ if (!Glib::file_test (fn, Glib::FILE_TEST_EXISTS)) {
+ return false;
+ }
+ std::ifstream ifs(fn.c_str());
+ msg.assign ((std::istreambuf_iterator<char>(ifs)), (std::istreambuf_iterator<char>()));
+ au_remove_crashlog ();
+ return true;
+}
+
+void
+AUPluginInfo::au_start_crashlog ()
+{
+ string fn = Glib::build_filename (ARDOUR::user_cache_directory(), "au_crashlog.txt");
+ assert(!_crashlog_fd);
+ DEBUG_TRACE (DEBUG::AudioUnits, string_compose ("Creating AU Log: %1\n", fn));
+ if (!(_crashlog_fd = fopen(fn.c_str(), "w"))) {
+ PBD::error << "Cannot create AU error-log\n";
+ }
+}
+
+void
+AUPluginInfo::au_remove_crashlog ()
+{
+ if (_crashlog_fd) {
+ ::fclose(_crashlog_fd);
+ _crashlog_fd = NULL;
+ }
+ string fn = Glib::build_filename (ARDOUR::user_cache_directory(), "au_crashlog.txt");
+ ::g_unlink(fn.c_str());
+ DEBUG_TRACE (DEBUG::AudioUnits, string_compose ("Remove AU Log: %1\n", fn));
+}
+
+
+void
+AUPluginInfo::au_crashlog (std::string msg)
+{
+ assert(_crashlog_fd);
+ fprintf(_crashlog_fd, "AU: %s\n", msg.c_str());
+ ::fflush(_crashlog_fd);
+}
+
void
AUPluginInfo::discover_by_description (PluginInfoList& plugs, CAComponentDescription& desc)
{
Component comp = 0;
+ au_crashlog(string_compose("Start AU discovery for Type: %1", (int)desc.componentType));
comp = FindNextComponent (NULL, &desc);
CAComponentDescription temp;
GetComponentInfo (comp, &temp, NULL, NULL, NULL);
+ {
+ CFStringRef compTypeString = UTCreateStringForOSType(temp.componentType);
+ CFStringRef compSubTypeString = UTCreateStringForOSType(temp.componentSubType);
+ CFStringRef compManufacturerString = UTCreateStringForOSType(temp.componentManufacturer);
+ CFStringRef itemName = CFStringCreateWithFormat(kCFAllocatorDefault, NULL, CFSTR("%@ - %@ - %@"),
+ compTypeString, compManufacturerString, compSubTypeString);
+ au_crashlog(string_compose("Scanning ID: %1", CFStringRefToStdString(itemName)));
+ if (compTypeString != NULL)
+ CFRelease(compTypeString);
+ if (compSubTypeString != NULL)
+ CFRelease(compSubTypeString);
+ if (compManufacturerString != NULL)
+ CFRelease(compManufacturerString);
+ }
+
AUPluginInfoPtr info (new AUPluginInfo
(boost::shared_ptr<CAComponentDescription> (new CAComponentDescription(temp))));
}
AUPluginInfo::get_names (temp, info->name, info->creator);
+ ARDOUR::PluginScanMessage(_("AU"), info->name, false);
+ au_crashlog(string_compose("Plugin: %1", info->name));
info->type = ARDOUR::AudioUnit;
info->unique_id = stringify_descriptor (*info->descriptor);
error << string_compose (_("Cannot get I/O configuration info for AU %1"), info->name) << endmsg;
}
+ au_crashlog("Success.");
comp = FindNextComponent (comp, &desc);
}
+ au_crashlog(string_compose("End AU discovery for Type: %1", (int)desc.componentType));
}
bool
if (!tree.write (path)) {
error << string_compose (_("could not save AU cache to %1"), path) << endmsg;
- unlink (path.c_str());
+ g_unlink (path.c_str());
}
}