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