fix for animation playback and build error when compiling without WITH_AUDASPACE
[blender.git] / source / blender / blenkernel / intern / sound.c
1 /** \file blender/blenkernel/intern/sound.c
2  *  \ingroup bke
3  */
4 /**
5  * sound.c (mar-2001 nzc)
6  *
7  * $Id$
8  */
9
10 #include <string.h>
11 #include <stdlib.h>
12
13 #include "MEM_guardedalloc.h"
14
15 #include "BLI_blenlib.h"
16
17 #include "DNA_anim_types.h"
18 #include "DNA_scene_types.h"
19 #include "DNA_sequence_types.h"
20 #include "DNA_packedFile_types.h"
21 #include "DNA_screen_types.h"
22 #include "DNA_sound_types.h"
23
24 #ifdef WITH_AUDASPACE
25 #  include "AUD_C-API.h"
26 #endif
27
28 #include "BKE_utildefines.h"
29 #include "BKE_global.h"
30 #include "BKE_main.h"
31 #include "BKE_sound.h"
32 #include "BKE_context.h"
33 #include "BKE_library.h"
34 #include "BKE_packedFile.h"
35 #include "BKE_fcurve.h"
36 #include "BKE_animsys.h"
37
38
39 struct bSound* sound_new_file(struct Main *bmain, const char *filename)
40 {
41         bSound* sound = NULL;
42
43         char str[FILE_MAX];
44         char *path;
45
46         int len;
47
48         strcpy(str, filename);
49
50         path = /*bmain ? bmain->name :*/ G.main->name;
51
52         BLI_path_abs(str, path);
53
54         len = strlen(filename);
55         while(len > 0 && filename[len-1] != '/' && filename[len-1] != '\\')
56                 len--;
57
58         sound = alloc_libblock(&bmain->sound, ID_SO, filename+len);
59         BLI_strncpy(sound->name, filename, FILE_MAX);
60 // XXX unused currently sound->type = SOUND_TYPE_FILE;
61
62         sound_load(bmain, sound);
63
64         if(!sound->playback_handle)
65         {
66                 free_libblock(&bmain->sound, sound);
67                 sound = NULL;
68         }
69
70         return sound;
71 }
72
73 void sound_free(struct bSound* sound)
74 {
75         if (sound->packedfile)
76         {
77                 freePackedFile(sound->packedfile);
78                 sound->packedfile = NULL;
79         }
80
81 #ifdef WITH_AUDASPACE
82         if(sound->handle)
83         {
84                 AUD_unload(sound->handle);
85                 sound->handle = NULL;
86                 sound->playback_handle = NULL;
87         }
88 #endif // WITH_AUDASPACE
89 }
90
91
92 #ifdef WITH_AUDASPACE
93
94 static int force_device = -1;
95
96 #ifdef WITH_JACK
97 static void sound_sync_callback(void* data, int mode, float time)
98 {
99         struct Main* bmain = (struct Main*)data;
100         struct Scene* scene;
101
102         scene = bmain->scene.first;
103         while(scene)
104         {
105                 if(scene->audio.flag & AUDIO_SYNC)
106                 {
107                         if(mode)
108                                 sound_play_scene(scene);
109                         else
110                                 sound_stop_scene(scene);
111                         AUD_seek(scene->sound_scene_handle, time);
112                 }
113                 scene = scene->id.next;
114         }
115 }
116 #endif
117
118 int sound_define_from_str(const char *str)
119 {
120         if (BLI_strcaseeq(str, "NULL"))
121                 return AUD_NULL_DEVICE;
122         if (BLI_strcaseeq(str, "SDL"))
123                 return AUD_SDL_DEVICE;
124         if (BLI_strcaseeq(str, "OPENAL"))
125                 return AUD_OPENAL_DEVICE;
126         if (BLI_strcaseeq(str, "JACK"))
127                 return AUD_JACK_DEVICE;
128
129         return -1;
130 }
131
132 void sound_force_device(int device)
133 {
134         force_device = device;
135 }
136
137 void sound_init_once(void)
138 {
139         AUD_initOnce();
140 }
141
142 void sound_init(struct Main *bmain)
143 {
144         AUD_DeviceSpecs specs;
145         int device, buffersize;
146
147         device = U.audiodevice;
148         buffersize = U.mixbufsize;
149         specs.channels = U.audiochannels;
150         specs.format = U.audioformat;
151         specs.rate = U.audiorate;
152
153         if(force_device >= 0)
154                 device = force_device;
155
156         if(buffersize < 128)
157                 buffersize = AUD_DEFAULT_BUFFER_SIZE;
158
159         if(specs.rate < AUD_RATE_8000)
160                 specs.rate = AUD_RATE_44100;
161
162         if(specs.format <= AUD_FORMAT_INVALID)
163                 specs.format = AUD_FORMAT_S16;
164
165         if(specs.channels <= AUD_CHANNELS_INVALID)
166                 specs.channels = AUD_CHANNELS_STEREO;
167
168         if(!AUD_init(device, specs, buffersize))
169                 AUD_init(AUD_NULL_DEVICE, specs, buffersize);
170                 
171 #ifdef WITH_JACK
172         AUD_setSyncCallback(sound_sync_callback, bmain);
173 #else
174         (void)bmain; /* unused */
175 #endif
176 }
177
178 void sound_exit(void)
179 {
180         AUD_exit();
181 }
182
183 // XXX unused currently
184 #if 0
185 struct bSound* sound_new_buffer(struct bContext *C, struct bSound *source)
186 {
187         bSound* sound = NULL;
188
189         char name[25];
190         strcpy(name, "buf_");
191         strcpy(name + 4, source->id.name);
192
193         sound = alloc_libblock(&CTX_data_main(C)->sound, ID_SO, name);
194
195         sound->child_sound = source;
196         sound->type = SOUND_TYPE_BUFFER;
197
198         sound_load(CTX_data_main(C), sound);
199
200         if(!sound->playback_handle)
201         {
202                 free_libblock(&CTX_data_main(C)->sound, sound);
203                 sound = NULL;
204         }
205
206         return sound;
207 }
208
209 struct bSound* sound_new_limiter(struct bContext *C, struct bSound *source, float start, float end)
210 {
211         bSound* sound = NULL;
212
213         char name[25];
214         strcpy(name, "lim_");
215         strcpy(name + 4, source->id.name);
216
217         sound = alloc_libblock(&CTX_data_main(C)->sound, ID_SO, name);
218
219         sound->child_sound = source;
220         sound->start = start;
221         sound->end = end;
222         sound->type = SOUND_TYPE_LIMITER;
223
224         sound_load(CTX_data_main(C), sound);
225
226         if(!sound->playback_handle)
227         {
228                 free_libblock(&CTX_data_main(C)->sound, sound);
229                 sound = NULL;
230         }
231
232         return sound;
233 }
234 #endif
235
236 void sound_delete(struct bContext *C, struct bSound* sound)
237 {
238         if(sound)
239         {
240                 sound_free(sound);
241
242                 free_libblock(&CTX_data_main(C)->sound, sound);
243         }
244 }
245
246 void sound_cache(struct bSound* sound, int ignore)
247 {
248         if(sound->cache && !ignore)
249                 AUD_unload(sound->cache);
250
251         sound->cache = AUD_bufferSound(sound->handle);
252         sound->playback_handle = sound->cache;
253 }
254
255 void sound_delete_cache(struct bSound* sound)
256 {
257         if(sound->cache)
258         {
259                 AUD_unload(sound->cache);
260                 sound->cache = NULL;
261                 sound->playback_handle = sound->handle;
262         }
263 }
264
265 void sound_load(struct Main *bmain, struct bSound* sound)
266 {
267         if(sound)
268         {
269                 if(sound->handle)
270                 {
271                         AUD_unload(sound->handle);
272                         sound->handle = NULL;
273                         sound->playback_handle = NULL;
274                 }
275
276 // XXX unused currently
277 #if 0
278                 switch(sound->type)
279                 {
280                 case SOUND_TYPE_FILE:
281 #endif
282                 {
283                         char fullpath[FILE_MAX];
284                         char *path;
285
286                         /* load sound */
287                         PackedFile* pf = sound->packedfile;
288
289                         /* dont modify soundact->sound->name, only change a copy */
290                         BLI_strncpy(fullpath, sound->name, sizeof(fullpath));
291
292                         if(sound->id.lib)
293                                 path = sound->id.lib->filepath;
294                         else
295                                 path = bmain->name;
296
297                         BLI_path_abs(fullpath, path);
298
299                         /* but we need a packed file then */
300                         if (pf)
301                                 sound->handle = AUD_loadBuffer((unsigned char*) pf->data, pf->size);
302                         /* or else load it from disk */
303                         else
304                                 sound->handle = AUD_load(fullpath);
305                 }
306 // XXX unused currently
307 #if 0
308                         break;
309                 }
310                 case SOUND_TYPE_BUFFER:
311                         if(sound->child_sound && sound->child_sound->handle)
312                                 sound->handle = AUD_bufferSound(sound->child_sound->handle);
313                         break;
314                 case SOUND_TYPE_LIMITER:
315                         if(sound->child_sound && sound->child_sound->handle)
316                                 sound->handle = AUD_limitSound(sound->child_sound, sound->start, sound->end);
317                         break;
318                 }
319 #endif
320                 if(sound->cache)
321                         sound->playback_handle = sound->cache;
322                 else
323                         sound->playback_handle = sound->handle;
324         }
325 }
326
327 static float sound_get_volume(Scene* scene, Sequence* sequence, float time)
328 {
329         AnimData *adt= BKE_animdata_from_id(&scene->id);
330         FCurve *fcu = NULL;
331         char buf[64];
332         
333         /* NOTE: this manually constructed path needs to be used here to avoid problems with RNA crashes */
334         sprintf(buf, "sequence_editor.sequences_all[\"%s\"].volume", sequence->name+2);
335         if (adt && adt->action && adt->action->curves.first)
336                 fcu= list_find_fcurve(&adt->action->curves, buf, 0);
337         
338         if(fcu)
339                 return evaluate_fcurve(fcu, time * (float)FPS);
340         else
341                 return sequence->volume;
342 }
343
344 AUD_Device* sound_mixdown(struct Scene *scene, AUD_DeviceSpecs specs, int start, float volume)
345 {
346         AUD_Device* mixdown = AUD_openReadDevice(specs);
347
348         AUD_setDeviceVolume(mixdown, volume);
349
350         AUD_playDevice(mixdown, scene->sound_scene, start / FPS);
351
352         return mixdown;
353 }
354
355 void sound_create_scene(struct Scene *scene)
356 {
357         scene->sound_scene = AUD_createSequencer(scene->audio.flag & AUDIO_MUTE, scene, (AUD_volumeFunction)&sound_get_volume);
358 }
359
360 void sound_destroy_scene(struct Scene *scene)
361 {
362         if(scene->sound_scene_handle)
363                 AUD_stop(scene->sound_scene_handle);
364         if(scene->sound_scene)
365                 AUD_destroySequencer(scene->sound_scene);
366 }
367
368 void sound_mute_scene(struct Scene *scene, int muted)
369 {
370         if(scene->sound_scene)
371                 AUD_setSequencerMuted(scene->sound_scene, muted);
372 }
373
374 void* sound_scene_add_scene_sound(struct Scene *scene, struct Sequence* sequence, int startframe, int endframe, int frameskip)
375 {
376         if(scene != sequence->scene)
377                 return AUD_addSequencer(scene->sound_scene, &(sequence->scene->sound_scene), startframe / FPS, endframe / FPS, frameskip / FPS, sequence);
378         return NULL;
379 }
380
381 void* sound_add_scene_sound(struct Scene *scene, struct Sequence* sequence, int startframe, int endframe, int frameskip)
382 {
383         return AUD_addSequencer(scene->sound_scene, &(sequence->sound->playback_handle), startframe / FPS, endframe / FPS, frameskip / FPS, sequence);
384 }
385
386 void sound_remove_scene_sound(struct Scene *scene, void* handle)
387 {
388         AUD_removeSequencer(scene->sound_scene, handle);
389 }
390
391 void sound_mute_scene_sound(struct Scene *scene, void* handle, char mute)
392 {
393         AUD_muteSequencer(scene->sound_scene, handle, mute);
394 }
395
396 void sound_move_scene_sound(struct Scene *scene, void* handle, int startframe, int endframe, int frameskip)
397 {
398         AUD_moveSequencer(scene->sound_scene, handle, startframe / FPS, endframe / FPS, frameskip / FPS);
399 }
400
401 static void sound_start_play_scene(struct Scene *scene)
402 {
403         scene->sound_scene_handle = AUD_play(scene->sound_scene, 1);
404         AUD_setLoop(scene->sound_scene_handle, -1);
405 }
406
407 void sound_play_scene(struct Scene *scene)
408 {
409         AUD_Status status;
410         AUD_lock();
411
412         status = AUD_getStatus(scene->sound_scene_handle);
413
414         if(status == AUD_STATUS_INVALID)
415                 sound_start_play_scene(scene);
416
417         if(status != AUD_STATUS_PLAYING)
418         {
419                 AUD_seek(scene->sound_scene_handle, CFRA / FPS);
420                 AUD_resume(scene->sound_scene_handle);
421         }
422
423         if(scene->audio.flag & AUDIO_SYNC)
424                 AUD_startPlayback();
425
426         AUD_unlock();
427 }
428
429 void sound_stop_scene(struct Scene *scene)
430 {
431         AUD_pause(scene->sound_scene_handle);
432
433         if(scene->audio.flag & AUDIO_SYNC)
434                 AUD_stopPlayback();
435 }
436
437 void sound_seek_scene(struct bContext *C)
438 {
439         struct Scene *scene = CTX_data_scene(C);
440         AUD_Status status;
441
442         AUD_lock();
443
444         status = AUD_getStatus(scene->sound_scene_handle);
445
446         if(status == AUD_STATUS_INVALID)
447         {
448                 sound_start_play_scene(scene);
449                 AUD_pause(scene->sound_scene_handle);
450         }
451
452         if(scene->audio.flag & AUDIO_SCRUB && !CTX_wm_screen(C)->animtimer)
453         {
454                 if(scene->audio.flag & AUDIO_SYNC)
455                 {
456                         AUD_seek(scene->sound_scene_handle, CFRA / FPS);
457                         AUD_seekSequencer(scene->sound_scene_handle, CFRA / FPS);
458                 }
459                 else
460                         AUD_seek(scene->sound_scene_handle, CFRA / FPS);
461                 AUD_resume(scene->sound_scene_handle);
462                 if(AUD_getStatus(scene->sound_scrub_handle) != AUD_STATUS_INVALID)
463                         AUD_seek(scene->sound_scrub_handle, 0);
464                 else
465                         scene->sound_scrub_handle = AUD_pauseAfter(scene->sound_scene_handle, 1 / FPS);
466         }
467         else
468         {
469                 if(scene->audio.flag & AUDIO_SYNC)
470                         AUD_seekSequencer(scene->sound_scene_handle, CFRA / FPS);
471                 else
472                 {
473                         if(status == AUD_STATUS_PLAYING)
474                                 AUD_seek(scene->sound_scene_handle, CFRA / FPS);
475                 }
476         }
477
478         AUD_unlock();
479 }
480
481 float sound_sync_scene(struct Scene *scene)
482 {
483         if(scene->audio.flag & AUDIO_SYNC)
484                 return AUD_getSequencerPosition(scene->sound_scene_handle);
485         else
486                 return AUD_getPosition(scene->sound_scene_handle);
487 }
488
489 int sound_scene_playing(struct Scene *scene)
490 {
491         if(scene->audio.flag & AUDIO_SYNC)
492                 return AUD_doesPlayback();
493         else
494                 return -1;
495 }
496
497 int sound_read_sound_buffer(struct bSound* sound, float* buffer, int length, float start, float end)
498 {
499         AUD_Sound* limiter = AUD_limitSound(sound->cache, start, end);
500         int ret= AUD_readSound(limiter, buffer, length);
501         AUD_unload(limiter);
502         return ret;
503 }
504
505 int sound_get_channels(struct bSound* sound)
506 {
507         AUD_SoundInfo info;
508
509         info = AUD_getInfo(sound->playback_handle);
510
511         return info.specs.channels;
512 }
513
514 #else // WITH_AUDASPACE
515
516 #include "BLI_utildefines.h"
517
518 int sound_define_from_str(const char *UNUSED(str)) { return -1;}
519 void sound_force_device(int UNUSED(device)) {}
520 void sound_init_once(void) {}
521 void sound_init(struct Main *UNUSED(bmain)) {}
522 void sound_exit(void) {}
523 void sound_cache(struct bSound* UNUSED(sound), int UNUSED(ignore)) { }
524 void sound_delete_cache(struct bSound* UNUSED(sound)) {}
525 void sound_load(struct Main *UNUSED(bmain), struct bSound* UNUSED(sound)) {}
526 void sound_create_scene(struct Scene *UNUSED(scene)) {}
527 void sound_destroy_scene(struct Scene *UNUSED(scene)) {}
528 void sound_mute_scene(struct Scene *UNUSED(scene), int UNUSED(muted)) {}
529 void* sound_scene_add_scene_sound(struct Scene *UNUSED(scene), struct Sequence* UNUSED(sequence), int UNUSED(startframe), int UNUSED(endframe), int UNUSED(frameskip)) { return NULL; }
530 void* sound_add_scene_sound(struct Scene *UNUSED(scene), struct Sequence* UNUSED(sequence), int UNUSED(startframe), int UNUSED(endframe), int UNUSED(frameskip)) { return NULL; }
531 void sound_remove_scene_sound(struct Scene *UNUSED(scene), void* UNUSED(handle)) {}
532 void sound_mute_scene_sound(struct Scene *UNUSED(scene), void* UNUSED(handle), char UNUSED(mute)) {}
533 void sound_move_scene_sound(struct Scene *UNUSED(scene), void* UNUSED(handle), int UNUSED(startframe), int UNUSED(endframe), int UNUSED(frameskip)) {}
534 static void sound_start_play_scene(struct Scene *UNUSED(scene)) {}
535 void sound_play_scene(struct Scene *UNUSED(scene)) {}
536 void sound_stop_scene(struct Scene *UNUSED(scene)) {}
537 void sound_seek_scene(struct bContext *UNUSED(C)) {}
538 float sound_sync_scene(struct Scene *UNUSED(scene)) { return 0.0f; }
539 int sound_scene_playing(struct Scene *UNUSED(scene)) { return -1; }
540 int sound_read_sound_buffer(struct bSound* UNUSED(sound), float* UNUSED(buffer), int UNUSED(length), float UNUSED(start), float UNUSED(end)) { return 0; }
541 int sound_get_channels(struct bSound* UNUSED(sound)) { return 1; }
542
543 #endif // WITH_AUDASPACE