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