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