Undo revision 23130 which was a merge with 2.5, a messy one because I did something...
[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_StreamBufferFactory.h"
29 #include "AUD_DelayFactory.h"
30 #include "AUD_LimiterFactory.h"
31 #include "AUD_PingPongFactory.h"
32 #include "AUD_LoopFactory.h"
33 #include "AUD_ReadDevice.h"
34 #include "AUD_SourceCaps.h"
35 #include "AUD_IReader.h"
36
37 #ifdef WITH_SDL
38 #include "AUD_SDLDevice.h"
39 #include "AUD_FloatMixer.h"
40 #endif
41
42 #ifdef WITH_OPENAL
43 #include "AUD_OpenALDevice.h"
44 #endif
45
46 #ifdef WITH_JACK
47 #include "AUD_JackDevice.h"
48 #endif
49
50 #ifdef WITH_FFMPEG
51 #include "AUD_FFMPEGFactory.h"
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 #ifdef WITH_FFMPEG
191         return new AUD_FFMPEGFactory(filename);
192 #else
193         return NULL;
194 #endif
195 }
196
197 AUD_Sound* AUD_loadBuffer(unsigned char* buffer, int size)
198 {
199         assert(buffer);
200 #ifdef WITH_FFMPEG
201         return new AUD_FFMPEGFactory(buffer, size);
202 #else
203         return NULL;
204 #endif
205 }
206
207 AUD_Sound* AUD_bufferSound(AUD_Sound* sound)
208 {
209         assert(sound);
210
211         try
212         {
213                 return new AUD_StreamBufferFactory(sound);
214         }
215         catch(AUD_Exception e)
216         {
217                 return NULL;
218         }
219 }
220
221 AUD_Sound* AUD_delaySound(AUD_Sound* sound, float delay)
222 {
223         assert(sound);
224
225         try
226         {
227                 return new AUD_DelayFactory(sound, delay);
228         }
229         catch(AUD_Exception e)
230         {
231                 return NULL;
232         }
233 }
234
235 extern AUD_Sound* AUD_limitSound(AUD_Sound* sound, float start, float end)
236 {
237         assert(sound);
238
239         try
240         {
241                 return new AUD_LimiterFactory(sound, start, end);
242         }
243         catch(AUD_Exception e)
244         {
245                 return NULL;
246         }
247 }
248
249 AUD_Sound* AUD_pingpongSound(AUD_Sound* sound)
250 {
251         assert(sound);
252
253         try
254         {
255                 return new AUD_PingPongFactory(sound);
256         }
257         catch(AUD_Exception e)
258         {
259                 return NULL;
260         }
261 }
262
263 AUD_Sound* AUD_loopSound(AUD_Sound* sound)
264 {
265         assert(sound);
266
267         try
268         {
269                 return new AUD_LoopFactory(sound);
270         }
271         catch(AUD_Exception e)
272         {
273                 return NULL;
274         }
275 }
276
277 int AUD_stopLoop(AUD_Handle* handle)
278 {
279         if(handle)
280         {
281                 AUD_Message message;
282                 message.type = AUD_MSG_LOOP;
283                 message.loopcount = 0;
284
285                 try
286                 {
287                         return AUD_device->sendMessage(handle, message);
288                 }
289                 catch(AUD_Exception e)
290                 {
291                 }
292         }
293         return false;
294 }
295
296 void AUD_unload(AUD_Sound* sound)
297 {
298         assert(sound);
299         delete sound;
300 }
301
302 AUD_Handle* AUD_play(AUD_Sound* sound, int keep)
303 {
304         assert(AUD_device);
305         assert(sound);
306         try
307         {
308                 return AUD_device->play(sound, keep);
309         }
310         catch(AUD_Exception e)
311         {
312                 return NULL;
313         }
314 }
315
316 int AUD_pause(AUD_Handle* handle)
317 {
318         assert(AUD_device);
319         return AUD_device->pause(handle);
320 }
321
322 int AUD_resume(AUD_Handle* handle)
323 {
324         assert(AUD_device);
325         return AUD_device->resume(handle);
326 }
327
328 int AUD_stop(AUD_Handle* handle)
329 {
330         if(AUD_device)
331                 return AUD_device->stop(handle);
332         return false;
333 }
334
335 int AUD_setKeep(AUD_Handle* handle, int keep)
336 {
337         assert(AUD_device);
338         return AUD_device->setKeep(handle, keep);
339 }
340
341 int AUD_seek(AUD_Handle* handle, float seekTo)
342 {
343         assert(AUD_device);
344         return AUD_device->seek(handle, seekTo);
345 }
346
347 float AUD_getPosition(AUD_Handle* handle)
348 {
349         assert(AUD_device);
350         return AUD_device->getPosition(handle);
351 }
352
353 AUD_Status AUD_getStatus(AUD_Handle* handle)
354 {
355         assert(AUD_device);
356         return AUD_device->getStatus(handle);
357 }
358
359 AUD_Handle* AUD_play3D(AUD_Sound* sound, int keep)
360 {
361         assert(AUD_device);
362         assert(sound);
363
364         try
365         {
366                 if(AUD_3ddevice)
367                         return AUD_3ddevice->play3D(sound, keep);
368                 else
369                         return AUD_device->play(sound, keep);
370         }
371         catch(AUD_Exception e)
372         {
373                 return NULL;
374         }
375 }
376
377 int AUD_updateListener(AUD_3DData* data)
378 {
379         assert(AUD_device);
380         assert(data);
381
382         try
383         {
384                 if(AUD_3ddevice)
385                         return AUD_3ddevice->updateListener(*data);
386         }
387         catch(AUD_Exception e)
388         {
389         }
390         return false;
391 }
392
393 int AUD_set3DSetting(AUD_3DSetting setting, float value)
394 {
395         assert(AUD_device);
396
397         try
398         {
399                 if(AUD_3ddevice)
400                         return AUD_3ddevice->setSetting(setting, value);
401         }
402         catch(AUD_Exception e)
403         {
404         }
405         return false;
406 }
407
408 float AUD_get3DSetting(AUD_3DSetting setting)
409 {
410         assert(AUD_device);
411
412         try
413         {
414                 if(AUD_3ddevice)
415                         return AUD_3ddevice->getSetting(setting);
416         }
417         catch(AUD_Exception e)
418         {
419         }
420         return 0.0;
421 }
422
423 int AUD_update3DSource(AUD_Handle* handle, AUD_3DData* data)
424 {
425         if(handle)
426         {
427                 assert(AUD_device);
428                 assert(data);
429
430                 try
431                 {
432                         if(AUD_3ddevice)
433                                 return AUD_3ddevice->updateSource(handle, *data);
434                 }
435                 catch(AUD_Exception e)
436                 {
437                 }
438         }
439         return false;
440 }
441
442 int AUD_set3DSourceSetting(AUD_Handle* handle,
443                                                    AUD_3DSourceSetting setting, float value)
444 {
445         if(handle)
446         {
447                 assert(AUD_device);
448
449                 try
450                 {
451                         if(AUD_3ddevice)
452                                 return AUD_3ddevice->setSourceSetting(handle, setting, value);
453                 }
454                 catch(AUD_Exception e)
455                 {
456                 }
457         }
458         return false;
459 }
460
461 float AUD_get3DSourceSetting(AUD_Handle* handle, AUD_3DSourceSetting setting)
462 {
463         if(handle)
464         {
465                 assert(AUD_device);
466
467                 try
468                 {
469                         if(AUD_3ddevice)
470                                 return AUD_3ddevice->getSourceSetting(handle, setting);
471                 }
472                 catch(AUD_Exception e)
473                 {
474                 }
475         }
476         return 0.0;
477 }
478
479 int AUD_setSoundVolume(AUD_Handle* handle, float volume)
480 {
481         if(handle)
482         {
483                 assert(AUD_device);
484                 AUD_SourceCaps caps;
485                 caps.handle = handle;
486                 caps.value = volume;
487
488                 try
489                 {
490                         return AUD_device->setCapability(AUD_CAPS_SOURCE_VOLUME, &caps);
491                 }
492                 catch(AUD_Exception e) {}
493         }
494         return false;
495 }
496
497 int AUD_setSoundPitch(AUD_Handle* handle, float pitch)
498 {
499         if(handle)
500         {
501                 assert(AUD_device);
502                 AUD_SourceCaps caps;
503                 caps.handle = handle;
504                 caps.value = pitch;
505
506                 try
507                 {
508                         return AUD_device->setCapability(AUD_CAPS_SOURCE_PITCH, &caps);
509                 }
510                 catch(AUD_Exception e) {}
511         }
512         return false;
513 }
514
515 AUD_Device* AUD_openReadDevice(AUD_Specs specs)
516 {
517         try
518         {
519                 return new AUD_ReadDevice(specs);
520         }
521         catch(AUD_Exception e)
522         {
523                 return NULL;
524         }
525 }
526
527 int AUD_playDevice(AUD_Device* device, AUD_Sound* sound)
528 {
529         assert(device);
530         assert(sound);
531
532         try
533         {
534                 return device->play(sound) != NULL;
535         }
536         catch(AUD_Exception e)
537         {
538                 return false;
539         }
540 }
541
542 int AUD_readDevice(AUD_Device* device, sample_t* buffer, int length)
543 {
544         assert(device);
545         assert(buffer);
546
547         try
548         {
549                 return device->read(buffer, length);
550         }
551         catch(AUD_Exception e)
552         {
553                 return false;
554         }
555 }
556
557 void AUD_closeReadDevice(AUD_Device* device)
558 {
559         assert(device);
560
561         try
562         {
563                 delete device;
564         }
565         catch(AUD_Exception e)
566         {
567         }
568 }