d0a9591a0d7706efdc8939c5984c6cadfd17dd75
[goodguy/cinelerra.git] / cinelerra-5.1 / plugins / liveaudio / liveaudio.C
1
2 /*
3  * CINELERRA
4  * Copyright (C) 2008 Adam Williams <broadcast at earthling dot net>
5  *
6  * This program is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; either version 2 of the License, or
9  * (at your option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program; if not, write to the Free Software
18  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
19  *
20  */
21
22 #include "asset.h"
23 #include "audiodevice.h"
24 #include "bcdisplayinfo.h"
25 #include "bcsignals.h"
26 #include "clip.h"
27 #include "bchash.h"
28 #include "edlsession.h"
29 #include "filexml.h"
30 #include "guicast.h"
31 #include "language.h"
32 #include "mwindow.h"
33 #include "pluginaclient.h"
34 #include "pluginserver.h"
35 #include "recordconfig.h"
36 #include "samples.h"
37 #include "transportque.inc"
38 #include "vframe.h"
39
40 #include <string.h>
41 #include <stdint.h>
42
43 class LiveAudio;
44 class LiveAudioWindow;
45
46
47 class LiveAudioConfig
48 {
49 public:
50         LiveAudioConfig();
51 };
52
53
54
55
56
57
58 class LiveAudioWindow : public PluginClientWindow
59 {
60 public:
61         LiveAudioWindow(LiveAudio *plugin);
62         ~LiveAudioWindow();
63
64         void create_objects();
65
66         LiveAudio *plugin;
67 };
68
69
70
71
72
73
74 class LiveAudio : public PluginAClient
75 {
76 public:
77         LiveAudio(PluginServer *server);
78         ~LiveAudio();
79
80
81         PLUGIN_CLASS_MEMBERS(LiveAudioConfig);
82
83         int process_buffer(int64_t size,
84                 Samples **buffer,
85                 int64_t start_position,
86                 int sample_rate);
87         int is_realtime();
88         int is_multichannel();
89         int is_synthesis();
90         void save_data(KeyFrame *keyframe);
91         void read_data(KeyFrame *keyframe);
92         void update_gui();
93         void render_stop();
94
95         AudioDevice *adevice;
96
97         Samples **history;
98         int history_ptr;
99         int history_channels;
100         int64_t history_position;
101         int history_size;
102 // Fragment size from the EDL session
103         int fragment_size;
104 };
105
106
107
108
109
110
111
112
113
114
115
116
117 LiveAudioConfig::LiveAudioConfig()
118 {
119 }
120
121
122
123
124
125
126
127
128 LiveAudioWindow::LiveAudioWindow(LiveAudio *plugin)
129  : PluginClientWindow(plugin,
130         300,
131         160,
132         300,
133         160,
134         0)
135 {
136         this->plugin = plugin;
137 }
138
139 LiveAudioWindow::~LiveAudioWindow()
140 {
141 }
142
143 void LiveAudioWindow::create_objects()
144 {
145         int x = 10, y = 10;
146
147         BC_Title *title;
148         add_subwindow(title = new BC_Title(x, y, _("Live audio")));
149         show_window();
150         flush();
151 }
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174 REGISTER_PLUGIN(LiveAudio)
175
176
177
178
179
180
181 LiveAudio::LiveAudio(PluginServer *server)
182  : PluginAClient(server)
183 {
184         adevice = 0;
185         history = 0;
186         history_channels = 0;
187         history_ptr = 0;
188         history_position = 0;
189         history_size = 0;
190
191         fragment_size = 0;
192 }
193
194
195 LiveAudio::~LiveAudio()
196 {
197         if(adevice)
198         {
199                 adevice->interrupt_crash();
200                 adevice->close_all();
201         }
202         delete adevice;
203         if(history)
204         {
205                 for(int i = 0; i < history_channels; i++)
206                         delete history[i];
207                 delete [] history;
208         }
209 }
210
211
212
213 int LiveAudio::process_buffer(int64_t size,
214         Samples **buffer,
215         int64_t start_position,
216         int sample_rate)
217 {
218         load_configuration();
219
220 // printf("LiveAudio::process_buffer 10 size=%lld buffer_size=%d channels=%d size=%d\n",
221 // size, get_buffer_size(), get_total_buffers(), size);
222
223         int first_buffer = 0;
224
225         if(!adevice)
226         {
227                 EDLSession *session = PluginClient::get_edlsession();
228                 if(session)
229                 {
230                         fragment_size = session->record_fragment_size;
231                         history_channels = session->aconfig_in->channels;
232
233                         adevice = new AudioDevice(server ? server->mwindow : 0);
234 // Take fragment size & channels from the recording config
235                         adevice->open_input(session->aconfig_in,
236                                 session->vconfig_in,
237                                 get_project_samplerate(),
238                                 fragment_size,
239                                 session->aconfig_in->channels,
240                                 session->real_time_record);
241                         adevice->start_recording();
242                         first_buffer = 1;
243                         history_position = start_position;
244                 }
245         }
246
247         if(!history || history[0]->get_allocated() < size)
248         {
249 // compute new history which is a multiple of our fragment size
250                 int new_history_size = fragment_size;
251                 while(new_history_size < size)
252                         new_history_size += fragment_size;
253
254
255                 if(!history)
256                 {
257                         history = new Samples*[history_channels];
258                         for(int i = 0; i < history_channels; i++)
259                                 history[i] = 0;
260                 }
261
262                 for(int i = 0; i < history_channels; i++)
263                 {
264                         delete history[i];
265                         history[i] = new Samples(new_history_size);
266                         bzero(history[i]->get_data(), sizeof(double) * new_history_size);
267                 }
268         }
269
270
271
272 //      if(get_direction() == PLAY_FORWARD)
273         {
274 // Reset history buffer to current position if before maximum history
275                 if(start_position < history_position - history[0]->get_allocated())
276                         history_position = start_position;
277
278
279
280 // Extend history buffer
281                 int64_t end_position = start_position + size;
282 // printf("LiveAudio::process_buffer %lld %lld %lld\n",
283 // end_position,
284 // history_position,
285 // end_position - history_position);
286                 if(end_position > history_position)
287                 {
288 // Reset history buffer to current position if after maximum history
289                         if(start_position >= history_position + history[0]->get_allocated())
290                                 history_position = start_position;
291 // A delay seems required because ALSA playback may get ahead of
292 // ALSA recording and never recover.
293                         if(first_buffer) end_position += sample_rate;
294                         int done = 0;
295                         while(!done && history_position < end_position)
296                         {
297                                 if(history_ptr + fragment_size  >= history[0]->get_allocated())
298                                 {
299                                         done = 1;
300                                 }
301
302 // Read rest of buffer from sound driver
303                                 if(adevice)
304                                 {
305                                         int over[history_channels];
306                                         double max[history_channels];
307                                         int result = adevice->read_buffer(history,
308                                                 history_channels,
309                                                 fragment_size,
310                                                 over,
311                                                 max,
312                                                 history_ptr);
313                                         if( result && adevice->config_updated() )
314                                                 adevice->config_update();
315                                 }
316
317                                 history_ptr += fragment_size;
318 // wrap around buffer
319                                 if(history_ptr >= history[0]->get_allocated())
320                                         history_ptr = 0;
321                                 history_position += fragment_size;
322                         }
323                 }
324
325 // Copy data from history buffer
326                 int buffer_position = 0;
327                 int history_buffer_ptr = history_ptr - history_position + start_position;
328                 while(history_buffer_ptr < 0)
329                         history_buffer_ptr += history[0]->get_allocated();
330                 while(buffer_position < size)
331                 {
332                         int fragment = size;
333                         if(history_buffer_ptr + fragment > history[0]->get_allocated())
334                                 fragment = history[0]->get_allocated() - history_buffer_ptr;
335                         if(buffer_position + fragment > size)
336                                 fragment = size - buffer_position;
337
338                         for(int i = 0; i < get_total_buffers(); i++)
339                         {
340                                 int input_channel = i;
341 // Clamp channel to total history channels
342                                 if(input_channel >= history_channels)
343                                         input_channel = history_channels - 1;
344                                 memcpy(buffer[i]->get_data() + buffer_position,
345                                         history[input_channel]->get_data() + history_buffer_ptr,
346                                         sizeof(double) * fragment);
347                         }
348
349                         history_buffer_ptr += fragment;
350                         if(history_buffer_ptr >= history[0]->get_allocated())
351                                 history_buffer_ptr = 0;
352                         buffer_position += fragment;
353                 }
354
355
356         }
357
358
359         return 0;
360 }
361
362 void LiveAudio::render_stop()
363 {
364         if(adevice)
365         {
366                 adevice->interrupt_crash();
367                 adevice->close_all();
368         }
369         delete adevice;
370         adevice = 0;
371         history_ptr = 0;
372         history_position = 0;
373         history_size = 0;
374 }
375
376
377 const char* LiveAudio::plugin_title() { return N_("Live Audio"); }
378 int LiveAudio::is_realtime() { return 1; }
379 int LiveAudio::is_multichannel() { return 1; }
380 int LiveAudio::is_synthesis() { return 1; }
381
382
383
384 NEW_WINDOW_MACRO(LiveAudio, LiveAudioWindow)
385
386
387
388 int LiveAudio::load_configuration()
389 {
390         return 0;
391 }
392
393
394 void LiveAudio::save_data(KeyFrame *keyframe)
395 {
396 }
397
398 void LiveAudio::read_data(KeyFrame *keyframe)
399 {
400 }
401
402 void LiveAudio::update_gui()
403 {
404 }
405
406
407
408
409