Audaspace:
[blender-staging.git] / intern / audaspace / intern / AUD_C-API.cpp
1 /*
2  * $Id$
3  *
4  * ***** BEGIN LGPL LICENSE BLOCK *****
5  *
6  * Copyright 2009 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 Lesser General Public License as published by
12  * the Free Software Foundation, either version 3 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 Lesser General Public License for more details.
19  *
20  * You should have received a copy of the GNU Lesser General Public License
21  * along with AudaSpace.  If not, see <http://www.gnu.org/licenses/>.
22  *
23  * ***** END LGPL LICENSE BLOCK *****
24  */
25
26 #ifdef WITH_PYTHON
27 #include "AUD_PyAPI.h"
28
29 Device* g_device;
30 bool g_pyinitialized = false;
31 #endif
32
33 #include <cstdlib>
34 #include <cstring>
35 #include <cmath>
36
37 #ifndef __STDC_CONSTANT_MACROS
38 // needed for INT64_C
39 #define __STDC_CONSTANT_MACROS
40 #endif
41
42 #include "AUD_NULLDevice.h"
43 #include "AUD_I3DDevice.h"
44 #include "AUD_FileFactory.h"
45 #include "AUD_StreamBufferFactory.h"
46 #include "AUD_DelayFactory.h"
47 #include "AUD_LimiterFactory.h"
48 #include "AUD_PingPongFactory.h"
49 #include "AUD_LoopFactory.h"
50 #include "AUD_RectifyFactory.h"
51 #include "AUD_EnvelopeFactory.h"
52 #include "AUD_LinearResampleFactory.h"
53 #include "AUD_LowpassFactory.h"
54 #include "AUD_HighpassFactory.h"
55 #include "AUD_AccumulatorFactory.h"
56 #include "AUD_SumFactory.h"
57 #include "AUD_SquareFactory.h"
58 #include "AUD_ChannelMapperFactory.h"
59 #include "AUD_Buffer.h"
60 #include "AUD_ReadDevice.h"
61 #include "AUD_SourceCaps.h"
62 #include "AUD_IReader.h"
63 #include "AUD_SequencerFactory.h"
64
65 #ifdef WITH_SDL
66 #include "AUD_SDLDevice.h"
67 #endif
68
69 #ifdef WITH_OPENAL
70 #include "AUD_OpenALDevice.h"
71 #endif
72
73 #ifdef WITH_JACK
74 #include "AUD_JackDevice.h"
75 #endif
76
77
78 #ifdef WITH_FFMPEG
79 extern "C" {
80 #include <libavformat/avformat.h>
81 }
82 #endif
83
84 #include <cassert>
85
86 typedef AUD_IFactory AUD_Sound;
87 typedef AUD_ReadDevice AUD_Device;
88 typedef AUD_Handle AUD_Channel;
89
90 #define AUD_CAPI_IMPLEMENTATION
91 #include "AUD_C-API.h"
92
93 #ifndef NULL
94 #define NULL 0
95 #endif
96
97 static AUD_IDevice* AUD_device = NULL;
98 static int AUD_available_devices[4];
99 static AUD_I3DDevice* AUD_3ddevice = NULL;
100
101 void AUD_initOnce()
102 {
103 #ifdef WITH_FFMPEG
104         av_register_all();
105 #endif
106 }
107
108 int AUD_init(AUD_DeviceType device, AUD_DeviceSpecs specs, int buffersize)
109 {
110         AUD_IDevice* dev = NULL;
111
112         if(AUD_device)
113                 AUD_exit();
114
115         try
116         {
117                 switch(device)
118                 {
119                 case AUD_NULL_DEVICE:
120                         dev = new AUD_NULLDevice();
121                         break;
122 #ifdef WITH_SDL
123                 case AUD_SDL_DEVICE:
124                         dev = new AUD_SDLDevice(specs, buffersize);
125                         break;
126 #endif
127 #ifdef WITH_OPENAL
128                 case AUD_OPENAL_DEVICE:
129                         dev = new AUD_OpenALDevice(specs, buffersize);
130                         break;
131 #endif
132 #ifdef WITH_JACK
133                 case AUD_JACK_DEVICE:
134                         dev = new AUD_JackDevice(specs, buffersize);
135                         break;
136 #endif
137                 default:
138                         return false;
139                 }
140
141                 AUD_device = dev;
142                 if(AUD_device->checkCapability(AUD_CAPS_3D_DEVICE))
143                         AUD_3ddevice = dynamic_cast<AUD_I3DDevice*>(AUD_device);
144
145 #ifdef WITH_PYTHON
146                 if(g_pyinitialized)
147                 {
148                         g_device = (Device*)Device_empty();
149                         if(g_device != NULL)
150                         {
151                                 g_device->device = dev;
152                         }
153                 }
154 #endif
155
156                 return true;
157         }
158         catch(AUD_Exception)
159         {
160                 return false;
161         }
162 }
163
164 int* AUD_enumDevices()
165 {
166         int i = 0;
167 #ifdef WITH_SDL
168         AUD_available_devices[i++] = AUD_SDL_DEVICE;
169 #endif
170 #ifdef WITH_OPENAL
171         AUD_available_devices[i++] = AUD_OPENAL_DEVICE;
172 #endif
173 #ifdef WITH_JACK
174         AUD_available_devices[i++] = AUD_JACK_DEVICE;
175 #endif
176         AUD_available_devices[i++] = AUD_NULL_DEVICE;
177         return AUD_available_devices;
178 }
179
180 void AUD_exit()
181 {
182 #ifdef WITH_PYTHON
183         if(g_device)
184         {
185                 Py_XDECREF(g_device);
186                 g_device = NULL;
187         }
188         else
189 #endif
190         if(AUD_device)
191                 delete AUD_device;
192         AUD_device = NULL;
193         AUD_3ddevice = NULL;
194 }
195
196 #ifdef WITH_PYTHON
197 static PyObject* AUD_getCDevice(PyObject* self)
198 {
199         if(g_device)
200         {
201                 Py_INCREF(g_device);
202                 return (PyObject*)g_device;
203         }
204         Py_RETURN_NONE;
205 }
206
207 static PyMethodDef meth_getcdevice[] = {{ "getCDevice", (PyCFunction)AUD_getCDevice, METH_NOARGS, "Returns the C API Device."}};
208
209 PyObject* AUD_initPython()
210 {
211         PyObject* module = PyInit_aud();
212         PyModule_AddObject(module, "getCDevice", (PyObject *)PyCFunction_New(meth_getcdevice, NULL));
213         PyDict_SetItemString(PySys_GetObject("modules"), "aud", module);
214         if(AUD_device)
215         {
216                 g_device = (Device*)Device_empty();
217                 if(g_device != NULL)
218                 {
219                         g_device->device = AUD_device;
220                 }
221         }
222         g_pyinitialized = true;
223
224         return module;
225 }
226 #endif
227
228 void AUD_lock()
229 {
230         assert(AUD_device);
231         AUD_device->lock();
232 }
233
234 void AUD_unlock()
235 {
236         assert(AUD_device);
237         AUD_device->unlock();
238 }
239
240 AUD_SoundInfo AUD_getInfo(AUD_Sound* sound)
241 {
242         assert(sound);
243
244         AUD_IReader* reader = sound->createReader();
245
246         AUD_SoundInfo info;
247
248         if(reader)
249         {
250                 info.specs = reader->getSpecs();
251                 info.length = reader->getLength() / (float) info.specs.rate;
252         }
253         else
254         {
255                 info.specs.channels = AUD_CHANNELS_INVALID;
256                 info.specs.rate = AUD_RATE_INVALID;
257                 info.length = 0.0f;
258         }
259
260         return info;
261 }
262
263 AUD_Sound* AUD_load(const char* filename)
264 {
265         assert(filename);
266         return new AUD_FileFactory(filename);
267 }
268
269 AUD_Sound* AUD_loadBuffer(unsigned char* buffer, int size)
270 {
271         assert(buffer);
272         return new AUD_FileFactory(buffer, size);
273 }
274
275 AUD_Sound* AUD_bufferSound(AUD_Sound* sound)
276 {
277         assert(sound);
278
279         try
280         {
281                 return new AUD_StreamBufferFactory(sound);
282         }
283         catch(AUD_Exception)
284         {
285                 return NULL;
286         }
287 }
288
289 AUD_Sound* AUD_delaySound(AUD_Sound* sound, float delay)
290 {
291         assert(sound);
292
293         try
294         {
295                 return new AUD_DelayFactory(sound, delay);
296         }
297         catch(AUD_Exception)
298         {
299                 return NULL;
300         }
301 }
302
303 AUD_Sound* AUD_limitSound(AUD_Sound* sound, float start, float end)
304 {
305         assert(sound);
306
307         try
308         {
309                 return new AUD_LimiterFactory(sound, start, end);
310         }
311         catch(AUD_Exception)
312         {
313                 return NULL;
314         }
315 }
316
317 AUD_Sound* AUD_pingpongSound(AUD_Sound* sound)
318 {
319         assert(sound);
320
321         try
322         {
323                 return new AUD_PingPongFactory(sound);
324         }
325         catch(AUD_Exception)
326         {
327                 return NULL;
328         }
329 }
330
331 AUD_Sound* AUD_loopSound(AUD_Sound* sound)
332 {
333         assert(sound);
334
335         try
336         {
337                 return new AUD_LoopFactory(sound);
338         }
339         catch(AUD_Exception)
340         {
341                 return NULL;
342         }
343 }
344
345 int AUD_setLoop(AUD_Channel* handle, int loops, float time)
346 {
347         if(handle)
348         {
349                 AUD_Message message;
350                 message.type = AUD_MSG_LOOP;
351                 message.loopcount = loops;
352                 message.time = time;
353
354                 try
355                 {
356                         return AUD_device->sendMessage(handle, message);
357                 }
358                 catch(AUD_Exception)
359                 {
360                 }
361         }
362         return false;
363 }
364
365 AUD_Sound* AUD_rectifySound(AUD_Sound* sound)
366 {
367         assert(sound);
368
369         try
370         {
371                 return new AUD_RectifyFactory(sound);
372         }
373         catch(AUD_Exception)
374         {
375                 return NULL;
376         }
377 }
378
379 void AUD_unload(AUD_Sound* sound)
380 {
381         assert(sound);
382         delete sound;
383 }
384
385 AUD_Channel* AUD_play(AUD_Sound* sound, int keep)
386 {
387         assert(AUD_device);
388         assert(sound);
389         try
390         {
391                 return AUD_device->play(sound, keep);
392         }
393         catch(AUD_Exception)
394         {
395                 return NULL;
396         }
397 }
398
399 int AUD_pause(AUD_Channel* handle)
400 {
401         assert(AUD_device);
402         return AUD_device->pause(handle);
403 }
404
405 int AUD_resume(AUD_Channel* handle)
406 {
407         assert(AUD_device);
408         return AUD_device->resume(handle);
409 }
410
411 int AUD_stop(AUD_Channel* handle)
412 {
413         if(AUD_device)
414                 return AUD_device->stop(handle);
415         return false;
416 }
417
418 int AUD_setKeep(AUD_Channel* handle, int keep)
419 {
420         assert(AUD_device);
421         return AUD_device->setKeep(handle, keep);
422 }
423
424 int AUD_seek(AUD_Channel* handle, float seekTo)
425 {
426         assert(AUD_device);
427         return AUD_device->seek(handle, seekTo);
428 }
429
430 float AUD_getPosition(AUD_Channel* handle)
431 {
432         assert(AUD_device);
433         return AUD_device->getPosition(handle);
434 }
435
436 AUD_Status AUD_getStatus(AUD_Channel* handle)
437 {
438         assert(AUD_device);
439         return AUD_device->getStatus(handle);
440 }
441
442 AUD_Channel* AUD_play3D(AUD_Sound* sound, int keep)
443 {
444         assert(AUD_device);
445         assert(sound);
446
447         try
448         {
449                 if(AUD_3ddevice)
450                         return AUD_3ddevice->play3D(sound, keep);
451                 else
452                         return AUD_device->play(sound, keep);
453         }
454         catch(AUD_Exception)
455         {
456                 return NULL;
457         }
458 }
459
460 int AUD_updateListener(AUD_3DData* data)
461 {
462         assert(AUD_device);
463         assert(data);
464
465         try
466         {
467                 if(AUD_3ddevice)
468                         return AUD_3ddevice->updateListener(*data);
469         }
470         catch(AUD_Exception)
471         {
472         }
473         return false;
474 }
475
476 int AUD_set3DSetting(AUD_3DSetting setting, float value)
477 {
478         assert(AUD_device);
479
480         try
481         {
482                 if(AUD_3ddevice)
483                         return AUD_3ddevice->setSetting(setting, value);
484         }
485         catch(AUD_Exception)
486         {
487         }
488         return false;
489 }
490
491 float AUD_get3DSetting(AUD_3DSetting setting)
492 {
493         assert(AUD_device);
494
495         try
496         {
497                 if(AUD_3ddevice)
498                         return AUD_3ddevice->getSetting(setting);
499         }
500         catch(AUD_Exception)
501         {
502         }
503         return 0.0f;
504 }
505
506 int AUD_update3DSource(AUD_Channel* handle, AUD_3DData* data)
507 {
508         if(handle)
509         {
510                 assert(AUD_device);
511                 assert(data);
512
513                 try
514                 {
515                         if(AUD_3ddevice)
516                                 return AUD_3ddevice->updateSource(handle, *data);
517                 }
518                 catch(AUD_Exception)
519                 {
520                 }
521         }
522         return false;
523 }
524
525 int AUD_set3DSourceSetting(AUD_Channel* handle,
526                                                    AUD_3DSourceSetting setting, float value)
527 {
528         if(handle)
529         {
530                 assert(AUD_device);
531
532                 try
533                 {
534                         if(AUD_3ddevice)
535                                 return AUD_3ddevice->setSourceSetting(handle, setting, value);
536                 }
537                 catch(AUD_Exception)
538                 {
539                 }
540         }
541         return false;
542 }
543
544 float AUD_get3DSourceSetting(AUD_Channel* handle, AUD_3DSourceSetting setting)
545 {
546         if(handle)
547         {
548                 assert(AUD_device);
549
550                 try
551                 {
552                         if(AUD_3ddevice)
553                                 return AUD_3ddevice->getSourceSetting(handle, setting);
554                 }
555                 catch(AUD_Exception)
556                 {
557                 }
558         }
559         return 0.0f;
560 }
561
562 int AUD_setSoundVolume(AUD_Channel* handle, float volume)
563 {
564         if(handle)
565         {
566                 assert(AUD_device);
567                 AUD_SourceCaps caps;
568                 caps.handle = handle;
569                 caps.value = volume;
570
571                 try
572                 {
573                         return AUD_device->setCapability(AUD_CAPS_SOURCE_VOLUME, &caps);
574                 }
575                 catch(AUD_Exception) {}
576         }
577         return false;
578 }
579
580 int AUD_setSoundPitch(AUD_Channel* handle, float pitch)
581 {
582         if(handle)
583         {
584                 assert(AUD_device);
585                 AUD_SourceCaps caps;
586                 caps.handle = handle;
587                 caps.value = pitch;
588
589                 try
590                 {
591                         return AUD_device->setCapability(AUD_CAPS_SOURCE_PITCH, &caps);
592                 }
593                 catch(AUD_Exception) {}
594         }
595         return false;
596 }
597
598 AUD_Device* AUD_openReadDevice(AUD_DeviceSpecs specs)
599 {
600         try
601         {
602                 return new AUD_ReadDevice(specs);
603         }
604         catch(AUD_Exception)
605         {
606                 return NULL;
607         }
608 }
609
610 AUD_Channel* AUD_playDevice(AUD_Device* device, AUD_Sound* sound, float seek)
611 {
612         assert(device);
613         assert(sound);
614
615         try
616         {
617                 AUD_Channel* handle = device->play(sound);
618                 device->seek(handle, seek);
619                 return handle;
620         }
621         catch(AUD_Exception)
622         {
623                 return NULL;
624         }
625 }
626
627 int AUD_setDeviceVolume(AUD_Device* device, float volume)
628 {
629         assert(device);
630
631         try
632         {
633                 return device->setCapability(AUD_CAPS_VOLUME, &volume);
634         }
635         catch(AUD_Exception) {}
636         
637         return false;
638 }
639
640 int AUD_setDeviceSoundVolume(AUD_Device* device, AUD_Channel* handle,
641                                                          float volume)
642 {
643         if(handle)
644         {
645                 assert(device);
646                 AUD_SourceCaps caps;
647                 caps.handle = handle;
648                 caps.value = volume;
649
650                 try
651                 {
652                         return device->setCapability(AUD_CAPS_SOURCE_VOLUME, &caps);
653                 }
654                 catch(AUD_Exception) {}
655         }
656         return false;
657 }
658
659 int AUD_readDevice(AUD_Device* device, data_t* buffer, int length)
660 {
661         assert(device);
662         assert(buffer);
663
664         try
665         {
666                 return device->read(buffer, length);
667         }
668         catch(AUD_Exception)
669         {
670                 return false;
671         }
672 }
673
674 void AUD_closeReadDevice(AUD_Device* device)
675 {
676         assert(device);
677
678         try
679         {
680                 delete device;
681         }
682         catch(AUD_Exception)
683         {
684         }
685 }
686
687 float* AUD_readSoundBuffer(const char* filename, float low, float high,
688                                                    float attack, float release, float threshold,
689                                                    int accumulate, int additive, int square,
690                                                    float sthreshold, int samplerate, int* length)
691 {
692         AUD_Buffer buffer;
693         AUD_DeviceSpecs specs;
694         specs.channels = AUD_CHANNELS_MONO;
695         specs.rate = (AUD_SampleRate)samplerate;
696         AUD_Sound* sound;
697
698         AUD_FileFactory file(filename);
699         AUD_ChannelMapperFactory mapper(&file, specs);
700         AUD_LowpassFactory lowpass(&mapper, high);
701         AUD_HighpassFactory highpass(&lowpass, low);
702         AUD_EnvelopeFactory envelope(&highpass, attack, release, threshold, 0.1f);
703         AUD_LinearResampleFactory resampler(&envelope, specs);
704         sound = &resampler;
705         AUD_SquareFactory squaref(sound, sthreshold);
706         if(square)
707                 sound = &squaref;
708         AUD_AccumulatorFactory accumulator(sound, additive);
709         AUD_SumFactory sum(sound);
710         if(accumulate)
711                 sound = &accumulator;
712         else if(additive)
713                 sound = &sum;
714
715         AUD_IReader* reader = sound->createReader();
716
717         if(reader == NULL)
718                 return NULL;
719
720         int len;
721         int position = 0;
722         sample_t* readbuffer;
723         do
724         {
725                 len = samplerate;
726                 buffer.resize((position + len) * sizeof(float), true);
727                 reader->read(len, readbuffer);
728                 memcpy(buffer.getBuffer() + position, readbuffer, len * sizeof(float));
729                 position += len;
730         } while(len != 0);
731         delete reader;
732
733         float* result = (float*)malloc(position * sizeof(float));
734         memcpy(result, buffer.getBuffer(), position * sizeof(float));
735         *length = position;
736         return result;
737 }
738
739 AUD_Sound* AUD_createSequencer(void* data, AUD_volumeFunction volume)
740 {
741 /* AUD_XXX should be this: but AUD_createSequencer is called before the device
742  * is initialized.
743
744         return new AUD_SequencerFactory(AUD_device->getSpecs().specs, data, volume);
745 */
746         AUD_Specs specs;
747         specs.channels = AUD_CHANNELS_STEREO;
748         specs.rate = AUD_RATE_44100;
749         return new AUD_SequencerFactory(specs, data, volume);
750 }
751
752 void AUD_destroySequencer(AUD_Sound* sequencer)
753 {
754         delete ((AUD_SequencerFactory*)sequencer);
755 }
756
757 AUD_SequencerEntry* AUD_addSequencer(AUD_Sound** sequencer, AUD_Sound* sound,
758                                                                  float begin, float end, float skip, void* data)
759 {
760         return ((AUD_SequencerFactory*)sequencer)->add((AUD_IFactory**) sound, begin, end, skip, data);
761 }
762
763 void AUD_removeSequencer(AUD_Sound* sequencer, AUD_SequencerEntry* entry)
764 {
765         ((AUD_SequencerFactory*)sequencer)->remove(entry);
766 }
767
768 void AUD_moveSequencer(AUD_Sound* sequencer, AUD_SequencerEntry* entry,
769                                    float begin, float end, float skip)
770 {
771         ((AUD_SequencerFactory*)sequencer)->move(entry, begin, end, skip);
772 }
773
774 void AUD_muteSequencer(AUD_Sound* sequencer, AUD_SequencerEntry* entry, char mute)
775 {
776         ((AUD_SequencerFactory*)sequencer)->mute(entry, mute);
777 }
778
779 int AUD_readSound(AUD_Sound* sound, sample_t* buffer, int length)
780 {
781         AUD_IReader* reader = sound->createReader();
782         AUD_DeviceSpecs specs;
783         sample_t* buf;
784
785         specs.specs = reader->getSpecs();
786         specs.channels = AUD_CHANNELS_MONO;
787         specs.format = AUD_FORMAT_FLOAT32;
788
789         AUD_ChannelMapperFactory mapper(reader, specs);
790
791         if(!reader || reader->getType() != AUD_TYPE_BUFFER)
792                 return -1;
793
794         reader = mapper.createReader();
795
796         if(!reader)
797                 return -1;
798
799         int len = reader->getLength();
800         float samplejump = (float)len / (float)length;
801         float min, max;
802
803         for(int i = 0; i < length; i++)
804         {
805                 len = floor(samplejump * (i+1)) - floor(samplejump * i);
806                 reader->read(len, buf);
807
808                 if(len < 1)
809                 {
810                         length = i;
811                         break;
812                 }
813
814                 max = min = *buf;
815                 for(int j = 1; j < len; j++)
816                 {
817                         if(buf[j] < min)
818                                 min = buf[j];
819                         if(buf[j] > max)
820                                 max = buf[j];
821                         buffer[i * 2] = min;
822                         buffer[i * 2 + 1] = max;
823                 }
824         }
825
826         delete reader; AUD_DELETE("reader")
827
828         return length;
829 }
830
831 void AUD_startPlayback()
832 {
833 #ifdef WITH_JACK
834         AUD_JackDevice* device = dynamic_cast<AUD_JackDevice*>(AUD_device);
835         if(device)
836                 device->startPlayback();
837 #endif
838 }
839
840 void AUD_stopPlayback()
841 {
842 #ifdef WITH_JACK
843         AUD_JackDevice* device = dynamic_cast<AUD_JackDevice*>(AUD_device);
844         if(device)
845                 device->stopPlayback();
846 #endif
847 }
848
849 void AUD_seekSequencer(AUD_Channel* handle, float time)
850 {
851 #ifdef WITH_JACK
852         AUD_JackDevice* device = dynamic_cast<AUD_JackDevice*>(AUD_device);
853         if(device)
854                 device->seekPlayback(time);
855         else
856 #endif
857         {
858                 AUD_device->seek(handle, time);
859         }
860 }
861
862 float AUD_getSequencerPosition(AUD_Channel* handle)
863 {
864 #ifdef WITH_JACK
865         AUD_JackDevice* device = dynamic_cast<AUD_JackDevice*>(AUD_device);
866         if(device)
867                 return device->getPlaybackPosition();
868         else
869 #endif
870         {
871                 return AUD_device->getPosition(handle);
872         }
873 }
874
875 #ifdef WITH_JACK
876 void AUD_setSyncCallback(AUD_syncFunction function, void* data)
877 {
878         AUD_JackDevice* device = dynamic_cast<AUD_JackDevice*>(AUD_device);
879         if(device)
880                 device->setSyncCallback(function, data);
881 }
882 #endif
883
884 int AUD_doesPlayback()
885 {
886 #ifdef WITH_JACK
887         AUD_JackDevice* device = dynamic_cast<AUD_JackDevice*>(AUD_device);
888         if(device)
889                 return device->doesPlayback();
890 #endif
891         return -1;
892 }
893
894 #ifdef AUD_DEBUG_MEMORY
895 int AUD_References(int count, const char* text)
896 {
897         static int m_count = 0;
898         m_count += count;
899         if(count > 0)
900                 printf("+%s\n", text);
901         if(count < 0)
902                 printf("-%s\n", text);
903         return m_count;
904 }
905 #endif