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