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