Fix for [#28916] 2.6 RC2 - Bake Sound to FCurve Crash
[blender.git] / intern / audaspace / intern / AUD_C-API.cpp
1 /*
2  * $Id$
3  *
4  * ***** BEGIN GPL LICENSE BLOCK *****
5  *
6  * Copyright 2009-2011 Jörg Hermann Müller
7  *
8  * This file is part of AudaSpace.
9  *
10  * Audaspace is free software; you can redistribute it and/or modify
11  * it under the terms of the GNU General Public License as published by
12  * the Free Software Foundation; either version 2 of the License, or
13  * (at your option) any later version.
14  *
15  * AudaSpace is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  * GNU General Public License for more details.
19  *
20  * You should have received a copy of the GNU General Public License
21  * along with Audaspace; if not, write to the Free Software Foundation,
22  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
23  *
24  * ***** END GPL LICENSE BLOCK *****
25  */
26
27 /** \file audaspace/intern/AUD_C-API.cpp
28  *  \ingroup audaspaceintern
29  */
30
31
32 // needed for INT64_C
33 #ifndef __STDC_CONSTANT_MACROS
34 #define __STDC_CONSTANT_MACROS
35 #endif
36
37 #ifdef WITH_PYTHON
38 #include "AUD_PyInit.h"
39 #include "AUD_PyAPI.h"
40 #endif
41
42 #include <set>
43 #include <cstdlib>
44 #include <cstring>
45 #include <cmath>
46
47 #include "AUD_NULLDevice.h"
48 #include "AUD_I3DDevice.h"
49 #include "AUD_I3DHandle.h"
50 #include "AUD_FileFactory.h"
51 #include "AUD_FileWriter.h"
52 #include "AUD_StreamBufferFactory.h"
53 #include "AUD_DelayFactory.h"
54 #include "AUD_LimiterFactory.h"
55 #include "AUD_PingPongFactory.h"
56 #include "AUD_LoopFactory.h"
57 #include "AUD_RectifyFactory.h"
58 #include "AUD_EnvelopeFactory.h"
59 #include "AUD_LinearResampleFactory.h"
60 #include "AUD_LowpassFactory.h"
61 #include "AUD_HighpassFactory.h"
62 #include "AUD_AccumulatorFactory.h"
63 #include "AUD_SumFactory.h"
64 #include "AUD_SquareFactory.h"
65 #include "AUD_ChannelMapperFactory.h"
66 #include "AUD_Buffer.h"
67 #include "AUD_ReadDevice.h"
68 #include "AUD_IReader.h"
69 #include "AUD_SequencerFactory.h"
70 #include "AUD_SequencerEntry.h"
71 #include "AUD_SilenceFactory.h"
72
73 #ifdef WITH_SDL
74 #include "AUD_SDLDevice.h"
75 #endif
76
77 #ifdef WITH_OPENAL
78 #include "AUD_OpenALDevice.h"
79 #endif
80
81 #ifdef WITH_JACK
82 #include "AUD_JackDevice.h"
83 #endif
84
85
86 #ifdef WITH_FFMPEG
87 extern "C" {
88 #include <libavformat/avformat.h>
89 }
90 #endif
91
92 #include <cassert>
93
94 typedef AUD_Reference<AUD_IFactory> AUD_Sound;
95 typedef AUD_Reference<AUD_ReadDevice> AUD_Device;
96 typedef AUD_Reference<AUD_IHandle> AUD_Handle;
97 typedef AUD_Reference<AUD_SequencerEntry> AUD_SEntry;
98
99 #define AUD_CAPI_IMPLEMENTATION
100 #include "AUD_C-API.h"
101
102 #ifndef NULL
103 #define NULL 0
104 #endif
105
106 static AUD_Reference<AUD_IDevice> AUD_device;
107 static AUD_I3DDevice* AUD_3ddevice;
108
109 void AUD_initOnce()
110 {
111 #ifdef WITH_FFMPEG
112         av_register_all();
113 #endif
114 }
115
116 int AUD_init(AUD_DeviceType device, AUD_DeviceSpecs specs, int buffersize)
117 {
118         AUD_Reference<AUD_IDevice> dev;
119
120         if(!AUD_device.isNull())
121                 AUD_exit();
122
123         try
124         {
125                 switch(device)
126                 {
127                 case AUD_NULL_DEVICE:
128                         dev = new AUD_NULLDevice();
129                         break;
130 #ifdef WITH_SDL
131                 case AUD_SDL_DEVICE:
132                         dev = new AUD_SDLDevice(specs, buffersize);
133                         break;
134 #endif
135 #ifdef WITH_OPENAL
136                 case AUD_OPENAL_DEVICE:
137                         dev = new AUD_OpenALDevice(specs, buffersize);
138                         break;
139 #endif
140 #ifdef WITH_JACK
141                 case AUD_JACK_DEVICE:
142                         dev = new AUD_JackDevice("Blender", specs, buffersize);
143                         break;
144 #endif
145                 default:
146                         return false;
147                 }
148
149                 AUD_device = dev;
150                 AUD_3ddevice = dynamic_cast<AUD_I3DDevice*>(AUD_device.get());
151
152                 return true;
153         }
154         catch(AUD_Exception&)
155         {
156                 return false;
157         }
158 }
159
160 void AUD_exit()
161 {
162         AUD_device = AUD_Reference<AUD_IDevice>();
163         AUD_3ddevice = NULL;
164 }
165
166 #ifdef WITH_PYTHON
167 static PyObject* AUD_getCDevice(PyObject* self)
168 {
169         if(!AUD_device.isNull())
170         {
171                 Device* device = (Device*)Device_empty();
172                 if(device != NULL)
173                 {
174                         device->device = new AUD_Reference<AUD_IDevice>(AUD_device);
175                         return (PyObject*)device;
176                 }
177         }
178
179         Py_RETURN_NONE;
180 }
181
182 static PyMethodDef meth_getcdevice[] = {{ "device", (PyCFunction)AUD_getCDevice, METH_NOARGS,
183                                                                                   "device()\n\n"
184                                                                                   "Returns the application's :class:`Device`.\n\n"
185                                                                                   ":return: The application's :class:`Device`.\n"
186                                                                                   ":rtype: :class:`Device`"}};
187
188 extern "C" {
189 extern void* sound_get_factory(void* sound);
190 }
191
192 static PyObject* AUD_getSoundFromPointer(PyObject* self, PyObject* args)
193 {
194         long int lptr;
195
196         if(PyArg_Parse(args, "l:_sound_from_pointer", &lptr))
197         {
198                 if(lptr)
199                 {
200                         AUD_Reference<AUD_IFactory>* factory = (AUD_Reference<AUD_IFactory>*) sound_get_factory((void*) lptr);
201
202                         if(factory)
203                         {
204                                 Factory* obj = (Factory*) Factory_empty();
205                                 if(obj)
206                                 {
207                                         obj->factory = new AUD_Reference<AUD_IFactory>(*factory);
208                                         return (PyObject*) obj;
209                                 }
210                         }
211                 }
212         }
213
214         Py_RETURN_NONE;
215 }
216
217 static PyMethodDef meth_sound_from_pointer[] = {{ "_sound_from_pointer", (PyCFunction)AUD_getSoundFromPointer, METH_O,
218                                                                                   "_sound_from_pointer(pointer)\n\n"
219                                                                                   "Returns the corresponding :class:`Factory` object.\n\n"
220                                                                                   ":arg pointer: The pointer to the bSound object as long.\n"
221                                                                                   ":type pointer: long\n"
222                                                                                   ":return: The corresponding :class:`Factory` object.\n"
223                                                                                   ":rtype: :class:`Factory`"}};
224
225 PyObject* AUD_initPython()
226 {
227         PyObject* module = PyInit_aud();
228         PyModule_AddObject(module, "device", (PyObject*)PyCFunction_New(meth_getcdevice, NULL));
229         PyModule_AddObject(module, "_sound_from_pointer", (PyObject*)PyCFunction_New(meth_sound_from_pointer, NULL));
230         PyDict_SetItemString(PyImport_GetModuleDict(), "aud", module);
231
232         return module;
233 }
234
235 PyObject* AUD_getPythonFactory(AUD_Sound* sound)
236 {
237         if(sound)
238         {
239                 Factory* obj = (Factory*) Factory_empty();
240                 if(obj)
241                 {
242                         obj->factory = new AUD_Reference<AUD_IFactory>(*sound);
243                         return (PyObject*) obj;
244                 }
245         }
246
247         return NULL;
248 }
249
250 AUD_Sound* AUD_getPythonSound(PyObject* sound)
251 {
252         Factory* factory = checkFactory(sound);
253
254         if(!factory)
255                 return NULL;
256
257         return new AUD_Reference<AUD_IFactory>(*reinterpret_cast<AUD_Reference<AUD_IFactory>*>(factory->factory));
258 }
259
260 #endif
261
262 void AUD_lock()
263 {
264         AUD_device->lock();
265 }
266
267 void AUD_unlock()
268 {
269         AUD_device->unlock();
270 }
271
272 AUD_SoundInfo AUD_getInfo(AUD_Sound* sound)
273 {
274         assert(sound);
275
276         AUD_SoundInfo info;
277         info.specs.channels = AUD_CHANNELS_INVALID;
278         info.specs.rate = AUD_RATE_INVALID;
279         info.length = 0.0f;
280
281         try
282         {
283                 AUD_Reference<AUD_IReader> reader = (*sound)->createReader();
284
285                 if(!reader.isNull())
286                 {
287                         info.specs = reader->getSpecs();
288                         info.length = reader->getLength() / (float) info.specs.rate;
289                 }
290         }
291         catch(AUD_Exception&)
292         {
293         }
294
295         return info;
296 }
297
298 AUD_Sound* AUD_load(const char* filename)
299 {
300         assert(filename);
301         return new AUD_Sound(new AUD_FileFactory(filename));
302 }
303
304 AUD_Sound* AUD_loadBuffer(unsigned char* buffer, int size)
305 {
306         assert(buffer);
307         return new AUD_Sound(new AUD_FileFactory(buffer, size));
308 }
309
310 AUD_Sound* AUD_bufferSound(AUD_Sound* sound)
311 {
312         assert(sound);
313
314         try
315         {
316                 return new AUD_Sound(new AUD_StreamBufferFactory(*sound));
317         }
318         catch(AUD_Exception&)
319         {
320                 return NULL;
321         }
322 }
323
324 AUD_Sound* AUD_monoSound(AUD_Sound* sound)
325 {
326         assert(sound);
327
328         try
329         {
330                 AUD_DeviceSpecs specs;
331                 specs.channels = AUD_CHANNELS_MONO;
332                 specs.rate = AUD_RATE_INVALID;
333                 specs.format = AUD_FORMAT_INVALID;
334                 return new AUD_Sound(new AUD_ChannelMapperFactory(*sound, specs));
335         }
336         catch(AUD_Exception&)
337         {
338                 return NULL;
339         }
340 }
341
342 AUD_Sound* AUD_delaySound(AUD_Sound* sound, float delay)
343 {
344         assert(sound);
345
346         try
347         {
348                 return new AUD_Sound(new AUD_DelayFactory(*sound, delay));
349         }
350         catch(AUD_Exception&)
351         {
352                 return NULL;
353         }
354 }
355
356 AUD_Sound* AUD_limitSound(AUD_Sound* sound, float start, float end)
357 {
358         assert(sound);
359
360         try
361         {
362                 return new AUD_Sound(new AUD_LimiterFactory(*sound, start, end));
363         }
364         catch(AUD_Exception&)
365         {
366                 return NULL;
367         }
368 }
369
370 AUD_Sound* AUD_pingpongSound(AUD_Sound* sound)
371 {
372         assert(sound);
373
374         try
375         {
376                 return new AUD_Sound(new AUD_PingPongFactory(*sound));
377         }
378         catch(AUD_Exception&)
379         {
380                 return NULL;
381         }
382 }
383
384 AUD_Sound* AUD_loopSound(AUD_Sound* sound)
385 {
386         assert(sound);
387
388         try
389         {
390                 return new AUD_Sound(new AUD_LoopFactory(*sound));
391         }
392         catch(AUD_Exception&)
393         {
394                 return NULL;
395         }
396 }
397
398 int AUD_setLoop(AUD_Handle* handle, int loops)
399 {
400         assert(handle);
401
402         try
403         {
404                 return (*handle)->setLoopCount(loops);
405         }
406         catch(AUD_Exception&)
407         {
408         }
409
410         return false;
411 }
412
413 AUD_Sound* AUD_rectifySound(AUD_Sound* sound)
414 {
415         assert(sound);
416
417         try
418         {
419                 return new AUD_Sound(new AUD_RectifyFactory(*sound));
420         }
421         catch(AUD_Exception&)
422         {
423                 return NULL;
424         }
425 }
426
427 void AUD_unload(AUD_Sound* sound)
428 {
429         assert(sound);
430         delete sound;
431 }
432
433 AUD_Handle* AUD_play(AUD_Sound* sound, int keep)
434 {
435         assert(sound);
436         try
437         {
438                 AUD_Handle handle = AUD_device->play(*sound, keep);
439                 if(!handle.isNull())
440                         return new AUD_Handle(handle);
441         }
442         catch(AUD_Exception&)
443         {
444         }
445         return NULL;
446 }
447
448 int AUD_pause(AUD_Handle* handle)
449 {
450         assert(handle);
451         return (*handle)->pause();
452 }
453
454 int AUD_resume(AUD_Handle* handle)
455 {
456         assert(handle);
457         return (*handle)->resume();
458 }
459
460 int AUD_stop(AUD_Handle* handle)
461 {
462         assert(handle);
463         int result = (*handle)->stop();
464         delete handle;
465         return result;
466 }
467
468 int AUD_setKeep(AUD_Handle* handle, int keep)
469 {
470         assert(handle);
471         return (*handle)->setKeep(keep);
472 }
473
474 int AUD_seek(AUD_Handle* handle, float seekTo)
475 {
476         assert(handle);
477         return (*handle)->seek(seekTo);
478 }
479
480 float AUD_getPosition(AUD_Handle* handle)
481 {
482         assert(handle);
483         return (*handle)->getPosition();
484 }
485
486 AUD_Status AUD_getStatus(AUD_Handle* handle)
487 {
488         assert(handle);
489         return (*handle)->getStatus();
490 }
491
492 int AUD_setListenerLocation(const float* location)
493 {
494         if(AUD_3ddevice)
495         {
496                 AUD_Vector3 v(location[0], location[1], location[2]);
497                 AUD_3ddevice->setListenerLocation(v);
498                 return true;
499         }
500
501         return false;
502 }
503
504 int AUD_setListenerVelocity(const float* velocity)
505 {
506         if(AUD_3ddevice)
507         {
508                 AUD_Vector3 v(velocity[0], velocity[1], velocity[2]);
509                 AUD_3ddevice->setListenerVelocity(v);
510                 return true;
511         }
512
513         return false;
514 }
515
516 int AUD_setListenerOrientation(const float* orientation)
517 {
518         if(AUD_3ddevice)
519         {
520                 AUD_Quaternion q(orientation[3], orientation[0], orientation[1], orientation[2]);
521                 AUD_3ddevice->setListenerOrientation(q);
522                 return true;
523         }
524
525         return false;
526 }
527
528 int AUD_setSpeedOfSound(float speed)
529 {
530         if(AUD_3ddevice)
531         {
532                 AUD_3ddevice->setSpeedOfSound(speed);
533                 return true;
534         }
535
536         return false;
537 }
538
539 int AUD_setDopplerFactor(float factor)
540 {
541         if(AUD_3ddevice)
542         {
543                 AUD_3ddevice->setDopplerFactor(factor);
544                 return true;
545         }
546
547         return false;
548 }
549
550 int AUD_setDistanceModel(AUD_DistanceModel model)
551 {
552         if(AUD_3ddevice)
553         {
554                 AUD_3ddevice->setDistanceModel(model);
555                 return true;
556         }
557
558         return false;
559 }
560
561 int AUD_setSourceLocation(AUD_Handle* handle, const float* location)
562 {
563         assert(handle);
564         AUD_Reference<AUD_I3DHandle> h(*handle);
565
566         if(!h.isNull())
567         {
568                 AUD_Vector3 v(location[0], location[1], location[2]);
569                 return h->setSourceLocation(v);
570         }
571
572         return false;
573 }
574
575 int AUD_setSourceVelocity(AUD_Handle* handle, const float* velocity)
576 {
577         assert(handle);
578         AUD_Reference<AUD_I3DHandle> h(*handle);
579
580         if(!h.isNull())
581         {
582                 AUD_Vector3 v(velocity[0], velocity[1], velocity[2]);
583                 return h->setSourceVelocity(v);
584         }
585
586         return false;
587 }
588
589 int AUD_setSourceOrientation(AUD_Handle* handle, const float* orientation)
590 {
591         assert(handle);
592         AUD_Reference<AUD_I3DHandle> h(*handle);
593
594         if(!h.isNull())
595         {
596                 AUD_Quaternion q(orientation[3], orientation[0], orientation[1], orientation[2]);
597                 return h->setSourceOrientation(q);
598         }
599
600         return false;
601 }
602
603 int AUD_setRelative(AUD_Handle* handle, int relative)
604 {
605         assert(handle);
606         AUD_Reference<AUD_I3DHandle> h(*handle);
607
608         if(!h.isNull())
609         {
610                 return h->setRelative(relative);
611         }
612
613         return false;
614 }
615
616 int AUD_setVolumeMaximum(AUD_Handle* handle, float volume)
617 {
618         assert(handle);
619         AUD_Reference<AUD_I3DHandle> h(*handle);
620
621         if(!h.isNull())
622         {
623                 return h->setVolumeMaximum(volume);
624         }
625
626         return false;
627 }
628
629 int AUD_setVolumeMinimum(AUD_Handle* handle, float volume)
630 {
631         assert(handle);
632         AUD_Reference<AUD_I3DHandle> h(*handle);
633
634         if(!h.isNull())
635         {
636                 return h->setVolumeMinimum(volume);
637         }
638
639         return false;
640 }
641
642 int AUD_setDistanceMaximum(AUD_Handle* handle, float distance)
643 {
644         assert(handle);
645         AUD_Reference<AUD_I3DHandle> h(*handle);
646
647         if(!h.isNull())
648         {
649                 return h->setDistanceMaximum(distance);
650         }
651
652         return false;
653 }
654
655 int AUD_setDistanceReference(AUD_Handle* handle, float distance)
656 {
657         assert(handle);
658         AUD_Reference<AUD_I3DHandle> h(*handle);
659
660         if(!h.isNull())
661         {
662                 return h->setDistanceReference(distance);
663         }
664
665         return false;
666 }
667
668 int AUD_setAttenuation(AUD_Handle* handle, float factor)
669 {
670         assert(handle);
671         AUD_Reference<AUD_I3DHandle> h(*handle);
672
673         if(!h.isNull())
674         {
675                 return h->setAttenuation(factor);
676         }
677
678         return false;
679 }
680
681 int AUD_setConeAngleOuter(AUD_Handle* handle, float angle)
682 {
683         assert(handle);
684         AUD_Reference<AUD_I3DHandle> h(*handle);
685
686         if(!h.isNull())
687         {
688                 return h->setConeAngleOuter(angle);
689         }
690
691         return false;
692 }
693
694 int AUD_setConeAngleInner(AUD_Handle* handle, float angle)
695 {
696         assert(handle);
697         AUD_Reference<AUD_I3DHandle> h(*handle);
698
699         if(!h.isNull())
700         {
701                 return h->setConeAngleInner(angle);
702         }
703
704         return false;
705 }
706
707 int AUD_setConeVolumeOuter(AUD_Handle* handle, float volume)
708 {
709         assert(handle);
710         AUD_Reference<AUD_I3DHandle> h(*handle);
711
712         if(!h.isNull())
713         {
714                 return h->setConeVolumeOuter(volume);
715         }
716
717         return false;
718 }
719
720 int AUD_setSoundVolume(AUD_Handle* handle, float volume)
721 {
722         assert(handle);
723         try
724         {
725                 return (*handle)->setVolume(volume);
726         }
727         catch(AUD_Exception&) {}
728         return false;
729 }
730
731 int AUD_setSoundPitch(AUD_Handle* handle, float pitch)
732 {
733         assert(handle);
734         try
735         {
736                 return (*handle)->setPitch(pitch);
737         }
738         catch(AUD_Exception&) {}
739         return false;
740 }
741
742 AUD_Device* AUD_openReadDevice(AUD_DeviceSpecs specs)
743 {
744         try
745         {
746                 return new AUD_Device(new AUD_ReadDevice(specs));
747         }
748         catch(AUD_Exception&)
749         {
750                 return NULL;
751         }
752 }
753
754 AUD_Handle* AUD_playDevice(AUD_Device* device, AUD_Sound* sound, float seek)
755 {
756         assert(device);
757         assert(sound);
758
759         try
760         {
761                 AUD_Handle handle = (*device)->play(*sound);
762                 if(!handle.isNull())
763                 {
764                         handle->seek(seek);
765                         return new AUD_Handle(handle);
766                 }
767         }
768         catch(AUD_Exception&)
769         {
770         }
771         return NULL;
772 }
773
774 int AUD_setDeviceVolume(AUD_Device* device, float volume)
775 {
776         assert(device);
777
778         try
779         {
780                 (*device)->setVolume(volume);
781                 return true;
782         }
783         catch(AUD_Exception&) {}
784
785         return false;
786 }
787
788 int AUD_readDevice(AUD_Device* device, data_t* buffer, int length)
789 {
790         assert(device);
791         assert(buffer);
792
793         try
794         {
795                 return (*device)->read(buffer, length);
796         }
797         catch(AUD_Exception&)
798         {
799                 return false;
800         }
801 }
802
803 void AUD_closeReadDevice(AUD_Device* device)
804 {
805         assert(device);
806
807         try
808         {
809                 delete device;
810         }
811         catch(AUD_Exception&)
812         {
813         }
814 }
815
816 float* AUD_readSoundBuffer(const char* filename, float low, float high,
817                                                    float attack, float release, float threshold,
818                                                    int accumulate, int additive, int square,
819                                                    float sthreshold, double samplerate, int* length)
820 {
821         AUD_Buffer buffer;
822         AUD_DeviceSpecs specs;
823         specs.channels = AUD_CHANNELS_MONO;
824         specs.rate = (AUD_SampleRate)samplerate;
825         AUD_Reference<AUD_IFactory> sound;
826
827         AUD_Reference<AUD_IFactory> file = new AUD_FileFactory(filename);
828
829         int position = 0;
830
831         try
832         {
833                 AUD_Reference<AUD_IReader> reader = file->createReader();
834
835                 AUD_SampleRate rate = reader->getSpecs().rate;
836
837                 sound = new AUD_ChannelMapperFactory(file, specs);
838
839                 if(high < rate)
840                         sound = new AUD_LowpassFactory(sound, high);
841                 if(low > 0)
842                         sound = new AUD_HighpassFactory(sound, low);
843
844                 sound = new AUD_EnvelopeFactory(sound, attack, release, threshold, 0.1f);
845                 sound = new AUD_LinearResampleFactory(sound, specs);
846
847                 if(square)
848                         sound = new AUD_SquareFactory(sound, sthreshold);
849
850                 if(accumulate)
851                         sound = new AUD_AccumulatorFactory(sound, additive);
852                 else if(additive)
853                         sound = new AUD_SumFactory(sound);
854
855                 reader = sound->createReader();
856
857                 if(reader.isNull())
858                         return NULL;
859
860                 int len;
861                 bool eos;
862                 do
863                 {
864                         len = samplerate;
865                         buffer.resize((position + len) * sizeof(float), true);
866                         reader->read(len, eos, buffer.getBuffer() + position);
867                         position += len;
868                 } while(!eos);
869         }
870         catch(AUD_Exception&)
871         {
872                 return NULL;
873         }
874
875         float* result = (float*)malloc(position * sizeof(float));
876         memcpy(result, buffer.getBuffer(), position * sizeof(float));
877         *length = position;
878         return result;
879 }
880
881 static void pauseSound(AUD_Handle* handle)
882 {
883         assert(handle);
884         (*handle)->pause();
885 }
886
887 AUD_Handle* AUD_pauseAfter(AUD_Handle* handle, float seconds)
888 {
889         AUD_Reference<AUD_IFactory> silence = new AUD_SilenceFactory;
890         AUD_Reference<AUD_IFactory> limiter = new AUD_LimiterFactory(silence, 0, seconds);
891
892         AUD_device->lock();
893
894         try
895         {
896                 AUD_Handle handle2 = AUD_device->play(limiter);
897                 if(!handle2.isNull())
898                 {
899                         handle2->setStopCallback((stopCallback)pauseSound, handle);
900                         AUD_device->unlock();
901                         return new AUD_Handle(handle2);
902                 }
903         }
904         catch(AUD_Exception&)
905         {
906         }
907
908         AUD_device->unlock();
909
910         return NULL;
911 }
912
913 AUD_Sound* AUD_createSequencer(float fps, int muted)
914 {
915         // specs are changed at a later point!
916         AUD_Specs specs;
917         specs.channels = AUD_CHANNELS_STEREO;
918         specs.rate = AUD_RATE_44100;
919         AUD_Sound* sequencer = new AUD_Sound(AUD_Reference<AUD_SequencerFactory>(new AUD_SequencerFactory(specs, fps, muted)));
920         return sequencer;
921 }
922
923 void AUD_destroySequencer(AUD_Sound* sequencer)
924 {
925         delete sequencer;
926 }
927
928 void AUD_setSequencerMuted(AUD_Sound* sequencer, int muted)
929 {
930         dynamic_cast<AUD_SequencerFactory*>(sequencer->get())->mute(muted);
931 }
932
933 void AUD_setSequencerFPS(AUD_Sound* sequencer, float fps)
934 {
935         dynamic_cast<AUD_SequencerFactory*>(sequencer->get())->setFPS(fps);
936 }
937
938 AUD_SEntry* AUD_addSequence(AUD_Sound* sequencer, AUD_Sound* sound,
939                                                          float begin, float end, float skip)
940 {
941         if(!sound)
942                 return new AUD_SEntry(((AUD_SequencerFactory*)sequencer->get())->add(AUD_Sound(), begin, end, skip));
943         return new AUD_SEntry(((AUD_SequencerFactory*)sequencer->get())->add(*sound, begin, end, skip));
944 }
945
946 void AUD_removeSequence(AUD_Sound* sequencer, AUD_SEntry* entry)
947 {
948         dynamic_cast<AUD_SequencerFactory*>(sequencer->get())->remove(*entry);
949         delete entry;
950 }
951
952 void AUD_moveSequence(AUD_SEntry* entry, float begin, float end, float skip)
953 {
954         (*entry)->move(begin, end, skip);
955 }
956
957 void AUD_muteSequence(AUD_SEntry* entry, char mute)
958 {
959         (*entry)->mute(mute);
960 }
961
962 void AUD_setRelativeSequence(AUD_SEntry* entry, char relative)
963 {
964         (*entry)->setRelative(relative);
965 }
966
967 void AUD_updateSequenceSound(AUD_SEntry* entry, AUD_Sound* sound)
968 {
969         if(sound)
970                 (*entry)->setSound(*sound);
971         else
972                 (*entry)->setSound(AUD_Sound());
973 }
974
975 void AUD_setSequenceAnimData(AUD_SEntry* entry, AUD_AnimateablePropertyType type, int frame, float* data, char animated)
976 {
977         AUD_AnimateableProperty* prop = (*entry)->getAnimProperty(type);
978         if(animated)
979         {
980                 if(frame >= 0)
981                         prop->write(data, frame, 1);
982         }
983         else
984                 prop->write(data);
985 }
986
987 void AUD_setSequencerAnimData(AUD_Sound* sequencer, AUD_AnimateablePropertyType type, int frame, float* data, char animated)
988 {
989         AUD_AnimateableProperty* prop = dynamic_cast<AUD_SequencerFactory*>(sequencer->get())->getAnimProperty(type);
990         if(animated)
991         {
992                 if(frame >= 0)
993                         prop->write(data, frame, 1);
994         }
995         else
996                 prop->write(data);
997 }
998
999 void AUD_updateSequenceData(AUD_SEntry* entry, float volume_max, float volume_min,
1000                                                         float distance_max, float distance_reference, float attenuation,
1001                                                         float cone_angle_outer, float cone_angle_inner, float cone_volume_outer)
1002 {
1003         (*entry)->updateAll(volume_max, volume_min, distance_max, distance_reference, attenuation,
1004                                                 cone_angle_outer, cone_angle_inner, cone_volume_outer);
1005 }
1006
1007 void AUD_updateSequencerData(AUD_Sound* sequencer, float speed_of_sound,
1008                                                          float factor, AUD_DistanceModel model)
1009 {
1010         AUD_SequencerFactory* f = dynamic_cast<AUD_SequencerFactory*>(sequencer->get());
1011         f->setSpeedOfSound(speed_of_sound);
1012         f->setDopplerFactor(factor);
1013         f->setDistanceModel(model);
1014 }
1015
1016 void AUD_setSequencerDeviceSpecs(AUD_Sound* sequencer)
1017 {
1018         dynamic_cast<AUD_SequencerFactory*>(sequencer->get())->setSpecs(AUD_device->getSpecs().specs);
1019 }
1020
1021 void AUD_setSequencerSpecs(AUD_Sound* sequencer, AUD_Specs specs)
1022 {
1023         dynamic_cast<AUD_SequencerFactory*>(sequencer->get())->setSpecs(specs);
1024 }
1025
1026 void AUD_seekSequencer(AUD_Handle* handle, float time)
1027 {
1028 #ifdef WITH_JACK
1029         AUD_JackDevice* device = dynamic_cast<AUD_JackDevice*>(AUD_device.get());
1030         if(device)
1031                 device->seekPlayback(time);
1032         else
1033 #endif
1034         {
1035                 assert(handle);
1036                 (*handle)->seek(time);
1037         }
1038 }
1039
1040 float AUD_getSequencerPosition(AUD_Handle* handle)
1041 {
1042 #ifdef WITH_JACK
1043         AUD_JackDevice* device = dynamic_cast<AUD_JackDevice*>(AUD_device.get());
1044         if(device)
1045                 return device->getPlaybackPosition();
1046         else
1047 #endif
1048         {
1049                 assert(handle);
1050                 return (*handle)->getPosition();
1051         }
1052 }
1053
1054 void AUD_startPlayback()
1055 {
1056 #ifdef WITH_JACK
1057         AUD_JackDevice* device = dynamic_cast<AUD_JackDevice*>(AUD_device.get());
1058         if(device)
1059                 device->startPlayback();
1060 #endif
1061 }
1062
1063 void AUD_stopPlayback()
1064 {
1065 #ifdef WITH_JACK
1066         AUD_JackDevice* device = dynamic_cast<AUD_JackDevice*>(AUD_device.get());
1067         if(device)
1068                 device->stopPlayback();
1069 #endif
1070 }
1071
1072 #ifdef WITH_JACK
1073 void AUD_setSyncCallback(AUD_syncFunction function, void* data)
1074 {
1075         AUD_JackDevice* device = dynamic_cast<AUD_JackDevice*>(AUD_device.get());
1076         if(device)
1077                 device->setSyncCallback(function, data);
1078 }
1079 #endif
1080
1081 int AUD_doesPlayback()
1082 {
1083 #ifdef WITH_JACK
1084         AUD_JackDevice* device = dynamic_cast<AUD_JackDevice*>(AUD_device.get());
1085         if(device)
1086                 return device->doesPlayback();
1087 #endif
1088         return -1;
1089 }
1090
1091 int AUD_readSound(AUD_Sound* sound, sample_t* buffer, int length, int samples_per_second)
1092 {
1093         AUD_DeviceSpecs specs;
1094         sample_t* buf;
1095         AUD_Buffer aBuffer;
1096
1097         specs.rate = AUD_RATE_INVALID;
1098         specs.channels = AUD_CHANNELS_MONO;
1099         specs.format = AUD_FORMAT_INVALID;
1100
1101         AUD_Reference<AUD_IReader> reader = AUD_ChannelMapperFactory(*sound, specs).createReader();
1102
1103         specs.specs = reader->getSpecs();
1104         int len;
1105         float samplejump = specs.rate / samples_per_second;
1106         float min, max, power, overallmax;
1107         bool eos;
1108
1109         overallmax = 0;
1110
1111         for(int i = 0; i < length; i++)
1112         {
1113                 len = floor(samplejump * (i+1)) - floor(samplejump * i);
1114
1115                 aBuffer.assureSize(len * AUD_SAMPLE_SIZE(specs));
1116                 buf = aBuffer.getBuffer();
1117
1118                 reader->read(len, eos, buf);
1119
1120                 max = min = *buf;
1121                 power = *buf * *buf;
1122                 for(int j = 1; j < len; j++)
1123                 {
1124                         if(buf[j] < min)
1125                                 min = buf[j];
1126                         if(buf[j] > max)
1127                                 max = buf[j];
1128                         power += buf[j] * buf[j];
1129                 }
1130
1131                 buffer[i * 3] = min;
1132                 buffer[i * 3 + 1] = max;
1133                 buffer[i * 3 + 2] = sqrt(power) / len;
1134
1135                 if(overallmax < max)
1136                         overallmax = max;
1137                 if(overallmax < -min)
1138                         overallmax = -min;
1139
1140                 if(eos)
1141                 {
1142                         length = i;
1143                         break;
1144                 }
1145         }
1146
1147         if(overallmax > 1.0f)
1148         {
1149                 for(int i = 0; i < length * 3; i++)
1150                 {
1151                         buffer[i] /= overallmax;
1152                 }
1153         }
1154
1155         return length;
1156 }
1157
1158 AUD_Sound* AUD_copy(AUD_Sound* sound)
1159 {
1160         return new AUD_Reference<AUD_IFactory>(*sound);
1161 }
1162
1163 void AUD_freeHandle(AUD_Handle* handle)
1164 {
1165         delete handle;
1166 }
1167
1168 void* AUD_createSet()
1169 {
1170         return new std::set<void*>();
1171 }
1172
1173 void AUD_destroySet(void* set)
1174 {
1175         delete reinterpret_cast<std::set<void*>*>(set);
1176 }
1177
1178 char AUD_removeSet(void* set, void* entry)
1179 {
1180         if(set)
1181                 return reinterpret_cast<std::set<void*>*>(set)->erase(entry);
1182         return 0;
1183 }
1184
1185 void AUD_addSet(void* set, void* entry)
1186 {
1187         if(entry)
1188                 reinterpret_cast<std::set<void*>*>(set)->insert(entry);
1189 }
1190
1191 void* AUD_getSet(void* set)
1192 {
1193         if(set)
1194         {
1195                 std::set<void*>* rset = reinterpret_cast<std::set<void*>*>(set);
1196                 if(!rset->empty())
1197                 {
1198                         std::set<void*>::iterator it = rset->begin();
1199                         void* result = *it;
1200                         rset->erase(it);
1201                         return result;
1202                 }
1203         }
1204
1205         return NULL;
1206 }
1207
1208 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)
1209 {
1210         try
1211         {
1212                 AUD_SequencerFactory* f = dynamic_cast<AUD_SequencerFactory*>(sound->get());
1213
1214                 f->setSpecs(specs.specs);
1215                 AUD_Reference<AUD_IReader> reader = f->createQualityReader();
1216                 reader->seek(start);
1217                 AUD_Reference<AUD_IWriter> writer = AUD_FileWriter::createWriter(filename, specs, format, codec, bitrate);
1218                 AUD_FileWriter::writeReader(reader, writer, length, buffersize);
1219
1220                 return NULL;
1221         }
1222         catch(AUD_Exception& e)
1223         {
1224                 return e.str;
1225         }
1226 }
1227
1228 AUD_Device* AUD_openMixdownDevice(AUD_DeviceSpecs specs, AUD_Sound* sequencer, float volume, float start)
1229 {
1230         try
1231         {
1232                 AUD_ReadDevice* device = new AUD_ReadDevice(specs);
1233                 device->setQuality(true);
1234                 device->setVolume(volume);
1235
1236                 dynamic_cast<AUD_SequencerFactory*>(sequencer->get())->setSpecs(specs.specs);
1237
1238                 AUD_Handle handle = device->play(*sequencer);
1239                 if(!handle.isNull())
1240                         handle->seek(start);
1241
1242                 return new AUD_Device(device);
1243         }
1244         catch(AUD_Exception&)
1245         {
1246                 return NULL;
1247         }
1248 }
1249
1250 AUD_Reference<AUD_IDevice> AUD_getDevice()
1251 {
1252         return AUD_device;
1253 }
1254
1255 AUD_I3DDevice* AUD_get3DDevice()
1256 {
1257         return AUD_3ddevice;
1258 }