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