Blender V2.61 - r43446
|
00001 /* 00002 * ***** BEGIN GPL LICENSE BLOCK ***** 00003 * 00004 * Copyright 2009-2011 Jörg Hermann Müller 00005 * 00006 * This file is part of AudaSpace. 00007 * 00008 * Audaspace is free software; you can redistribute it and/or modify 00009 * it under the terms of the GNU General Public License as published by 00010 * the Free Software Foundation; either version 2 of the License, or 00011 * (at your option) any later version. 00012 * 00013 * AudaSpace is distributed in the hope that it will be useful, 00014 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00015 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00016 * GNU General Public License for more details. 00017 * 00018 * You should have received a copy of the GNU General Public License 00019 * along with Audaspace; if not, write to the Free Software Foundation, 00020 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 00021 * 00022 * ***** END GPL LICENSE BLOCK ***** 00023 */ 00024 00030 // needed for INT64_C 00031 #ifndef __STDC_CONSTANT_MACROS 00032 #define __STDC_CONSTANT_MACROS 00033 #endif 00034 00035 #ifdef WITH_PYTHON 00036 #include "AUD_PyInit.h" 00037 #include "AUD_PyAPI.h" 00038 #endif 00039 00040 #include <set> 00041 #include <cstdlib> 00042 #include <cstring> 00043 #include <cmath> 00044 00045 #include "AUD_NULLDevice.h" 00046 #include "AUD_I3DDevice.h" 00047 #include "AUD_I3DHandle.h" 00048 #include "AUD_FileFactory.h" 00049 #include "AUD_FileWriter.h" 00050 #include "AUD_StreamBufferFactory.h" 00051 #include "AUD_DelayFactory.h" 00052 #include "AUD_LimiterFactory.h" 00053 #include "AUD_PingPongFactory.h" 00054 #include "AUD_LoopFactory.h" 00055 #include "AUD_RectifyFactory.h" 00056 #include "AUD_EnvelopeFactory.h" 00057 #include "AUD_LinearResampleFactory.h" 00058 #include "AUD_LowpassFactory.h" 00059 #include "AUD_HighpassFactory.h" 00060 #include "AUD_AccumulatorFactory.h" 00061 #include "AUD_SumFactory.h" 00062 #include "AUD_SquareFactory.h" 00063 #include "AUD_ChannelMapperFactory.h" 00064 #include "AUD_Buffer.h" 00065 #include "AUD_ReadDevice.h" 00066 #include "AUD_IReader.h" 00067 #include "AUD_SequencerFactory.h" 00068 #include "AUD_SequencerEntry.h" 00069 #include "AUD_SilenceFactory.h" 00070 00071 #ifdef WITH_SDL 00072 #include "AUD_SDLDevice.h" 00073 #endif 00074 00075 #ifdef WITH_OPENAL 00076 #include "AUD_OpenALDevice.h" 00077 #endif 00078 00079 #ifdef WITH_JACK 00080 #include "AUD_JackDevice.h" 00081 #endif 00082 00083 00084 #ifdef WITH_FFMPEG 00085 extern "C" { 00086 #include <libavformat/avformat.h> 00087 } 00088 #endif 00089 00090 #include <cassert> 00091 00092 typedef AUD_Reference<AUD_IFactory> AUD_Sound; 00093 typedef AUD_Reference<AUD_ReadDevice> AUD_Device; 00094 typedef AUD_Reference<AUD_IHandle> AUD_Handle; 00095 typedef AUD_Reference<AUD_SequencerEntry> AUD_SEntry; 00096 00097 #define AUD_CAPI_IMPLEMENTATION 00098 #include "AUD_C-API.h" 00099 00100 #ifndef NULL 00101 #define NULL 0 00102 #endif 00103 00104 static AUD_Reference<AUD_IDevice> AUD_device; 00105 static AUD_I3DDevice* AUD_3ddevice; 00106 00107 void AUD_initOnce() 00108 { 00109 #ifdef WITH_FFMPEG 00110 av_register_all(); 00111 #endif 00112 } 00113 00114 int AUD_init(AUD_DeviceType device, AUD_DeviceSpecs specs, int buffersize) 00115 { 00116 AUD_Reference<AUD_IDevice> dev; 00117 00118 if(!AUD_device.isNull()) 00119 AUD_exit(); 00120 00121 try 00122 { 00123 switch(device) 00124 { 00125 case AUD_NULL_DEVICE: 00126 dev = new AUD_NULLDevice(); 00127 break; 00128 #ifdef WITH_SDL 00129 case AUD_SDL_DEVICE: 00130 dev = new AUD_SDLDevice(specs, buffersize); 00131 break; 00132 #endif 00133 #ifdef WITH_OPENAL 00134 case AUD_OPENAL_DEVICE: 00135 dev = new AUD_OpenALDevice(specs, buffersize); 00136 break; 00137 #endif 00138 #ifdef WITH_JACK 00139 case AUD_JACK_DEVICE: 00140 #ifdef __APPLE__ 00141 struct stat st; 00142 if(stat("/Library/Frameworks/Jackmp.framework", &st) != 0) 00143 { 00144 printf("Warning: Jack Framework not installed\n"); 00145 // No break, fall through to default, to return false 00146 } 00147 else 00148 { 00149 #endif 00150 dev = new AUD_JackDevice("Blender", specs, buffersize); 00151 break; 00152 #ifdef __APPLE__ 00153 } 00154 #endif 00155 #endif 00156 default: 00157 return false; 00158 } 00159 00160 AUD_device = dev; 00161 AUD_3ddevice = dynamic_cast<AUD_I3DDevice*>(AUD_device.get()); 00162 00163 return true; 00164 } 00165 catch(AUD_Exception&) 00166 { 00167 return false; 00168 } 00169 } 00170 00171 void AUD_exit() 00172 { 00173 AUD_device = AUD_Reference<AUD_IDevice>(); 00174 AUD_3ddevice = NULL; 00175 } 00176 00177 #ifdef WITH_PYTHON 00178 static PyObject* AUD_getCDevice(PyObject* self) 00179 { 00180 if(!AUD_device.isNull()) 00181 { 00182 Device* device = (Device*)Device_empty(); 00183 if(device != NULL) 00184 { 00185 device->device = new AUD_Reference<AUD_IDevice>(AUD_device); 00186 return (PyObject*)device; 00187 } 00188 } 00189 00190 Py_RETURN_NONE; 00191 } 00192 00193 static PyMethodDef meth_getcdevice[] = {{ "device", (PyCFunction)AUD_getCDevice, METH_NOARGS, 00194 "device()\n\n" 00195 "Returns the application's :class:`Device`.\n\n" 00196 ":return: The application's :class:`Device`.\n" 00197 ":rtype: :class:`Device`"}}; 00198 00199 extern "C" { 00200 extern void* sound_get_factory(void* sound); 00201 } 00202 00203 static PyObject* AUD_getSoundFromPointer(PyObject* self, PyObject* args) 00204 { 00205 long int lptr; 00206 00207 if(PyArg_Parse(args, "l:_sound_from_pointer", &lptr)) 00208 { 00209 if(lptr) 00210 { 00211 AUD_Reference<AUD_IFactory>* factory = (AUD_Reference<AUD_IFactory>*) sound_get_factory((void*) lptr); 00212 00213 if(factory) 00214 { 00215 Factory* obj = (Factory*) Factory_empty(); 00216 if(obj) 00217 { 00218 obj->factory = new AUD_Reference<AUD_IFactory>(*factory); 00219 return (PyObject*) obj; 00220 } 00221 } 00222 } 00223 } 00224 00225 Py_RETURN_NONE; 00226 } 00227 00228 static PyMethodDef meth_sound_from_pointer[] = {{ "_sound_from_pointer", (PyCFunction)AUD_getSoundFromPointer, METH_O, 00229 "_sound_from_pointer(pointer)\n\n" 00230 "Returns the corresponding :class:`Factory` object.\n\n" 00231 ":arg pointer: The pointer to the bSound object as long.\n" 00232 ":type pointer: long\n" 00233 ":return: The corresponding :class:`Factory` object.\n" 00234 ":rtype: :class:`Factory`"}}; 00235 00236 PyObject* AUD_initPython() 00237 { 00238 PyObject* module = PyInit_aud(); 00239 PyModule_AddObject(module, "device", (PyObject*)PyCFunction_New(meth_getcdevice, NULL)); 00240 PyModule_AddObject(module, "_sound_from_pointer", (PyObject*)PyCFunction_New(meth_sound_from_pointer, NULL)); 00241 PyDict_SetItemString(PyImport_GetModuleDict(), "aud", module); 00242 00243 return module; 00244 } 00245 00246 PyObject* AUD_getPythonFactory(AUD_Sound* sound) 00247 { 00248 if(sound) 00249 { 00250 Factory* obj = (Factory*) Factory_empty(); 00251 if(obj) 00252 { 00253 obj->factory = new AUD_Reference<AUD_IFactory>(*sound); 00254 return (PyObject*) obj; 00255 } 00256 } 00257 00258 return NULL; 00259 } 00260 00261 AUD_Sound* AUD_getPythonSound(PyObject* sound) 00262 { 00263 Factory* factory = checkFactory(sound); 00264 00265 if(!factory) 00266 return NULL; 00267 00268 return new AUD_Reference<AUD_IFactory>(*reinterpret_cast<AUD_Reference<AUD_IFactory>*>(factory->factory)); 00269 } 00270 00271 #endif 00272 00273 void AUD_lock() 00274 { 00275 AUD_device->lock(); 00276 } 00277 00278 void AUD_unlock() 00279 { 00280 AUD_device->unlock(); 00281 } 00282 00283 AUD_SoundInfo AUD_getInfo(AUD_Sound* sound) 00284 { 00285 assert(sound); 00286 00287 AUD_SoundInfo info; 00288 info.specs.channels = AUD_CHANNELS_INVALID; 00289 info.specs.rate = AUD_RATE_INVALID; 00290 info.length = 0.0f; 00291 00292 try 00293 { 00294 AUD_Reference<AUD_IReader> reader = (*sound)->createReader(); 00295 00296 if(!reader.isNull()) 00297 { 00298 info.specs = reader->getSpecs(); 00299 info.length = reader->getLength() / (float) info.specs.rate; 00300 } 00301 } 00302 catch(AUD_Exception&) 00303 { 00304 } 00305 00306 return info; 00307 } 00308 00309 AUD_Sound* AUD_load(const char* filename) 00310 { 00311 assert(filename); 00312 return new AUD_Sound(new AUD_FileFactory(filename)); 00313 } 00314 00315 AUD_Sound* AUD_loadBuffer(unsigned char* buffer, int size) 00316 { 00317 assert(buffer); 00318 return new AUD_Sound(new AUD_FileFactory(buffer, size)); 00319 } 00320 00321 AUD_Sound* AUD_bufferSound(AUD_Sound* sound) 00322 { 00323 assert(sound); 00324 00325 try 00326 { 00327 return new AUD_Sound(new AUD_StreamBufferFactory(*sound)); 00328 } 00329 catch(AUD_Exception&) 00330 { 00331 return NULL; 00332 } 00333 } 00334 00335 AUD_Sound* AUD_monoSound(AUD_Sound* sound) 00336 { 00337 assert(sound); 00338 00339 try 00340 { 00341 AUD_DeviceSpecs specs; 00342 specs.channels = AUD_CHANNELS_MONO; 00343 specs.rate = AUD_RATE_INVALID; 00344 specs.format = AUD_FORMAT_INVALID; 00345 return new AUD_Sound(new AUD_ChannelMapperFactory(*sound, specs)); 00346 } 00347 catch(AUD_Exception&) 00348 { 00349 return NULL; 00350 } 00351 } 00352 00353 AUD_Sound* AUD_delaySound(AUD_Sound* sound, float delay) 00354 { 00355 assert(sound); 00356 00357 try 00358 { 00359 return new AUD_Sound(new AUD_DelayFactory(*sound, delay)); 00360 } 00361 catch(AUD_Exception&) 00362 { 00363 return NULL; 00364 } 00365 } 00366 00367 AUD_Sound* AUD_limitSound(AUD_Sound* sound, float start, float end) 00368 { 00369 assert(sound); 00370 00371 try 00372 { 00373 return new AUD_Sound(new AUD_LimiterFactory(*sound, start, end)); 00374 } 00375 catch(AUD_Exception&) 00376 { 00377 return NULL; 00378 } 00379 } 00380 00381 AUD_Sound* AUD_pingpongSound(AUD_Sound* sound) 00382 { 00383 assert(sound); 00384 00385 try 00386 { 00387 return new AUD_Sound(new AUD_PingPongFactory(*sound)); 00388 } 00389 catch(AUD_Exception&) 00390 { 00391 return NULL; 00392 } 00393 } 00394 00395 AUD_Sound* AUD_loopSound(AUD_Sound* sound) 00396 { 00397 assert(sound); 00398 00399 try 00400 { 00401 return new AUD_Sound(new AUD_LoopFactory(*sound)); 00402 } 00403 catch(AUD_Exception&) 00404 { 00405 return NULL; 00406 } 00407 } 00408 00409 int AUD_setLoop(AUD_Handle* handle, int loops) 00410 { 00411 assert(handle); 00412 00413 try 00414 { 00415 return (*handle)->setLoopCount(loops); 00416 } 00417 catch(AUD_Exception&) 00418 { 00419 } 00420 00421 return false; 00422 } 00423 00424 AUD_Sound* AUD_rectifySound(AUD_Sound* sound) 00425 { 00426 assert(sound); 00427 00428 try 00429 { 00430 return new AUD_Sound(new AUD_RectifyFactory(*sound)); 00431 } 00432 catch(AUD_Exception&) 00433 { 00434 return NULL; 00435 } 00436 } 00437 00438 void AUD_unload(AUD_Sound* sound) 00439 { 00440 assert(sound); 00441 delete sound; 00442 } 00443 00444 AUD_Handle* AUD_play(AUD_Sound* sound, int keep) 00445 { 00446 assert(sound); 00447 try 00448 { 00449 AUD_Handle handle = AUD_device->play(*sound, keep); 00450 if(!handle.isNull()) 00451 return new AUD_Handle(handle); 00452 } 00453 catch(AUD_Exception&) 00454 { 00455 } 00456 return NULL; 00457 } 00458 00459 int AUD_pause(AUD_Handle* handle) 00460 { 00461 assert(handle); 00462 return (*handle)->pause(); 00463 } 00464 00465 int AUD_resume(AUD_Handle* handle) 00466 { 00467 assert(handle); 00468 return (*handle)->resume(); 00469 } 00470 00471 int AUD_stop(AUD_Handle* handle) 00472 { 00473 assert(handle); 00474 int result = (*handle)->stop(); 00475 delete handle; 00476 return result; 00477 } 00478 00479 int AUD_setKeep(AUD_Handle* handle, int keep) 00480 { 00481 assert(handle); 00482 return (*handle)->setKeep(keep); 00483 } 00484 00485 int AUD_seek(AUD_Handle* handle, float seekTo) 00486 { 00487 assert(handle); 00488 return (*handle)->seek(seekTo); 00489 } 00490 00491 float AUD_getPosition(AUD_Handle* handle) 00492 { 00493 assert(handle); 00494 return (*handle)->getPosition(); 00495 } 00496 00497 AUD_Status AUD_getStatus(AUD_Handle* handle) 00498 { 00499 assert(handle); 00500 return (*handle)->getStatus(); 00501 } 00502 00503 int AUD_setListenerLocation(const float* location) 00504 { 00505 if(AUD_3ddevice) 00506 { 00507 AUD_Vector3 v(location[0], location[1], location[2]); 00508 AUD_3ddevice->setListenerLocation(v); 00509 return true; 00510 } 00511 00512 return false; 00513 } 00514 00515 int AUD_setListenerVelocity(const float* velocity) 00516 { 00517 if(AUD_3ddevice) 00518 { 00519 AUD_Vector3 v(velocity[0], velocity[1], velocity[2]); 00520 AUD_3ddevice->setListenerVelocity(v); 00521 return true; 00522 } 00523 00524 return false; 00525 } 00526 00527 int AUD_setListenerOrientation(const float* orientation) 00528 { 00529 if(AUD_3ddevice) 00530 { 00531 AUD_Quaternion q(orientation[3], orientation[0], orientation[1], orientation[2]); 00532 AUD_3ddevice->setListenerOrientation(q); 00533 return true; 00534 } 00535 00536 return false; 00537 } 00538 00539 int AUD_setSpeedOfSound(float speed) 00540 { 00541 if(AUD_3ddevice) 00542 { 00543 AUD_3ddevice->setSpeedOfSound(speed); 00544 return true; 00545 } 00546 00547 return false; 00548 } 00549 00550 int AUD_setDopplerFactor(float factor) 00551 { 00552 if(AUD_3ddevice) 00553 { 00554 AUD_3ddevice->setDopplerFactor(factor); 00555 return true; 00556 } 00557 00558 return false; 00559 } 00560 00561 int AUD_setDistanceModel(AUD_DistanceModel model) 00562 { 00563 if(AUD_3ddevice) 00564 { 00565 AUD_3ddevice->setDistanceModel(model); 00566 return true; 00567 } 00568 00569 return false; 00570 } 00571 00572 int AUD_setSourceLocation(AUD_Handle* handle, const float* location) 00573 { 00574 assert(handle); 00575 AUD_Reference<AUD_I3DHandle> h(*handle); 00576 00577 if(!h.isNull()) 00578 { 00579 AUD_Vector3 v(location[0], location[1], location[2]); 00580 return h->setSourceLocation(v); 00581 } 00582 00583 return false; 00584 } 00585 00586 int AUD_setSourceVelocity(AUD_Handle* handle, const float* velocity) 00587 { 00588 assert(handle); 00589 AUD_Reference<AUD_I3DHandle> h(*handle); 00590 00591 if(!h.isNull()) 00592 { 00593 AUD_Vector3 v(velocity[0], velocity[1], velocity[2]); 00594 return h->setSourceVelocity(v); 00595 } 00596 00597 return false; 00598 } 00599 00600 int AUD_setSourceOrientation(AUD_Handle* handle, const float* orientation) 00601 { 00602 assert(handle); 00603 AUD_Reference<AUD_I3DHandle> h(*handle); 00604 00605 if(!h.isNull()) 00606 { 00607 AUD_Quaternion q(orientation[3], orientation[0], orientation[1], orientation[2]); 00608 return h->setSourceOrientation(q); 00609 } 00610 00611 return false; 00612 } 00613 00614 int AUD_setRelative(AUD_Handle* handle, int relative) 00615 { 00616 assert(handle); 00617 AUD_Reference<AUD_I3DHandle> h(*handle); 00618 00619 if(!h.isNull()) 00620 { 00621 return h->setRelative(relative); 00622 } 00623 00624 return false; 00625 } 00626 00627 int AUD_setVolumeMaximum(AUD_Handle* handle, float volume) 00628 { 00629 assert(handle); 00630 AUD_Reference<AUD_I3DHandle> h(*handle); 00631 00632 if(!h.isNull()) 00633 { 00634 return h->setVolumeMaximum(volume); 00635 } 00636 00637 return false; 00638 } 00639 00640 int AUD_setVolumeMinimum(AUD_Handle* handle, float volume) 00641 { 00642 assert(handle); 00643 AUD_Reference<AUD_I3DHandle> h(*handle); 00644 00645 if(!h.isNull()) 00646 { 00647 return h->setVolumeMinimum(volume); 00648 } 00649 00650 return false; 00651 } 00652 00653 int AUD_setDistanceMaximum(AUD_Handle* handle, float distance) 00654 { 00655 assert(handle); 00656 AUD_Reference<AUD_I3DHandle> h(*handle); 00657 00658 if(!h.isNull()) 00659 { 00660 return h->setDistanceMaximum(distance); 00661 } 00662 00663 return false; 00664 } 00665 00666 int AUD_setDistanceReference(AUD_Handle* handle, float distance) 00667 { 00668 assert(handle); 00669 AUD_Reference<AUD_I3DHandle> h(*handle); 00670 00671 if(!h.isNull()) 00672 { 00673 return h->setDistanceReference(distance); 00674 } 00675 00676 return false; 00677 } 00678 00679 int AUD_setAttenuation(AUD_Handle* handle, float factor) 00680 { 00681 assert(handle); 00682 AUD_Reference<AUD_I3DHandle> h(*handle); 00683 00684 if(!h.isNull()) 00685 { 00686 return h->setAttenuation(factor); 00687 } 00688 00689 return false; 00690 } 00691 00692 int AUD_setConeAngleOuter(AUD_Handle* handle, float angle) 00693 { 00694 assert(handle); 00695 AUD_Reference<AUD_I3DHandle> h(*handle); 00696 00697 if(!h.isNull()) 00698 { 00699 return h->setConeAngleOuter(angle); 00700 } 00701 00702 return false; 00703 } 00704 00705 int AUD_setConeAngleInner(AUD_Handle* handle, float angle) 00706 { 00707 assert(handle); 00708 AUD_Reference<AUD_I3DHandle> h(*handle); 00709 00710 if(!h.isNull()) 00711 { 00712 return h->setConeAngleInner(angle); 00713 } 00714 00715 return false; 00716 } 00717 00718 int AUD_setConeVolumeOuter(AUD_Handle* handle, float volume) 00719 { 00720 assert(handle); 00721 AUD_Reference<AUD_I3DHandle> h(*handle); 00722 00723 if(!h.isNull()) 00724 { 00725 return h->setConeVolumeOuter(volume); 00726 } 00727 00728 return false; 00729 } 00730 00731 int AUD_setSoundVolume(AUD_Handle* handle, float volume) 00732 { 00733 assert(handle); 00734 try 00735 { 00736 return (*handle)->setVolume(volume); 00737 } 00738 catch(AUD_Exception&) {} 00739 return false; 00740 } 00741 00742 int AUD_setSoundPitch(AUD_Handle* handle, float pitch) 00743 { 00744 assert(handle); 00745 try 00746 { 00747 return (*handle)->setPitch(pitch); 00748 } 00749 catch(AUD_Exception&) {} 00750 return false; 00751 } 00752 00753 AUD_Device* AUD_openReadDevice(AUD_DeviceSpecs specs) 00754 { 00755 try 00756 { 00757 return new AUD_Device(new AUD_ReadDevice(specs)); 00758 } 00759 catch(AUD_Exception&) 00760 { 00761 return NULL; 00762 } 00763 } 00764 00765 AUD_Handle* AUD_playDevice(AUD_Device* device, AUD_Sound* sound, float seek) 00766 { 00767 assert(device); 00768 assert(sound); 00769 00770 try 00771 { 00772 AUD_Handle handle = (*device)->play(*sound); 00773 if(!handle.isNull()) 00774 { 00775 handle->seek(seek); 00776 return new AUD_Handle(handle); 00777 } 00778 } 00779 catch(AUD_Exception&) 00780 { 00781 } 00782 return NULL; 00783 } 00784 00785 int AUD_setDeviceVolume(AUD_Device* device, float volume) 00786 { 00787 assert(device); 00788 00789 try 00790 { 00791 (*device)->setVolume(volume); 00792 return true; 00793 } 00794 catch(AUD_Exception&) {} 00795 00796 return false; 00797 } 00798 00799 int AUD_readDevice(AUD_Device* device, data_t* buffer, int length) 00800 { 00801 assert(device); 00802 assert(buffer); 00803 00804 try 00805 { 00806 return (*device)->read(buffer, length); 00807 } 00808 catch(AUD_Exception&) 00809 { 00810 return false; 00811 } 00812 } 00813 00814 void AUD_closeReadDevice(AUD_Device* device) 00815 { 00816 assert(device); 00817 00818 try 00819 { 00820 delete device; 00821 } 00822 catch(AUD_Exception&) 00823 { 00824 } 00825 } 00826 00827 float* AUD_readSoundBuffer(const char* filename, float low, float high, 00828 float attack, float release, float threshold, 00829 int accumulate, int additive, int square, 00830 float sthreshold, double samplerate, int* length) 00831 { 00832 AUD_Buffer buffer; 00833 AUD_DeviceSpecs specs; 00834 specs.channels = AUD_CHANNELS_MONO; 00835 specs.rate = (AUD_SampleRate)samplerate; 00836 AUD_Reference<AUD_IFactory> sound; 00837 00838 AUD_Reference<AUD_IFactory> file = new AUD_FileFactory(filename); 00839 00840 int position = 0; 00841 00842 try 00843 { 00844 AUD_Reference<AUD_IReader> reader = file->createReader(); 00845 00846 AUD_SampleRate rate = reader->getSpecs().rate; 00847 00848 sound = new AUD_ChannelMapperFactory(file, specs); 00849 00850 if(high < rate) 00851 sound = new AUD_LowpassFactory(sound, high); 00852 if(low > 0) 00853 sound = new AUD_HighpassFactory(sound, low); 00854 00855 sound = new AUD_EnvelopeFactory(sound, attack, release, threshold, 0.1f); 00856 sound = new AUD_LinearResampleFactory(sound, specs); 00857 00858 if(square) 00859 sound = new AUD_SquareFactory(sound, sthreshold); 00860 00861 if(accumulate) 00862 sound = new AUD_AccumulatorFactory(sound, additive); 00863 else if(additive) 00864 sound = new AUD_SumFactory(sound); 00865 00866 reader = sound->createReader(); 00867 00868 if(reader.isNull()) 00869 return NULL; 00870 00871 int len; 00872 bool eos; 00873 do 00874 { 00875 len = samplerate; 00876 buffer.resize((position + len) * sizeof(float), true); 00877 reader->read(len, eos, buffer.getBuffer() + position); 00878 position += len; 00879 } while(!eos); 00880 } 00881 catch(AUD_Exception&) 00882 { 00883 return NULL; 00884 } 00885 00886 float* result = (float*)malloc(position * sizeof(float)); 00887 memcpy(result, buffer.getBuffer(), position * sizeof(float)); 00888 *length = position; 00889 return result; 00890 } 00891 00892 static void pauseSound(AUD_Handle* handle) 00893 { 00894 assert(handle); 00895 (*handle)->pause(); 00896 } 00897 00898 AUD_Handle* AUD_pauseAfter(AUD_Handle* handle, float seconds) 00899 { 00900 AUD_Reference<AUD_IFactory> silence = new AUD_SilenceFactory; 00901 AUD_Reference<AUD_IFactory> limiter = new AUD_LimiterFactory(silence, 0, seconds); 00902 00903 AUD_device->lock(); 00904 00905 try 00906 { 00907 AUD_Handle handle2 = AUD_device->play(limiter); 00908 if(!handle2.isNull()) 00909 { 00910 handle2->setStopCallback((stopCallback)pauseSound, handle); 00911 AUD_device->unlock(); 00912 return new AUD_Handle(handle2); 00913 } 00914 } 00915 catch(AUD_Exception&) 00916 { 00917 } 00918 00919 AUD_device->unlock(); 00920 00921 return NULL; 00922 } 00923 00924 AUD_Sound* AUD_createSequencer(float fps, int muted) 00925 { 00926 // specs are changed at a later point! 00927 AUD_Specs specs; 00928 specs.channels = AUD_CHANNELS_STEREO; 00929 specs.rate = AUD_RATE_44100; 00930 AUD_Sound* sequencer = new AUD_Sound(AUD_Reference<AUD_SequencerFactory>(new AUD_SequencerFactory(specs, fps, muted))); 00931 return sequencer; 00932 } 00933 00934 void AUD_destroySequencer(AUD_Sound* sequencer) 00935 { 00936 delete sequencer; 00937 } 00938 00939 void AUD_setSequencerMuted(AUD_Sound* sequencer, int muted) 00940 { 00941 dynamic_cast<AUD_SequencerFactory*>(sequencer->get())->mute(muted); 00942 } 00943 00944 void AUD_setSequencerFPS(AUD_Sound* sequencer, float fps) 00945 { 00946 dynamic_cast<AUD_SequencerFactory*>(sequencer->get())->setFPS(fps); 00947 } 00948 00949 AUD_SEntry* AUD_addSequence(AUD_Sound* sequencer, AUD_Sound* sound, 00950 float begin, float end, float skip) 00951 { 00952 if(!sound) 00953 return new AUD_SEntry(((AUD_SequencerFactory*)sequencer->get())->add(AUD_Sound(), begin, end, skip)); 00954 return new AUD_SEntry(((AUD_SequencerFactory*)sequencer->get())->add(*sound, begin, end, skip)); 00955 } 00956 00957 void AUD_removeSequence(AUD_Sound* sequencer, AUD_SEntry* entry) 00958 { 00959 dynamic_cast<AUD_SequencerFactory*>(sequencer->get())->remove(*entry); 00960 delete entry; 00961 } 00962 00963 void AUD_moveSequence(AUD_SEntry* entry, float begin, float end, float skip) 00964 { 00965 (*entry)->move(begin, end, skip); 00966 } 00967 00968 void AUD_muteSequence(AUD_SEntry* entry, char mute) 00969 { 00970 (*entry)->mute(mute); 00971 } 00972 00973 void AUD_setRelativeSequence(AUD_SEntry* entry, char relative) 00974 { 00975 (*entry)->setRelative(relative); 00976 } 00977 00978 void AUD_updateSequenceSound(AUD_SEntry* entry, AUD_Sound* sound) 00979 { 00980 if(sound) 00981 (*entry)->setSound(*sound); 00982 else 00983 (*entry)->setSound(AUD_Sound()); 00984 } 00985 00986 void AUD_setSequenceAnimData(AUD_SEntry* entry, AUD_AnimateablePropertyType type, int frame, float* data, char animated) 00987 { 00988 AUD_AnimateableProperty* prop = (*entry)->getAnimProperty(type); 00989 if(animated) 00990 { 00991 if(frame >= 0) 00992 prop->write(data, frame, 1); 00993 } 00994 else 00995 prop->write(data); 00996 } 00997 00998 void AUD_setSequencerAnimData(AUD_Sound* sequencer, AUD_AnimateablePropertyType type, int frame, float* data, char animated) 00999 { 01000 AUD_AnimateableProperty* prop = dynamic_cast<AUD_SequencerFactory*>(sequencer->get())->getAnimProperty(type); 01001 if(animated) 01002 { 01003 if(frame >= 0) 01004 prop->write(data, frame, 1); 01005 } 01006 else 01007 prop->write(data); 01008 } 01009 01010 void AUD_updateSequenceData(AUD_SEntry* entry, float volume_max, float volume_min, 01011 float distance_max, float distance_reference, float attenuation, 01012 float cone_angle_outer, float cone_angle_inner, float cone_volume_outer) 01013 { 01014 (*entry)->updateAll(volume_max, volume_min, distance_max, distance_reference, attenuation, 01015 cone_angle_outer, cone_angle_inner, cone_volume_outer); 01016 } 01017 01018 void AUD_updateSequencerData(AUD_Sound* sequencer, float speed_of_sound, 01019 float factor, AUD_DistanceModel model) 01020 { 01021 AUD_SequencerFactory* f = dynamic_cast<AUD_SequencerFactory*>(sequencer->get()); 01022 f->setSpeedOfSound(speed_of_sound); 01023 f->setDopplerFactor(factor); 01024 f->setDistanceModel(model); 01025 } 01026 01027 void AUD_setSequencerDeviceSpecs(AUD_Sound* sequencer) 01028 { 01029 dynamic_cast<AUD_SequencerFactory*>(sequencer->get())->setSpecs(AUD_device->getSpecs().specs); 01030 } 01031 01032 void AUD_setSequencerSpecs(AUD_Sound* sequencer, AUD_Specs specs) 01033 { 01034 dynamic_cast<AUD_SequencerFactory*>(sequencer->get())->setSpecs(specs); 01035 } 01036 01037 void AUD_seekSequencer(AUD_Handle* handle, float time) 01038 { 01039 #ifdef WITH_JACK 01040 AUD_JackDevice* device = dynamic_cast<AUD_JackDevice*>(AUD_device.get()); 01041 if(device) 01042 device->seekPlayback(time); 01043 else 01044 #endif 01045 { 01046 assert(handle); 01047 (*handle)->seek(time); 01048 } 01049 } 01050 01051 float AUD_getSequencerPosition(AUD_Handle* handle) 01052 { 01053 #ifdef WITH_JACK 01054 AUD_JackDevice* device = dynamic_cast<AUD_JackDevice*>(AUD_device.get()); 01055 if(device) 01056 return device->getPlaybackPosition(); 01057 else 01058 #endif 01059 { 01060 assert(handle); 01061 return (*handle)->getPosition(); 01062 } 01063 } 01064 01065 void AUD_startPlayback() 01066 { 01067 #ifdef WITH_JACK 01068 AUD_JackDevice* device = dynamic_cast<AUD_JackDevice*>(AUD_device.get()); 01069 if(device) 01070 device->startPlayback(); 01071 #endif 01072 } 01073 01074 void AUD_stopPlayback() 01075 { 01076 #ifdef WITH_JACK 01077 AUD_JackDevice* device = dynamic_cast<AUD_JackDevice*>(AUD_device.get()); 01078 if(device) 01079 device->stopPlayback(); 01080 #endif 01081 } 01082 01083 #ifdef WITH_JACK 01084 void AUD_setSyncCallback(AUD_syncFunction function, void* data) 01085 { 01086 AUD_JackDevice* device = dynamic_cast<AUD_JackDevice*>(AUD_device.get()); 01087 if(device) 01088 device->setSyncCallback(function, data); 01089 } 01090 #endif 01091 01092 int AUD_doesPlayback() 01093 { 01094 #ifdef WITH_JACK 01095 AUD_JackDevice* device = dynamic_cast<AUD_JackDevice*>(AUD_device.get()); 01096 if(device) 01097 return device->doesPlayback(); 01098 #endif 01099 return -1; 01100 } 01101 01102 int AUD_readSound(AUD_Sound* sound, sample_t* buffer, int length, int samples_per_second) 01103 { 01104 AUD_DeviceSpecs specs; 01105 sample_t* buf; 01106 AUD_Buffer aBuffer; 01107 01108 specs.rate = AUD_RATE_INVALID; 01109 specs.channels = AUD_CHANNELS_MONO; 01110 specs.format = AUD_FORMAT_INVALID; 01111 01112 AUD_Reference<AUD_IReader> reader = AUD_ChannelMapperFactory(*sound, specs).createReader(); 01113 01114 specs.specs = reader->getSpecs(); 01115 int len; 01116 float samplejump = specs.rate / samples_per_second; 01117 float min, max, power, overallmax; 01118 bool eos; 01119 01120 overallmax = 0; 01121 01122 for(int i = 0; i < length; i++) 01123 { 01124 len = floor(samplejump * (i+1)) - floor(samplejump * i); 01125 01126 aBuffer.assureSize(len * AUD_SAMPLE_SIZE(specs)); 01127 buf = aBuffer.getBuffer(); 01128 01129 reader->read(len, eos, buf); 01130 01131 max = min = *buf; 01132 power = *buf * *buf; 01133 for(int j = 1; j < len; j++) 01134 { 01135 if(buf[j] < min) 01136 min = buf[j]; 01137 if(buf[j] > max) 01138 max = buf[j]; 01139 power += buf[j] * buf[j]; 01140 } 01141 01142 buffer[i * 3] = min; 01143 buffer[i * 3 + 1] = max; 01144 buffer[i * 3 + 2] = sqrt(power) / len; 01145 01146 if(overallmax < max) 01147 overallmax = max; 01148 if(overallmax < -min) 01149 overallmax = -min; 01150 01151 if(eos) 01152 { 01153 length = i; 01154 break; 01155 } 01156 } 01157 01158 if(overallmax > 1.0f) 01159 { 01160 for(int i = 0; i < length * 3; i++) 01161 { 01162 buffer[i] /= overallmax; 01163 } 01164 } 01165 01166 return length; 01167 } 01168 01169 AUD_Sound* AUD_copy(AUD_Sound* sound) 01170 { 01171 return new AUD_Reference<AUD_IFactory>(*sound); 01172 } 01173 01174 void AUD_freeHandle(AUD_Handle* handle) 01175 { 01176 delete handle; 01177 } 01178 01179 void* AUD_createSet() 01180 { 01181 return new std::set<void*>(); 01182 } 01183 01184 void AUD_destroySet(void* set) 01185 { 01186 delete reinterpret_cast<std::set<void*>*>(set); 01187 } 01188 01189 char AUD_removeSet(void* set, void* entry) 01190 { 01191 if(set) 01192 return reinterpret_cast<std::set<void*>*>(set)->erase(entry); 01193 return 0; 01194 } 01195 01196 void AUD_addSet(void* set, void* entry) 01197 { 01198 if(entry) 01199 reinterpret_cast<std::set<void*>*>(set)->insert(entry); 01200 } 01201 01202 void* AUD_getSet(void* set) 01203 { 01204 if(set) 01205 { 01206 std::set<void*>* rset = reinterpret_cast<std::set<void*>*>(set); 01207 if(!rset->empty()) 01208 { 01209 std::set<void*>::iterator it = rset->begin(); 01210 void* result = *it; 01211 rset->erase(it); 01212 return result; 01213 } 01214 } 01215 01216 return NULL; 01217 } 01218 01219 const char* AUD_mixdown(AUD_Sound* sound, unsigned int start, unsigned int length, unsigned int buffersize, const char* filename, AUD_DeviceSpecs specs, AUD_Container format, AUD_Codec codec, unsigned int bitrate) 01220 { 01221 try 01222 { 01223 AUD_SequencerFactory* f = dynamic_cast<AUD_SequencerFactory*>(sound->get()); 01224 01225 f->setSpecs(specs.specs); 01226 AUD_Reference<AUD_IReader> reader = f->createQualityReader(); 01227 reader->seek(start); 01228 AUD_Reference<AUD_IWriter> writer = AUD_FileWriter::createWriter(filename, specs, format, codec, bitrate); 01229 AUD_FileWriter::writeReader(reader, writer, length, buffersize); 01230 01231 return NULL; 01232 } 01233 catch(AUD_Exception& e) 01234 { 01235 return e.str; 01236 } 01237 } 01238 01239 AUD_Device* AUD_openMixdownDevice(AUD_DeviceSpecs specs, AUD_Sound* sequencer, float volume, float start) 01240 { 01241 try 01242 { 01243 AUD_ReadDevice* device = new AUD_ReadDevice(specs); 01244 device->setQuality(true); 01245 device->setVolume(volume); 01246 01247 dynamic_cast<AUD_SequencerFactory*>(sequencer->get())->setSpecs(specs.specs); 01248 01249 AUD_Handle handle = device->play(*sequencer); 01250 if(!handle.isNull()) 01251 handle->seek(start); 01252 01253 return new AUD_Device(device); 01254 } 01255 catch(AUD_Exception&) 01256 { 01257 return NULL; 01258 } 01259 } 01260 01261 AUD_Reference<AUD_IDevice> AUD_getDevice() 01262 { 01263 return AUD_device; 01264 } 01265 01266 AUD_I3DDevice* AUD_get3DDevice() 01267 { 01268 return AUD_3ddevice; 01269 }