2 * $Id: seqaudio.c 12979 2007-12-23 17:01:44Z schlaile $
4 * ***** BEGIN GPL/BL DUAL LICENSE BLOCK *****
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
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.
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.
23 * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
24 * All rights reserved.
26 * The Original Code is: all of this file.
28 * Contributor(s): intrr, Peter Schlaile
30 * ***** END GPL/BL DUAL LICENSE BLOCK *****
38 #define __USE_XOPEN /* Needed for swab on linux */
48 #include "MEM_guardedalloc.h"
54 #include "BLI_blenlib.h"
55 #include "BLI_arithb.h"
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"
64 #include "BKE_utildefines.h"
65 #include "BKE_global.h"
66 #include "BKE_library.h"
67 #include "BKE_blender.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"
84 #include "BSE_seqaudio.h"
85 #include "BIF_editsound.h"
91 void audio_fill(void *mixdown
, Uint8
*sstream
, int len
);
92 /* ************ GLOBALS ************* */
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;
102 /* local protos ------------------- */
103 void audio_mixdown(void);
105 void makewavstring (char *string
)
109 if (string
==0) return;
111 strcpy(string
, G
.scene
->r
.pic
);
112 BLI_convertstringcode(string
, G
.sce
, G
.scene
->r
.cfra
);
114 BLI_make_existing_file(string
);
116 if (BLI_strcasecmp(string
+ strlen(string
) - 4, ".wav")) {
117 sprintf(txt
, "%04d_%04d.wav", (G
.scene
->r
.sfra
) , (G
.scene
->r
.efra
) );
124 int file
, c
, totlen
, totframe
, i
, oldcfra
;
127 buf
= MEM_mallocN(65536, "audio_mixdown");
130 file
= open(buf
, O_BINARY
+O_WRONLY
+O_CREAT
+O_TRUNC
, 0666);
134 error("Can't open output file");
140 printf("Saving: %s ", buf
);
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);
147 totlen
+= 36; /* len is filesize-8 in WAV spec, total header is 44 bytes */
148 memcpy(buf
+4, &totlen
, 4);
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;
158 memcpy(buf
+40, &i
, 4);
160 if (G
.order
== B_ENDIAN
) {
161 /* swap the four ints to little endian */
169 /* audio mixrate * 4 */
176 c
= write(file
, buf
, 44);
179 audiostream_play(SFRA
, 0, 1);
182 while ( totlen
> 0 ) {
185 memset(buf
+i
, 0, 64);
187 CFRA
=(int) ( ((float)(audio_pos
-64)/( G
.scene
->audio
.mixrate
*4 ))*FPS
);
189 audio_fill(buf
+i
, NULL
, 64);
190 if (G
.order
== B_ENDIAN
) {
192 memcpy(tbuf
, buf
+i
, 64);
193 swab(tbuf
, buf
+i
, 64);
195 if (i
== (65536-64)) {
197 write(file
, buf
, 65536);
211 void audiostream_fill(Uint8
*mixdown
, int len
)
216 memset(mixdown
, 0, len
);
218 for (i
= 0; i
< len
; i
+= 64) {
219 CFRA
= (int) ( ((float)(audio_pos
-64)
220 /( G
.scene
->audio
.mixrate
*4 ))
223 audio_fill(mixdown
+ i
, NULL
,
224 (len
- i
) > 64 ? 64 : (len
- i
));
231 static void audio_levels(Uint8
*buf
, int len
, float db
, float facf
, float pan
)
234 float facl
, facr
, fac
;
235 signed short *sample
;
237 if (pan
>=0) { facr
= 1.0; facl
= 1.0-pan
; }
238 else { facr
= pan
+1.0; facl
= 1.0; }
240 fac
= pow(10.0, ((-(db
+G
.scene
->audio
.main
))/20.0)) / facf
;
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
);
251 /* convert mono/stereo and sampling rate, alloc a buffer for
252 * sound->stream to contain the new sample, and set sound->streamlen
255 void audio_makestream(bSound
*sound
)
257 signed short *source
, *dest
;
261 if ( (!sound
)||(sound
->stream
)||(!sound
->sample
)||(!G
.scene
) ) {
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
);
272 for (source
= (signed short*)(sound
->sample
->data
),
273 dest
= (signed short*)(sound
->stream
),
275 i
<sound
->streamlen
/4;
276 dest
+= 2, source
++, i
++) dest
[0] = dest
[1] = source
[0];
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
)];
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];
294 static void audio_fill_ram_sound(Sequence
*seq
, void * mixdown
,
295 Uint8
* sstream
, int len
)
302 audio_makestream(sound
);
303 if ((seq
->curpos
<sound
->streamlen
-len
) && (seq
->curpos
>=0) &&
304 (seq
->startdisp
<= CFRA
) && ((seq
->enddisp
) > CFRA
))
306 if(seq
->ipo
&& seq
->ipo
->curve
.first
) {
312 cvtbuf
= malloc(len
);
313 memcpy(cvtbuf
, ((Uint8
*)sound
->stream
)+(seq
->curpos
& (~3)), len
);
314 audio_levels(cvtbuf
, len
, seq
->level
, facf
, seq
->pan
);
316 SDL_MixAudio(sstream
, cvtbuf
, len
, SDL_MIX_MAXVOLUME
);
318 SDL_MixAudio((Uint8
*)mixdown
, cvtbuf
, len
, SDL_MIX_MAXVOLUME
);
325 static void audio_fill_hd_sound(Sequence
*seq
,
326 void * mixdown
, Uint8
* sstream
,
332 if ((seq
->curpos
>= 0) &&
333 (seq
->startdisp
<= CFRA
) && ((seq
->enddisp
) > CFRA
))
335 if(seq
->ipo
&& seq
->ipo
->curve
.first
) {
341 cvtbuf
= malloc(len
);
343 sound_hdaudio_extract(seq
->hdaudio
, (short*) cvtbuf
,
345 G
.scene
->audio
.mixrate
,
348 audio_levels(cvtbuf
, len
, seq
->level
, facf
, seq
->pan
);
350 SDL_MixAudio(sstream
,
351 cvtbuf
, len
, SDL_MIX_MAXVOLUME
);
353 SDL_MixAudio((Uint8
*)mixdown
,
354 cvtbuf
, len
, SDL_MIX_MAXVOLUME
);
361 static void audio_fill_seq(Sequence
* seq
, void * mixdown
,
362 Uint8
*sstream
, int len
, int advance_only
)
365 if (seq
->type
== SEQ_META
&&
366 (!(seq
->flag
& SEQ_MUTE
))) {
367 if (seq
->startdisp
<= CFRA
&& seq
->enddisp
> CFRA
) {
368 audio_fill_seq(seq
->seqbase
.first
,
369 mixdown
, sstream
, len
,
372 audio_fill_seq(seq
->seqbase
.first
,
373 mixdown
, sstream
, len
,
377 if ( (seq
->type
== SEQ_RAM_SOUND
) &&
379 (!(seq
->flag
& SEQ_MUTE
))) {
383 audio_fill_ram_sound(
384 seq
, mixdown
, sstream
, len
);
387 if ( (seq
->type
== SEQ_HD_SOUND
) &&
388 (!(seq
->flag
& SEQ_MUTE
))) {
393 char name
[FILE_MAXDIR
+FILE_MAXFILE
];
395 strncpy(name
, seq
->strip
->dir
,
398 seq
->strip
->stripdata
->name
,
400 BLI_convertstringcode(name
, G
.sce
,
403 seq
->hdaudio
= sound_open_hdaudio(name
);
406 audio_fill_hd_sound(seq
, mixdown
,
415 void audio_fill(void *mixdown
, Uint8
*sstream
, int len
)
421 if((ed
) && (!(G
.scene
->audio
.flag
& AUDIO_MUTE
))) {
422 seq
= ed
->seqbasep
->first
;
423 audio_fill_seq(seq
, mixdown
, sstream
, len
, 0);
435 static int audio_init(SDL_AudioSpec
*desired
)
437 SDL_AudioSpec
*obtained
, *hardware_spec
;
441 obtained
= (SDL_AudioSpec
*)MEM_mallocN(sizeof(SDL_AudioSpec
),
444 desired
->callback
=audio_fill
;
446 if ( SDL_OpenAudio(desired
, obtained
) < 0 ) {
447 fprintf(stderr
, "Couldn't open audio: %s\n", SDL_GetError());
448 if (obtained
) MEM_freeN(obtained
);
451 audio_initialised
= 1;
452 hardware_spec
=obtained
;
460 static int audiostream_play_seq(Sequence
* seq
, Uint32 startframe
)
462 char name
[FILE_MAXDIR
+FILE_MAXFILE
];
466 if (seq
->type
== SEQ_META
) {
467 if (audiostream_play_seq(
468 seq
->seqbase
.first
, startframe
)) {
472 if ((seq
->type
== SEQ_RAM_SOUND
) && (seq
->sound
)) {
474 seq
->curpos
= (int)( (FRA2TIME((double) startframe
-
476 * ((float)G
.scene
->audio
.mixrate
)
479 if ((seq
->type
== SEQ_HD_SOUND
)) {
482 strncpy(name
, seq
->strip
->dir
, FILE_MAXDIR
-1);
483 strncat(name
, seq
->strip
->stripdata
->name
,
486 seq
->hdaudio
= sound_open_hdaudio(name
);
488 seq
->curpos
= (int)( (FRA2TIME((double) startframe
-
490 * ((float)G
.scene
->audio
.mixrate
)
498 void audiostream_play(Uint32 startframe
, Uint32 duration
, int mixdown
)
500 static SDL_AudioSpec desired
;
507 audiostream_play_seq(ed
->seqbasep
->first
, startframe
);
511 /* this call used to be in startup */
515 if (U
.mixbufsize
&& !audio_initialised
&& !mixdown
) {
516 desired
.freq
=G
.scene
->audio
.mixrate
;
517 desired
.format
=AUDIO_S16SYS
;
519 desired
.samples
=U
.mixbufsize
;
522 fprintf(stderr
, "freq: %d, samples: %d\n",
523 G
.scene
->audio
.mixrate
, U
.mixbufsize
);
525 if (audio_init(&desired
)==0) {
526 U
.mixbufsize
= 0; /* no audio */
530 audio_startframe
= startframe
;
531 audio_pos
= ( ((int)( FRA2TIME(startframe
)
532 *(G
.scene
->audio
.mixrate
)*4 )) & (~3) );
534 /* if audio already is playing, just reseek, otherwise
535 remember scrub-duration */
536 if (!(audio_playing
&& !audio_scrub
)) {
537 audio_scrub
= duration
;
545 void audiostream_start(Uint32 frame
)
547 audiostream_play(frame
, 0, 0);
550 void audiostream_scrub(Uint32 frame
)
552 if (U
.mixbufsize
) audiostream_play(frame
, 4096/U
.mixbufsize
, 0);
555 void audiostream_stop(void)
561 int audiostream_pos(void)
566 pos
= (int) (((double)(audio_pos
-U
.mixbufsize
)
567 / ( G
.scene
->audio
.mixrate
*4 ))
569 } else { /* fallback to seconds_timer when no audio available */
570 pos
= (int) ((PIL_check_seconds_timer() - audio_starttime
)
574 if (pos
< audio_startframe
) pos
= audio_startframe
;