Blender  V2.59
sound_ops.c
Go to the documentation of this file.
00001 /*
00002  * $Id: sound_ops.c 37750 2011-06-23 09:27:56Z campbellbarton $
00003  *
00004  * ***** BEGIN GPL LICENSE BLOCK *****
00005  *
00006  * This program is free software; you can redistribute it and/or
00007  * modify it under the terms of the GNU General Public License
00008  * as published by the Free Software Foundation; either version 2
00009  * of the License, or (at your option) any later version. 
00010  *
00011  * This program is distributed in the hope that it will be useful,
00012  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00013  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00014  * GNU General Public License for more details.
00015  *
00016  * You should have received a copy of the GNU General Public License
00017  * along with this program; if not, write to the Free Software Foundation,
00018  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
00019  *
00020  * The Original Code is Copyright (C) 2007 Blender Foundation.
00021  * All rights reserved.
00022  *
00023  * 
00024  * Contributor(s): Blender Foundation
00025  *
00026  * ***** END GPL LICENSE BLOCK *****
00027  */
00028 
00034 #include <string.h>
00035 #include <stdlib.h>
00036 #include <stdio.h>
00037 #include <stddef.h>
00038 
00039 #include "MEM_guardedalloc.h"
00040 
00041 #include "BLI_blenlib.h"
00042 #include "BLI_utildefines.h"
00043 
00044 #include "DNA_packedFile_types.h"
00045 #include "DNA_scene_types.h"
00046 #include "DNA_space_types.h"
00047 #include "DNA_sequence_types.h"
00048 #include "DNA_sound_types.h"
00049 #include "DNA_userdef_types.h"
00050 
00051 #include "BKE_context.h"
00052 #include "BKE_global.h"
00053 #include "BKE_main.h"
00054 #include "BKE_report.h"
00055 #include "BKE_packedFile.h"
00056 #include "BKE_sound.h"
00057 
00058 #include "RNA_access.h"
00059 #include "RNA_define.h"
00060 #include "RNA_enum_types.h"
00061 
00062 #include "UI_interface.h"
00063 
00064 #include "WM_api.h"
00065 #include "WM_types.h"
00066 
00067 #ifdef WITH_AUDASPACE
00068 #  include "AUD_C-API.h"
00069 #endif
00070 
00071 #include "ED_sound.h"
00072 #include "ED_util.h"
00073 
00074 #include "sound_intern.h"
00075 
00076 /******************** open sound operator ********************/
00077 
00078 static void open_init(bContext *C, wmOperator *op)
00079 {
00080         PropertyPointerRNA *pprop;
00081         
00082         op->customdata= pprop= MEM_callocN(sizeof(PropertyPointerRNA), "OpenPropertyPointerRNA");
00083         uiIDContextProperty(C, &pprop->ptr, &pprop->prop);
00084 }
00085 
00086 #ifdef WITH_AUDASPACE
00087 static int open_exec(bContext *C, wmOperator *op)
00088 {
00089         char path[FILE_MAX];
00090         bSound *sound;
00091         PropertyPointerRNA *pprop;
00092         PointerRNA idptr;
00093         AUD_SoundInfo info;
00094 
00095         RNA_string_get(op->ptr, "filepath", path);
00096         sound = sound_new_file(CTX_data_main(C), path);
00097 
00098         if(!op->customdata)
00099                 open_init(C, op);
00100         
00101         if (sound==NULL || sound->playback_handle == NULL) {
00102                 if(op->customdata) MEM_freeN(op->customdata);
00103                 BKE_report(op->reports, RPT_ERROR, "Unsupported audio format");
00104                 return OPERATOR_CANCELLED;
00105         }
00106 
00107         info = AUD_getInfo(sound->playback_handle);
00108 
00109         if (info.specs.channels == AUD_CHANNELS_INVALID) {
00110                 sound_delete(C, sound);
00111                 if(op->customdata) MEM_freeN(op->customdata);
00112                 BKE_report(op->reports, RPT_ERROR, "Unsupported audio format");
00113                 return OPERATOR_CANCELLED;
00114         }
00115 
00116         if (RNA_boolean_get(op->ptr, "cache")) {
00117                 sound_cache(sound, 0);
00118         }
00119         
00120         /* hook into UI */
00121         pprop= op->customdata;
00122         
00123         if(pprop->prop) {
00124                 /* when creating new ID blocks, use is already 1, but RNA
00125                  * pointer se also increases user, so this compensates it */
00126                 sound->id.us--;
00127                 
00128                 RNA_id_pointer_create(&sound->id, &idptr);
00129                 RNA_property_pointer_set(&pprop->ptr, pprop->prop, idptr);
00130                 RNA_property_update(C, &pprop->ptr, pprop->prop);
00131         }
00132 
00133         if(op->customdata) MEM_freeN(op->customdata);
00134         return OPERATOR_FINISHED;
00135 }
00136 
00137 #else //WITH_AUDASPACE
00138 
00139 static int open_exec(bContext *UNUSED(C), wmOperator *op)
00140 {
00141         BKE_report(op->reports, RPT_ERROR, "Compiled without sound support");
00142 
00143         return OPERATOR_CANCELLED;
00144 }
00145 
00146 #endif
00147 
00148 static int open_invoke(bContext *C, wmOperator *op, wmEvent *event)
00149 {
00150         if(!RNA_property_is_set(op->ptr, "relative_path"))
00151                 RNA_boolean_set(op->ptr, "relative_path", U.flag & USER_RELPATHS);
00152         
00153         if(RNA_property_is_set(op->ptr, "filepath"))
00154                 return open_exec(C, op);
00155         
00156         open_init(C, op);
00157         
00158         return WM_operator_filesel(C, op, event);
00159 }
00160 
00161 void SOUND_OT_open(wmOperatorType *ot)
00162 {
00163         /* identifiers */
00164         ot->name= "Open Sound";
00165         ot->description= "Load a sound file";
00166         ot->idname= "SOUND_OT_open";
00167 
00168         /* api callbacks */
00169         ot->exec= open_exec;
00170         ot->invoke= open_invoke;
00171 
00172         /* flags */
00173         ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
00174 
00175         /* properties */
00176         WM_operator_properties_filesel(ot, FOLDERFILE|SOUNDFILE|MOVIEFILE, FILE_SPECIAL, FILE_OPENFILE, WM_FILESEL_FILEPATH | WM_FILESEL_RELPATH);
00177         RNA_def_boolean(ot->srna, "cache", FALSE, "Cache", "Cache the sound in memory.");
00178 }
00179 
00180 /* ******************************************************* */
00181 
00182 static int sound_poll(bContext *C)
00183 {
00184         Editing* ed = CTX_data_scene(C)->ed;
00185 
00186         if(!ed || !ed->act_seq || ed->act_seq->type != SEQ_SOUND)
00187                 return 0;
00188 
00189         return 1;
00190 }
00191 /********************* pack operator *********************/
00192 
00193 static int pack_exec(bContext *C, wmOperator *op)
00194 {
00195         Editing* ed = CTX_data_scene(C)->ed;
00196         bSound* sound;
00197 
00198         if(!ed || !ed->act_seq || ed->act_seq->type != SEQ_SOUND)
00199                 return OPERATOR_CANCELLED;
00200 
00201         sound = ed->act_seq->sound;
00202 
00203         if(!sound || sound->packedfile)
00204                 return OPERATOR_CANCELLED;
00205 
00206         sound->packedfile= newPackedFile(op->reports, sound->name);
00207         sound_load(CTX_data_main(C), sound);
00208 
00209         return OPERATOR_FINISHED;
00210 }
00211 
00212 static void SOUND_OT_pack(wmOperatorType *ot)
00213 {
00214         /* identifiers */
00215         ot->name= "Pack Sound";
00216         ot->description= "Pack the sound into the current blend file";
00217         ot->idname= "SOUND_OT_pack";
00218 
00219         /* api callbacks */
00220         ot->exec= pack_exec;
00221         ot->poll= sound_poll;
00222 
00223         /* flags */
00224         ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
00225 }
00226 
00227 /********************* unpack operator *********************/
00228 
00229 static int sound_unpack_exec(bContext *C, wmOperator *op)
00230 {
00231         int method= RNA_enum_get(op->ptr, "method");
00232         bSound* sound= NULL;
00233 
00234         /* find the suppplied image by name */
00235         if (RNA_property_is_set(op->ptr, "id")) {
00236                 char sndname[MAX_ID_NAME-2];
00237                 RNA_string_get(op->ptr, "id", sndname);
00238                 sound = BLI_findstring(&CTX_data_main(C)->sound, sndname, offsetof(ID, name) + 2);
00239         }
00240 
00241         if(!sound || !sound->packedfile)
00242                 return OPERATOR_CANCELLED;
00243 
00244         if(G.fileflags & G_AUTOPACK)
00245                 BKE_report(op->reports, RPT_WARNING, "AutoPack is enabled, so image will be packed again on file save.");
00246 
00247         unpackSound(CTX_data_main(C), op->reports, sound, method);
00248 
00249         return OPERATOR_FINISHED;
00250 }
00251 
00252 static int sound_unpack_invoke(bContext *C, wmOperator *op, wmEvent *UNUSED(event))
00253 {
00254         Editing* ed = CTX_data_scene(C)->ed;
00255         bSound* sound;
00256 
00257         if(RNA_property_is_set(op->ptr, "id"))
00258                 return sound_unpack_exec(C, op);
00259 
00260         if(!ed || !ed->act_seq || ed->act_seq->type != SEQ_SOUND)
00261                 return OPERATOR_CANCELLED;
00262 
00263         sound = ed->act_seq->sound;
00264 
00265         if(!sound || !sound->packedfile)
00266                 return OPERATOR_CANCELLED;
00267 
00268         if(G.fileflags & G_AUTOPACK)
00269                 BKE_report(op->reports, RPT_WARNING, "AutoPack is enabled, so image will be packed again on file save.");
00270 
00271         unpack_menu(C, "SOUND_OT_unpack", sound->id.name+2, sound->name, "sounds", sound->packedfile);
00272 
00273         return OPERATOR_FINISHED;
00274 }
00275 
00276 static void SOUND_OT_unpack(wmOperatorType *ot)
00277 {
00278         /* identifiers */
00279         ot->name= "Unpack Sound";
00280         ot->description= "Unpack the sound to the samples filename";
00281         ot->idname= "SOUND_OT_unpack";
00282 
00283         /* api callbacks */
00284         ot->exec= sound_unpack_exec;
00285         ot->invoke= sound_unpack_invoke;
00286         ot->poll= sound_poll;
00287 
00288         /* flags */
00289         ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
00290 
00291         /* properties */
00292         RNA_def_enum(ot->srna, "method", unpack_method_items, PF_USE_LOCAL, "Method", "How to unpack.");
00293         RNA_def_string(ot->srna, "id", "", MAX_ID_NAME-2, "Sound Name", "Sound datablock name to unpack."); /* XXX, weark!, will fail with library, name collisions */
00294 }
00295 
00296 /* ******************************************************* */
00297 
00298 void ED_operatortypes_sound(void)
00299 {
00300         WM_operatortype_append(SOUND_OT_open);
00301         WM_operatortype_append(SOUND_OT_pack);
00302         WM_operatortype_append(SOUND_OT_unpack);
00303 }