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