Blender V2.61 - r43446

AUD_C-API.cpp

Go to the documentation of this file.
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 }