along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- $Id$
*/
#include <cmath>
#include <pbd/error.h>
#include <pbd/failed_constructor.h>
#include <pbd/xml++.h>
+#include <pbd/enumwriter.h>
#include <ardour/session.h>
#include <ardour/panner.h>
void
BaseStereoPanner::transport_stopped (nframes_t frame)
{
- _automation.reposition_for_rt_add (frame);
-
if (_automation.automation_state() != Off) {
set_position (_automation.eval (frame));
}
+
+ _automation.reposition_for_rt_add (frame);
}
void
}
}
+int
+BaseStereoPanner::load (istream& in, string path, uint32_t& linecnt)
+{
+ char line[128];
+ LocaleGuard lg (X_("POSIX"));
+
+ _automation.clear ();
+
+ while (in.getline (line, sizeof (line), '\n')) {
+ jack_nframes_t when;
+ double value;
+
+ ++linecnt;
+
+ if (strcmp (line, "end") == 0) {
+ break;
+ }
+
+ if (sscanf (line, "%" PRIu32 " %lf", &when, &value) != 2) {
+ warning << string_compose(_("badly formatted pan automation event record at line %1 of %2 (ignored) [%3]"), linecnt, path, line) << endmsg;
+ continue;
+ }
+
+ _automation.fast_simple_add (when, value);
+ }
+
+ /* now that we are done loading */
+
+ _automation.StateChanged ();
+
+ return 0;
+}
+
void
BaseStereoPanner::distribute (Sample* src, Sample** obufs, gain_t gain_coeff, nframes_t nframes)
{
root->add_property (X_("x"), buf);
root->add_property (X_("type"), EqualPowerStereoPanner::name);
- if (full_state) {
- XMLNode* autonode = new XMLNode (X_("Automation"));
- autonode->add_child_nocopy (_automation.get_state ());
- root->add_child_nocopy (*autonode);
- } else {
- /* never store automation states other than off in a template */
- snprintf (buf, sizeof (buf), "0x%x", ARDOUR::Off);
- }
-
- root->add_property (X_("automation-state"), buf);
- snprintf (buf, sizeof (buf), "0x%x", _automation.automation_style());
- root->add_property (X_("automation-style"), buf);
+ XMLNode* autonode = new XMLNode (X_("Automation"));
+ autonode->add_child_nocopy (_automation.state (full_state));
+ root->add_child_nocopy (*autonode);
StreamPanner::add_state (*root);
+
root->add_child_nocopy (_control.get_state ());
return *root;
EqualPowerStereoPanner::set_state (const XMLNode& node)
{
const XMLProperty* prop;
- int x;
float pos;
LocaleGuard lg (X_("POSIX"));
StreamPanner::set_state (node);
for (XMLNodeConstIterator iter = node.children().begin(); iter != node.children().end(); ++iter) {
- if ((*iter)->name() == X_("panner")) {
- _control.set_state (**iter);
+
+ if ((*iter)->name() == X_("controllable")) {
+ if ((prop = (*iter)->property("name")) != 0 && prop->value() == "panner") {
+ _control.set_state (**iter);
+ }
+
} else if ((*iter)->name() == X_("Automation")) {
+
_automation.set_state (*((*iter)->children().front()));
- }
- }
-
- if ((prop = node.property (X_("automation-state")))) {
- sscanf (prop->value().c_str(), "0x%x", &x);
- _automation.set_automation_state ((AutoState) x);
- if (x != Off) {
- set_position (_automation.eval (parent.session().transport_frame()));
+ if (_automation.automation_state() != Off) {
+ set_position (_automation.eval (parent.session().transport_frame()));
+ }
}
}
- if ((prop = node.property (X_("automation-style")))) {
- sscanf (prop->value().c_str(), "0x%x", &x);
- _automation.set_automation_style ((AutoStyle) x);
- }
-
return 0;
}
}
pan = left * gain_coeff;
-
- for (; n < nframes; ++n) {
- dst[n] += src[n] * pan;
- }
+ Session::mix_buffers_with_gain(dst+n,src+n,nframes-n,pan);
} else {
if ((pan *= gain_coeff) != 1.0f) {
if (pan != 0.0f) {
-
- for (nframes_t n = 0; n < nframes; ++n) {
- dst[n] += src[n] * pan;
- }
-
+ Session::mix_buffers_with_gain(dst,src,nframes,pan);
}
-
-
} else {
-
- for (nframes_t n = 0; n < nframes; ++n) {
- dst[n] += src[n];
- }
-
+ Session::mix_buffers_no_gain(dst,src,nframes);
}
#endif
#ifdef CAN_INTERP
return new Multi2dPanner (p);
}
+int
+Multi2dPanner::load (istream& in, string path, uint32_t& linecnt)
+{
+ return 0;
+}
+
XMLNode&
Multi2dPanner::get_state (void)
{
Panner::Panner (string name, Session& s)
: _session (s)
{
+ set_name (name);
+
_linked = false;
_link_direction = SameDirection;
_bypassed = false;
char buf[32];
root->add_property (X_("linked"), (_linked ? "yes" : "no"));
- snprintf (buf, sizeof (buf), "%d", _link_direction);
- root->add_property (X_("link_direction"), buf);
+ root->add_property (X_("link_direction"), enum_2_string (_link_direction));
root->add_property (X_("bypassed"), (bypassed() ? "yes" : "no"));
/* add each output */
}
if ((prop = node.property (X_("link_direction"))) != 0) {
- sscanf (prop->value().c_str(), "%d", &i);
- set_link_direction ((LinkDirection) (i));
+ LinkDirection ld; /* here to provide type information */
+ set_link_direction (LinkDirection (string_2_enum (prop->value(), ld)));
}
nlist = node.children();
}
}
+ /* don't try to do old-school automation loading if it wasn't marked as existing */
+
+ if ((prop = node.property (X_("automation")))) {
+
+ /* automation path is relative */
+
+ automation_path = _session.automation_dir();
+ automation_path += prop->value ();
+ }
+
return 0;
}
}
}
}
+
+/* old school automation handling */
+
+void
+Panner::set_name (string str)
+{
+ automation_path = _session.automation_dir();
+ automation_path += _session.snap_name();
+ automation_path += "-pan-";
+ automation_path += legalize_for_path (str);
+ automation_path += ".automation";
+}
+
+int
+Panner::load ()
+{
+ char line[128];
+ uint32_t linecnt = 0;
+ float version;
+ iterator sp;
+ LocaleGuard lg (X_("POSIX"));
+
+ if (automation_path.length() == 0) {
+ return 0;
+ }
+
+ if (access (automation_path.c_str(), F_OK)) {
+ return 0;
+ }
+
+ ifstream in (automation_path.c_str());
+
+ if (!in) {
+ error << string_compose (_("cannot open pan automation file %1 (%2)"),
+ automation_path, strerror (errno))
+ << endmsg;
+ return -1;
+ }
+
+ sp = begin();
+
+ while (in.getline (line, sizeof(line), '\n')) {
+
+ if (++linecnt == 1) {
+ if (memcmp (line, X_("version"), 7) == 0) {
+ if (sscanf (line, "version %f", &version) != 1) {
+ error << string_compose(_("badly formed version number in pan automation event file \"%1\""), automation_path) << endmsg;
+ return -1;
+ }
+ } else {
+ error << string_compose(_("no version information in pan automation event file \"%1\" (first line = %2)"),
+ automation_path, line) << endmsg;
+ return -1;
+ }
+
+ continue;
+ }
+
+ if (strlen (line) == 0 || line[0] == '#') {
+ continue;
+ }
+
+ if (strcmp (line, "begin") == 0) {
+
+ if (sp == end()) {
+ error << string_compose (_("too many panner states found in pan automation file %1"),
+ automation_path)
+ << endmsg;
+ return -1;
+ }
+
+ if ((*sp)->load (in, automation_path, linecnt)) {
+ return -1;
+ }
+
+ ++sp;
+ }
+ }
+
+ return 0;
+}