Blender  V2.59
AUD_C-API.cpp
Go to the documentation of this file.
00001 /*
00002  * $Id: AUD_C-API.cpp 36092 2011-04-10 22:40:37Z nexyon $
00003  *
00004  * ***** BEGIN GPL LICENSE BLOCK *****
00005  *
00006  * Copyright 2009-2011 Jörg Hermann Müller
00007  *
00008  * This file is part of AudaSpace.
00009  *
00010  * Audaspace is free software; you can redistribute it and/or modify
00011  * it under the terms of the GNU General Public License as published by
00012  * the Free Software Foundation; either version 2 of the License, or
00013  * (at your option) any later version.
00014  *
00015  * AudaSpace is distributed in the hope that it will be useful,
00016  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00017  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00018  * GNU General Public License for more details.
00019  *
00020  * You should have received a copy of the GNU General Public License
00021  * along with Audaspace; if not, write to the Free Software Foundation,
00022  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
00023  *
00024  * ***** END GPL LICENSE BLOCK *****
00025  */
00026 
00032 // needed for INT64_C
00033 #ifndef __STDC_CONSTANT_MACROS
00034 #define __STDC_CONSTANT_MACROS
00035 #endif
00036 
00037 #ifdef WITH_PYTHON
00038 #include "AUD_PyInit.h"
00039 #include "AUD_PyAPI.h"
00040 
00041 Device* g_device;
00042 bool g_pyinitialized = false;
00043 #endif
00044 
00045 #include <cstdlib>
00046 #include <cstring>
00047 #include <cmath>
00048 
00049 #include "AUD_NULLDevice.h"
00050 #include "AUD_I3DDevice.h"
00051 #include "AUD_FileFactory.h"
00052 #include "AUD_StreamBufferFactory.h"
00053 #include "AUD_DelayFactory.h"
00054 #include "AUD_LimiterFactory.h"
00055 #include "AUD_PingPongFactory.h"
00056 #include "AUD_LoopFactory.h"
00057 #include "AUD_RectifyFactory.h"
00058 #include "AUD_EnvelopeFactory.h"
00059 #include "AUD_LinearResampleFactory.h"
00060 #include "AUD_LowpassFactory.h"
00061 #include "AUD_HighpassFactory.h"
00062 #include "AUD_AccumulatorFactory.h"
00063 #include "AUD_SumFactory.h"
00064 #include "AUD_SquareFactory.h"
00065 #include "AUD_ChannelMapperFactory.h"
00066 #include "AUD_Buffer.h"
00067 #include "AUD_ReadDevice.h"
00068 #include "AUD_IReader.h"
00069 #include "AUD_SequencerFactory.h"
00070 #include "AUD_SilenceFactory.h"
00071 
00072 #ifdef WITH_SDL
00073 #include "AUD_SDLDevice.h"
00074 #endif
00075 
00076 #ifdef WITH_OPENAL
00077 #include "AUD_OpenALDevice.h"
00078 #endif
00079 
00080 #ifdef WITH_JACK
00081 #include "AUD_JackDevice.h"
00082 #endif
00083 
00084 
00085 #ifdef WITH_FFMPEG
00086 extern "C" {
00087 #include <libavformat/avformat.h>
00088 }
00089 #endif
00090 
00091 #include <cassert>
00092 
00093 typedef AUD_IFactory AUD_Sound;
00094 typedef AUD_ReadDevice AUD_Device;
00095 typedef AUD_Handle AUD_Channel;
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_IDevice* AUD_device = NULL;
00105 static AUD_I3DDevice* AUD_3ddevice = NULL;
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_IDevice* dev = NULL;
00117 
00118         if(AUD_device)
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                         dev = new AUD_JackDevice("Blender", specs, buffersize);
00141                         break;
00142 #endif
00143                 default:
00144                         return false;
00145                 }
00146 
00147                 AUD_device = dev;
00148                 AUD_3ddevice = dynamic_cast<AUD_I3DDevice*>(AUD_device);
00149 
00150 #ifdef WITH_PYTHON
00151                 if(g_pyinitialized)
00152                 {
00153                         g_device = (Device*)Device_empty();
00154                         if(g_device != NULL)
00155                         {
00156                                 g_device->device = dev;
00157                         }
00158                 }
00159 #endif
00160 
00161                 return true;
00162         }
00163         catch(AUD_Exception&)
00164         {
00165                 return false;
00166         }
00167 }
00168 
00169 void AUD_exit()
00170 {
00171 #ifdef WITH_PYTHON
00172         if(g_device)
00173         {
00174                 Py_XDECREF(g_device);
00175                 g_device = NULL;
00176         }
00177         else
00178 #endif
00179         if(AUD_device)
00180                 delete AUD_device;
00181         AUD_device = NULL;
00182         AUD_3ddevice = NULL;
00183 }
00184 
00185 #ifdef WITH_PYTHON
00186 static PyObject* AUD_getCDevice(PyObject* self)
00187 {
00188         if(g_device)
00189         {
00190                 Py_INCREF(g_device);
00191                 return (PyObject*)g_device;
00192         }
00193         Py_RETURN_NONE;
00194 }
00195 
00196 static PyMethodDef meth_getcdevice[] = {{ "device", (PyCFunction)AUD_getCDevice, METH_NOARGS,
00197                                                                                   "device()\n\n"
00198                                                                                   "Returns the application's :class:`Device`.\n\n"
00199                                                                                   ":return: The application's :class:`Device`.\n"
00200                                                                                   ":rtype: :class:`Device`"}};
00201 
00202 PyObject* AUD_initPython()
00203 {
00204         PyObject* module = PyInit_aud();
00205         PyModule_AddObject(module, "device", (PyObject *)PyCFunction_New(meth_getcdevice, NULL));
00206         PyDict_SetItemString(PyImport_GetModuleDict(), "aud", module);
00207         if(AUD_device)
00208         {
00209                 g_device = (Device*)Device_empty();
00210                 if(g_device != NULL)
00211                 {
00212                         g_device->device = AUD_device;
00213                 }
00214         }
00215         g_pyinitialized = true;
00216 
00217         return module;
00218 }
00219 #endif
00220 
00221 void AUD_lock()
00222 {
00223         assert(AUD_device);
00224         AUD_device->lock();
00225 }
00226 
00227 void AUD_unlock()
00228 {
00229         assert(AUD_device);
00230         AUD_device->unlock();
00231 }
00232 
00233 AUD_SoundInfo AUD_getInfo(AUD_Sound* sound)
00234 {
00235         assert(sound);
00236 
00237         AUD_SoundInfo info;
00238         info.specs.channels = AUD_CHANNELS_INVALID;
00239         info.specs.rate = AUD_RATE_INVALID;
00240         info.length = 0.0f;
00241 
00242         try
00243         {
00244                 AUD_IReader* reader = sound->createReader();
00245 
00246                 if(reader)
00247                 {
00248                         info.specs = reader->getSpecs();
00249                         info.length = reader->getLength() / (float) info.specs.rate;
00250                         delete reader;
00251                 }
00252         }
00253         catch(AUD_Exception&)
00254         {
00255         }
00256 
00257         return info;
00258 }
00259 
00260 AUD_Sound* AUD_load(const char* filename)
00261 {
00262         assert(filename);
00263         return new AUD_FileFactory(filename);
00264 }
00265 
00266 AUD_Sound* AUD_loadBuffer(unsigned char* buffer, int size)
00267 {
00268         assert(buffer);
00269         return new AUD_FileFactory(buffer, size);
00270 }
00271 
00272 AUD_Sound* AUD_bufferSound(AUD_Sound* sound)
00273 {
00274         assert(sound);
00275 
00276         try
00277         {
00278                 return new AUD_StreamBufferFactory(sound);
00279         }
00280         catch(AUD_Exception&)
00281         {
00282                 return NULL;
00283         }
00284 }
00285 
00286 AUD_Sound* AUD_delaySound(AUD_Sound* sound, float delay)
00287 {
00288         assert(sound);
00289 
00290         try
00291         {
00292                 return new AUD_DelayFactory(sound, delay);
00293         }
00294         catch(AUD_Exception&)
00295         {
00296                 return NULL;
00297         }
00298 }
00299 
00300 AUD_Sound* AUD_limitSound(AUD_Sound* sound, float start, float end)
00301 {
00302         assert(sound);
00303 
00304         try
00305         {
00306                 return new AUD_LimiterFactory(sound, start, end);
00307         }
00308         catch(AUD_Exception&)
00309         {
00310                 return NULL;
00311         }
00312 }
00313 
00314 AUD_Sound* AUD_pingpongSound(AUD_Sound* sound)
00315 {
00316         assert(sound);
00317 
00318         try
00319         {
00320                 return new AUD_PingPongFactory(sound);
00321         }
00322         catch(AUD_Exception&)
00323         {
00324                 return NULL;
00325         }
00326 }
00327 
00328 AUD_Sound* AUD_loopSound(AUD_Sound* sound)
00329 {
00330         assert(sound);
00331 
00332         try
00333         {
00334                 return new AUD_LoopFactory(sound);
00335         }
00336         catch(AUD_Exception&)
00337         {
00338                 return NULL;
00339         }
00340 }
00341 
00342 int AUD_setLoop(AUD_Channel* handle, int loops)
00343 {
00344         if(handle)
00345         {
00346                 try
00347                 {
00348                         return AUD_device->setLoopCount(handle, loops);
00349                 }
00350                 catch(AUD_Exception&)
00351                 {
00352                 }
00353         }
00354         return false;
00355 }
00356 
00357 AUD_Sound* AUD_rectifySound(AUD_Sound* sound)
00358 {
00359         assert(sound);
00360 
00361         try
00362         {
00363                 return new AUD_RectifyFactory(sound);
00364         }
00365         catch(AUD_Exception&)
00366         {
00367                 return NULL;
00368         }
00369 }
00370 
00371 void AUD_unload(AUD_Sound* sound)
00372 {
00373         assert(sound);
00374         delete sound;
00375 }
00376 
00377 AUD_Channel* AUD_play(AUD_Sound* sound, int keep)
00378 {
00379         assert(AUD_device);
00380         assert(sound);
00381         try
00382         {
00383                 return AUD_device->play(sound, keep);
00384         }
00385         catch(AUD_Exception&)
00386         {
00387                 return NULL;
00388         }
00389 }
00390 
00391 int AUD_pause(AUD_Channel* handle)
00392 {
00393         assert(AUD_device);
00394         return AUD_device->pause(handle);
00395 }
00396 
00397 int AUD_resume(AUD_Channel* handle)
00398 {
00399         assert(AUD_device);
00400         return AUD_device->resume(handle);
00401 }
00402 
00403 int AUD_stop(AUD_Channel* handle)
00404 {
00405         if(AUD_device)
00406                 return AUD_device->stop(handle);
00407         return false;
00408 }
00409 
00410 int AUD_setKeep(AUD_Channel* handle, int keep)
00411 {
00412         assert(AUD_device);
00413         return AUD_device->setKeep(handle, keep);
00414 }
00415 
00416 int AUD_seek(AUD_Channel* handle, float seekTo)
00417 {
00418         assert(AUD_device);
00419         return AUD_device->seek(handle, seekTo);
00420 }
00421 
00422 float AUD_getPosition(AUD_Channel* handle)
00423 {
00424         assert(AUD_device);
00425         return AUD_device->getPosition(handle);
00426 }
00427 
00428 AUD_Status AUD_getStatus(AUD_Channel* handle)
00429 {
00430         assert(AUD_device);
00431         return AUD_device->getStatus(handle);
00432 }
00433 
00434 int AUD_setListenerLocation(const float* location)
00435 {
00436         assert(AUD_device);
00437 
00438         if(AUD_3ddevice)
00439         {
00440                 AUD_Vector3 v(location[0], location[1], location[2]);
00441                 AUD_3ddevice->setListenerLocation(v);
00442                 return true;
00443         }
00444 
00445         return false;
00446 }
00447 
00448 int AUD_setListenerVelocity(const float* velocity)
00449 {
00450         assert(AUD_device);
00451 
00452         if(AUD_3ddevice)
00453         {
00454                 AUD_Vector3 v(velocity[0], velocity[1], velocity[2]);
00455                 AUD_3ddevice->setListenerVelocity(v);
00456                 return true;
00457         }
00458 
00459         return false;
00460 }
00461 
00462 int AUD_setListenerOrientation(const float* orientation)
00463 {
00464         assert(AUD_device);
00465 
00466         if(AUD_3ddevice)
00467         {
00468                 AUD_Quaternion q(orientation[3], orientation[0], orientation[1], orientation[2]);
00469                 AUD_3ddevice->setListenerOrientation(q);
00470                 return true;
00471         }
00472 
00473         return false;
00474 }
00475 
00476 int AUD_setSpeedOfSound(float speed)
00477 {
00478         assert(AUD_device);
00479 
00480         if(AUD_3ddevice)
00481         {
00482                 AUD_3ddevice->setSpeedOfSound(speed);
00483                 return true;
00484         }
00485 
00486         return false;
00487 }
00488 
00489 int AUD_setDopplerFactor(float factor)
00490 {
00491         assert(AUD_device);
00492 
00493         if(AUD_3ddevice)
00494         {
00495                 AUD_3ddevice->setDopplerFactor(factor);
00496                 return true;
00497         }
00498 
00499         return false;
00500 }
00501 
00502 int AUD_setDistanceModel(AUD_DistanceModel model)
00503 {
00504         assert(AUD_device);
00505 
00506         if(AUD_3ddevice)
00507         {
00508                 AUD_3ddevice->setDistanceModel(model);
00509                 return true;
00510         }
00511 
00512         return false;
00513 }
00514 
00515 int AUD_setSourceLocation(AUD_Channel* handle, const float* location)
00516 {
00517         assert(AUD_device);
00518 
00519         if(AUD_3ddevice)
00520         {
00521                 AUD_Vector3 v(location[0], location[1], location[2]);
00522                 return AUD_3ddevice->setSourceLocation(handle, v);
00523         }
00524 
00525         return false;
00526 }
00527 
00528 int AUD_setSourceVelocity(AUD_Channel* handle, const float* velocity)
00529 {
00530         assert(AUD_device);
00531 
00532         if(AUD_3ddevice)
00533         {
00534                 AUD_Vector3 v(velocity[0], velocity[1], velocity[2]);
00535                 return AUD_3ddevice->setSourceVelocity(handle, v);
00536         }
00537 
00538         return false;
00539 }
00540 
00541 int AUD_setSourceOrientation(AUD_Channel* handle, const float* orientation)
00542 {
00543         assert(AUD_device);
00544 
00545         if(AUD_3ddevice)
00546         {
00547                 AUD_Quaternion q(orientation[3], orientation[0], orientation[1], orientation[2]);
00548                 return AUD_3ddevice->setSourceOrientation(handle, q);
00549         }
00550 
00551         return false;
00552 }
00553 
00554 int AUD_setRelative(AUD_Channel* handle, int relative)
00555 {
00556         assert(AUD_device);
00557 
00558         if(AUD_3ddevice)
00559         {
00560                 return AUD_3ddevice->setRelative(handle, relative);
00561         }
00562 
00563         return false;
00564 }
00565 
00566 int AUD_setVolumeMaximum(AUD_Channel* handle, float volume)
00567 {
00568         assert(AUD_device);
00569 
00570         if(AUD_3ddevice)
00571         {
00572                 return AUD_3ddevice->setVolumeMaximum(handle, volume);
00573         }
00574 
00575         return false;
00576 }
00577 
00578 int AUD_setVolumeMinimum(AUD_Channel* handle, float volume)
00579 {
00580         assert(AUD_device);
00581 
00582         if(AUD_3ddevice)
00583         {
00584                 return AUD_3ddevice->setVolumeMinimum(handle, volume);
00585         }
00586 
00587         return false;
00588 }
00589 
00590 int AUD_setDistanceMaximum(AUD_Channel* handle, float distance)
00591 {
00592         assert(AUD_device);
00593 
00594         if(AUD_3ddevice)
00595         {
00596                 return AUD_3ddevice->setDistanceMaximum(handle, distance);
00597         }
00598 
00599         return false;
00600 }
00601 
00602 int AUD_setDistanceReference(AUD_Channel* handle, float distance)
00603 {
00604         assert(AUD_device);
00605 
00606         if(AUD_3ddevice)
00607         {
00608                 return AUD_3ddevice->setDistanceReference(handle, distance);
00609         }
00610 
00611         return false;
00612 }
00613 
00614 int AUD_setAttenuation(AUD_Channel* handle, float factor)
00615 {
00616         assert(AUD_device);
00617 
00618         if(AUD_3ddevice)
00619         {
00620                 return AUD_3ddevice->setAttenuation(handle, factor);
00621         }
00622 
00623         return false;
00624 }
00625 
00626 int AUD_setConeAngleOuter(AUD_Channel* handle, float angle)
00627 {
00628         assert(AUD_device);
00629 
00630         if(AUD_3ddevice)
00631         {
00632                 return AUD_3ddevice->setConeAngleOuter(handle, angle);
00633         }
00634 
00635         return false;
00636 }
00637 
00638 int AUD_setConeAngleInner(AUD_Channel* handle, float angle)
00639 {
00640         assert(AUD_device);
00641 
00642         if(AUD_3ddevice)
00643         {
00644                 return AUD_3ddevice->setConeAngleInner(handle, angle);
00645         }
00646 
00647         return false;
00648 }
00649 
00650 int AUD_setConeVolumeOuter(AUD_Channel* handle, float volume)
00651 {
00652         assert(AUD_device);
00653 
00654         if(AUD_3ddevice)
00655         {
00656                 return AUD_3ddevice->setConeVolumeOuter(handle, volume);
00657         }
00658 
00659         return false;
00660 }
00661 
00662 int AUD_setSoundVolume(AUD_Channel* handle, float volume)
00663 {
00664         if(handle)
00665         {
00666                 assert(AUD_device);
00667 
00668                 try
00669                 {
00670                         return AUD_device->setVolume(handle, volume);
00671                 }
00672                 catch(AUD_Exception&) {}
00673         }
00674         return false;
00675 }
00676 
00677 int AUD_setSoundPitch(AUD_Channel* handle, float pitch)
00678 {
00679         if(handle)
00680         {
00681                 assert(AUD_device);
00682 
00683                 try
00684                 {
00685                         return AUD_device->setPitch(handle, pitch);
00686                 }
00687                 catch(AUD_Exception&) {}
00688         }
00689         return false;
00690 }
00691 
00692 AUD_Device* AUD_openReadDevice(AUD_DeviceSpecs specs)
00693 {
00694         try
00695         {
00696                 return new AUD_ReadDevice(specs);
00697         }
00698         catch(AUD_Exception&)
00699         {
00700                 return NULL;
00701         }
00702 }
00703 
00704 AUD_Channel* AUD_playDevice(AUD_Device* device, AUD_Sound* sound, float seek)
00705 {
00706         assert(device);
00707         assert(sound);
00708 
00709         try
00710         {
00711                 AUD_Channel* handle = device->play(sound);
00712                 device->seek(handle, seek);
00713                 return handle;
00714         }
00715         catch(AUD_Exception&)
00716         {
00717                 return NULL;
00718         }
00719 }
00720 
00721 int AUD_setDeviceVolume(AUD_Device* device, float volume)
00722 {
00723         assert(device);
00724 
00725         try
00726         {
00727                 device->setVolume(volume);
00728                 return true;
00729         }
00730         catch(AUD_Exception&) {}
00731 
00732         return false;
00733 }
00734 
00735 int AUD_setDeviceSoundVolume(AUD_Device* device, AUD_Channel* handle,
00736                                                          float volume)
00737 {
00738         if(handle)
00739         {
00740                 assert(device);
00741 
00742                 try
00743                 {
00744                         return device->setVolume(handle, volume);
00745                 }
00746                 catch(AUD_Exception&) {}
00747         }
00748         return false;
00749 }
00750 
00751 int AUD_readDevice(AUD_Device* device, data_t* buffer, int length)
00752 {
00753         assert(device);
00754         assert(buffer);
00755 
00756         try
00757         {
00758                 return device->read(buffer, length);
00759         }
00760         catch(AUD_Exception&)
00761         {
00762                 return false;
00763         }
00764 }
00765 
00766 void AUD_closeReadDevice(AUD_Device* device)
00767 {
00768         assert(device);
00769 
00770         try
00771         {
00772                 delete device;
00773         }
00774         catch(AUD_Exception&)
00775         {
00776         }
00777 }
00778 
00779 float* AUD_readSoundBuffer(const char* filename, float low, float high,
00780                                                    float attack, float release, float threshold,
00781                                                    int accumulate, int additive, int square,
00782                                                    float sthreshold, int samplerate, int* length)
00783 {
00784         AUD_Buffer buffer;
00785         AUD_DeviceSpecs specs;
00786         specs.channels = AUD_CHANNELS_MONO;
00787         specs.rate = (AUD_SampleRate)samplerate;
00788         AUD_Sound* sound;
00789 
00790         AUD_FileFactory file(filename);
00791 
00792         AUD_IReader* reader = file.createReader();
00793         AUD_SampleRate rate = reader->getSpecs().rate;
00794         delete reader;
00795 
00796         AUD_ChannelMapperFactory mapper(&file, specs);
00797         sound = &mapper;
00798         AUD_LowpassFactory lowpass(sound, high);
00799         if(high < rate)
00800                 sound = &lowpass;
00801         AUD_HighpassFactory highpass(sound, low);
00802         if(low > 0)
00803                 sound = &highpass;
00804         AUD_EnvelopeFactory envelope(sound, attack, release, threshold, 0.1f);
00805         AUD_LinearResampleFactory resampler(&envelope, specs);
00806         sound = &resampler;
00807         AUD_SquareFactory squaref(sound, sthreshold);
00808         if(square)
00809                 sound = &squaref;
00810         AUD_AccumulatorFactory accumulator(sound, additive);
00811         AUD_SumFactory sum(sound);
00812         if(accumulate)
00813                 sound = &accumulator;
00814         else if(additive)
00815                 sound = &sum;
00816 
00817         reader = sound->createReader();
00818 
00819         if(reader == NULL)
00820                 return NULL;
00821 
00822         int len;
00823         int position = 0;
00824         sample_t* readbuffer;
00825         do
00826         {
00827                 len = samplerate;
00828                 buffer.resize((position + len) * sizeof(float), true);
00829                 reader->read(len, readbuffer);
00830                 memcpy(buffer.getBuffer() + position, readbuffer, len * sizeof(float));
00831                 position += len;
00832         } while(len != 0);
00833         delete reader;
00834 
00835         float* result = (float*)malloc(position * sizeof(float));
00836         memcpy(result, buffer.getBuffer(), position * sizeof(float));
00837         *length = position;
00838         return result;
00839 }
00840 
00841 static void pauseSound(AUD_Channel* handle)
00842 {
00843         assert(AUD_device);
00844 
00845         AUD_device->pause(handle);
00846 }
00847 
00848 AUD_Channel* AUD_pauseAfter(AUD_Channel* handle, float seconds)
00849 {
00850         assert(AUD_device);
00851 
00852         AUD_SilenceFactory silence;
00853         AUD_LimiterFactory limiter(&silence, 0, seconds);
00854 
00855         try
00856         {
00857                 AUD_Channel* channel = AUD_device->play(&limiter);
00858                 AUD_device->setStopCallback(channel, (stopCallback)pauseSound, handle);
00859                 return channel;
00860         }
00861         catch(AUD_Exception&)
00862         {
00863                 return NULL;
00864         }
00865 }
00866 
00867 AUD_Sound* AUD_createSequencer(int muted, void* data, AUD_volumeFunction volume)
00868 {
00869 /* AUD_XXX should be this: but AUD_createSequencer is called before the device
00870  * is initialized.
00871 
00872         return new AUD_SequencerFactory(AUD_device->getSpecs().specs, data, volume);
00873 */
00874         AUD_Specs specs;
00875         specs.channels = AUD_CHANNELS_STEREO;
00876         specs.rate = AUD_RATE_44100;
00877         return new AUD_SequencerFactory(specs, muted, data, volume);
00878 }
00879 
00880 void AUD_destroySequencer(AUD_Sound* sequencer)
00881 {
00882         delete ((AUD_SequencerFactory*)sequencer);
00883 }
00884 
00885 void AUD_setSequencerMuted(AUD_Sound* sequencer, int muted)
00886 {
00887         ((AUD_SequencerFactory*)sequencer)->mute(muted);
00888 }
00889 
00890 AUD_SequencerEntry* AUD_addSequencer(AUD_Sound** sequencer, AUD_Sound* sound,
00891                                                                  float begin, float end, float skip, void* data)
00892 {
00893         return ((AUD_SequencerFactory*)sequencer)->add((AUD_IFactory**) sound, begin, end, skip, data);
00894 }
00895 
00896 void AUD_removeSequencer(AUD_Sound* sequencer, AUD_SequencerEntry* entry)
00897 {
00898         ((AUD_SequencerFactory*)sequencer)->remove(entry);
00899 }
00900 
00901 void AUD_moveSequencer(AUD_Sound* sequencer, AUD_SequencerEntry* entry,
00902                                    float begin, float end, float skip)
00903 {
00904         ((AUD_SequencerFactory*)sequencer)->move(entry, begin, end, skip);
00905 }
00906 
00907 void AUD_muteSequencer(AUD_Sound* sequencer, AUD_SequencerEntry* entry, char mute)
00908 {
00909         ((AUD_SequencerFactory*)sequencer)->mute(entry, mute);
00910 }
00911 
00912 int AUD_readSound(AUD_Sound* sound, sample_t* buffer, int length)
00913 {
00914         AUD_DeviceSpecs specs;
00915         sample_t* buf;
00916 
00917         specs.rate = AUD_RATE_INVALID;
00918         specs.channels = AUD_CHANNELS_MONO;
00919         specs.format = AUD_FORMAT_INVALID;
00920 
00921         AUD_ChannelMapperFactory mapper(sound, specs);
00922 
00923         AUD_IReader* reader = mapper.createReader();
00924 
00925         int len = reader->getLength();
00926         float samplejump = (float)len / (float)length;
00927         float min, max;
00928 
00929         for(int i = 0; i < length; i++)
00930         {
00931                 len = floor(samplejump * (i+1)) - floor(samplejump * i);
00932                 reader->read(len, buf);
00933 
00934                 if(len < 1)
00935                 {
00936                         length = i;
00937                         break;
00938                 }
00939 
00940                 max = min = *buf;
00941                 for(int j = 1; j < len; j++)
00942                 {
00943                         if(buf[j] < min)
00944                                 min = buf[j];
00945                         if(buf[j] > max)
00946                                 max = buf[j];
00947                         buffer[i * 2] = min;
00948                         buffer[i * 2 + 1] = max;
00949                 }
00950         }
00951 
00952         delete reader;
00953 
00954         return length;
00955 }
00956 
00957 void AUD_startPlayback()
00958 {
00959 #ifdef WITH_JACK
00960         AUD_JackDevice* device = dynamic_cast<AUD_JackDevice*>(AUD_device);
00961         if(device)
00962                 device->startPlayback();
00963 #endif
00964 }
00965 
00966 void AUD_stopPlayback()
00967 {
00968 #ifdef WITH_JACK
00969         AUD_JackDevice* device = dynamic_cast<AUD_JackDevice*>(AUD_device);
00970         if(device)
00971                 device->stopPlayback();
00972 #endif
00973 }
00974 
00975 void AUD_seekSequencer(AUD_Channel* handle, float time)
00976 {
00977 #ifdef WITH_JACK
00978         AUD_JackDevice* device = dynamic_cast<AUD_JackDevice*>(AUD_device);
00979         if(device)
00980                 device->seekPlayback(time);
00981         else
00982 #endif
00983         {
00984                 AUD_device->seek(handle, time);
00985         }
00986 }
00987 
00988 float AUD_getSequencerPosition(AUD_Channel* handle)
00989 {
00990 #ifdef WITH_JACK
00991         AUD_JackDevice* device = dynamic_cast<AUD_JackDevice*>(AUD_device);
00992         if(device)
00993                 return device->getPlaybackPosition();
00994         else
00995 #endif
00996         {
00997                 return AUD_device->getPosition(handle);
00998         }
00999 }
01000 
01001 #ifdef WITH_JACK
01002 void AUD_setSyncCallback(AUD_syncFunction function, void* data)
01003 {
01004         AUD_JackDevice* device = dynamic_cast<AUD_JackDevice*>(AUD_device);
01005         if(device)
01006                 device->setSyncCallback(function, data);
01007 }
01008 #endif
01009 
01010 int AUD_doesPlayback()
01011 {
01012 #ifdef WITH_JACK
01013         AUD_JackDevice* device = dynamic_cast<AUD_JackDevice*>(AUD_device);
01014         if(device)
01015                 return device->doesPlayback();
01016 #endif
01017         return -1;
01018 }