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