Fix a tiny memory-leak when calling vfork
[ardour.git] / libs / ardour / process_thread.cc
1 /*
2     Copyright (C) 2010 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 #include <iostream>
20
21 #include "ardour/buffer.h"
22 #include "ardour/buffer_manager.h"
23 #include "ardour/buffer_set.h"
24 #include "ardour/process_thread.h"
25 #include "ardour/thread_buffers.h"
26
27 using namespace ARDOUR;
28 using namespace Glib;
29 using namespace std;
30
31 static void
32 release_thread_buffer (void* arg)
33 {
34         BufferManager::put_thread_buffers ((ThreadBuffers*) arg);
35 }
36
37 Glib::Threads::Private<ThreadBuffers> ProcessThread::_private_thread_buffers (release_thread_buffer);
38
39 void
40 ProcessThread::init ()
41 {
42 }
43
44 ProcessThread::ProcessThread ()
45 {
46 }
47
48 ProcessThread::~ProcessThread ()
49 {
50 }
51
52 void
53 ProcessThread::get_buffers ()
54 {
55         ThreadBuffers* tb = BufferManager::get_thread_buffers ();
56
57         assert (tb);
58         _private_thread_buffers.set (tb);
59 }
60
61 void
62 ProcessThread::drop_buffers ()
63 {
64         ThreadBuffers* tb = _private_thread_buffers.get();
65         assert (tb);
66         BufferManager::put_thread_buffers (tb);
67         _private_thread_buffers.set (0);
68 }
69
70 BufferSet&
71 ProcessThread::get_silent_buffers (ChanCount count)
72 {
73         ThreadBuffers* tb = _private_thread_buffers.get();
74         assert (tb);
75
76         BufferSet* sb = tb->silent_buffers;
77         assert (sb);
78
79         assert(sb->available() >= count);
80         sb->set_count(count);
81
82         for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
83                 for (size_t i= 0; i < count.get(*t); ++i) {
84                         sb->get(*t, i).clear();
85                 }
86         }
87
88         return *sb;
89 }
90
91 BufferSet&
92 ProcessThread::get_scratch_buffers (ChanCount count, bool silence)
93 {
94         ThreadBuffers* tb = _private_thread_buffers.get();
95         assert (tb);
96
97         BufferSet* sb = tb->scratch_buffers;
98         assert (sb);
99
100         if (count != ChanCount::ZERO) {
101                 assert(sb->available() >= count);
102                 sb->set_count (count);
103         } else {
104                 sb->set_count (sb->available());
105         }
106
107         if (silence) {
108                 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
109                         for (uint32_t i = 0; i < sb->count().get(*t); ++i) {
110                                 sb->get(*t, i).clear();
111                         }
112                 }
113         }
114
115         return *sb;
116 }
117
118 BufferSet&
119 ProcessThread::get_noinplace_buffers (ChanCount count)
120 {
121         ThreadBuffers* tb = _private_thread_buffers.get();
122         assert (tb);
123
124         BufferSet* sb = tb->noinplace_buffers;
125         assert (sb);
126
127         if (count != ChanCount::ZERO) {
128                 assert(sb->available() >= count);
129                 sb->set_count (count);
130         } else {
131                 sb->set_count (sb->available());
132         }
133
134         return *sb;
135 }
136
137 BufferSet&
138 ProcessThread::get_route_buffers (ChanCount count, bool silence)
139 {
140         ThreadBuffers* tb = _private_thread_buffers.get();
141         assert (tb);
142
143         BufferSet* sb = tb->route_buffers;
144         assert (sb);
145
146         if (count != ChanCount::ZERO) {
147                 assert(sb->available() >= count);
148                 sb->set_count (count);
149         } else {
150                 sb->set_count (sb->available());
151         }
152
153         if (silence) {
154                 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
155                         for (uint32_t i = 0; i < sb->count().get(*t); ++i) {
156                                 sb->get(*t, i).clear();
157                         }
158                 }
159         }
160
161         return *sb;
162 }
163
164 BufferSet&
165 ProcessThread::get_mix_buffers (ChanCount count)
166 {
167         ThreadBuffers* tb = _private_thread_buffers.get();
168         assert (tb);
169
170         BufferSet* mb = tb->mix_buffers;
171
172         assert (mb);
173         assert (mb->available() >= count);
174         mb->set_count(count);
175         return *mb;
176 }
177
178 gain_t*
179 ProcessThread::gain_automation_buffer()
180 {
181         ThreadBuffers* tb = _private_thread_buffers.get();
182         assert (tb);
183
184         gain_t *g =  tb->gain_automation_buffer;
185         assert (g);
186         return g;
187 }
188
189 gain_t*
190 ProcessThread::trim_automation_buffer()
191 {
192         ThreadBuffers* tb = _private_thread_buffers.get();
193         assert (tb);
194
195         gain_t *g =  tb->trim_automation_buffer;
196         assert (g);
197         return g;
198 }
199
200 gain_t*
201 ProcessThread::send_gain_automation_buffer()
202 {
203         ThreadBuffers* tb = _private_thread_buffers.get();
204         assert (tb);
205
206         gain_t* g = tb->send_gain_automation_buffer;
207         assert (g);
208         return g;
209 }
210
211 gain_t*
212 ProcessThread::scratch_automation_buffer()
213 {
214         ThreadBuffers* tb = _private_thread_buffers.get();
215         assert (tb);
216
217         gain_t* g = tb->scratch_automation_buffer;
218         assert (g);
219         return g;
220 }
221
222 pan_t**
223 ProcessThread::pan_automation_buffer()
224 {
225         ThreadBuffers* tb = _private_thread_buffers.get();
226         assert (tb);
227
228         pan_t** p = tb->pan_automation_buffer;
229         assert (p);
230         return p;
231 }