enough with umpteen "i18n.h" files. Consolidate on pbd/i18n.h
[ardour.git] / libs / ardour / audio_unit.cc
index 15b63c8f37b3b4933c8080f666e6fd8a02098b16..88cc197d60d5b50023d047dfd56db65f7edf258d 100644 (file)
@@ -71,7 +71,7 @@
 #define ArdourFindNext AudioComponentFindNext
 #endif
 
-#include "i18n.h"
+#include "pbd/i18n.h"
 
 using namespace std;
 using namespace PBD;
@@ -448,7 +448,8 @@ AUPlugin::AUPlugin (AudioEngine& engine, Session& session, boost::shared_ptr<CAC
        , audio_input_cnt (0)
        , _parameter_listener (0)
        , _parameter_listener_arg (0)
-       , last_transport_rolling (false)
+       , transport_frame (false)
+       , transport_speed (false)
        , last_transport_speed (0.0)
 {
        if (!preset_search_path_initialized) {
@@ -1255,7 +1256,42 @@ AUPlugin::can_support_io_configuration (const ChanCount& in, ChanCount& out, Cha
                return false;
        }
 
-       vector<pair<int,int> >& io_configs = pinfo->cache.io_configs;
+       vector<pair<int,int> > io_configs = pinfo->cache.io_configs;
+
+       if (input_elements > 1) {
+               const vector<pair<int,int> >& ioc (pinfo->cache.io_configs);
+               for (vector<pair<int,int> >::const_iterator i = ioc.begin(); i != ioc.end(); ++i) {
+                       int32_t possible_in = i->first;
+                       int32_t possible_out = i->second;
+                       if (possible_in < 1 || possible_out < 1) {
+                               continue;
+                       }
+                       for (uint32_t i = 1; i < input_elements; ++i) {
+                               // can't use up-to bus_inputs[]
+                               // waves' SC-C6(s) for example fails to configure with only 1 input
+                               // on the 2nd bus.
+                               io_configs.push_back (pair<int,int> (possible_in + bus_inputs[i], possible_out));
+                       }
+               }
+       }
+
+       if (output_elements > 1) {
+               const vector<pair<int,int> >& ioc (pinfo->cache.io_configs);
+               for (vector<pair<int,int> >::const_iterator i = ioc.begin(); i != ioc.end(); ++i) {
+                       int32_t possible_in = i->first;
+                       int32_t possible_out = i->second;
+                       if (possible_in < 1 || possible_out < 1) {
+                               continue;
+                       }
+                       for (uint32_t i = 1; i < output_elements; ++i) {
+                               int32_t c = bus_outputs[i];
+                               for (uint32_t j = 1; j < i; ++j) {
+                                       c += bus_outputs [j];
+                               }
+                               io_configs.push_back (pair<int,int> (possible_in, possible_out + c));
+                       }
+               }
+       }
 
        DEBUG_TRACE (DEBUG::AudioUnits, string_compose ("%1 has %2 IO configurations, looking for %3 in, %4 out\n",
                                                        name(), io_configs.size(), in, out));
@@ -1584,9 +1620,15 @@ AUPlugin::render_callback(AudioUnitRenderActionFlags*,
 }
 
 int
-AUPlugin::connect_and_run (BufferSet& bufs, ChanMapping in_map, ChanMapping out_map, pframes_t nframes, framecnt_t offset)
+AUPlugin::connect_and_run (BufferSet& bufs,
+               framepos_t start, framepos_t end, double speed,
+               ChanMapping in_map, ChanMapping out_map,
+               pframes_t nframes, framecnt_t offset)
 {
-       Plugin::connect_and_run (bufs, in_map, out_map, nframes, offset);
+       Plugin::connect_and_run(bufs, start, end, speed, in_map, out_map, nframes, offset);
+
+       transport_frame = start;
+       transport_speed = speed;
 
        AudioUnitRenderActionFlags flags = 0;
        AudioTimeStamp ts;
@@ -1760,9 +1802,8 @@ AUPlugin::get_beat_and_tempo_callback (Float64* outCurrentBeat,
                return kAudioUnitErr_CannotDoInCurrentContext;
        }
 
-       Timecode::BBT_Time bbt;
-       TempoMetric metric = tmap.metric_at (_session.transport_frame() + input_offset);
-       tmap.bbt_time (_session.transport_frame() + input_offset, bbt);
+       TempoMetric metric = tmap.metric_at (transport_frame + input_offset);
+       Timecode::BBT_Time bbt = _session.tempo_map().bbt_at_frame (transport_frame + input_offset);
 
        if (outCurrentBeat) {
                const double ppq_scaling = metric.meter().note_divisor() / 4.0;
@@ -1800,18 +1841,16 @@ AUPlugin::get_musical_time_location_callback (UInt32*   outDeltaSampleOffsetToNe
                return kAudioUnitErr_CannotDoInCurrentContext;
        }
 
-       Timecode::BBT_Time bbt;
-       TempoMetric metric = tmap.metric_at (_session.transport_frame() + input_offset);
-       tmap.bbt_time (_session.transport_frame() + input_offset, bbt);
+       TempoMetric metric = tmap.metric_at (transport_frame + input_offset);
+       Timecode::BBT_Time bbt = _session.tempo_map().bbt_at_frame (transport_frame + input_offset);
 
        if (outDeltaSampleOffsetToNextBeat) {
                if (bbt.ticks == 0) {
                        /* on the beat */
                        *outDeltaSampleOffsetToNextBeat = 0;
                } else {
-                       *outDeltaSampleOffsetToNextBeat = (UInt32)
-                               floor (((Timecode::BBT_Time::ticks_per_beat - bbt.ticks)/Timecode::BBT_Time::ticks_per_beat) * // fraction of a beat to next beat
-                                      metric.tempo().frames_per_beat (_session.frame_rate())); // frames per beat
+                       double const beat_frac_to_next = (Timecode::BBT_Time::ticks_per_beat - bbt.ticks) / Timecode::BBT_Time::ticks_per_beat;
+                       *outDeltaSampleOffsetToNextBeat = tmap.frame_at_beat (tmap.beat_at_frame (transport_frame + input_offset) + beat_frac_to_next);
                }
        }
 
@@ -1845,22 +1884,20 @@ AUPlugin::get_transport_state_callback (Boolean*  outIsPlaying,
                                        Float64*  outCycleStartBeat,
                                        Float64*  outCycleEndBeat)
 {
-       bool rolling;
-       float speed;
+       const bool rolling = (transport_speed != 0);
+       const bool last_transport_rolling = (last_transport_speed != 0);
 
        DEBUG_TRACE (DEBUG::AudioUnits, "AU calls ardour transport state callback\n");
 
-       rolling = _session.transport_rolling();
-       speed = _session.transport_speed ();
 
        if (outIsPlaying) {
-               *outIsPlaying = _session.transport_rolling();
+               *outIsPlaying = rolling;
        }
 
        if (outTransportStateChanged) {
                if (rolling != last_transport_rolling) {
                        *outTransportStateChanged = true;
-               } else if (speed != last_transport_speed) {
+               } else if (transport_speed != last_transport_speed) {
                        *outTransportStateChanged = true;
                } else {
                        *outTransportStateChanged = false;
@@ -1871,13 +1908,14 @@ AUPlugin::get_transport_state_callback (Boolean*  outIsPlaying,
                /* this assumes that the AU can only call this host callback from render context,
                   where input_offset is valid.
                */
-               *outCurrentSampleInTimeLine = _session.transport_frame() + input_offset;
+               *outCurrentSampleInTimeLine = transport_frame + input_offset;
        }
 
        if (outIsCycling) {
+               // TODO check bounce-processing
                Location* loc = _session.locations()->auto_loop_location();
 
-               *outIsCycling = (loc && _session.transport_rolling() && _session.get_play_loop());
+               *outIsCycling = (loc && rolling && _session.get_play_loop());
 
                if (*outIsCycling) {
 
@@ -1897,7 +1935,7 @@ AUPlugin::get_transport_state_callback (Boolean*  outIsPlaying,
 
                                if (outCycleStartBeat) {
                                        TempoMetric metric = tmap.metric_at (loc->start() + input_offset);
-                                       _session.tempo_map().bbt_time (loc->start(), bbt);
+                                       bbt = _session.tempo_map().bbt_at_frame (loc->start() + input_offset);
 
                                        float beat;
                                        beat = metric.meter().divisions_per_bar() * bbt.bars;
@@ -1909,7 +1947,7 @@ AUPlugin::get_transport_state_callback (Boolean*  outIsPlaying,
 
                                if (outCycleEndBeat) {
                                        TempoMetric metric = tmap.metric_at (loc->end() + input_offset);
-                                       _session.tempo_map().bbt_time (loc->end(), bbt);
+                                       bbt = _session.tempo_map().bbt_at_frame (loc->end() + input_offset);
 
                                        float beat;
                                        beat = metric.meter().divisions_per_bar() * bbt.bars;
@@ -1922,8 +1960,7 @@ AUPlugin::get_transport_state_callback (Boolean*  outIsPlaying,
                }
        }
 
-       last_transport_rolling = rolling;
-       last_transport_speed = speed;
+       last_transport_speed = transport_speed;
 
        return noErr;
 }