2 * ***** BEGIN GPL LICENSE BLOCK *****
4 * Copyright 2009-2011 Jörg Hermann Müller
6 * This file is part of AudaSpace.
8 * Audaspace is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
13 * AudaSpace is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
18 * You should have received a copy of the GNU General Public License
19 * along with Audaspace; if not, write to the Free Software Foundation,
20 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
22 * ***** END GPL LICENSE BLOCK *****
25 /** \file audaspace/intern/AUD_C-API.cpp
26 * \ingroup audaspaceintern
30 #ifndef __STDC_CONSTANT_MACROS
31 #define __STDC_CONSTANT_MACROS
34 // quiet unudef define warning
35 #ifdef __STDC_CONSTANT_MACROS
40 # include "AUD_PyInit.h"
41 # include "AUD_PyAPI.h"
50 #include "AUD_NULLDevice.h"
51 #include "AUD_I3DDevice.h"
52 #include "AUD_I3DHandle.h"
53 #include "AUD_FileFactory.h"
54 #include "AUD_FileWriter.h"
55 #include "AUD_StreamBufferFactory.h"
56 #include "AUD_DelayFactory.h"
57 #include "AUD_LimiterFactory.h"
58 #include "AUD_PingPongFactory.h"
59 #include "AUD_LoopFactory.h"
60 #include "AUD_RectifyFactory.h"
61 #include "AUD_EnvelopeFactory.h"
62 #include "AUD_LinearResampleFactory.h"
63 #include "AUD_LowpassFactory.h"
64 #include "AUD_HighpassFactory.h"
65 #include "AUD_AccumulatorFactory.h"
66 #include "AUD_SumFactory.h"
67 #include "AUD_SquareFactory.h"
68 #include "AUD_ChannelMapperFactory.h"
69 #include "AUD_Buffer.h"
70 #include "AUD_ReadDevice.h"
71 #include "AUD_IReader.h"
72 #include "AUD_SequencerFactory.h"
73 #include "AUD_SequencerEntry.h"
74 #include "AUD_SilenceFactory.h"
75 #include "AUD_MutexLock.h"
78 #include "AUD_SDLDevice.h"
82 #include "AUD_OpenALDevice.h"
86 #include "AUD_JackDevice.h"
87 #include "AUD_JackLibrary.h"
93 #include <libavformat/avformat.h>
99 typedef boost::shared_ptr<AUD_IFactory> AUD_Sound;
100 typedef boost::shared_ptr<AUD_IDevice> AUD_Device;
101 typedef boost::shared_ptr<AUD_IHandle> AUD_Handle;
102 typedef boost::shared_ptr<AUD_SequencerEntry> AUD_SEntry;
104 #define AUD_CAPI_IMPLEMENTATION
105 #include "AUD_C-API.h"
108 # define NULL (void *)0
111 static boost::shared_ptr<AUD_IDevice> AUD_device;
112 static AUD_I3DDevice *AUD_3ddevice;
131 AUD_Device* AUD_init(const char* device, AUD_DeviceSpecs specs, int buffersize, const char* name)
133 boost::shared_ptr<AUD_IDevice> dev;
135 if (AUD_device.get()) {
139 std::string dname = device;
142 if(dname == "Null") {
143 dev = boost::shared_ptr<AUD_IDevice>(new AUD_NULLDevice());
146 else if(dname == "SDL")
148 dev = boost::shared_ptr<AUD_IDevice>(new AUD_SDLDevice(specs, buffersize));
152 else if(dname == "OpenAL")
154 dev = boost::shared_ptr<AUD_IDevice>(new AUD_OpenALDevice(specs, buffersize));
158 else if(dname == "JACK")
162 if (stat("/Library/Frameworks/Jackmp.framework", &st) != 0) {
163 printf("Warning: JACK Framework not installed\n");
168 if (!AUD_jack_supported()) {
169 printf("Warning: JACK cllient not installed\n");
173 dev = boost::shared_ptr<AUD_IDevice>(new AUD_JackDevice(name, specs, buffersize));
183 AUD_3ddevice = dynamic_cast<AUD_I3DDevice *>(AUD_device.get());
185 return (AUD_Device*)1;
187 catch(AUD_Exception&)
193 void AUD_exit(AUD_Device* device)
195 AUD_device = boost::shared_ptr<AUD_IDevice>();
200 static PyObject *AUD_getCDevice(PyObject *self)
202 if (AUD_device.get()) {
203 Device *device = (Device *)Device_empty();
204 if (device != NULL) {
205 device->device = new boost::shared_ptr<AUD_IDevice>(AUD_device);
206 return (PyObject *)device;
213 static PyMethodDef meth_getcdevice[] = {
214 {"device", (PyCFunction)AUD_getCDevice, METH_NOARGS,
216 "Returns the application's :class:`Device`.\n\n"
217 ":return: The application's :class:`Device`.\n"
218 ":rtype: :class:`Device`"}
222 extern void *BKE_sound_get_factory(void *sound);
225 static PyObject *AUD_getSoundFromPointer(PyObject *self, PyObject *args)
229 if (PyArg_Parse(args, "l:_sound_from_pointer", &lptr)) {
231 boost::shared_ptr<AUD_IFactory>* factory = (boost::shared_ptr<AUD_IFactory>*) BKE_sound_get_factory((void *) lptr);
234 Factory *obj = (Factory *)Factory_empty();
236 obj->factory = new boost::shared_ptr<AUD_IFactory>(*factory);
237 return (PyObject *) obj;
246 static PyMethodDef meth_sound_from_pointer[] = {
247 {"_sound_from_pointer", (PyCFunction)AUD_getSoundFromPointer, METH_O,
248 "_sound_from_pointer(pointer)\n\n"
249 "Returns the corresponding :class:`Factory` object.\n\n"
250 ":arg pointer: The pointer to the bSound object as long.\n"
251 ":type pointer: long\n"
252 ":return: The corresponding :class:`Factory` object.\n"
253 ":rtype: :class:`Factory`"}
256 PyObject *AUD_initPython()
258 PyObject *module = PyInit_aud();
259 PyModule_AddObject(module, "device", (PyObject *)PyCFunction_New(meth_getcdevice, NULL));
260 PyModule_AddObject(module, "_sound_from_pointer", (PyObject *)PyCFunction_New(meth_sound_from_pointer, NULL));
261 PyDict_SetItemString(PyImport_GetModuleDict(), "aud", module);
266 void *AUD_getPythonSound(AUD_Sound *sound)
269 Factory *obj = (Factory *) Factory_empty();
271 obj->factory = new boost::shared_ptr<AUD_IFactory>(*sound);
272 return (PyObject *) obj;
279 AUD_Sound *AUD_getSoundFromPython(void *sound)
281 Factory *factory = checkFactory((PyObject *)sound);
286 return new boost::shared_ptr<AUD_IFactory>(*reinterpret_cast<boost::shared_ptr<AUD_IFactory>*>(factory->factory));
291 void AUD_Device_lock(AUD_Device* device)
296 void AUD_Device_unlock(AUD_Device* device)
298 AUD_device->unlock();
301 AUD_Channels AUD_Device_getChannels(AUD_Device* device)
303 return AUD_device->getSpecs().channels;
306 AUD_SampleRate AUD_Device_getRate(AUD_Device* device)
308 return AUD_device->getSpecs().rate;
311 AUD_SoundInfo AUD_getInfo(AUD_Sound *sound)
316 info.specs.channels = AUD_CHANNELS_INVALID;
317 info.specs.rate = AUD_RATE_INVALID;
321 boost::shared_ptr<AUD_IReader> reader = (*sound)->createReader();
324 info.specs = reader->getSpecs();
325 info.length = reader->getLength() / (float) info.specs.rate;
328 catch(AUD_Exception &ae)
330 std::cout << ae.str << std::endl;
336 AUD_Sound *AUD_Sound_file(const char *filename)
339 return new AUD_Sound(new AUD_FileFactory(filename));
342 AUD_Sound *AUD_Sound_bufferFile(unsigned char *buffer, int size)
345 return new AUD_Sound(new AUD_FileFactory(buffer, size));
348 AUD_Sound *AUD_Sound_cache(AUD_Sound *sound)
353 return new AUD_Sound(new AUD_StreamBufferFactory(*sound));
355 catch(AUD_Exception&)
361 AUD_Sound *AUD_Sound_rechannel(AUD_Sound *sound, AUD_Channels channels)
366 AUD_DeviceSpecs specs;
367 specs.channels = channels;
368 specs.rate = AUD_RATE_INVALID;
369 specs.format = AUD_FORMAT_INVALID;
370 return new AUD_Sound(new AUD_ChannelMapperFactory(*sound, specs));
372 catch(AUD_Exception&)
378 AUD_Sound *AUD_Sound_delay(AUD_Sound *sound, float delay)
383 return new AUD_Sound(new AUD_DelayFactory(*sound, delay));
385 catch(AUD_Exception&)
391 AUD_Sound *AUD_Sound_limit(AUD_Sound *sound, float start, float end)
396 return new AUD_Sound(new AUD_LimiterFactory(*sound, start, end));
398 catch(AUD_Exception&)
404 AUD_Sound *AUD_Sound_pingpong(AUD_Sound *sound)
409 return new AUD_Sound(new AUD_PingPongFactory(*sound));
411 catch(AUD_Exception&)
417 AUD_Sound *AUD_Sound_loop(AUD_Sound *sound)
422 return new AUD_Sound(new AUD_LoopFactory(*sound));
424 catch(AUD_Exception&)
430 int AUD_Handle_setLoopCount(AUD_Handle *handle, int loops)
435 return (*handle)->setLoopCount(loops);
437 catch(AUD_Exception&)
444 AUD_Sound *AUD_rectifySound(AUD_Sound *sound)
449 return new AUD_Sound(new AUD_RectifyFactory(*sound));
451 catch(AUD_Exception&)
457 void AUD_Sound_free(AUD_Sound *sound)
463 AUD_Handle *AUD_Device_play(AUD_Device* device, AUD_Sound *sound, int keep)
467 AUD_Handle handle = AUD_device->play(*sound, keep);
469 return new AUD_Handle(handle);
472 catch(AUD_Exception&)
478 int AUD_Handle_pause(AUD_Handle *handle)
481 return (*handle)->pause();
484 int AUD_Handle_resume(AUD_Handle *handle)
487 return (*handle)->resume();
490 int AUD_Handle_stop(AUD_Handle *handle)
493 int result = (*handle)->stop();
498 void AUD_Device_stopAll(void* device)
500 AUD_device->stopAll();
503 int AUD_Handle_setKeep(AUD_Handle *handle, int keep)
506 return (*handle)->setKeep(keep);
509 int AUD_Handle_setPosition(AUD_Handle *handle, float seekTo)
512 return (*handle)->seek(seekTo);
515 float AUD_Handle_getPosition(AUD_Handle *handle)
518 return (*handle)->getPosition();
521 AUD_Status AUD_Handle_getStatus(AUD_Handle *handle)
524 return (*handle)->getStatus();
527 int AUD_Device_setListenerLocation(const float location[3])
530 AUD_Vector3 v(location[0], location[1], location[2]);
531 AUD_3ddevice->setListenerLocation(v);
538 int AUD_Device_setListenerVelocity(const float velocity[3])
541 AUD_Vector3 v(velocity[0], velocity[1], velocity[2]);
542 AUD_3ddevice->setListenerVelocity(v);
549 int AUD_Device_setListenerOrientation(const float orientation[4])
552 AUD_Quaternion q(orientation[3], orientation[0], orientation[1], orientation[2]);
553 AUD_3ddevice->setListenerOrientation(q);
560 int AUD_Device_setSpeedOfSound(void* device, float speed)
563 AUD_3ddevice->setSpeedOfSound(speed);
570 int AUD_Device_setDopplerFactor(void* device, float factor)
573 AUD_3ddevice->setDopplerFactor(factor);
580 int AUD_Device_setDistanceModel(void* device, AUD_DistanceModel model)
583 AUD_3ddevice->setDistanceModel(model);
590 int AUD_Handle_setLocation(AUD_Handle *handle, const float location[3])
593 boost::shared_ptr<AUD_I3DHandle> h = boost::dynamic_pointer_cast<AUD_I3DHandle>(*handle);
596 AUD_Vector3 v(location[0], location[1], location[2]);
597 return h->setSourceLocation(v);
603 int AUD_Handle_setVelocity(AUD_Handle *handle, const float velocity[3])
606 boost::shared_ptr<AUD_I3DHandle> h = boost::dynamic_pointer_cast<AUD_I3DHandle>(*handle);
609 AUD_Vector3 v(velocity[0], velocity[1], velocity[2]);
610 return h->setSourceVelocity(v);
616 int AUD_Handle_setOrientation(AUD_Handle *handle, const float orientation[4])
619 boost::shared_ptr<AUD_I3DHandle> h = boost::dynamic_pointer_cast<AUD_I3DHandle>(*handle);
622 AUD_Quaternion q(orientation[3], orientation[0], orientation[1], orientation[2]);
623 return h->setSourceOrientation(q);
629 int AUD_Handle_setRelative(AUD_Handle *handle, int relative)
632 boost::shared_ptr<AUD_I3DHandle> h = boost::dynamic_pointer_cast<AUD_I3DHandle>(*handle);
635 return h->setRelative(relative);
641 int AUD_Handle_setVolumeMaximum(AUD_Handle *handle, float volume)
644 boost::shared_ptr<AUD_I3DHandle> h = boost::dynamic_pointer_cast<AUD_I3DHandle>(*handle);
647 return h->setVolumeMaximum(volume);
653 int AUD_Handle_setVolumeMinimum(AUD_Handle *handle, float volume)
656 boost::shared_ptr<AUD_I3DHandle> h = boost::dynamic_pointer_cast<AUD_I3DHandle>(*handle);
659 return h->setVolumeMinimum(volume);
665 int AUD_Handle_setDistanceMaximum(AUD_Handle *handle, float distance)
668 boost::shared_ptr<AUD_I3DHandle> h = boost::dynamic_pointer_cast<AUD_I3DHandle>(*handle);
671 return h->setDistanceMaximum(distance);
677 int AUD_Handle_setDistanceReference(AUD_Handle *handle, float distance)
680 boost::shared_ptr<AUD_I3DHandle> h = boost::dynamic_pointer_cast<AUD_I3DHandle>(*handle);
683 return h->setDistanceReference(distance);
689 int AUD_Handle_setAttenuation(AUD_Handle *handle, float factor)
692 boost::shared_ptr<AUD_I3DHandle> h = boost::dynamic_pointer_cast<AUD_I3DHandle>(*handle);
695 return h->setAttenuation(factor);
701 int AUD_Handle_setConeAngleOuter(AUD_Handle *handle, float angle)
704 boost::shared_ptr<AUD_I3DHandle> h = boost::dynamic_pointer_cast<AUD_I3DHandle>(*handle);
707 return h->setConeAngleOuter(angle);
713 int AUD_Handle_setConeAngleInner(AUD_Handle *handle, float angle)
716 boost::shared_ptr<AUD_I3DHandle> h = boost::dynamic_pointer_cast<AUD_I3DHandle>(*handle);
719 return h->setConeAngleInner(angle);
725 int AUD_Handle_setConeVolumeOuter(AUD_Handle *handle, float volume)
728 boost::shared_ptr<AUD_I3DHandle> h = boost::dynamic_pointer_cast<AUD_I3DHandle>(*handle);
731 return h->setConeVolumeOuter(volume);
737 int AUD_Handle_setVolume(AUD_Handle *handle, float volume)
741 return (*handle)->setVolume(volume);
743 catch(AUD_Exception&) {}
747 int AUD_Handle_setPitch(AUD_Handle *handle, float pitch)
751 return (*handle)->setPitch(pitch);
753 catch(AUD_Exception&) {}
757 AUD_Device *AUD_openReadDevice(AUD_DeviceSpecs specs)
760 return new AUD_Device(new AUD_ReadDevice(specs));
762 catch(AUD_Exception&)
768 AUD_Handle *AUD_playDevice(AUD_Device *device, AUD_Sound *sound, float seek)
774 AUD_Handle handle = (*device)->play(*sound);
777 return new AUD_Handle(handle);
780 catch(AUD_Exception&)
786 int AUD_setDeviceVolume(AUD_Device *device, float volume)
791 (*device)->setVolume(volume);
794 catch(AUD_Exception&) {}
799 int AUD_Device_read(AUD_Device *device, data_t *buffer, int length)
805 return boost::dynamic_pointer_cast<AUD_ReadDevice>(*device)->read(buffer, length);
807 catch(AUD_Exception&)
813 void AUD_Device_free(AUD_Device *device)
816 if(device != &AUD_device)
819 catch(AUD_Exception&)
824 float *AUD_readSoundBuffer(const char *filename, float low, float high,
825 float attack, float release, float threshold,
826 int accumulate, int additive, int square,
827 float sthreshold, double samplerate, int *length)
830 AUD_DeviceSpecs specs;
831 specs.channels = AUD_CHANNELS_MONO;
832 specs.rate = (AUD_SampleRate)samplerate;
833 boost::shared_ptr<AUD_IFactory> sound;
835 boost::shared_ptr<AUD_IFactory> file = boost::shared_ptr<AUD_IFactory>(new AUD_FileFactory(filename));
840 boost::shared_ptr<AUD_IReader> reader = file->createReader();
842 AUD_SampleRate rate = reader->getSpecs().rate;
844 sound = boost::shared_ptr<AUD_IFactory>(new AUD_ChannelMapperFactory(file, specs));
847 sound = boost::shared_ptr<AUD_IFactory>(new AUD_LowpassFactory(sound, high));
849 sound = boost::shared_ptr<AUD_IFactory>(new AUD_HighpassFactory(sound, low));
851 sound = boost::shared_ptr<AUD_IFactory>(new AUD_EnvelopeFactory(sound, attack, release, threshold, 0.1f));
852 sound = boost::shared_ptr<AUD_IFactory>(new AUD_LinearResampleFactory(sound, specs));
855 sound = boost::shared_ptr<AUD_IFactory>(new AUD_SquareFactory(sound, sthreshold));
858 sound = boost::shared_ptr<AUD_IFactory>(new AUD_AccumulatorFactory(sound, additive));
860 sound = boost::shared_ptr<AUD_IFactory>(new AUD_SumFactory(sound));
862 reader = sound->createReader();
872 buffer.resize((position + len) * sizeof(float), true);
873 reader->read(len, eos, buffer.getBuffer() + position);
877 catch(AUD_Exception&)
882 float * result = (float *)malloc(position * sizeof(float));
883 memcpy(result, buffer.getBuffer(), position * sizeof(float));
888 static void pauseSound(AUD_Handle *handle)
894 AUD_Handle *AUD_pauseAfter(AUD_Handle *handle, float seconds)
896 boost::shared_ptr<AUD_IFactory> silence = boost::shared_ptr<AUD_IFactory>(new AUD_SilenceFactory);
897 boost::shared_ptr<AUD_IFactory> limiter = boost::shared_ptr<AUD_IFactory>(new AUD_LimiterFactory(silence, 0, seconds));
899 AUD_MutexLock lock(*AUD_device);
902 AUD_Handle handle2 = AUD_device->play(limiter);
904 handle2->setStopCallback((stopCallback)pauseSound, handle);
905 return new AUD_Handle(handle2);
908 catch(AUD_Exception&)
915 AUD_Sound *AUD_Sequence_create(float fps, int muted)
917 // specs are changed at a later point!
919 specs.channels = AUD_CHANNELS_STEREO;
920 specs.rate = AUD_RATE_48000;
921 AUD_Sound *sequencer = new AUD_Sound(boost::shared_ptr<AUD_SequencerFactory>(new AUD_SequencerFactory(specs, fps, muted)));
925 void AUD_Sequence_free(AUD_Sound *sequencer)
930 void AUD_Sequence_setMuted(AUD_Sound *sequencer, int muted)
932 dynamic_cast<AUD_SequencerFactory *>(sequencer->get())->mute(muted);
935 void AUD_Sequence_setFPS(AUD_Sound *sequencer, float fps)
937 dynamic_cast<AUD_SequencerFactory *>(sequencer->get())->setFPS(fps);
940 AUD_SEntry *AUD_Sequence_add(AUD_Sound *sequencer, AUD_Sound *sound,
941 float begin, float end, float skip)
944 return new AUD_SEntry(((AUD_SequencerFactory *)sequencer->get())->add(AUD_Sound(), begin, end, skip));
945 return new AUD_SEntry(((AUD_SequencerFactory *)sequencer->get())->add(*sound, begin, end, skip));
948 void AUD_Sequence_remove(AUD_Sound *sequencer, AUD_SEntry *entry)
950 dynamic_cast<AUD_SequencerFactory *>(sequencer->get())->remove(*entry);
954 void AUD_SequenceEntry_move(AUD_SEntry *entry, float begin, float end, float skip)
956 (*entry)->move(begin, end, skip);
959 void AUD_SequenceEntry_setMuted(AUD_SEntry *entry, char mute)
961 (*entry)->mute(mute);
964 void AUD_SequenceEntry_setSound(AUD_SEntry *entry, AUD_Sound *sound)
967 (*entry)->setSound(*sound);
969 (*entry)->setSound(AUD_Sound());
972 void AUD_SequenceEntry_setAnimationData(AUD_SEntry *entry, AUD_AnimateablePropertyType type, int frame, float *data, char animated)
974 AUD_AnimateableProperty *prop = (*entry)->getAnimProperty(type);
977 prop->write(data, frame, 1);
984 void AUD_Sequence_setAnimationData(AUD_Sound *sequencer, AUD_AnimateablePropertyType type, int frame, float *data, char animated)
986 AUD_AnimateableProperty *prop = dynamic_cast<AUD_SequencerFactory *>(sequencer->get())->getAnimProperty(type);
989 prop->write(data, frame, 1);
997 void AUD_Sequence_setDistanceModel(AUD_Sound* sequence, AUD_DistanceModel value)
1000 dynamic_cast<AUD_SequencerFactory *>(sequence->get())->setDistanceModel(static_cast<AUD_DistanceModel>(value));
1003 void AUD_Sequence_setDopplerFactor(AUD_Sound* sequence, float value)
1006 dynamic_cast<AUD_SequencerFactory *>(sequence->get())->setDopplerFactor(value);
1009 void AUD_Sequence_setSpeedOfSound(AUD_Sound* sequence, float value)
1012 dynamic_cast<AUD_SequencerFactory *>(sequence->get())->setSpeedOfSound(value);
1015 void AUD_SequenceEntry_setAttenuation(AUD_SEntry* sequence_entry, float value)
1017 assert(sequence_entry);
1018 (*sequence_entry)->setAttenuation(value);
1021 void AUD_SequenceEntry_setConeAngleInner(AUD_SEntry* sequence_entry, float value)
1023 assert(sequence_entry);
1024 (*sequence_entry)->setConeAngleInner(value);
1027 void AUD_SequenceEntry_setConeAngleOuter(AUD_SEntry* sequence_entry, float value)
1029 assert(sequence_entry);
1030 (*sequence_entry)->setConeAngleOuter(value);
1033 void AUD_SequenceEntry_setConeVolumeOuter(AUD_SEntry* sequence_entry, float value)
1035 assert(sequence_entry);
1036 (*sequence_entry)->setConeVolumeOuter(value);
1039 void AUD_SequenceEntry_setDistanceMaximum(AUD_SEntry* sequence_entry, float value)
1041 assert(sequence_entry);
1042 (*sequence_entry)->setDistanceMaximum(value);
1045 void AUD_SequenceEntry_setDistanceReference(AUD_SEntry* sequence_entry, float value)
1047 assert(sequence_entry);
1048 (*sequence_entry)->setDistanceReference(value);
1051 void AUD_SequenceEntry_setRelative(AUD_SEntry* sequence_entry, int value)
1053 assert(sequence_entry);
1054 (*sequence_entry)->setRelative(value);
1057 void AUD_SequenceEntry_setVolumeMaximum(AUD_SEntry* sequence_entry, float value)
1059 assert(sequence_entry);
1060 (*sequence_entry)->setVolumeMaximum(value);
1063 void AUD_SequenceEntry_setVolumeMinimum(AUD_SEntry* sequence_entry, float value)
1065 assert(sequence_entry);
1066 (*sequence_entry)->setVolumeMinimum(value);
1069 void AUD_setSequencerDeviceSpecs(AUD_Sound *sequencer)
1071 dynamic_cast<AUD_SequencerFactory *>(sequencer->get())->setSpecs(AUD_device->getSpecs().specs);
1074 void AUD_Sequence_setSpecs(AUD_Sound *sequencer, AUD_Specs specs)
1076 dynamic_cast<AUD_SequencerFactory *>(sequencer->get())->setSpecs(specs);
1079 void AUD_seekSynchronizer(AUD_Handle *handle, float time)
1082 AUD_JackDevice *device = dynamic_cast<AUD_JackDevice *>(AUD_device.get());
1084 device->seekPlayback(time);
1090 (*handle)->seek(time);
1094 float AUD_getSynchronizerPosition(AUD_Handle *handle)
1097 AUD_JackDevice *device = dynamic_cast<AUD_JackDevice *>(AUD_device.get());
1099 return device->getPlaybackPosition();
1105 return (*handle)->getPosition();
1109 void AUD_playSynchronizer()
1112 AUD_JackDevice *device = dynamic_cast<AUD_JackDevice *>(AUD_device.get());
1114 device->startPlayback();
1119 void AUD_stopSynchronizer()
1122 AUD_JackDevice *device = dynamic_cast<AUD_JackDevice *>(AUD_device.get());
1124 device->stopPlayback();
1130 void AUD_setSynchronizerCallback(AUD_syncFunction function, void *data)
1132 AUD_JackDevice *device = dynamic_cast<AUD_JackDevice *>(AUD_device.get());
1134 device->setSyncCallback(function, data);
1139 int AUD_isSynchronizerPlaying()
1142 AUD_JackDevice *device = dynamic_cast<AUD_JackDevice *>(AUD_device.get());
1144 return device->doesPlayback();
1150 int AUD_readSound(AUD_Sound *sound, sample_t *buffer, int length, int samples_per_second, short *interrupt)
1152 AUD_DeviceSpecs specs;
1156 specs.rate = AUD_RATE_INVALID;
1157 specs.channels = AUD_CHANNELS_MONO;
1158 specs.format = AUD_FORMAT_INVALID;
1160 boost::shared_ptr<AUD_IReader> reader = AUD_ChannelMapperFactory(*sound, specs).createReader();
1162 specs.specs = reader->getSpecs();
1164 float samplejump = specs.rate / samples_per_second;
1165 float min, max, power, overallmax;
1170 for (int i = 0; i < length; i++) {
1171 len = floor(samplejump * (i+1)) - floor(samplejump * i);
1176 aBuffer.assureSize(len * AUD_SAMPLE_SIZE(specs));
1177 buf = aBuffer.getBuffer();
1179 reader->read(len, eos, buf);
1182 power = *buf * *buf;
1183 for (int j = 1; j < len; j++) {
1188 power += buf[j] * buf[j];
1191 buffer[i * 3] = min;
1192 buffer[i * 3 + 1] = max;
1193 buffer[i * 3 + 2] = sqrt(power) / len;
1195 if (overallmax < max)
1197 if (overallmax < -min)
1206 if (overallmax > 1.0f) {
1207 for (int i = 0; i < length * 3; i++) {
1208 buffer[i] /= overallmax;
1215 AUD_Sound *AUD_Sound_copy(AUD_Sound *sound)
1217 return new boost::shared_ptr<AUD_IFactory>(*sound);
1220 void AUD_Handle_free(AUD_Handle *handle)
1225 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)
1228 AUD_SequencerFactory *f = dynamic_cast<AUD_SequencerFactory *>(sound->get());
1230 f->setSpecs(specs.specs);
1231 boost::shared_ptr<AUD_IReader> reader = f->createQualityReader();
1232 reader->seek(start);
1233 boost::shared_ptr<AUD_IWriter> writer = AUD_FileWriter::createWriter(filename, specs, format, codec, bitrate);
1234 AUD_FileWriter::writeReader(reader, writer, length, buffersize);
1238 catch(AUD_Exception& e)
1244 const char *AUD_mixdown_per_channel(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)
1247 AUD_SequencerFactory *f = dynamic_cast<AUD_SequencerFactory *>(sound->get());
1249 f->setSpecs(specs.specs);
1251 std::vector<boost::shared_ptr<AUD_IWriter> > writers;
1253 int channels = specs.channels;
1254 specs.channels = AUD_CHANNELS_MONO;
1256 for (int i = 0; i < channels; i++) {
1257 std::stringstream stream;
1258 std::string fn = filename;
1259 size_t index = fn.find_last_of('.');
1260 size_t index_slash = fn.find_last_of('/');
1261 size_t index_backslash = fn.find_last_of('\\');
1263 if ((index == std::string::npos) ||
1264 ((index < index_slash) && (index_slash != std::string::npos)) ||
1265 ((index < index_backslash) && (index_backslash != std::string::npos)))
1267 stream << filename << "_" << (i + 1);
1270 stream << fn.substr(0, index) << "_" << (i + 1) << fn.substr(index);
1272 writers.push_back(AUD_FileWriter::createWriter(stream.str(), specs, format, codec, bitrate));
1275 boost::shared_ptr<AUD_IReader> reader = f->createQualityReader();
1276 reader->seek(start);
1277 AUD_FileWriter::writeReader(reader, writers, length, buffersize);
1281 catch(AUD_Exception& e)
1287 AUD_Device *AUD_openMixdownDevice(AUD_DeviceSpecs specs, AUD_Sound *sequencer, float volume, float start)
1290 AUD_ReadDevice *device = new AUD_ReadDevice(specs);
1291 device->setQuality(true);
1292 device->setVolume(volume);
1294 AUD_SequencerFactory *f = dynamic_cast<AUD_SequencerFactory *>(sequencer->get());
1296 f->setSpecs(specs.specs);
1298 AUD_Handle handle = device->play(f->createQualityReader());
1300 handle->seek(start);
1303 return new AUD_Device(device);
1305 catch(AUD_Exception&)
1311 AUD_Device *AUD_Device_getCurrent(void)
1316 int AUD_isJackSupported(void)
1319 return AUD_jack_supported();