fix input metering:
[ardour.git] / libs / ardour / session_butler.cc
1 /*
2     Copyright (C) 1999-2002 Paul Davis
3
4     This program is free software; you can redistribute it and/or modify
5     it under the terms of the GNU General Public License as published by
6     the Free Software Foundation; either version 2 of the License, or
7     (at your option) any later version.
8
9     This program is distributed in the hope that it will be useful,
10     but WITHOUT ANY WARRANTY; without even the implied warranty of
11     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12     GNU General Public License for more details.
13
14     You should have received a copy of the GNU General Public License
15     along with this program; if not, write to the Free Software
16     Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
17
18 */
19
20 #include <algorithm>
21 #include <string>
22 #include <cmath>
23 #include <cerrno>
24 #include <unistd.h>
25 #include <fcntl.h>
26 #include <poll.h>
27
28 #include <glibmm/threads.h>
29
30 #include "pbd/error.h"
31 #include "pbd/pthread_utils.h"
32 #include "pbd/stacktrace.h"
33
34 #include "ardour/butler.h"
35 #include "ardour/route.h"
36 #include "ardour/session.h"
37 #include "ardour/session_event.h"
38 #include "ardour/track.h"
39 #include "ardour/types.h"
40
41 #include "i18n.h"
42
43 using namespace std;
44 using namespace ARDOUR;
45 using namespace PBD;
46
47 /* XXX put this in the right place */
48
49 static inline uint32_t next_power_of_two (uint32_t n)
50 {
51         --n;
52         n |= n >> 16;
53         n |= n >> 8;
54         n |= n >> 4;
55         n |= n >> 2;
56         n |= n >> 1;
57         ++n;
58         return n;
59 }
60
61 /*---------------------------------------------------------------------------
62  BUTLER THREAD
63  ---------------------------------------------------------------------------*/
64
65 void
66 Session::adjust_playback_buffering ()
67 {
68         request_stop (false, false);
69         SessionEvent *ev = new SessionEvent (SessionEvent::AdjustPlaybackBuffering, SessionEvent::Add, SessionEvent::Immediate, 0, 0, 0.0);
70         queue_event (ev);
71 }
72
73 void
74 Session::adjust_capture_buffering ()
75 {
76         request_stop (false, false);
77         SessionEvent *ev = new SessionEvent (SessionEvent::AdjustCaptureBuffering, SessionEvent::Add, SessionEvent::Immediate, 0, 0, 0.0);
78         queue_event (ev);
79 }
80
81 void
82 Session::schedule_playback_buffering_adjustment ()
83 {
84         add_post_transport_work (PostTransportAdjustPlaybackBuffering);
85         _butler->schedule_transport_work ();
86 }
87
88 void
89 Session::schedule_capture_buffering_adjustment ()
90 {
91         add_post_transport_work (PostTransportAdjustCaptureBuffering);
92         _butler->schedule_transport_work ();
93 }
94
95 void
96 Session::schedule_curve_reallocation ()
97 {
98         add_post_transport_work (PostTransportCurveRealloc);
99         _butler->schedule_transport_work ();
100 }
101
102 void
103 Session::request_overwrite_buffer (Track* t)
104 {
105         SessionEvent *ev = new SessionEvent (SessionEvent::Overwrite, SessionEvent::Add, SessionEvent::Immediate, 0, 0, 0.0);
106         ev->set_ptr (t);
107         queue_event (ev);
108 }
109
110 /** Process thread. */
111 void
112 Session::overwrite_some_buffers (Track* t)
113 {
114         if (actively_recording()) {
115                 return;
116         }
117
118         if (t) {
119
120                 t->set_pending_overwrite (true);
121
122         } else {
123
124                 boost::shared_ptr<RouteList> rl = routes.reader();
125                 for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
126                         boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
127                         if (tr) {
128                                 tr->set_pending_overwrite (true);
129                         }
130                 }
131         }
132
133         add_post_transport_work (PostTransportOverWrite);
134         _butler->schedule_transport_work ();
135 }
136
137 uint32_t
138 Session::playback_load ()
139 {
140         return (uint32_t) g_atomic_int_get (&_playback_load);
141 }
142
143 uint32_t
144 Session::capture_load ()
145 {
146         return (uint32_t) g_atomic_int_get (&_capture_load);
147 }