root/sweep/trunk/src/play.c

Revision 688, 25.5 kB (checked in by erikd, 2 years ago)

Clean up large number of '#if 0' and '#if 1' code blocks.

Remove code chunks surrounded by '#if 0' .. '#endif'.
Remove '#if 1' and '#endif' around code chunks that are actually being used.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
Line 
1 /*
2  * Sweep, a sound wave editor.
3  *
4  * Copyright (C) 2000 Conrad Parker
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 #ifdef HAVE_CONFIG_H
22 #  include <config.h>
23 #endif
24
25 /* Define this to record all output to files in /tmp */
26 /* #define RECORD_DEMO_FILES */
27
28 #include <stdio.h>
29 #include <stdlib.h>
30 #include <string.h>
31 #include <sys/time.h>
32 #include <sys/types.h>
33 #include <sys/stat.h>
34 #include <unistd.h>
35 #include <fcntl.h>
36 #include <math.h>
37 #include <sys/ioctl.h>
38 #include <pthread.h>
39
40 #ifdef RECORD_DEMO_FILES
41 #include <sndfile.h>
42
43 #if !defined (SNDFILE_1)
44 #error Recording demo files requires libsndfile version 1
45 #endif
46
47 #endif
48
49 #include <sweep/sweep_types.h>
50 #include <sweep/sweep_sample.h>
51 #include <sweep/sweep_typeconvert.h>
52
53 #include "play.h"
54 #include "head.h"
55 #include "driver.h"
56 #include "preferences.h"
57 #include "sample-display.h"
58
59 /*#define DEBUG*/
60
61 #define SCRUB_SLACKNESS 2.0
62
63 #define USE_MONITOR_KEY "UseMonitor"
64
65 static GMutex * play_mutex = NULL;
66
67 static sw_handle * main_handle = NULL;
68 static sw_handle * monitor_handle = NULL;
69
70 static GList * active_main_heads = NULL;
71 static GList * active_monitor_heads = NULL;
72
73 /*static int realoffset = 0;*/
74 static sw_sample * prev_sample = NULL;
75 static pthread_t player_thread = (pthread_t)-1;
76
77 static gboolean stop_all = FALSE;
78
79 static sw_audio_t * pbuf = NULL, * devbuf = NULL;
80 static int pbuf_chans = 0, devbuf_chans = 0;
81
82
83 /*
84  * update_playmarker ()
85  *
86  * Update the position of the playback marker line for the sample
87  * being played.
88  *
89  * Called within the main sweep interface thread.
90  * gtk_idle will keep calling this function as long as this sample is
91  * playing, unless otherwise stopped.
92  */
93 static gint
94 update_playmarker (gpointer data)
95 {
96   sw_sample * s = (sw_sample *)data;
97   sw_head * head = s->play_head;
98
99   if (!sample_bank_contains (s)) {
100     return FALSE;
101   } else if (!head->going) {
102
103 #ifdef DEBUG
104     g_print ("update_playmarker: !head->going\n");
105 #endif
106     s->playmarker_tag = 0;
107
108     /* Set user offset to correct offset */
109     if (head->previewing) {
110       sample_set_playmarker (s, head->stop_offset, TRUE);
111       head_set_previewing (head, FALSE);
112     } else {
113       sample_set_playmarker (s, (sw_framecount_t)head->offset, TRUE);
114     }
115    
116     /* As this may have been stopped by the player thread, refresh the
117      * interface */
118     head_set_going (head, FALSE);
119     sample_refresh_playmode (s);
120    
121     return FALSE;
122   } else {
123     sample_set_playmarker (s, head->realoffset, FALSE);
124
125     return TRUE;
126   }
127 }
128
129 static void
130 start_playmarker (sw_sample * s)
131 {
132   if (s->playmarker_tag > 0) {
133     g_source_remove (s->playmarker_tag);
134   }
135
136   s->playmarker_tag =
137     g_timeout_add ((guint32)30,
138                      (GSourceFunc) update_playmarker,
139                      (gpointer)s);
140 }
141
142 static sw_framecount_t
143 head_read_unrestricted (sw_head * head, sw_audio_t * buf,
144                         sw_framecount_t count, int driver_rate)
145 {
146   sw_sample * sample = head->sample;
147   sw_sounddata * sounddata = sample->sounddata;
148   sw_format * f = sounddata->format;
149   sw_audio_t * d;
150   gdouble po = 0.0, p;
151   gfloat relpitch;
152   sw_framecount_t i, j, b;
153   gint si=0, si_next = 0;
154   gboolean interpolate = FALSE;
155   gboolean do_smoothing = FALSE;
156   sw_framecount_t last_user_offset = -1;
157   int pbuf_size = count * f->channels;
158   gdouble scrub_rate = f->rate / 30.0;
159
160   d = (sw_audio_t *)sounddata->data;
161
162   b = 0;
163
164   po = head->offset;
165
166   /* compensate for sampling rate of driver */
167   relpitch = (gfloat)((gdouble)f->rate / (gdouble)driver_rate);
168  
169   for (i = 0; i < count; i++) {
170     if (head->mute || sample->user_offset == last_user_offset) {
171       for (j = 0; j < f->channels; j++) {
172         buf[b] = 0.0;
173         b++;
174       }
175     } else {
176       si = (int)floor(po);
177      
178       interpolate = (si < sounddata->nr_frames);
179      
180       p = po - (gdouble)si;
181       si *= f->channels;
182       g_mutex_lock(head->sample->sounddata->data_mutex);
183
184       if (interpolate) {
185         si_next = si+f->channels;
186         for (j = 0; j < f->channels; j++) {
187          buf[b] = head->gain * (((sw_audio_t *)head->sample->sounddata->data)[si] * p + ((sw_audio_t *)head->sample->sounddata->data)[si_next] * (1 - p));
188           if (do_smoothing) {
189             sw_framecount_t b1, b2;
190             b1 = (b - f->channels + pbuf_size) % pbuf_size;
191             b2 = (b1 - f->channels + pbuf_size) % pbuf_size;
192             buf[b] += buf[b] * 2.0;
193             buf[b] += buf[b1] * 3.0 + buf[b2] * 4.0;
194             buf[b] /= 10.0;
195           }
196           b++; si++; si_next++;
197         }
198       } else {
199         for (j = 0; j < f->channels; j++) {
200          buf[b] = head->gain * ((sw_audio_t *)head->sample->sounddata->data)[si];
201           if (do_smoothing) {
202             sw_framecount_t b1, b2;
203             b1 = (b - f->channels + pbuf_size) % pbuf_size;
204             b2 = (b1 - f->channels + pbuf_size) % pbuf_size;
205             buf[b] += buf[b] * 2.0;
206             buf[b] += buf[b1] * 3.0 + buf[b2] * 4.0;
207             buf[b] /= 10.0;
208           }
209           b++; si++;
210         }
211       }
212      g_mutex_unlock(head->sample->sounddata->data_mutex);
213     }
214
215     if (head->scrubbing) {
216       gfloat new_delta;
217
218       if (sample->by_user) {
219         new_delta = (sample->user_offset - po) / scrub_rate;
220        
221         head->delta = head->delta * 0.9 + new_delta * 0.1;
222        
223         sample->by_user = FALSE;
224        
225         last_user_offset = sample->user_offset;
226       } else  {
227         gfloat new_po, u_po = (gdouble)sample->user_offset;
228
229         new_delta = (sample->user_offset - po) / scrub_rate;
230        
231         head->delta = head->delta * 0.99 + new_delta * 0.01;
232        
233         new_po = po + (head->delta * relpitch);
234        
235         if ((head->delta < 0 && new_po < u_po) ||
236             (head->delta > 0 && new_po > u_po)) {
237           po = u_po;
238           head->delta = 0.0;
239         }
240       }
241      
242       do_smoothing = TRUE;
243
244     } else {
245       gfloat tdelta = head->rate * sample->rate;
246       gfloat hdelta = head->delta * (head->reverse ? -1.0 : 1.0);
247
248       if (sample->by_user) {
249         head->offset = (gdouble)sample->user_offset;
250         po = head->offset;
251         head->delta = tdelta;
252
253         sample->by_user = FALSE;
254         do_smoothing = TRUE;
255
256         last_user_offset = sample->user_offset;
257       }
258
259       if (hdelta < -0.3 * tdelta || hdelta > 1.001 * tdelta) {
260         head->delta *= 0.9999;
261       } else if (hdelta < 0.7 * tdelta) {
262         head->delta = 0.8 * tdelta * (head->reverse ? -1.0 : 1.0);
263       } else if (hdelta < .999 * tdelta) {
264         head->delta *= 1.0001;
265       } else {
266         head->delta = tdelta * (head->reverse ? -1.0 : 1.0);
267       }
268
269       do_smoothing = FALSE;
270     }
271
272     po += head->delta * relpitch;
273
274     {
275       gdouble nr_frames = (gdouble)sample->sounddata->nr_frames;
276       if (head->looping) {
277         while (po < 0.0) po += nr_frames;
278         while (po > nr_frames) po -= nr_frames;
279       } else {
280         if (po < 0.0) po = 0.0;
281         else if (po > nr_frames) po = nr_frames;
282       }
283     }
284
285     head->offset = po;
286
287   }
288
289   return count;
290 }
291
292 sw_framecount_t
293 head_read (sw_head * head, sw_audio_t * buf, sw_framecount_t count,
294            int driver_rate)
295 {
296   sw_sample * sample = head->sample;
297   sw_sounddata * sounddata = sample->sounddata;
298   sw_format * f = sounddata->format;
299   sw_framecount_t head_offset;
300   sw_framecount_t remaining = count, written = 0, n = 0;
301   sw_framecount_t delta, bound;
302   GList * gl;
303   sw_sel * sel, * osel;
304
305   while (head->going && remaining > 0) {
306     n = 0;
307
308     if (head->restricted /* && !head->scrubbing */) {
309       g_mutex_lock (sounddata->sels_mutex);
310
311       if (g_list_length (sounddata->sels) == 0) {
312         g_mutex_unlock (sounddata->sels_mutex);
313
314         if (head->previewing && !head->scrubbing) {
315           if (head->reverse) {
316             n = MIN (remaining, head->offset - head->stop_offset);
317           } else {
318             n = MIN (remaining, head->stop_offset - head->offset);
319           }
320           goto got_n;
321
322         } else {
323           goto zero_pad;
324         }
325       }
326
327       if (head->previewing && !head->scrubbing) {
328         /* Find selection region that offset is or should be playing to */
329         if (head->reverse) {
330           osel = NULL;
331           for (gl = g_list_last (sounddata->sels); gl; gl = gl->prev) {
332             sel = (sw_sel *)gl->data;
333            
334             if (osel && ((sw_framecount_t)head->offset > osel->sel_start))
335               head->offset = osel->sel_start;
336
337             osel = sel;
338
339             head_offset = (sw_framecount_t)head->offset;
340            
341             if (head_offset > sel->sel_end) {
342               n = MIN (remaining, head_offset - sel->sel_end);
343               break;
344             }
345           }
346
347           /* If now at start of first selection region ... */
348           if (gl == NULL && osel != NULL) {
349             if ((sw_framecount_t)head->offset > osel->sel_start)
350               head->offset = osel->sel_start;
351
352             head_offset = (sw_framecount_t)head->offset;
353            
354             /* continue 1 second */
355             delta = time_to_frames (sounddata->format, 1.0);
356             bound = MAX((osel->sel_start - delta), 0);
357             if (head_offset > bound) {
358               n = MIN (remaining, head_offset - bound);
359             }
360           }
361
362         } else {
363           osel = NULL;
364           for (gl = sounddata->sels; gl; gl = gl->next) {
365             sel = (sw_sel *)gl->data;
366            
367             if (osel && ((sw_framecount_t)head->offset < osel->sel_end))
368               head->offset = osel->sel_end;
369
370             osel = sel;
371            
372             head_offset = (sw_framecount_t)head->offset;
373
374             if (head_offset < sel->sel_start) {
375               n = MIN (remaining, sel->sel_start - head_offset);
376               break;
377             }
378           }
379          
380           /* If now at end of last selection region ... */
381           if (gl == NULL && osel != NULL) {
382             if ((sw_framecount_t)head->offset < osel->sel_end)
383               head->offset = osel->sel_end;
384
385             head_offset = head->offset;
386
387             /* continue 1 second */
388             delta = time_to_frames (sounddata->format, 1.0);
389             bound = MIN ((osel->sel_end + delta), sounddata->nr_frames);
390             if (head_offset < bound) {
391               n = MIN (remaining, bound - head_offset);
392             }
393           }
394         }
395       } else {
396         /* Find selection region that offset is or should be in */
397         if (head->reverse) {
398           for (gl = g_list_last (sounddata->sels); gl; gl = gl->prev) {
399             sel = (sw_sel *)gl->data;
400            
401             if ((sw_framecount_t)head->offset > sel->sel_end)
402               head->offset = sel->sel_end;
403            
404             if ((sw_framecount_t)head->offset > sel->sel_start) {
405               n = MIN (remaining, (sw_framecount_t)head->offset - sel->sel_start);
406               break;
407             }
408           }
409         } else {
410           for (gl = sounddata->sels; gl; gl = gl->next) {
411             sel = (sw_sel *)gl->data;
412            
413             if ((sw_framecount_t)head->offset < sel->sel_start)
414               head->offset = sel->sel_start;
415            
416             if ((sw_framecount_t)head->offset < sel->sel_end) {
417               n = MIN (remaining, sel->sel_end - (sw_framecount_t)head->offset);
418               break;
419             }
420           }
421         }
422       }
423
424       g_mutex_unlock (sounddata->sels_mutex);
425
426     } else { /* unrestricted */
427       if (head->previewing && !head->scrubbing) {
428         if (head->reverse) {
429           n = MIN (remaining, (sw_framecount_t)head->offset - head->stop_offset);
430         } else {
431           n = MIN (remaining, head->stop_offset - (sw_framecount_t)head->offset);
432         }
433       } else {
434         if (head->reverse) {
435           n = MIN (remaining, (sw_framecount_t)head->offset);
436         } else {
437           n = MIN (remaining, sounddata->nr_frames - (sw_framecount_t)head->offset);
438         }
439       }
440     }
441
442   got_n:
443
444     if (n == 0) {
445       if (head->previewing) {
446         head->offset = head->stop_offset;
447       } else if (!head->restricted || sounddata->sels == NULL) {
448         head->offset = head->reverse ? sounddata->nr_frames : 0;
449       } else {
450         g_mutex_lock (sounddata->sels_mutex);
451         if (head->reverse) {
452           gl = g_list_last (sounddata->sels);
453           sel = (sw_sel *)gl->data;
454           head->offset = sel->sel_end;
455         } else {
456           gl = sounddata->sels;
457           sel = (sw_sel *)gl->data;
458           head->offset = sel->sel_start;
459         }
460         g_mutex_unlock (sounddata->sels_mutex);
461       }
462
463       if (!head->looping || head->previewing) {
464         head->going = FALSE;
465       }
466     } else {
467       if (n < 0) {
468 #ifdef DEBUG
469         printf ("n = %d\n", n);
470 #endif
471         head->going = FALSE;
472 #ifdef DEUBG
473       } else if (n > count) {
474         printf ("n = %d \t>\tcount = %d\n", n, count);
475 #endif
476       } else {
477       written += head_read_unrestricted (head, buf, n, driver_rate);
478       buf += (int)frames_to_samples (f, n);
479       remaining -= n;
480       }
481     }
482   }
483
484  zero_pad:
485
486   if (remaining > 0) {
487     n = frames_to_bytes (f, remaining);
488     memset (buf, 0, n);
489     written += remaining;
490   }
491
492   return written;
493 }
494
495 /* initialise a head for playback */
496 static void
497 head_init_playback (sw_sample * s)
498 {
499   sw_head * head = s->play_head;
500   GList * gl;
501   sw_sel * sel;
502   sw_framecount_t sels_start, sels_end;
503   sw_framecount_t delta;
504
505   /*  g_mutex_lock (s->play_mutex);*/
506
507   s->by_user = FALSE;
508
509   if (!head->going) {
510     head_set_offset (head, s->user_offset);
511     head->delta = head->rate * s->rate;
512   }
513
514
515   if (head->restricted) {
516     g_mutex_lock (s->sounddata->sels_mutex);
517
518     if ((gl = s->sounddata->sels) != NULL) {
519       sel = (sw_sel *)gl->data;
520       sels_start = sel->sel_start;
521      
522       gl = g_list_last (s->sounddata->sels);
523      
524       sel = (sw_sel *)gl->data;
525       sels_end = sel->sel_end;
526       g_mutex_unlock (s->sounddata->sels_mutex);
527      
528       if (head->previewing) {
529         /* preroll 1 second */
530         delta = time_to_frames (s->sounddata->format, 1.0);
531        
532         if (head->reverse) {
533           head_set_offset (head, sels_end + delta);
534         } else {
535           head_set_offset (head, sels_start - delta);
536         }
537        
538         head_set_offset (head,
539                          CLAMP((sw_framecount_t)head->offset, 0, s->sounddata->nr_frames));
540       } else {
541         if (head->reverse && head->offset <= sels_start) {
542           head_set_offset (head, sels_end);
543         } else if (!head->reverse && head->offset >= sels_end) {
544           head_set_offset (head, sels_start);
545         }
546       }
547     } else if (head->previewing) {
548         /* preroll 1 second */
549         delta = time_to_frames (s->sounddata->format, 1.0);
550        
551         if (head->reverse) {
552           head_set_offset (head, head->offset + delta);
553         } else {
554           head_set_offset (head, head->offset - delta);
555         }
556        
557         head_set_offset (head,
558                          CLAMP(head->offset, 0, s->sounddata->nr_frames));
559     }
560   } else {
561
562     if (head->previewing) {
563       /* preroll 1 second */
564       delta = time_to_frames (s->sounddata->format, 1.0);
565       if (head->reverse) head_set_offset (head, head->offset + delta);
566       else head_set_offset (head, head->offset - delta);
567     }
568
569     if (head->reverse && head->offset <= 0) {
570       head_set_offset (head,  s->sounddata->nr_frames);
571     } else if (!head->reverse && head->offset >= s->sounddata->nr_frames) {
572       head_set_offset (head, 0);
573     }
574   }
575
576   /*  g_mutex_unlock (s->play_mutex);*/
577 }
578
579 static void
580 channel_convert_adding (sw_audio_t * src, int src_channels,
581                         sw_audio_t * dest, int dest_channels,
582                         sw_framecount_t n)
583 {
584   int j;
585   sw_framecount_t i, b = 0;
586   sw_audio_intermediate_t a;
587
588   if (src_channels == 1) { /* mix mono data up */
589     for (i = 0; i < n; i++) {
590       for (j = 0; j < dest_channels; j++) {
591         dest[b] += src[i];
592         b++;
593       }
594     }
595   } else if (dest_channels == 1) { /* mix down to mono */
596     for (i = 0; i < n; i++) {
597       a = 0.0;
598       for (j = 0; j < src_channels; j++) {
599         a += src[b];
600         b++;
601       }
602       a /= (sw_audio_intermediate_t)src_channels;
603       dest[i] += (sw_audio_t)a;
604     }
605   } else if (src_channels < dest_channels) { /* copy to first channels */
606     for (i = 0; i < n; i++) {
607       for (j = 0; j < src_channels; j++) {
608         dest[i * dest_channels + j] += src[b];
609         b++;
610       }
611     }
612   } else if (dest_channels < src_channels) { /* copy first channels only */
613     for (i = 0; i < n; i++) {
614       for (j = 0; j < dest_channels; j++) {
615         dest[b] += src[i * src_channels + j];
616         b++;
617       }
618     }
619   } else if (src_channels == dest_channels) { /* just add */
620     for (i = 0; i < n * src_channels; i ++) {
621       dest[i] += src[i];
622     }
623   }
624 }
625
626 static void
627 play_head_update_device (sw_head * head)
628 {
629   g_mutex_lock (play_mutex);
630   g_mutex_lock (head->head_mutex);
631
632   if (head->monitor) {
633     if (g_list_find (active_monitor_heads, head) == 0) {
634       active_monitor_heads = g_list_append (active_monitor_heads, head);
635     }
636     active_main_heads = g_list_remove (active_main_heads, head);
637   } else {
638     if (g_list_find (active_main_heads, head) == 0) {
639       active_main_heads = g_list_append (active_main_heads, head);
640     }
641     active_monitor_heads = g_list_remove (active_monitor_heads, head);
642   }
643
644   g_mutex_unlock (head->head_mutex);
645   g_mutex_unlock (play_mutex);
646 }
647
648 #ifdef RECORD_DEMO_FILES
649 static gchar *
650 generate_demo_filename (void)
651 {
652   return g_strdup_printf ("/tmp/sweep-demo-%d.au", getpid ());
653 }
654 #endif
655
656 #define PSIZ 64
657
658 static void
659 prepare_to_play_heads (GList * heads, sw_handle * handle)
660 {
661   sw_head * head;
662   sw_format * f;
663
664   GList * gl;
665
666   if ((gl = heads) != NULL) {
667     head = (sw_head *)gl->data;
668
669     f = head->sample->sounddata->format;
670    
671     if (f->channels > pbuf_chans) {
672       pbuf = g_realloc (pbuf, PSIZ * f->channels * sizeof (sw_audio_t));
673       pbuf_chans = f->channels;
674     }
675   }
676
677   device_wait (handle);
678
679   return;
680 }
681
682 static void
683 play_heads (GList ** heads, sw_handle * handle)
684 {
685   sw_sample * s;
686   sw_head * head;
687   sw_format * f;
688   sw_framecount_t n;
689
690   GList * gl, * gl_next;
691
692   if (*heads == NULL) return;
693
694   n = PSIZ;
695  
696   for (gl = *heads; gl; gl = gl_next) {
697
698     g_mutex_lock (play_mutex);
699     head = (sw_head *)gl->data;
700     gl_next = gl->next;
701     g_mutex_unlock (play_mutex);
702
703     if (!head) {
704       /* XXX: wtf??? */
705       return;
706     } else if (!head->going || !sample_bank_contains (head->sample)) {
707       g_mutex_lock (play_mutex);
708       *heads = g_list_remove (*heads, head);
709       g_mutex_unlock (play_mutex);
710     } else {
711       s = head->sample;
712       f = s->sounddata->format;
713          
714       if (f->channels > pbuf_chans) {
715         pbuf = g_realloc (pbuf, n * f->channels * sizeof (sw_audio_t));
716         pbuf_chans = f->channels;
717       }
718
719       head_read (head, pbuf, n, handle->driver_rate);
720
721       channel_convert_adding (pbuf, f->channels, devbuf,
722                               handle->driver_channels, n);
723        
724       /* XXX: store the head->offset NOW for device_offset referencing */
725          
726       g_mutex_lock (s->play_mutex);
727          
728       head->realoffset = device_offset (handle);
729       if (head->realoffset == -1) {
730         head->realoffset = head->offset;
731       }
732        
733       head->offset = head->realoffset;
734          
735       if (s->by_user /* && s->play_scrubbing */) {
736         /*head->offset = s->user_offset;*/
737       } else {
738         if (!head->scrubbing) s->user_offset = head->realoffset;
739       }
740          
741       /*        if (!head->going) active = FALSE;*/
742          
743       g_mutex_unlock (s->play_mutex);
744     }
745   }
746
747   return;
748 }
749
750 /* how many inactive writes to do before closing */
751 #define INACTIVE_TIMEOUT 256
752
753 static gboolean
754 monitor_active (void)
755 {
756   int * use_monitor;
757
758   use_monitor = prefs_get_int (USE_MONITOR_KEY);
759
760   if (use_monitor == NULL) return 0;
761   else return (*use_monitor != 0);
762 }
763
764 static void
765 play_active_heads (void)
766 {
767   sw_framecount_t count;
768   int inactive_writes = 0;
769   GList * gl;
770   sw_head * head;
771   sw_format * f;
772   int max_driver_chans = 0;
773
774   gboolean use_monitor;
775
776 #ifdef RECORD_DEMO_FILES
777   gchar * filename;
778   SNDFILE * sndfile = NULL;
779   SF_INFO sfinfo;
780 #endif
781
782   if (!active_main_heads && !active_monitor_heads) return;
783
784   use_monitor = (monitor_handle != NULL);
785
786   if (use_monitor) {
787     if ((gl = active_monitor_heads)) {
788       head = (sw_head *)gl->data;
789       f = head->sample->sounddata->format;
790      
791       device_setup (monitor_handle, f);
792     } else if ((gl = active_main_heads)) {
793       head = (sw_head *)gl->data;
794       f = head->sample->sounddata->format;
795      
796       device_setup (monitor_handle, f);
797     }
798   }
799
800   if ((gl = active_main_heads)) {
801     head = (sw_head *)gl->data;
802     f = head->sample->sounddata->format;
803
804     device_setup (main_handle, f);
805
806 #ifdef RECORD_DEMO_FILES   
807     filename = generate_demo_filename ();
808     sfinfo.samplerate = f->rate;
809     sfinfo.channels = handle->driver_channels;
810     sfinfo.format = SF_FORMAT_AU | SF_FORMAT_FLOAT | SF_ENDIAN_CPU;
811     sndfile = sf_open (filename, SFM_WRITE, &sfinfo);
812     if (sndfile == NULL) sf_perror (NULL);
813     else printf ("Writing to %s\n", filename);
814 #endif
815   } else if ((gl = active_monitor_heads)) {
816     head = (sw_head *)gl->data;
817     f = head->sample->sounddata->format;
818
819     device_setup (main_handle, f);
820   } else {
821     return;
822   }
823
824   if (use_monitor) {
825     max_driver_chans = MAX (main_handle->driver_channels,
826                             monitor_handle->driver_channels);
827   } else {
828     max_driver_chans = main_handle->driver_channels;
829   }
830
831   if (max_driver_chans > devbuf_chans) {
832     devbuf = g_realloc (devbuf,
833                         PSIZ * max_driver_chans * sizeof (sw_audio_t));
834     devbuf_chans = max_driver_chans;
835   }
836
837   while (!stop_all && inactive_writes < INACTIVE_TIMEOUT) {
838
839     if (active_main_heads == NULL && active_monitor_heads == NULL) {
840       inactive_writes++;
841     } else {
842       inactive_writes = 0;
843     }
844
845     g_mutex_lock (play_mutex);
846     if (use_monitor) {
847       prepare_to_play_heads (active_monitor_heads, monitor_handle);
848       prepare_to_play_heads (active_main_heads, main_handle);
849     } else {
850       prepare_to_play_heads (active_monitor_heads, main_handle);
851       prepare_to_play_heads (active_main_heads, main_handle);
852     }
853     g_mutex_unlock (play_mutex);
854
855     if (use_monitor) {
856       count = PSIZ * monitor_handle->driver_channels;
857       memset (devbuf, 0, count * sizeof (sw_audio_t));
858       play_heads (&active_monitor_heads, monitor_handle);
859       device_write (monitor_handle, devbuf, count); 
860      
861       count = PSIZ * main_handle->driver_channels;
862       memset (devbuf, 0, count * sizeof (sw_audio_t));
863       play_heads (&active_main_heads, main_handle);
864       device_write (main_handle, devbuf, count);
865     } else {
866       count = PSIZ * main_handle->driver_channels;
867       memset (devbuf, 0, count * sizeof (sw_audio_t));
868       play_heads (&active_monitor_heads, main_handle);
869       play_heads (&active_main_heads, main_handle);
870       device_write (main_handle, devbuf, count); 
871     }
872
873 #ifdef RECORD_DEMO_FILES
874     if (sndfile)
875       sf_writef_float (sndfile, devbuf, count / main_handle->driver_channels);
876 #endif
877   }
878
879   if (use_monitor) {
880     device_reset (monitor_handle);
881     device_close (monitor_handle);
882   }
883
884   device_reset (main_handle);
885   device_close (main_handle);
886
887 #ifdef RECORD_DEMO_FILES
888   if (sndfile) {
889     printf ("Closing %s\n", filename);
890     sf_close (sndfile);
891   }
892 #endif
893
894   player_thread = (pthread_t) -1;
895 }
896
897 static gboolean
898 ensure_playing (void)
899 {
900   sw_handle * h;
901
902   if (player_thread == (pthread_t) -1) {
903     if ((h = device_open (0, O_WRONLY)) != NULL) {
904       main_handle = h;
905       if (monitor_active()) {
906         monitor_handle = device_open (1, O_WRONLY);
907       } else {
908         monitor_handle = NULL;
909       }
910
911       pthread_create (&player_thread, NULL, (void *) (*play_active_heads),
912                       NULL);
913       return TRUE;
914     } else {
915       return FALSE;
916     }
917   }
918
919   return TRUE;
920 }
921
922 void
923 sample_play (sw_sample * sample)
924 {
925   sw_head * head = sample->play_head;
926
927   play_head_update_device (head);
928   head_init_playback (sample);
929
930   head_set_going (head, TRUE);
931
932   sample_refresh_playmode (sample);
933
934   if (ensure_playing()) {
935     start_playmarker (sample);
936   } else {
937     head_set_going (head, FALSE);
938     sample_refresh_playmode (sample);
939   }
940 }
941
942 void
943 sample_update_device (sw_sample * sample)
944 {
945   sw_head * head = sample->play_head;
946
947   if (!head->going) return;
948
949   play_head_update_device (head);
950 }
951
952 void
953 play_view_all (sw_view * view)
954 {
955   sw_sample * s = view->sample;
956   sw_head * head = s->play_head;
957
958   sample_set_stop_offset (s);
959   sample_set_previewing (s, FALSE);
960    
961   prev_sample = s;
962
963   head_set_restricted (head, FALSE);
964
965   sample_play (s);
966 }
967
968 void
969 play_view_sel (sw_view * view)
970 {
971   sw_sample * s = view->sample;
972   sw_head * head = s->play_head;
973
974   if (s->sounddata->sels == NULL) {
975     head_set_going (head, FALSE);
976     sample_refresh_playmode (s);
977     return;
978   }
979
980   sample_set_stop_offset (s);
981   sample_set_previewing (s, FALSE);
982
983   prev_sample = s;
984
985   head_set_restricted (head, TRUE);
986
987   sample_play (s);
988 }
989
990 void
991 play_preroll (sw_view * view)
992 {
993   sw_sample * s = view->sample;
994   sw_head * head = s->play_head;
995
996   sample_set_stop_offset (s);
997   sample_set_previewing (s, TRUE);
998   sample_set_scrubbing (s, FALSE);
999    
1000   prev_sample = s;
1001
1002   head_set_restricted (head, FALSE);
1003
1004   sample_play (s);
1005 }
1006
1007 void
1008 play_preview_cut (sw_view * view)
1009 {
1010   sw_sample * s = view->sample;
1011   sw_head * head = s->play_head;
1012
1013   if (s->sounddata->sels == NULL) {
1014     head_set_going (head, FALSE);
1015     sample_refresh_playmode (s);
1016     return;
1017   }
1018
1019   sample_set_stop_offset (s);
1020   sample_set_previewing (s, TRUE);
1021   sample_set_scrubbing (s, FALSE);
1022    
1023   prev_sample = s;
1024
1025   head_set_restricted (head, TRUE);
1026
1027   sample_play (s);
1028 }
1029
1030 void
1031 play_view_all_pitch (sw_view * view, gfloat pitch)
1032 {
1033   sw_sample * s = view->sample;
1034   sw_head * head = s->play_head;
1035   sw_framecount_t mouse_offset;
1036
1037   mouse_offset =
1038     sample_display_get_mouse_offset (SAMPLE_DISPLAY(view->display));
1039   sample_set_playmarker (s, mouse_offset, TRUE);
1040
1041   sample_set_stop_offset (s);
1042   sample_set_previewing (s, FALSE);
1043
1044   prev_sample = s;
1045
1046   head_set_restricted (head, FALSE);
1047   head_set_rate (head, pitch);
1048
1049   sample_play (s);
1050 }
1051
1052 void
1053 stop_all_playback (void)
1054 {
1055   stop_all = TRUE;
1056   g_list_free (active_main_heads);
1057   active_main_heads = NULL;
1058 }
1059
1060 void
1061 pause_playback (sw_sample * s)
1062 {
1063   sw_head * head;
1064
1065   if (s == NULL) return;
1066
1067   head = s->play_head;
1068
1069   if (head->going) {
1070     head_set_going (head, FALSE);
1071   }
1072
1073   sample_set_stop_offset (s);
1074 }
1075
1076 void
1077 stop_playback (sw_sample * s)
1078 {
1079   sw_head * head;
1080
1081   if (s == NULL) return;
1082
1083   head = s->play_head;
1084
1085   if (head->going) {
1086     head_set_going (head, FALSE);
1087     sample_set_playmarker (s, head->stop_offset, TRUE);
1088
1089     g_mutex_lock (play_mutex);
1090     active_main_heads = g_list_remove (active_main_heads, head);
1091     g_mutex_unlock (play_mutex);
1092   }
1093 }
1094
1095 gboolean
1096 any_playing (void)
1097 {
1098   return ((player_thread != (pthread_t) -1) && (active_main_heads != NULL));
1099 }
1100
1101 void
1102 init_playback (void)
1103 {
1104   play_mutex = g_mutex_new ();
1105 }
Note: See TracBrowser for help on using the browser.