2
* $Id: seqaudio.c 16941 2008-10-06 01:59:11Z campbellbarton $
4
* ***** BEGIN GPL 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.
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.
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.
20
* The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
21
* All rights reserved.
23
* The Original Code is: all of this file.
25
* Contributor(s): intrr, Peter Schlaile
27
* ***** END GPL LICENSE BLOCK *****
36
#define __USE_XOPEN /* Needed for swab on linux */
46
#include "MEM_guardedalloc.h"
52
#include "BLI_blenlib.h"
53
#include "BLI_arithb.h"
55
#include "DNA_screen_types.h"
56
#include "DNA_sound_types.h"
57
#include "DNA_userdef_types.h"
58
#include "DNA_sequence_types.h"
59
#include "DNA_scene_types.h"
60
#include "DNA_ipo_types.h"
62
#include "BKE_utildefines.h"
63
#include "BKE_global.h"
64
#include "BKE_library.h"
65
#include "BKE_blender.h"
70
#include "BIF_graphics.h"
71
#include "BIF_keyval.h"
72
#include "BIF_mainqueue.h"
73
#include "BIF_resources.h"
74
#include "BIF_screen.h"
75
#include "BIF_toolbox.h"
76
#include "BIF_mywindow.h"
77
#include "BIF_space.h"
78
#include "BIF_glutil.h"
79
#include "BIF_interface.h"
82
#include "BSE_seqaudio.h"
83
#include "BIF_editsound.h"
89
static void audio_fill(void *mixdown, uint8_t *sstream, int len);
90
/* ************ GLOBALS ************* */
93
static int audio_scrub=0;
94
static int audio_playing=0;
95
static int audio_initialised=0;
96
static int audio_startframe=0;
97
static double audio_starttime = 0.0;
100
/* local protos ------------------- */
101
void audio_mixdown(void);
103
void makewavstring (char *string)
107
if (string==0) return;
109
strcpy(string, G.scene->r.pic);
110
BLI_convertstringcode(string, G.sce);
112
BLI_make_existing_file(string);
114
if (BLI_strcasecmp(string + strlen(string) - 4, ".wav")) {
115
sprintf(txt, "%04d_%04d.wav", (G.scene->r.sfra) , (G.scene->r.efra) );
123
int file, c, totlen, totframe, i, oldcfra;
126
buf = MEM_mallocN(65536, "audio_mixdown");
129
file = open(buf, O_BINARY+O_WRONLY+O_CREAT+O_TRUNC, 0666);
133
error("Can't open output file");
139
printf("Saving: %s ", buf);
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);
146
totlen+= 36; /* len is filesize-8 in WAV spec, total header is 44 bytes */
147
memcpy(buf+4, &totlen, 4);
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;
157
memcpy(buf+40, &i, 4);
159
if (G.order == B_ENDIAN) {
160
/* swap the four ints to little endian */
168
/* audio mixrate * 4 */
175
c = write(file, buf, 44);
178
audiostream_play(SFRA, 0, 1);
181
while ( totlen > 0 ) {
184
memset(buf+i, 0, 64);
186
CFRA=(int) ( ((float)(audio_pos-64)/( G.scene->audio.mixrate*4 ))*FPS );
188
audio_fill(buf+i, NULL, 64);
189
if (G.order == B_ENDIAN) {
191
memcpy(tbuf, buf+i, 64);
192
swab(tbuf, buf+i, 64);
194
if (i == (65536-64)) {
196
write(file, buf, 65536);
211
void audiostream_fill(uint8_t *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));
232
static void audio_levels(uint8_t *buf, int len, float db, float facf, float pan)
235
float facl, facr, fac;
236
signed short *sample;
238
if (pan>=0) { facr = 1.0; facl = 1.0-pan; }
239
else { facr = pan+1.0; facl = 1.0; }
241
fac = pow(10.0, ((-(db+G.scene->audio.main))/20.0)) / facf;
245
for (i=0; i<len; i+=4) {
246
sample = (signed short*)(buf+i);
247
sample[0] = (short) ((float)sample[0] * facl);
248
sample[1] = (short) ((float)sample[1] * facr);
252
/* convert mono/stereo and sampling rate, alloc a buffer for
253
* sound->stream to contain the new sample, and set sound->streamlen
256
void audio_makestream(bSound *sound)
258
signed short *source, *dest;
262
if ( (!sound)||(sound->stream)||(!sound->sample)||(!G.scene) ) {
265
ratio = (float)G.scene->audio.mixrate / (float)sound->sample->rate;
266
sound->streamlen = (int) ( (float)sound->sample->len * ratio * 2.0/((float)sound->sample->channels) );
267
sound->stream = malloc((int) ((float)sound->streamlen * 1.05));
268
if (sound->sample->rate == G.scene->audio.mixrate) {
269
if (sound->sample->channels == 2) {
270
memcpy(sound->stream, sound->sample->data, sound->streamlen);
273
for (source = (signed short*)(sound->sample->data),
274
dest = (signed short*)(sound->stream),
276
i<sound->streamlen/4;
277
dest += 2, source++, i++) dest[0] = dest[1] = source[0];
281
if (sound->sample->channels == 1) {
282
for (dest=(signed short*)(sound->stream), i=0, source=(signed short*)(sound->sample->data);
283
i<(sound->streamlen/4); dest+=2, i++)
284
dest[0] = dest[1] = source[(int)((float)i/ratio)];
286
else if (sound->sample->channels == 2) {
287
for (dest=(signed short*)(sound->stream), i=0, source=(signed short*)(sound->sample->data);
288
i<(sound->streamlen/2); dest+=2, i+=2) {
289
dest[1] = source[(int)((float)i/ratio)];
290
dest[0] = source[(int)((float)i/ratio)+1];
296
static void audio_fill_ram_sound(Sequence *seq, void * mixdown,
297
uint8_t * sstream, int len)
304
audio_makestream(sound);
305
if ((seq->curpos<sound->streamlen -len) && (seq->curpos>=0) &&
306
(seq->startdisp <= CFRA) && ((seq->enddisp) > CFRA))
308
if(seq->ipo && seq->ipo->curve.first) {
309
do_seq_ipo(seq, CFRA);
314
cvtbuf = malloc(len);
315
memcpy(cvtbuf, ((uint8_t*)sound->stream)+(seq->curpos & (~3)), len);
316
audio_levels(cvtbuf, len, seq->level, facf, seq->pan);
318
SDL_MixAudio(sstream, cvtbuf, len, SDL_MIX_MAXVOLUME);
320
SDL_MixAudio((uint8_t*)mixdown, cvtbuf, len, SDL_MIX_MAXVOLUME);
329
static void audio_fill_hd_sound(Sequence *seq,
330
void * mixdown, uint8_t * sstream,
336
if ((seq->curpos >= 0) &&
337
(seq->startdisp <= CFRA) && ((seq->enddisp) > CFRA))
339
if(seq->ipo && seq->ipo->curve.first) {
340
do_seq_ipo(seq, CFRA);
345
cvtbuf = malloc(len);
347
sound_hdaudio_extract(seq->hdaudio, (short*) cvtbuf,
349
G.scene->audio.mixrate,
352
audio_levels(cvtbuf, len, seq->level, facf, seq->pan);
354
SDL_MixAudio(sstream,
355
cvtbuf, len, SDL_MIX_MAXVOLUME);
357
SDL_MixAudio((uint8_t*)mixdown,
358
cvtbuf, len, SDL_MIX_MAXVOLUME);
367
static void audio_fill_seq(Sequence * seq, void * mixdown,
368
uint8_t *sstream, int len, int advance_only)
371
if (seq->type == SEQ_META &&
372
(!(seq->flag & SEQ_MUTE))) {
373
if (seq->startdisp <= CFRA && seq->enddisp > CFRA) {
374
audio_fill_seq(seq->seqbase.first,
375
mixdown, sstream, len,
378
audio_fill_seq(seq->seqbase.first,
379
mixdown, sstream, len,
383
if ( (seq->type == SEQ_RAM_SOUND) &&
385
(!(seq->flag & SEQ_MUTE))) {
389
audio_fill_ram_sound(
390
seq, mixdown, sstream, len);
393
if ( (seq->type == SEQ_HD_SOUND) &&
394
(!(seq->flag & SEQ_MUTE))) {
399
char name[FILE_MAXDIR+FILE_MAXFILE];
401
strncpy(name, seq->strip->dir,
404
seq->strip->stripdata->name,
406
BLI_convertstringcode(name, G.sce);
408
seq->hdaudio= sound_open_hdaudio(name);
411
audio_fill_hd_sound(seq, mixdown,
422
static void audio_fill(void *mixdown, uint8_t *sstream, int len)
428
if((ed) && (!(G.scene->audio.flag & AUDIO_MUTE))) {
429
seq = ed->seqbasep->first;
430
audio_fill_seq(seq, mixdown, sstream, len, 0);
444
static int audio_init(SDL_AudioSpec *desired)
446
SDL_AudioSpec *obtained, *hardware_spec;
450
obtained = (SDL_AudioSpec*)MEM_mallocN(sizeof(SDL_AudioSpec),
453
desired->callback=audio_fill;
455
if ( SDL_OpenAudio(desired, obtained) < 0 ) {
456
fprintf(stderr, "Couldn't open audio: %s\n", SDL_GetError());
457
if (obtained) MEM_freeN(obtained);
460
audio_initialised = 1;
461
hardware_spec=obtained;
470
static int audiostream_play_seq(Sequence * seq, uint32_t startframe)
472
char name[FILE_MAXDIR+FILE_MAXFILE];
476
if (seq->type == SEQ_META) {
477
if (audiostream_play_seq(
478
seq->seqbase.first, startframe)) {
482
if ((seq->type == SEQ_RAM_SOUND) && (seq->sound)) {
484
seq->curpos = (int)( (FRA2TIME(
485
(double) startframe -
486
(double) seq->start +
489
* ((float)G.scene->audio.mixrate)
492
if ((seq->type == SEQ_HD_SOUND)) {
495
strncpy(name, seq->strip->dir, FILE_MAXDIR-1);
496
strncat(name, seq->strip->stripdata->name,
499
seq->hdaudio = sound_open_hdaudio(name);
501
seq->curpos = (int)( (FRA2TIME((double) startframe -
502
(double) seq->start +
505
* ((float)G.scene->audio.mixrate)
513
void audiostream_play(uint32_t startframe, uint32_t duration, int mixdown)
516
static SDL_AudioSpec desired;
523
audiostream_play_seq(ed->seqbasep->first, startframe);
527
/* this call used to be in startup */
531
if (U.mixbufsize && !audio_initialised && !mixdown) {
532
desired.freq=G.scene->audio.mixrate;
533
desired.format=AUDIO_S16SYS;
535
desired.samples=U.mixbufsize;
538
if (audio_init(&desired)==0) {
539
U.mixbufsize = 0; /* no audio */
543
audio_startframe = startframe;
544
audio_pos = ( ((int)( FRA2TIME(startframe)
545
*(G.scene->audio.mixrate)*4 )) & (~3) );
546
audio_starttime = PIL_check_seconds_timer();
548
/* if audio already is playing, just reseek, otherwise
549
remember scrub-duration */
550
if (!(audio_playing && !audio_scrub)) {
551
audio_scrub = duration;
560
void audiostream_start(uint32_t frame)
562
audiostream_play(frame, 0, 0);
565
void audiostream_scrub(uint32_t frame)
567
if (U.mixbufsize) audiostream_play(frame, 4096/U.mixbufsize, 0);
570
void audiostream_stop(void)
578
int audiostream_pos(void)
583
pos = (int) (((double)(audio_pos-U.mixbufsize)
584
/ ( G.scene->audio.mixrate*4 ))
586
} else { /* fallback to seconds_timer when no audio available */
587
pos = (int) ((PIL_check_seconds_timer() - audio_starttime)
591
if (pos < audio_startframe) pos = audio_startframe;