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