Audio file loading backend libsndfile!
[blender.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 #include "AUD_NULLDevice.h"
27 #include "AUD_I3DDevice.h"
28 #include "AUD_FileFactory.h"
29 #include "AUD_StreamBufferFactory.h"
30 #include "AUD_DelayFactory.h"
31 #include "AUD_LimiterFactory.h"
32 #include "AUD_PingPongFactory.h"
33 #include "AUD_LoopFactory.h"
34 #include "AUD_ReadDevice.h"
35 #include "AUD_SourceCaps.h"
36 #include "AUD_IReader.h"
37
38 #ifdef WITH_SDL
39 #include "AUD_SDLDevice.h"
40 #include "AUD_FloatMixer.h"
41 #endif
42
43 #ifdef WITH_OPENAL
44 #include "AUD_OpenALDevice.h"
45 #endif
46
47 #ifdef WITH_JACK
48 #include "AUD_JackDevice.h"
49 #endif
50
51 #ifdef WITH_FFMPEG
52 extern "C" {
53 #include <libavformat/avformat.h>
54 }
55 #endif
56
57 #include <assert.h>
58
59 typedef AUD_IFactory AUD_Sound;
60 typedef AUD_ReadDevice AUD_Device;
61
62 #define AUD_CAPI_IMPLEMENTATION
63 #include "AUD_C-API.h"
64
65 #ifndef NULL
66 #define NULL 0
67 #endif
68
69 static AUD_IDevice* AUD_device = NULL;
70 static int AUD_available_devices[3];
71 static AUD_I3DDevice* AUD_3ddevice = NULL;
72
73 int AUD_init(AUD_DeviceType device, AUD_Specs specs, int buffersize)
74 {
75 #ifdef WITH_FFMPEG
76         av_register_all();
77 #endif
78         AUD_IDevice* dev = NULL;
79
80         try
81         {
82                 switch(device)
83                 {
84                 case AUD_NULL_DEVICE:
85                         dev = new AUD_NULLDevice();
86                         break;
87 #ifdef WITH_SDL
88                 case AUD_SDL_DEVICE:
89                         {
90                                 dev = new AUD_SDLDevice(specs, buffersize);
91                                 AUD_FloatMixer* mixer = new AUD_FloatMixer();
92                                 ((AUD_SDLDevice*)dev)->setMixer(mixer);
93                                 break;
94                         }
95 #endif
96 #ifdef WITH_OPENAL
97                 case AUD_OPENAL_DEVICE:
98                         dev = new AUD_OpenALDevice(specs, buffersize);
99                         break;
100 #endif
101 #ifdef WITH_JACK
102                 case AUD_JACK_DEVICE:
103                         dev = new AUD_JackDevice(specs);
104                         break;
105 #endif
106                 default:
107                         return false;
108                 }
109
110                 if(AUD_device)
111                         AUD_exit();
112
113                 AUD_device = dev;
114                 if(AUD_device->checkCapability(AUD_CAPS_3D_DEVICE))
115                         AUD_3ddevice = dynamic_cast<AUD_I3DDevice*>(AUD_device);
116
117                 return true;
118         }
119         catch(AUD_Exception e)
120         {
121                 return false;
122         }
123 }
124
125 int* AUD_enumDevices()
126 {
127         int i = 0;
128 #ifdef WITH_SDL
129         AUD_available_devices[i++] = AUD_SDL_DEVICE;
130 #endif
131 #ifdef WITH_OPENAL
132         AUD_available_devices[i++] = AUD_OPENAL_DEVICE;
133 #endif
134 #ifdef WITH_JACK
135         AUD_available_devices[i++] = AUD_JACK_DEVICE;
136 #endif
137         AUD_available_devices[i++] = AUD_NULL_DEVICE;
138         return AUD_available_devices;
139 }
140
141 void AUD_exit()
142 {
143         if(AUD_device)
144         {
145                 delete AUD_device;
146                 AUD_device = NULL;
147                 AUD_3ddevice = NULL;
148         }
149 }
150
151 void AUD_lock()
152 {
153         assert(AUD_device);
154         AUD_device->lock();
155 }
156
157 void AUD_unlock()
158 {
159         assert(AUD_device);
160         AUD_device->unlock();
161 }
162
163 AUD_SoundInfo AUD_getInfo(AUD_Sound* sound)
164 {
165         assert(sound);
166
167         AUD_IReader* reader = sound->createReader();
168
169         AUD_SoundInfo info;
170
171         if(reader)
172         {
173                 info.specs = reader->getSpecs();
174                 info.length = reader->getLength() / (float) info.specs.rate;
175         }
176         else
177         {
178                 info.specs.channels = AUD_CHANNELS_INVALID;
179                 info.specs.format = AUD_FORMAT_INVALID;
180                 info.specs.rate = AUD_RATE_INVALID;
181                 info.length = 0.0;
182         }
183
184         return info;
185 }
186
187 AUD_Sound* AUD_load(const char* filename)
188 {
189         assert(filename);
190         return new AUD_FileFactory(filename);
191 }
192
193 AUD_Sound* AUD_loadBuffer(unsigned char* buffer, int size)
194 {
195         assert(buffer);
196         return new AUD_FileFactory(buffer, size);
197 }
198
199 AUD_Sound* AUD_bufferSound(AUD_Sound* sound)
200 {
201         assert(sound);
202
203         try
204         {
205                 return new AUD_StreamBufferFactory(sound);
206         }
207         catch(AUD_Exception e)
208         {
209                 return NULL;
210         }
211 }
212
213 AUD_Sound* AUD_delaySound(AUD_Sound* sound, float delay)
214 {
215         assert(sound);
216
217         try
218         {
219                 return new AUD_DelayFactory(sound, delay);
220         }
221         catch(AUD_Exception e)
222         {
223                 return NULL;
224         }
225 }
226
227 extern AUD_Sound* AUD_limitSound(AUD_Sound* sound, float start, float end)
228 {
229         assert(sound);
230
231         try
232         {
233                 return new AUD_LimiterFactory(sound, start, end);
234         }
235         catch(AUD_Exception e)
236         {
237                 return NULL;
238         }
239 }
240
241 AUD_Sound* AUD_pingpongSound(AUD_Sound* sound)
242 {
243         assert(sound);
244
245         try
246         {
247                 return new AUD_PingPongFactory(sound);
248         }
249         catch(AUD_Exception e)
250         {
251                 return NULL;
252         }
253 }
254
255 AUD_Sound* AUD_loopSound(AUD_Sound* sound)
256 {
257         assert(sound);
258
259         try
260         {
261                 return new AUD_LoopFactory(sound);
262         }
263         catch(AUD_Exception e)
264         {
265                 return NULL;
266         }
267 }
268
269 int AUD_stopLoop(AUD_Handle* handle)
270 {
271         if(handle)
272         {
273                 AUD_Message message;
274                 message.type = AUD_MSG_LOOP;
275                 message.loopcount = 0;
276
277                 try
278                 {
279                         return AUD_device->sendMessage(handle, message);
280                 }
281                 catch(AUD_Exception e)
282                 {
283                 }
284         }
285         return false;
286 }
287
288 void AUD_unload(AUD_Sound* sound)
289 {
290         assert(sound);
291         delete sound;
292 }
293
294 AUD_Handle* AUD_play(AUD_Sound* sound, int keep)
295 {
296         assert(AUD_device);
297         assert(sound);
298         try
299         {
300                 return AUD_device->play(sound, keep);
301         }
302         catch(AUD_Exception e)
303         {
304                 return NULL;
305         }
306 }
307
308 int AUD_pause(AUD_Handle* handle)
309 {
310         assert(AUD_device);
311         return AUD_device->pause(handle);
312 }
313
314 int AUD_resume(AUD_Handle* handle)
315 {
316         assert(AUD_device);
317         return AUD_device->resume(handle);
318 }
319
320 int AUD_stop(AUD_Handle* handle)
321 {
322         if(AUD_device)
323                 return AUD_device->stop(handle);
324         return false;
325 }
326
327 int AUD_setKeep(AUD_Handle* handle, int keep)
328 {
329         assert(AUD_device);
330         return AUD_device->setKeep(handle, keep);
331 }
332
333 int AUD_seek(AUD_Handle* handle, float seekTo)
334 {
335         assert(AUD_device);
336         return AUD_device->seek(handle, seekTo);
337 }
338
339 float AUD_getPosition(AUD_Handle* handle)
340 {
341         assert(AUD_device);
342         return AUD_device->getPosition(handle);
343 }
344
345 AUD_Status AUD_getStatus(AUD_Handle* handle)
346 {
347         assert(AUD_device);
348         return AUD_device->getStatus(handle);
349 }
350
351 AUD_Handle* AUD_play3D(AUD_Sound* sound, int keep)
352 {
353         assert(AUD_device);
354         assert(sound);
355
356         try
357         {
358                 if(AUD_3ddevice)
359                         return AUD_3ddevice->play3D(sound, keep);
360                 else
361                         return AUD_device->play(sound, keep);
362         }
363         catch(AUD_Exception e)
364         {
365                 return NULL;
366         }
367 }
368
369 int AUD_updateListener(AUD_3DData* data)
370 {
371         assert(AUD_device);
372         assert(data);
373
374         try
375         {
376                 if(AUD_3ddevice)
377                         return AUD_3ddevice->updateListener(*data);
378         }
379         catch(AUD_Exception e)
380         {
381         }
382         return false;
383 }
384
385 int AUD_set3DSetting(AUD_3DSetting setting, float value)
386 {
387         assert(AUD_device);
388
389         try
390         {
391                 if(AUD_3ddevice)
392                         return AUD_3ddevice->setSetting(setting, value);
393         }
394         catch(AUD_Exception e)
395         {
396         }
397         return false;
398 }
399
400 float AUD_get3DSetting(AUD_3DSetting setting)
401 {
402         assert(AUD_device);
403
404         try
405         {
406                 if(AUD_3ddevice)
407                         return AUD_3ddevice->getSetting(setting);
408         }
409         catch(AUD_Exception e)
410         {
411         }
412         return 0.0;
413 }
414
415 int AUD_update3DSource(AUD_Handle* handle, AUD_3DData* data)
416 {
417         if(handle)
418         {
419                 assert(AUD_device);
420                 assert(data);
421
422                 try
423                 {
424                         if(AUD_3ddevice)
425                                 return AUD_3ddevice->updateSource(handle, *data);
426                 }
427                 catch(AUD_Exception e)
428                 {
429                 }
430         }
431         return false;
432 }
433
434 int AUD_set3DSourceSetting(AUD_Handle* handle,
435                                                    AUD_3DSourceSetting setting, float value)
436 {
437         if(handle)
438         {
439                 assert(AUD_device);
440
441                 try
442                 {
443                         if(AUD_3ddevice)
444                                 return AUD_3ddevice->setSourceSetting(handle, setting, value);
445                 }
446                 catch(AUD_Exception e)
447                 {
448                 }
449         }
450         return false;
451 }
452
453 float AUD_get3DSourceSetting(AUD_Handle* handle, AUD_3DSourceSetting setting)
454 {
455         if(handle)
456         {
457                 assert(AUD_device);
458
459                 try
460                 {
461                         if(AUD_3ddevice)
462                                 return AUD_3ddevice->getSourceSetting(handle, setting);
463                 }
464                 catch(AUD_Exception e)
465                 {
466                 }
467         }
468         return 0.0;
469 }
470
471 int AUD_setSoundVolume(AUD_Handle* handle, float volume)
472 {
473         if(handle)
474         {
475                 assert(AUD_device);
476                 AUD_SourceCaps caps;
477                 caps.handle = handle;
478                 caps.value = volume;
479
480                 try
481                 {
482                         return AUD_device->setCapability(AUD_CAPS_SOURCE_VOLUME, &caps);
483                 }
484                 catch(AUD_Exception e) {}
485         }
486         return false;
487 }
488
489 int AUD_setSoundPitch(AUD_Handle* handle, float pitch)
490 {
491         if(handle)
492         {
493                 assert(AUD_device);
494                 AUD_SourceCaps caps;
495                 caps.handle = handle;
496                 caps.value = pitch;
497
498                 try
499                 {
500                         return AUD_device->setCapability(AUD_CAPS_SOURCE_PITCH, &caps);
501                 }
502                 catch(AUD_Exception e) {}
503         }
504         return false;
505 }
506
507 AUD_Device* AUD_openReadDevice(AUD_Specs specs)
508 {
509         try
510         {
511                 return new AUD_ReadDevice(specs);
512         }
513         catch(AUD_Exception e)
514         {
515                 return NULL;
516         }
517 }
518
519 int AUD_playDevice(AUD_Device* device, AUD_Sound* sound)
520 {
521         assert(device);
522         assert(sound);
523
524         try
525         {
526                 return device->play(sound) != NULL;
527         }
528         catch(AUD_Exception e)
529         {
530                 return false;
531         }
532 }
533
534 int AUD_readDevice(AUD_Device* device, sample_t* buffer, int length)
535 {
536         assert(device);
537         assert(buffer);
538
539         try
540         {
541                 return device->read(buffer, length);
542         }
543         catch(AUD_Exception e)
544         {
545                 return false;
546         }
547 }
548
549 void AUD_closeReadDevice(AUD_Device* device)
550 {
551         assert(device);
552
553         try
554         {
555                 delete device;
556         }
557         catch(AUD_Exception e)
558         {
559         }
560 }