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