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