Blender  V2.59
sound.c
Go to the documentation of this file.
00001 
00010 #include <string.h>
00011 #include <stdlib.h>
00012 
00013 #include "MEM_guardedalloc.h"
00014 
00015 #include "BLI_blenlib.h"
00016 
00017 #include "DNA_anim_types.h"
00018 #include "DNA_scene_types.h"
00019 #include "DNA_sequence_types.h"
00020 #include "DNA_packedFile_types.h"
00021 #include "DNA_screen_types.h"
00022 #include "DNA_sound_types.h"
00023 
00024 #ifdef WITH_AUDASPACE
00025 #  include "AUD_C-API.h"
00026 #endif
00027 
00028 #include "BKE_utildefines.h"
00029 #include "BKE_global.h"
00030 #include "BKE_main.h"
00031 #include "BKE_sound.h"
00032 #include "BKE_context.h"
00033 #include "BKE_library.h"
00034 #include "BKE_packedFile.h"
00035 #include "BKE_fcurve.h"
00036 #include "BKE_animsys.h"
00037 
00038 
00039 struct bSound* sound_new_file(struct Main *bmain, const char *filename)
00040 {
00041         bSound* sound = NULL;
00042 
00043         char str[FILE_MAX];
00044         char *path;
00045 
00046         int len;
00047 
00048         strcpy(str, filename);
00049 
00050         path = /*bmain ? bmain->name :*/ G.main->name;
00051 
00052         BLI_path_abs(str, path);
00053 
00054         len = strlen(filename);
00055         while(len > 0 && filename[len-1] != '/' && filename[len-1] != '\\')
00056                 len--;
00057 
00058         sound = alloc_libblock(&bmain->sound, ID_SO, filename+len);
00059         BLI_strncpy(sound->name, filename, FILE_MAX);
00060 // XXX unused currently sound->type = SOUND_TYPE_FILE;
00061 
00062         sound_load(bmain, sound);
00063 
00064         if(!sound->playback_handle)
00065         {
00066                 free_libblock(&bmain->sound, sound);
00067                 sound = NULL;
00068         }
00069 
00070         return sound;
00071 }
00072 
00073 void sound_free(struct bSound* sound)
00074 {
00075         if (sound->packedfile)
00076         {
00077                 freePackedFile(sound->packedfile);
00078                 sound->packedfile = NULL;
00079         }
00080 
00081 #ifdef WITH_AUDASPACE
00082         if(sound->handle)
00083         {
00084                 AUD_unload(sound->handle);
00085                 sound->handle = NULL;
00086                 sound->playback_handle = NULL;
00087         }
00088 #endif // WITH_AUDASPACE
00089 }
00090 
00091 
00092 #ifdef WITH_AUDASPACE
00093 
00094 static int force_device = -1;
00095 
00096 #ifdef WITH_JACK
00097 static void sound_sync_callback(void* data, int mode, float time)
00098 {
00099         struct Main* bmain = (struct Main*)data;
00100         struct Scene* scene;
00101 
00102         scene = bmain->scene.first;
00103         while(scene)
00104         {
00105                 if(scene->audio.flag & AUDIO_SYNC)
00106                 {
00107                         if(mode)
00108                                 sound_play_scene(scene);
00109                         else
00110                                 sound_stop_scene(scene);
00111                         AUD_seek(scene->sound_scene_handle, time);
00112                 }
00113                 scene = scene->id.next;
00114         }
00115 }
00116 #endif
00117 
00118 int sound_define_from_str(const char *str)
00119 {
00120         if (BLI_strcaseeq(str, "NULL"))
00121                 return AUD_NULL_DEVICE;
00122         if (BLI_strcaseeq(str, "SDL"))
00123                 return AUD_SDL_DEVICE;
00124         if (BLI_strcaseeq(str, "OPENAL"))
00125                 return AUD_OPENAL_DEVICE;
00126         if (BLI_strcaseeq(str, "JACK"))
00127                 return AUD_JACK_DEVICE;
00128 
00129         return -1;
00130 }
00131 
00132 void sound_force_device(int device)
00133 {
00134         force_device = device;
00135 }
00136 
00137 void sound_init_once(void)
00138 {
00139         AUD_initOnce();
00140 }
00141 
00142 void sound_init(struct Main *bmain)
00143 {
00144         AUD_DeviceSpecs specs;
00145         int device, buffersize;
00146 
00147         device = U.audiodevice;
00148         buffersize = U.mixbufsize;
00149         specs.channels = U.audiochannels;
00150         specs.format = U.audioformat;
00151         specs.rate = U.audiorate;
00152 
00153         if(force_device >= 0)
00154                 device = force_device;
00155 
00156         if(buffersize < 128)
00157                 buffersize = AUD_DEFAULT_BUFFER_SIZE;
00158 
00159         if(specs.rate < AUD_RATE_8000)
00160                 specs.rate = AUD_RATE_44100;
00161 
00162         if(specs.format <= AUD_FORMAT_INVALID)
00163                 specs.format = AUD_FORMAT_S16;
00164 
00165         if(specs.channels <= AUD_CHANNELS_INVALID)
00166                 specs.channels = AUD_CHANNELS_STEREO;
00167 
00168         if(!AUD_init(device, specs, buffersize))
00169                 AUD_init(AUD_NULL_DEVICE, specs, buffersize);
00170                 
00171 #ifdef WITH_JACK
00172         AUD_setSyncCallback(sound_sync_callback, bmain);
00173 #else
00174         (void)bmain; /* unused */
00175 #endif
00176 }
00177 
00178 void sound_exit(void)
00179 {
00180         AUD_exit();
00181 }
00182 
00183 // XXX unused currently
00184 #if 0
00185 struct bSound* sound_new_buffer(struct bContext *C, struct bSound *source)
00186 {
00187         bSound* sound = NULL;
00188 
00189         char name[25];
00190         strcpy(name, "buf_");
00191         strcpy(name + 4, source->id.name);
00192 
00193         sound = alloc_libblock(&CTX_data_main(C)->sound, ID_SO, name);
00194 
00195         sound->child_sound = source;
00196         sound->type = SOUND_TYPE_BUFFER;
00197 
00198         sound_load(CTX_data_main(C), sound);
00199 
00200         if(!sound->playback_handle)
00201         {
00202                 free_libblock(&CTX_data_main(C)->sound, sound);
00203                 sound = NULL;
00204         }
00205 
00206         return sound;
00207 }
00208 
00209 struct bSound* sound_new_limiter(struct bContext *C, struct bSound *source, float start, float end)
00210 {
00211         bSound* sound = NULL;
00212 
00213         char name[25];
00214         strcpy(name, "lim_");
00215         strcpy(name + 4, source->id.name);
00216 
00217         sound = alloc_libblock(&CTX_data_main(C)->sound, ID_SO, name);
00218 
00219         sound->child_sound = source;
00220         sound->start = start;
00221         sound->end = end;
00222         sound->type = SOUND_TYPE_LIMITER;
00223 
00224         sound_load(CTX_data_main(C), sound);
00225 
00226         if(!sound->playback_handle)
00227         {
00228                 free_libblock(&CTX_data_main(C)->sound, sound);
00229                 sound = NULL;
00230         }
00231 
00232         return sound;
00233 }
00234 #endif
00235 
00236 void sound_delete(struct bContext *C, struct bSound* sound)
00237 {
00238         if(sound)
00239         {
00240                 sound_free(sound);
00241 
00242                 free_libblock(&CTX_data_main(C)->sound, sound);
00243         }
00244 }
00245 
00246 void sound_cache(struct bSound* sound, int ignore)
00247 {
00248         if(sound->cache && !ignore)
00249                 AUD_unload(sound->cache);
00250 
00251         sound->cache = AUD_bufferSound(sound->handle);
00252         sound->playback_handle = sound->cache;
00253 }
00254 
00255 void sound_delete_cache(struct bSound* sound)
00256 {
00257         if(sound->cache)
00258         {
00259                 AUD_unload(sound->cache);
00260                 sound->cache = NULL;
00261                 sound->playback_handle = sound->handle;
00262         }
00263 }
00264 
00265 void sound_load(struct Main *bmain, struct bSound* sound)
00266 {
00267         if(sound)
00268         {
00269                 if(sound->handle)
00270                 {
00271                         AUD_unload(sound->handle);
00272                         sound->handle = NULL;
00273                         sound->playback_handle = NULL;
00274                 }
00275 
00276 // XXX unused currently
00277 #if 0
00278                 switch(sound->type)
00279                 {
00280                 case SOUND_TYPE_FILE:
00281 #endif
00282                 {
00283                         char fullpath[FILE_MAX];
00284                         char *path;
00285 
00286                         /* load sound */
00287                         PackedFile* pf = sound->packedfile;
00288 
00289                         /* dont modify soundact->sound->name, only change a copy */
00290                         BLI_strncpy(fullpath, sound->name, sizeof(fullpath));
00291 
00292                         if(sound->id.lib)
00293                                 path = sound->id.lib->filepath;
00294                         else
00295                                 path = bmain->name;
00296 
00297                         BLI_path_abs(fullpath, path);
00298 
00299                         /* but we need a packed file then */
00300                         if (pf)
00301                                 sound->handle = AUD_loadBuffer((unsigned char*) pf->data, pf->size);
00302                         /* or else load it from disk */
00303                         else
00304                                 sound->handle = AUD_load(fullpath);
00305                 }
00306 // XXX unused currently
00307 #if 0
00308                         break;
00309                 }
00310                 case SOUND_TYPE_BUFFER:
00311                         if(sound->child_sound && sound->child_sound->handle)
00312                                 sound->handle = AUD_bufferSound(sound->child_sound->handle);
00313                         break;
00314                 case SOUND_TYPE_LIMITER:
00315                         if(sound->child_sound && sound->child_sound->handle)
00316                                 sound->handle = AUD_limitSound(sound->child_sound, sound->start, sound->end);
00317                         break;
00318                 }
00319 #endif
00320                 if(sound->cache)
00321                         sound->playback_handle = sound->cache;
00322                 else
00323                         sound->playback_handle = sound->handle;
00324         }
00325 }
00326 
00327 static float sound_get_volume(Scene* scene, Sequence* sequence, float time)
00328 {
00329         AnimData *adt= BKE_animdata_from_id(&scene->id);
00330         FCurve *fcu = NULL;
00331         char buf[64];
00332         
00333         /* NOTE: this manually constructed path needs to be used here to avoid problems with RNA crashes */
00334         sprintf(buf, "sequence_editor.sequences_all[\"%s\"].volume", sequence->name+2);
00335         if (adt && adt->action && adt->action->curves.first)
00336                 fcu= list_find_fcurve(&adt->action->curves, buf, 0);
00337         
00338         if(fcu)
00339                 return evaluate_fcurve(fcu, time * (float)FPS);
00340         else
00341                 return sequence->volume;
00342 }
00343 
00344 AUD_Device* sound_mixdown(struct Scene *scene, AUD_DeviceSpecs specs, int start, float volume)
00345 {
00346         AUD_Device* mixdown = AUD_openReadDevice(specs);
00347 
00348         AUD_setDeviceVolume(mixdown, volume);
00349 
00350         AUD_playDevice(mixdown, scene->sound_scene, start / FPS);
00351 
00352         return mixdown;
00353 }
00354 
00355 void sound_create_scene(struct Scene *scene)
00356 {
00357         scene->sound_scene = AUD_createSequencer(scene->audio.flag & AUDIO_MUTE, scene, (AUD_volumeFunction)&sound_get_volume);
00358 }
00359 
00360 void sound_destroy_scene(struct Scene *scene)
00361 {
00362         if(scene->sound_scene_handle)
00363                 AUD_stop(scene->sound_scene_handle);
00364         if(scene->sound_scene)
00365                 AUD_destroySequencer(scene->sound_scene);
00366 }
00367 
00368 void sound_mute_scene(struct Scene *scene, int muted)
00369 {
00370         if(scene->sound_scene)
00371                 AUD_setSequencerMuted(scene->sound_scene, muted);
00372 }
00373 
00374 void* sound_scene_add_scene_sound(struct Scene *scene, struct Sequence* sequence, int startframe, int endframe, int frameskip)
00375 {
00376         if(scene != sequence->scene)
00377                 return AUD_addSequencer(scene->sound_scene, &(sequence->scene->sound_scene), startframe / FPS, endframe / FPS, frameskip / FPS, sequence);
00378         return NULL;
00379 }
00380 
00381 void* sound_add_scene_sound(struct Scene *scene, struct Sequence* sequence, int startframe, int endframe, int frameskip)
00382 {
00383         return AUD_addSequencer(scene->sound_scene, &(sequence->sound->playback_handle), startframe / FPS, endframe / FPS, frameskip / FPS, sequence);
00384 }
00385 
00386 void sound_remove_scene_sound(struct Scene *scene, void* handle)
00387 {
00388         AUD_removeSequencer(scene->sound_scene, handle);
00389 }
00390 
00391 void sound_mute_scene_sound(struct Scene *scene, void* handle, char mute)
00392 {
00393         AUD_muteSequencer(scene->sound_scene, handle, mute);
00394 }
00395 
00396 void sound_move_scene_sound(struct Scene *scene, void* handle, int startframe, int endframe, int frameskip)
00397 {
00398         AUD_moveSequencer(scene->sound_scene, handle, startframe / FPS, endframe / FPS, frameskip / FPS);
00399 }
00400 
00401 static void sound_start_play_scene(struct Scene *scene)
00402 {
00403         scene->sound_scene_handle = AUD_play(scene->sound_scene, 1);
00404         AUD_setLoop(scene->sound_scene_handle, -1);
00405 }
00406 
00407 void sound_play_scene(struct Scene *scene)
00408 {
00409         AUD_Status status;
00410         AUD_lock();
00411 
00412         status = AUD_getStatus(scene->sound_scene_handle);
00413 
00414         if(status == AUD_STATUS_INVALID)
00415                 sound_start_play_scene(scene);
00416 
00417         if(status != AUD_STATUS_PLAYING)
00418         {
00419                 AUD_seek(scene->sound_scene_handle, CFRA / FPS);
00420                 AUD_resume(scene->sound_scene_handle);
00421         }
00422 
00423         if(scene->audio.flag & AUDIO_SYNC)
00424                 AUD_startPlayback();
00425 
00426         AUD_unlock();
00427 }
00428 
00429 void sound_stop_scene(struct Scene *scene)
00430 {
00431         AUD_pause(scene->sound_scene_handle);
00432 
00433         if(scene->audio.flag & AUDIO_SYNC)
00434                 AUD_stopPlayback();
00435 }
00436 
00437 void sound_seek_scene(struct bContext *C)
00438 {
00439         struct Scene *scene = CTX_data_scene(C);
00440         AUD_Status status;
00441 
00442         AUD_lock();
00443 
00444         status = AUD_getStatus(scene->sound_scene_handle);
00445 
00446         if(status == AUD_STATUS_INVALID)
00447         {
00448                 sound_start_play_scene(scene);
00449                 AUD_pause(scene->sound_scene_handle);
00450         }
00451 
00452         if(scene->audio.flag & AUDIO_SCRUB && !CTX_wm_screen(C)->animtimer)
00453         {
00454                 if(scene->audio.flag & AUDIO_SYNC)
00455                 {
00456                         AUD_seek(scene->sound_scene_handle, CFRA / FPS);
00457                         AUD_seekSequencer(scene->sound_scene_handle, CFRA / FPS);
00458                 }
00459                 else
00460                         AUD_seek(scene->sound_scene_handle, CFRA / FPS);
00461                 AUD_resume(scene->sound_scene_handle);
00462                 if(AUD_getStatus(scene->sound_scrub_handle) != AUD_STATUS_INVALID)
00463                         AUD_seek(scene->sound_scrub_handle, 0);
00464                 else
00465                         scene->sound_scrub_handle = AUD_pauseAfter(scene->sound_scene_handle, 1 / FPS);
00466         }
00467         else
00468         {
00469                 if(scene->audio.flag & AUDIO_SYNC)
00470                         AUD_seekSequencer(scene->sound_scene_handle, CFRA / FPS);
00471                 else
00472                 {
00473                         if(status == AUD_STATUS_PLAYING)
00474                                 AUD_seek(scene->sound_scene_handle, CFRA / FPS);
00475                 }
00476         }
00477 
00478         AUD_unlock();
00479 }
00480 
00481 float sound_sync_scene(struct Scene *scene)
00482 {
00483         if(scene->audio.flag & AUDIO_SYNC)
00484                 return AUD_getSequencerPosition(scene->sound_scene_handle);
00485         else
00486                 return AUD_getPosition(scene->sound_scene_handle);
00487 }
00488 
00489 int sound_scene_playing(struct Scene *scene)
00490 {
00491         if(scene->audio.flag & AUDIO_SYNC)
00492                 return AUD_doesPlayback();
00493         else
00494                 return -1;
00495 }
00496 
00497 int sound_read_sound_buffer(struct bSound* sound, float* buffer, int length, float start, float end)
00498 {
00499         AUD_Sound* limiter = AUD_limitSound(sound->cache, start, end);
00500         int ret= AUD_readSound(limiter, buffer, length);
00501         AUD_unload(limiter);
00502         return ret;
00503 }
00504 
00505 int sound_get_channels(struct bSound* sound)
00506 {
00507         AUD_SoundInfo info;
00508 
00509         info = AUD_getInfo(sound->playback_handle);
00510 
00511         return info.specs.channels;
00512 }
00513 
00514 #else // WITH_AUDASPACE
00515 
00516 #include "BLI_utildefines.h"
00517 
00518 int sound_define_from_str(const char *UNUSED(str)) { return -1;}
00519 void sound_force_device(int UNUSED(device)) {}
00520 void sound_init_once(void) {}
00521 void sound_init(struct Main *UNUSED(bmain)) {}
00522 void sound_exit(void) {}
00523 void sound_cache(struct bSound* UNUSED(sound), int UNUSED(ignore)) { }
00524 void sound_delete_cache(struct bSound* UNUSED(sound)) {}
00525 void sound_load(struct Main *UNUSED(bmain), struct bSound* UNUSED(sound)) {}
00526 void sound_create_scene(struct Scene *UNUSED(scene)) {}
00527 void sound_destroy_scene(struct Scene *UNUSED(scene)) {}
00528 void sound_mute_scene(struct Scene *UNUSED(scene), int UNUSED(muted)) {}
00529 void* sound_scene_add_scene_sound(struct Scene *UNUSED(scene), struct Sequence* UNUSED(sequence), int UNUSED(startframe), int UNUSED(endframe), int UNUSED(frameskip)) { return NULL; }
00530 void* sound_add_scene_sound(struct Scene *UNUSED(scene), struct Sequence* UNUSED(sequence), int UNUSED(startframe), int UNUSED(endframe), int UNUSED(frameskip)) { return NULL; }
00531 void sound_remove_scene_sound(struct Scene *UNUSED(scene), void* UNUSED(handle)) {}
00532 void sound_mute_scene_sound(struct Scene *UNUSED(scene), void* UNUSED(handle), char UNUSED(mute)) {}
00533 void sound_move_scene_sound(struct Scene *UNUSED(scene), void* UNUSED(handle), int UNUSED(startframe), int UNUSED(endframe), int UNUSED(frameskip)) {}
00534 static void sound_start_play_scene(struct Scene *UNUSED(scene)) {}
00535 void sound_play_scene(struct Scene *UNUSED(scene)) {}
00536 void sound_stop_scene(struct Scene *UNUSED(scene)) {}
00537 void sound_seek_scene(struct bContext *UNUSED(C)) {}
00538 float sound_sync_scene(struct Scene *UNUSED(scene)) { return 0.0f; }
00539 int sound_scene_playing(struct Scene *UNUSED(scene)) { return -1; }
00540 int sound_read_sound_buffer(struct bSound* UNUSED(sound), float* UNUSED(buffer), int UNUSED(length), float UNUSED(start), float UNUSED(end)) { return 0; }
00541 int sound_get_channels(struct bSound* UNUSED(sound)) { return 1; }
00542 
00543 #endif // WITH_AUDASPACE