== Core ==
[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 /////
100 //
101 /* local protos ------------------- */
102 void audio_mixdown(void);
103
104 void makewavstring (char *string) 
105 {
106         char txt[64];
107
108         if (string==0) return;
109
110         strcpy(string, G.scene->r.pic);
111         BLI_convertstringcode(string, G.sce, G.scene->r.cfra);
112
113         BLI_make_existing_file(string);
114
115         if (BLI_strcasecmp(string + strlen(string) - 4, ".wav")) {
116                 sprintf(txt, "%04d_%04d.wav", (G.scene->r.sfra) , (G.scene->r.efra) );
117                 strcat(string, txt);
118         }
119 }
120
121 void audio_mixdown()
122 {
123         int file, c, totlen, totframe, i, oldcfra;
124         char *buf;
125
126         buf = MEM_mallocN(65536, "audio_mixdown");
127         makewavstring(buf);
128
129         file = open(buf, O_BINARY+O_WRONLY+O_CREAT+O_TRUNC, 0666);
130
131         if(file == -1) 
132         {
133                 error("Can't open output file");
134                 return;
135         }
136         
137         waitcursor(1);
138         
139         printf("Saving: %s ", buf);
140
141         strcpy(buf, "RIFFlengWAVEfmt fmln01ccRATEbsecBP16dataDLEN");
142         totframe = (EFRA - SFRA + 1);
143         totlen = (int) ( FRA2TIME(totframe) * (float)G.scene->audio.mixrate * 4.0);
144         printf(" totlen %d\n", totlen+36+8);
145         
146         totlen+= 36;    /* len is filesize-8 in WAV spec, total header is 44 bytes */
147         memcpy(buf+4, &totlen, 4);
148         totlen-= 36;
149         
150         buf[16] = 0x10; buf[17] = buf[18] = buf[19] = 0; buf[20] = 1; buf[21] = 0;
151         buf[22] = 2; buf[23]= 0;
152         memcpy(buf+24, &G.scene->audio.mixrate, 4);
153         i = G.scene->audio.mixrate * 4;
154         memcpy(buf+28, &i, 4);
155         buf[32] = 4; buf[33] = 0; buf[34] = 16; buf[35] = 0;
156         i = totlen;
157         memcpy(buf+40, &i, 4);
158
159         if (G.order == B_ENDIAN) {
160                 /* swap the four ints to little endian */
161                 
162                 /* length */
163                 SWITCH_INT(buf[4]);
164                 
165                 /* audio rate */
166                 SWITCH_INT(buf[24]);
167
168                 /* audio mixrate * 4 */
169                 SWITCH_INT(buf[28]);
170                 
171                 /* length */
172                 SWITCH_INT(buf[40]);
173         }
174         
175         c = write(file, buf, 44);
176         
177         oldcfra = CFRA;
178         audiostream_play(SFRA, 0, 1);
179         
180         i= 0;
181         while ( totlen > 0 ) {
182                 totlen -= 64;
183                 
184                 memset(buf+i, 0, 64);
185                 
186                 CFRA=(int) ( ((float)(audio_pos-64)/( G.scene->audio.mixrate*4 ))*FPS );
187                         
188                 audio_fill(buf+i, NULL, 64);
189                 if (G.order == B_ENDIAN) {
190                         char tbuf[64];
191                         memcpy(tbuf, buf+i, 64);
192                         swab(tbuf, buf+i, 64);
193                 }
194                 if (i == (65536-64)) {
195                         i=0;
196                         write(file, buf, 65536);                        
197                 } 
198                 else i+=64;
199         }
200         write(file, buf, i);
201         
202         waitcursor(0);
203         CFRA = oldcfra;
204         close(file);
205         MEM_freeN(buf);
206
207         return;
208 }
209
210 void audiostream_fill(Uint8 *mixdown, int len)
211 {    
212         int oldcfra = CFRA;
213         int i;
214
215         memset(mixdown, 0, len);
216
217         for (i = 0; i < len; i += 64) {
218                 CFRA = (int) ( ((float)(audio_pos-64)
219                                 /( G.scene->audio.mixrate*4 ))
220                                * FPS );
221
222                 audio_fill(mixdown + i, NULL, 
223                            (len - i) > 64 ? 64 : (len - i));
224         }
225
226         CFRA = oldcfra;
227 }
228
229
230 static void audio_levels(Uint8 *buf, int len, float db, float facf, float pan)
231 {
232         int i;
233         float facl, facr, fac;
234         signed short *sample;
235         
236         if (pan>=0) { facr = 1.0; facl = 1.0-pan; }
237                else { facr = pan+1.0; facl = 1.0; }
238         
239         fac = pow(10.0, ((-(db+G.scene->audio.main))/20.0)) / facf;
240         facl /= fac;
241         facr /= fac;
242         
243         for (i=0; i<len; i+=4) {
244                 sample = (signed short*)(buf+i);
245                 sample[0] = (short) ((float)sample[0] * facl);
246                 sample[1] = (short) ((float)sample[1] * facr);
247         }
248 }
249
250 /* convert mono/stereo and sampling rate, alloc a buffer for
251  * sound->stream to contain the new sample, and set sound->streamlen
252  * accordingly.
253  */
254 void audio_makestream(bSound *sound)
255 {
256         signed short *source, *dest;
257         float ratio;
258         int i;
259
260         if ( (!sound)||(sound->stream)||(!sound->sample)||(!G.scene) ) {
261                 return;
262         }
263         ratio = (float)G.scene->audio.mixrate / (float)sound->sample->rate;
264         sound->streamlen = (int) ( (float)sound->sample->len * ratio * 2.0/((float)sound->sample->channels) );
265         sound->stream = malloc((int) ((float)sound->streamlen * 1.05));
266         if (sound->sample->rate == G.scene->audio.mixrate) {
267                 if (sound->sample->channels == 2) {
268                         memcpy(sound->stream, sound->sample->data, sound->streamlen);
269                         return;
270                 } else {
271                         for (source = (signed short*)(sound->sample->data),
272                              dest = (signed short*)(sound->stream),
273                                  i=0;
274                                  i<sound->streamlen/4;
275                                  dest += 2, source++, i++) dest[0] = dest[1] = source[0];
276                         return;
277                 }
278         }
279         if (sound->sample->channels == 1) {
280                 for (dest=(signed short*)(sound->stream), i=0, source=(signed short*)(sound->sample->data); 
281                      i<(sound->streamlen/4); dest+=2, i++)
282                         dest[0] = dest[1] = source[(int)((float)i/ratio)];
283         }
284         else if (sound->sample->channels == 2) {
285                 for (dest=(signed short*)(sound->stream), i=0, source=(signed short*)(sound->sample->data); 
286                      i<(sound->streamlen/2); dest+=2, i+=2) {
287                         dest[1] = source[(int)((float)i/ratio)];
288                         dest[0] = source[(int)((float)i/ratio)+1];                      
289                 }
290         }       
291 }
292
293 static void audio_fill_ram_sound(Sequence *seq, void * mixdown, 
294                                  Uint8 * sstream, int len)
295 {
296         Uint8* cvtbuf;
297         bSound* sound;
298         float facf;
299
300         sound = seq->sound;
301         audio_makestream(sound);
302         if ((seq->curpos<sound->streamlen -len) && (seq->curpos>=0) &&
303             (seq->startdisp <= CFRA) && ((seq->enddisp) > CFRA))
304         {
305                 if(seq->ipo && seq->ipo->curve.first) {
306                         do_seq_ipo(seq);
307                         facf = seq->facf0;
308                 } else {
309                         facf = 1.0;
310                 }
311                 cvtbuf = malloc(len);                                   
312                 memcpy(cvtbuf, ((Uint8*)sound->stream)+(seq->curpos & (~3)), len);
313                 audio_levels(cvtbuf, len, seq->level, facf, seq->pan);
314                 if (!mixdown) {
315                         SDL_MixAudio(sstream, cvtbuf, len, SDL_MIX_MAXVOLUME);
316                 } else {
317                         SDL_MixAudio((Uint8*)mixdown, cvtbuf, len, SDL_MIX_MAXVOLUME);
318                 }
319                 free(cvtbuf);
320         }
321         seq->curpos += len;
322 }
323
324 static void audio_fill_hd_sound(Sequence *seq, 
325                                 void * mixdown, Uint8 * sstream, 
326                                 int len)
327 {
328         Uint8* cvtbuf;
329         float facf;
330
331         if ((seq->curpos >= 0) &&
332             (seq->startdisp <= CFRA) && ((seq->enddisp) > CFRA))
333         {
334                 if(seq->ipo && seq->ipo->curve.first) {
335                         do_seq_ipo(seq);
336                         facf = seq->facf0; 
337                 } else {
338                         facf = 1.0;
339                 }
340                 cvtbuf = malloc(len);
341                 
342                 sound_hdaudio_extract(seq->hdaudio, (short*) cvtbuf,
343                                       seq->curpos / 4,
344                                       G.scene->audio.mixrate,
345                                       2,
346                                       len / 4);
347                 audio_levels(cvtbuf, len, seq->level, facf, seq->pan);
348                 if (!mixdown) {
349                         SDL_MixAudio(sstream, 
350                                      cvtbuf, len, SDL_MIX_MAXVOLUME);
351                 } else {
352                         SDL_MixAudio((Uint8*)mixdown, 
353                                      cvtbuf, len, SDL_MIX_MAXVOLUME);
354                 }
355                 free(cvtbuf);
356         }
357         seq->curpos += len;
358 }
359
360 static void audio_fill_seq(Sequence * seq, void * mixdown,
361                            Uint8 *sstream, int len)
362 {
363         while(seq) {
364                 if (seq->type == SEQ_META) {
365                         audio_fill_seq(seq->seqbase.first,
366                                        mixdown, sstream, len);
367                 }
368                 if ( (seq->type == SEQ_RAM_SOUND) &&
369                      (seq->sound) &&
370                      (!(seq->flag & SEQ_MUTE))) {
371                         audio_fill_ram_sound(seq, mixdown, sstream, len);
372                 }
373                 if ( (seq->type == SEQ_HD_SOUND) &&
374                      (!(seq->flag & SEQ_MUTE))) {
375                         if (!seq->hdaudio) {
376                                 char name[FILE_MAXDIR+FILE_MAXFILE];
377
378                                 strncpy(name, seq->strip->dir, 
379                                         FILE_MAXDIR-1);
380                                 strncat(name, 
381                                         seq->strip->stripdata->name, 
382                                         FILE_MAXFILE-1);
383                                 BLI_convertstringcode(name, G.sce, 
384                                                       G.scene->r.cfra);
385                                 
386                                 seq->hdaudio= sound_open_hdaudio(name);
387                         }
388                         if (seq->hdaudio) {
389                                 audio_fill_hd_sound(seq, mixdown, 
390                                                     sstream, len);
391                         }
392                 }
393                 seq = seq->next;
394         }
395 }
396
397 void audio_fill(void *mixdown, Uint8 *sstream, int len)
398 {    
399         Editing *ed;
400         Sequence *seq;
401
402         ed = G.scene->ed;
403         if((ed) && (!(G.scene->audio.flag & AUDIO_MUTE))) {
404                 seq = ed->seqbasep->first;
405                 audio_fill_seq(seq, mixdown, sstream, len);
406         }
407        
408         audio_pos += len;    
409         if (audio_scrub) { 
410                 audio_scrub--;
411                 if (!audio_scrub) {
412                         audiostream_stop();
413                 }
414         }
415 }    
416
417 static int audio_init(SDL_AudioSpec *desired)
418 {
419         SDL_AudioSpec *obtained, *hardware_spec;
420
421         SDL_CloseAudio();
422
423         obtained = (SDL_AudioSpec*)MEM_mallocN(sizeof(SDL_AudioSpec), 
424                                                "SDL_AudioSpec");
425
426         desired->callback=audio_fill;
427
428         if ( SDL_OpenAudio(desired, obtained) < 0 ) {
429                 fprintf(stderr, "Couldn't open audio: %s\n", SDL_GetError());
430                 if (obtained) MEM_freeN(obtained);
431                 return 0;
432         }
433         audio_initialised = 1;
434         hardware_spec=obtained;
435         
436         MEM_freeN(obtained);
437
438         SDL_PauseAudio(0);
439         return 1;
440 }
441
442 static int audiostream_play_seq(Sequence * seq, Uint32 startframe)
443 {
444         char name[FILE_MAXDIR+FILE_MAXFILE];
445         int have_sound = 0;
446
447         while(seq) {
448                 if (seq->type == SEQ_META) {
449                         if (audiostream_play_seq(
450                                     seq->seqbase.first, startframe)) {
451                                 have_sound = 1;
452                         }
453                 }
454                 if ((seq->type == SEQ_RAM_SOUND) && (seq->sound)) {
455                         have_sound = 1;
456                         seq->curpos = (int)( (FRA2TIME((double) startframe -
457                                                        (double) seq->start)
458                                               * ((float)G.scene->audio.mixrate)
459                                               * 4 ));
460                 }
461                 if ((seq->type == SEQ_HD_SOUND)) {
462                         have_sound = 1;
463                         if (!seq->hdaudio) {
464                                 strncpy(name, seq->strip->dir, FILE_MAXDIR-1);
465                                 strncat(name, seq->strip->stripdata->name, 
466                                         FILE_MAXFILE-1);
467                                 
468                                 seq->hdaudio = sound_open_hdaudio(name);
469                         }
470                         seq->curpos = (int)( (FRA2TIME((double) startframe - 
471                                                        (double) seq->start)
472                                               * ((float)G.scene->audio.mixrate)
473                                               * 4 ));
474                 }
475                 seq= seq->next;
476         }
477         return have_sound;
478 }
479
480 void audiostream_play(Uint32 startframe, Uint32 duration, int mixdown)
481 {
482         static SDL_AudioSpec desired;
483         Editing *ed;
484         int have_sound = 0;
485
486         ed= G.scene->ed;
487         if(ed) {
488                 have_sound = 
489                         audiostream_play_seq(ed->seqbasep->first, startframe);
490         }
491
492         if(have_sound) {
493                 /* this call used to be in startup */
494                 sound_init_audio();
495         }
496
497         if (!audio_initialised && !(duration + mixdown)) {
498                 desired.freq=G.scene->audio.mixrate;
499                 desired.format=AUDIO_S16SYS;
500                 desired.channels=2;
501                 desired.samples=U.mixbufsize;
502                 desired.userdata=0;     
503                 if (audio_init(&desired)==0) {
504                         U.mixbufsize = 0;       /* no audio */
505                 }
506         }
507
508         audio_startframe = startframe;
509         audio_pos = ( ((int)( FRA2TIME(startframe)
510                               *(G.scene->audio.mixrate)*4 )) & (~3) );
511         
512         audio_scrub = duration;
513         if (!mixdown) {
514                 SDL_PauseAudio(0);
515                 audio_playing++;
516         }
517 }
518
519 void audiostream_start(Uint32 frame)
520 {
521         audiostream_play(frame, 0, 0);
522 }
523
524 void audiostream_scrub(Uint32 frame)
525 {
526         if (U.mixbufsize) audiostream_play(frame, 4096/U.mixbufsize, 0);
527 }
528
529 void audiostream_stop(void)
530 {
531         SDL_PauseAudio(1);
532         audio_playing=0;
533 }
534
535 int audiostream_pos(void) 
536 {
537         int pos;
538         
539         pos = (int) (((double)(audio_pos-U.mixbufsize)
540                       / ( G.scene->audio.mixrate*4 ))
541                      * FPS );
542
543         if (pos < audio_startframe) pos = audio_startframe;
544         return ( pos );
545 }
546