soc-2008-mxcurioni: foundations for Freestyle as a render layer - new UI buttons...
[blender.git] / source / blender / src / seqaudio.c
1 /*
2  *  $Id$
3  *
4  * ***** BEGIN GPL LICENSE BLOCK *****
5  *
6  * This program is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU General Public License
8  * as published by the Free Software Foundation; either version 2
9  * of the License, or (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 Foundation,
18  * Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
19  *
20  * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
21  * All rights reserved.
22  *
23  * The Original Code is: all of this file.
24  *
25  * Contributor(s): intrr, Peter Schlaile
26  *
27  * ***** END GPL LICENSE BLOCK *****
28  */
29
30 #include <math.h>
31 #include <stdlib.h>
32 #include <string.h>
33
34 #ifndef WIN32
35 #define __USE_XOPEN /* Needed for swab on linux */
36 #include <unistd.h>
37 #undef __USE_XOPEN
38 #else
39 #include <io.h>
40 #endif   
41
42 #include <fcntl.h>
43 #include <stdio.h>
44
45 #include "MEM_guardedalloc.h"
46
47 #include "PIL_time.h"
48
49 #include "BMF_Api.h"
50
51 #include "BLI_blenlib.h"
52 #include "BLI_arithb.h"
53
54 #include "DNA_screen_types.h"
55 #include "DNA_sound_types.h"
56 #include "DNA_userdef_types.h"
57 #include "DNA_sequence_types.h"
58 #include "DNA_scene_types.h"
59 #include "DNA_ipo_types.h"
60
61 #include "BKE_utildefines.h"
62 #include "BKE_global.h"
63 #include "BKE_library.h" 
64 #include "BKE_blender.h" 
65 #include "BKE_main.h"    
66 #include "BKE_ipo.h"
67
68 #include "BIF_gl.h"
69 #include "BIF_graphics.h"
70 #include "BIF_keyval.h"
71 #include "BIF_mainqueue.h"
72 #include "BIF_resources.h"
73 #include "BIF_screen.h"
74 #include "BIF_toolbox.h"
75 #include "BIF_mywindow.h"
76 #include "BIF_space.h"
77 #include "BIF_glutil.h"
78 #include "BIF_interface.h"
79
80 #include "BSE_view.h"
81 #include "BSE_seqaudio.h"
82 #include "BIF_editsound.h"
83
84 #include "mydevice.h"
85 #include "blendef.h"
86
87
88 void audio_fill(void *mixdown, Uint8 *sstream, int len);
89 /* ************ GLOBALS ************* */
90
91 static int audio_pos;
92 static int audio_scrub=0;
93 static int audio_playing=0;
94 static int audio_initialised=0;
95 static int audio_startframe=0;
96 static double audio_starttime = 0.0;
97 /////
98 //
99 /* local protos ------------------- */
100 void audio_mixdown(void);
101
102 void makewavstring (char *string) 
103 {
104         char txt[64];
105
106         if (string==0) return;
107
108         strcpy(string, G.scene->r.pic);
109         BLI_convertstringcode(string, G.sce);
110
111         BLI_make_existing_file(string);
112
113         if (BLI_strcasecmp(string + strlen(string) - 4, ".wav")) {
114                 sprintf(txt, "%04d_%04d.wav", (G.scene->r.sfra) , (G.scene->r.efra) );
115                 strcat(string, txt);
116         }
117 }
118
119 void audio_mixdown()
120 {
121         int file, c, totlen, totframe, i, oldcfra;
122         char *buf;
123
124         buf = MEM_mallocN(65536, "audio_mixdown");
125         makewavstring(buf);
126
127         file = open(buf, O_BINARY+O_WRONLY+O_CREAT+O_TRUNC, 0666);
128
129         if(file == -1) 
130         {
131                 error("Can't open output file");
132                 return;
133         }
134         
135         waitcursor(1);
136         
137         printf("Saving: %s ", buf);
138
139         strcpy(buf, "RIFFlengWAVEfmt fmln01ccRATEbsecBP16dataDLEN");
140         totframe = (EFRA - SFRA + 1);
141         totlen = (int) ( FRA2TIME(totframe) * (float)G.scene->audio.mixrate * 4.0);
142         printf(" totlen %d\n", totlen+36+8);
143         
144         totlen+= 36;    /* len is filesize-8 in WAV spec, total header is 44 bytes */
145         memcpy(buf+4, &totlen, 4);
146         totlen-= 36;
147         
148         buf[16] = 0x10; buf[17] = buf[18] = buf[19] = 0; buf[20] = 1; buf[21] = 0;
149         buf[22] = 2; buf[23]= 0;
150         memcpy(buf+24, &G.scene->audio.mixrate, 4);
151         i = G.scene->audio.mixrate * 4;
152         memcpy(buf+28, &i, 4);
153         buf[32] = 4; buf[33] = 0; buf[34] = 16; buf[35] = 0;
154         i = totlen;
155         memcpy(buf+40, &i, 4);
156
157         if (G.order == B_ENDIAN) {
158                 /* swap the four ints to little endian */
159                 
160                 /* length */
161                 SWITCH_INT(buf[4]);
162                 
163                 /* audio rate */
164                 SWITCH_INT(buf[24]);
165
166                 /* audio mixrate * 4 */
167                 SWITCH_INT(buf[28]);
168                 
169                 /* length */
170                 SWITCH_INT(buf[40]);
171         }
172         
173         c = write(file, buf, 44);
174         
175         oldcfra = CFRA;
176         audiostream_play(SFRA, 0, 1);
177         
178         i= 0;
179         while ( totlen > 0 ) {
180                 totlen -= 64;
181                 
182                 memset(buf+i, 0, 64);
183                 
184                 CFRA=(int) ( ((float)(audio_pos-64)/( G.scene->audio.mixrate*4 ))*FPS );
185                         
186                 audio_fill(buf+i, NULL, 64);
187                 if (G.order == B_ENDIAN) {
188                         char tbuf[64];
189                         memcpy(tbuf, buf+i, 64);
190                         swab(tbuf, buf+i, 64);
191                 }
192                 if (i == (65536-64)) {
193                         i=0;
194                         write(file, buf, 65536);                        
195                 } 
196                 else i+=64;
197         }
198         write(file, buf, i);
199         
200         waitcursor(0);
201         CFRA = oldcfra;
202         close(file);
203         MEM_freeN(buf);
204
205         return;
206 }
207
208 void audiostream_fill(Uint8 *mixdown, int len)
209 {    
210         int oldcfra = CFRA;
211         int i;
212
213         memset(mixdown, 0, len);
214
215         for (i = 0; i < len; i += 64) {
216                 CFRA = (int) ( ((float)(audio_pos-64)
217                                 /( G.scene->audio.mixrate*4 ))
218                                * FPS );
219
220                 audio_fill(mixdown + i, NULL, 
221                            (len - i) > 64 ? 64 : (len - i));
222         }
223
224         CFRA = oldcfra;
225 }
226
227
228 static void audio_levels(Uint8 *buf, int len, float db, float facf, float pan)
229 {
230         int i;
231         float facl, facr, fac;
232         signed short *sample;
233         
234         if (pan>=0) { facr = 1.0; facl = 1.0-pan; }
235                else { facr = pan+1.0; facl = 1.0; }
236         
237         fac = pow(10.0, ((-(db+G.scene->audio.main))/20.0)) / facf;
238         facl /= fac;
239         facr /= fac;
240         
241         for (i=0; i<len; i+=4) {
242                 sample = (signed short*)(buf+i);
243                 sample[0] = (short) ((float)sample[0] * facl);
244                 sample[1] = (short) ((float)sample[1] * facr);
245         }
246 }
247
248 /* convert mono/stereo and sampling rate, alloc a buffer for
249  * sound->stream to contain the new sample, and set sound->streamlen
250  * accordingly.
251  */
252 void audio_makestream(bSound *sound)
253 {
254         signed short *source, *dest;
255         float ratio;
256         int i;
257
258         if ( (!sound)||(sound->stream)||(!sound->sample)||(!G.scene) ) {
259                 return;
260         }
261         ratio = (float)G.scene->audio.mixrate / (float)sound->sample->rate;
262         sound->streamlen = (int) ( (float)sound->sample->len * ratio * 2.0/((float)sound->sample->channels) );
263         sound->stream = malloc((int) ((float)sound->streamlen * 1.05));
264         if (sound->sample->rate == G.scene->audio.mixrate) {
265                 if (sound->sample->channels == 2) {
266                         memcpy(sound->stream, sound->sample->data, sound->streamlen);
267                         return;
268                 } else {
269                         for (source = (signed short*)(sound->sample->data),
270                              dest = (signed short*)(sound->stream),
271                                  i=0;
272                                  i<sound->streamlen/4;
273                                  dest += 2, source++, i++) dest[0] = dest[1] = source[0];
274                         return;
275                 }
276         }
277         if (sound->sample->channels == 1) {
278                 for (dest=(signed short*)(sound->stream), i=0, source=(signed short*)(sound->sample->data); 
279                      i<(sound->streamlen/4); dest+=2, i++)
280                         dest[0] = dest[1] = source[(int)((float)i/ratio)];
281         }
282         else if (sound->sample->channels == 2) {
283                 for (dest=(signed short*)(sound->stream), i=0, source=(signed short*)(sound->sample->data); 
284                      i<(sound->streamlen/2); dest+=2, i+=2) {
285                         dest[1] = source[(int)((float)i/ratio)];
286                         dest[0] = source[(int)((float)i/ratio)+1];                      
287                 }
288         }       
289 }
290
291 static void audio_fill_ram_sound(Sequence *seq, void * mixdown, 
292                                  Uint8 * sstream, int len)
293 {
294         Uint8* cvtbuf;
295         bSound* sound;
296         float facf;
297
298         sound = seq->sound;
299         audio_makestream(sound);
300         if ((seq->curpos<sound->streamlen -len) && (seq->curpos>=0) &&
301             (seq->startdisp <= CFRA) && ((seq->enddisp) > CFRA))
302         {
303                 if(seq->ipo && seq->ipo->curve.first) {
304                         do_seq_ipo(seq, CFRA);
305                         facf = seq->facf0;
306                 } else {
307                         facf = 1.0;
308                 }
309                 cvtbuf = malloc(len);                                   
310                 memcpy(cvtbuf, ((Uint8*)sound->stream)+(seq->curpos & (~3)), len);
311                 audio_levels(cvtbuf, len, seq->level, facf, seq->pan);
312                 if (!mixdown) {
313                         SDL_MixAudio(sstream, cvtbuf, len, SDL_MIX_MAXVOLUME);
314                 } else {
315                         SDL_MixAudio((Uint8*)mixdown, cvtbuf, len, SDL_MIX_MAXVOLUME);
316                 }
317                 free(cvtbuf);
318         }
319         seq->curpos += len;
320 }
321
322 static void audio_fill_hd_sound(Sequence *seq, 
323                                 void * mixdown, Uint8 * sstream, 
324                                 int len)
325 {
326         Uint8* cvtbuf;
327         float facf;
328
329         if ((seq->curpos >= 0) &&
330             (seq->startdisp <= CFRA) && ((seq->enddisp) > CFRA))
331         {
332                 if(seq->ipo && seq->ipo->curve.first) {
333                         do_seq_ipo(seq, CFRA);
334                         facf = seq->facf0; 
335                 } else {
336                         facf = 1.0;
337                 }
338                 cvtbuf = malloc(len);
339                 
340                 sound_hdaudio_extract(seq->hdaudio, (short*) cvtbuf,
341                                       seq->curpos / 4,
342                                       G.scene->audio.mixrate,
343                                       2,
344                                       len / 4);
345                 audio_levels(cvtbuf, len, seq->level, facf, seq->pan);
346                 if (!mixdown) {
347                         SDL_MixAudio(sstream, 
348                                      cvtbuf, len, SDL_MIX_MAXVOLUME);
349                 } else {
350                         SDL_MixAudio((Uint8*)mixdown, 
351                                      cvtbuf, len, SDL_MIX_MAXVOLUME);
352                 }
353                 free(cvtbuf);
354         }
355         seq->curpos += len;
356 }
357
358 static void audio_fill_seq(Sequence * seq, void * mixdown,
359                            Uint8 *sstream, int len, int advance_only)
360 {
361         while(seq) {
362                 if (seq->type == SEQ_META &&
363                     (!(seq->flag & SEQ_MUTE))) {
364                         if (seq->startdisp <= CFRA && seq->enddisp > CFRA) {
365                                 audio_fill_seq(seq->seqbase.first,
366                                                mixdown, sstream, len, 
367                                                advance_only);
368                         } else {
369                                 audio_fill_seq(seq->seqbase.first,
370                                                mixdown, sstream, len, 
371                                                1);
372                         }
373                 }
374                 if ( (seq->type == SEQ_RAM_SOUND) &&
375                      (seq->sound) &&
376                      (!(seq->flag & SEQ_MUTE))) {
377                         if (advance_only) {
378                                 seq->curpos += len;
379                         } else {
380                                 audio_fill_ram_sound(
381                                         seq, mixdown, sstream, len);
382                         }
383                 }
384                 if ( (seq->type == SEQ_HD_SOUND) &&
385                      (!(seq->flag & SEQ_MUTE))) {
386                         if (advance_only) {
387                                 seq->curpos += len;
388                         } else {
389                                 if (!seq->hdaudio) {
390                                         char name[FILE_MAXDIR+FILE_MAXFILE];
391
392                                         strncpy(name, seq->strip->dir, 
393                                                 FILE_MAXDIR-1);
394                                         strncat(name, 
395                                                 seq->strip->stripdata->name, 
396                                                 FILE_MAXFILE-1);
397                                         BLI_convertstringcode(name, G.sce);
398                                 
399                                         seq->hdaudio= sound_open_hdaudio(name);
400                                 }
401                                 if (seq->hdaudio) {
402                                         audio_fill_hd_sound(seq, mixdown, 
403                                                             sstream, len);
404                                 }
405                         }
406                 }
407                 seq = seq->next;
408         }
409 }
410
411 void audio_fill(void *mixdown, Uint8 *sstream, int len)
412 {    
413         Editing *ed;
414         Sequence *seq;
415
416         ed = G.scene->ed;
417         if((ed) && (!(G.scene->audio.flag & AUDIO_MUTE))) {
418                 seq = ed->seqbasep->first;
419                 audio_fill_seq(seq, mixdown, sstream, len, 0);
420         }
421        
422         audio_pos += len;    
423         if (audio_scrub) { 
424                 audio_scrub--;
425                 if (!audio_scrub) {
426                         audiostream_stop();
427                 }
428         }
429 }    
430
431 static int audio_init(SDL_AudioSpec *desired)
432 {
433         SDL_AudioSpec *obtained, *hardware_spec;
434
435         SDL_CloseAudio();
436
437         obtained = (SDL_AudioSpec*)MEM_mallocN(sizeof(SDL_AudioSpec), 
438                                                "SDL_AudioSpec");
439
440         desired->callback=audio_fill;
441
442         if ( SDL_OpenAudio(desired, obtained) < 0 ) {
443                 fprintf(stderr, "Couldn't open audio: %s\n", SDL_GetError());
444                 if (obtained) MEM_freeN(obtained);
445                 return 0;
446         }
447         audio_initialised = 1;
448         hardware_spec=obtained;
449         
450         MEM_freeN(obtained);
451
452         SDL_PauseAudio(0);
453         return 1;
454 }
455
456 static int audiostream_play_seq(Sequence * seq, Uint32 startframe)
457 {
458         char name[FILE_MAXDIR+FILE_MAXFILE];
459         int have_sound = 0;
460
461         while(seq) {
462                 if (seq->type == SEQ_META) {
463                         if (audiostream_play_seq(
464                                     seq->seqbase.first, startframe)) {
465                                 have_sound = 1;
466                         }
467                 }
468                 if ((seq->type == SEQ_RAM_SOUND) && (seq->sound)) {
469                         have_sound = 1;
470                         seq->curpos = (int)( (FRA2TIME(
471                                                       (double) startframe -
472                                                       (double) seq->start +
473                                                       (double) 
474                                                       seq->anim_startofs)
475                                               * ((float)G.scene->audio.mixrate)
476                                               * 4 ));
477                 }
478                 if ((seq->type == SEQ_HD_SOUND)) {
479                         have_sound = 1;
480                         if (!seq->hdaudio) {
481                                 strncpy(name, seq->strip->dir, FILE_MAXDIR-1);
482                                 strncat(name, seq->strip->stripdata->name, 
483                                         FILE_MAXFILE-1);
484                                 
485                                 seq->hdaudio = sound_open_hdaudio(name);
486                         }
487                         seq->curpos = (int)( (FRA2TIME((double) startframe - 
488                                                        (double) seq->start +
489                                                        (double)
490                                                        seq->anim_startofs)
491                                               * ((float)G.scene->audio.mixrate)
492                                               * 4 ));
493                 }
494                 seq= seq->next;
495         }
496         return have_sound;
497 }
498
499 void audiostream_play(Uint32 startframe, Uint32 duration, int mixdown)
500 {
501         static SDL_AudioSpec desired;
502         Editing *ed;
503         int have_sound = 0;
504
505         ed= G.scene->ed;
506         if(ed) {
507                 have_sound = 
508                         audiostream_play_seq(ed->seqbasep->first, startframe);
509         }
510
511         if(have_sound) {
512                 /* this call used to be in startup */
513                 sound_init_audio();
514         }
515
516         if (U.mixbufsize && !audio_initialised && !mixdown) {
517                 desired.freq=G.scene->audio.mixrate;
518                 desired.format=AUDIO_S16SYS;
519                 desired.channels=2;
520                 desired.samples=U.mixbufsize;
521                 desired.userdata=0;
522
523                 if (audio_init(&desired)==0) {
524                         U.mixbufsize = 0;       /* no audio */
525                 }
526         }
527
528         audio_startframe = startframe;
529         audio_pos = ( ((int)( FRA2TIME(startframe)
530                               *(G.scene->audio.mixrate)*4 )) & (~3) );
531         audio_starttime = PIL_check_seconds_timer();
532
533         /* if audio already is playing, just reseek, otherwise
534            remember scrub-duration */
535         if (!(audio_playing && !audio_scrub)) {
536                 audio_scrub = duration;
537         }
538         if (!mixdown) {
539                 SDL_PauseAudio(0);
540                 audio_playing++;
541         }
542 }
543
544 void audiostream_start(Uint32 frame)
545 {
546         audiostream_play(frame, 0, 0);
547 }
548
549 void audiostream_scrub(Uint32 frame)
550 {
551         if (U.mixbufsize) audiostream_play(frame, 4096/U.mixbufsize, 0);
552 }
553
554 void audiostream_stop(void)
555 {
556         SDL_PauseAudio(1);
557         audio_playing=0;
558 }
559
560 int audiostream_pos(void) 
561 {
562         int pos;
563
564         if (U.mixbufsize) {
565                 pos = (int) (((double)(audio_pos-U.mixbufsize)
566                               / ( G.scene->audio.mixrate*4 ))
567                              * FPS );
568         } else { /* fallback to seconds_timer when no audio available */
569                 pos = (int) ((PIL_check_seconds_timer() - audio_starttime) 
570                              * FPS);
571         }
572
573         if (pos < audio_startframe) pos = audio_startframe;
574         return ( pos );
575 }
576