diff options
author | Joerg Mueller <nexyon@gmail.com> | 2010-01-01 08:09:30 +0300 |
---|---|---|
committer | Joerg Mueller <nexyon@gmail.com> | 2010-01-01 08:09:30 +0300 |
commit | 174eccf07851c4e7f669b194cd8951ca98bc5c81 (patch) | |
tree | 42d11467df2d006fcbaa562023ffe09796879716 /intern/audaspace/SDL | |
parent | 3fa927a42e893709ac78f7d9419c22979b05bf3f (diff) |
Huge new year audio commit!
* Refactored the whole audaspace library to use float as sample format over all readers.
* Added new Readers like the linear resampler, envelope, lowpass, highpass and butterworth.
* Note: The butterworth filter isn't working correctly, some bug in there... Maybe also true for the envelope.
* Added a sound to f-curve operator that behaves mostly like the soundtracker script of technoestupido.
Diffstat (limited to 'intern/audaspace/SDL')
-rw-r--r-- | intern/audaspace/SDL/AUD_SDLDevice.cpp | 8 | ||||
-rw-r--r-- | intern/audaspace/SDL/AUD_SDLDevice.h | 3 | ||||
-rw-r--r-- | intern/audaspace/SDL/AUD_SDLMixer.cpp | 83 | ||||
-rw-r--r-- | intern/audaspace/SDL/AUD_SDLMixer.h | 76 | ||||
-rw-r--r-- | intern/audaspace/SDL/AUD_SDLMixerFactory.cpp | 65 | ||||
-rw-r--r-- | intern/audaspace/SDL/AUD_SDLMixerFactory.h | 45 | ||||
-rw-r--r-- | intern/audaspace/SDL/AUD_SDLMixerReader.cpp | 216 | ||||
-rw-r--r-- | intern/audaspace/SDL/AUD_SDLMixerReader.h | 128 |
8 files changed, 4 insertions, 620 deletions
diff --git a/intern/audaspace/SDL/AUD_SDLDevice.cpp b/intern/audaspace/SDL/AUD_SDLDevice.cpp index dd443e7f5c7..1a385af8a0c 100644 --- a/intern/audaspace/SDL/AUD_SDLDevice.cpp +++ b/intern/audaspace/SDL/AUD_SDLDevice.cpp @@ -23,7 +23,6 @@ * ***** END LGPL LICENSE BLOCK ***** */ -#include "AUD_SDLMixer.h" #include "AUD_SDLDevice.h" #include "AUD_IReader.h" @@ -31,10 +30,10 @@ void AUD_SDLDevice::SDL_mix(void *data, Uint8* buffer, int length) { AUD_SDLDevice* device = (AUD_SDLDevice*)data; - device->mix((sample_t*)buffer, length/AUD_SAMPLE_SIZE(device->m_specs)); + device->mix((data_t*)buffer,length/AUD_DEVICE_SAMPLE_SIZE(device->m_specs)); } -AUD_SDLDevice::AUD_SDLDevice(AUD_Specs specs, int buffersize) +AUD_SDLDevice::AUD_SDLDevice(AUD_DeviceSpecs specs, int buffersize) { if(specs.channels == AUD_CHANNELS_INVALID) specs.channels = AUD_CHANNELS_STEREO; @@ -69,9 +68,6 @@ AUD_SDLDevice::AUD_SDLDevice(AUD_Specs specs, int buffersize) else AUD_THROW(AUD_ERROR_SDL); - m_mixer = new AUD_SDLMixer(); AUD_NEW("mixer") - m_mixer->setSpecs(m_specs); - create(); } diff --git a/intern/audaspace/SDL/AUD_SDLDevice.h b/intern/audaspace/SDL/AUD_SDLDevice.h index e2c6f7631b7..4b7de1996e8 100644 --- a/intern/audaspace/SDL/AUD_SDLDevice.h +++ b/intern/audaspace/SDL/AUD_SDLDevice.h @@ -55,7 +55,8 @@ public: * \note The specification really used for opening the device may differ. * \exception AUD_Exception Thrown if the audio device cannot be opened. */ - AUD_SDLDevice(AUD_Specs specs, int buffersize = AUD_DEFAULT_BUFFER_SIZE); + AUD_SDLDevice(AUD_DeviceSpecs specs, + int buffersize = AUD_DEFAULT_BUFFER_SIZE); /** * Closes the SDL audio device. diff --git a/intern/audaspace/SDL/AUD_SDLMixer.cpp b/intern/audaspace/SDL/AUD_SDLMixer.cpp deleted file mode 100644 index cacc0c7063c..00000000000 --- a/intern/audaspace/SDL/AUD_SDLMixer.cpp +++ /dev/null @@ -1,83 +0,0 @@ -/* - * $Id$ - * - * ***** BEGIN LGPL LICENSE BLOCK ***** - * - * Copyright 2009 Jörg Hermann Müller - * - * This file is part of AudaSpace. - * - * AudaSpace is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * AudaSpace is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with AudaSpace. If not, see <http://www.gnu.org/licenses/>. - * - * ***** END LGPL LICENSE BLOCK ***** - */ - -#include "AUD_SDLMixer.h" -#include "AUD_SDLMixerFactory.h" - -#include <SDL.h> - -AUD_SDLMixer::AUD_SDLMixer() -{ - m_factory = NULL; -} - -AUD_SDLMixer::~AUD_SDLMixer() -{ - if(m_factory) - { - delete m_factory; AUD_DELETE("factory") - } -} - -AUD_IReader* AUD_SDLMixer::prepare(AUD_IReader* reader) -{ - m_factory->setReader(reader); - return m_factory->createReader(); -} - -void AUD_SDLMixer::setSpecs(AUD_Specs specs) -{ - m_samplesize = AUD_SAMPLE_SIZE(specs); - if(m_factory) - { - delete m_factory; AUD_DELETE("factory") - } - m_factory = new AUD_SDLMixerFactory(specs); AUD_NEW("factory") -} - -void AUD_SDLMixer::add(sample_t* buffer, AUD_Specs specs, int length, - float volume) -{ - AUD_SDLMixerBuffer buf; - buf.buffer = buffer; - buf.length = length; - buf.volume = volume; - m_buffers.push_back(buf); -} - -void AUD_SDLMixer::superpose(sample_t* buffer, int length, float volume) -{ - AUD_SDLMixerBuffer buf; - - while(!m_buffers.empty()) - { - buf = m_buffers.front(); - m_buffers.pop_front(); - SDL_MixAudio((Uint8*)buffer, - (Uint8*)buf.buffer, - buf.length * m_samplesize, - (int)(SDL_MIX_MAXVOLUME * volume * buf.volume)); - } -} diff --git a/intern/audaspace/SDL/AUD_SDLMixer.h b/intern/audaspace/SDL/AUD_SDLMixer.h deleted file mode 100644 index 2cc4e51f66d..00000000000 --- a/intern/audaspace/SDL/AUD_SDLMixer.h +++ /dev/null @@ -1,76 +0,0 @@ -/* - * $Id$ - * - * ***** BEGIN LGPL LICENSE BLOCK ***** - * - * Copyright 2009 Jörg Hermann Müller - * - * This file is part of AudaSpace. - * - * AudaSpace is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * AudaSpace is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with AudaSpace. If not, see <http://www.gnu.org/licenses/>. - * - * ***** END LGPL LICENSE BLOCK ***** - */ - -#ifndef AUD_SDLMIXER -#define AUD_SDLMIXER - -#include "AUD_IMixer.h" -class AUD_SDLMixerFactory; -#include <list> - -struct AUD_SDLMixerBuffer -{ - sample_t* buffer; - int length; - float volume; -}; - -/** - * This class is able to mix audiosignals with the help of SDL. - */ -class AUD_SDLMixer : public AUD_IMixer -{ -private: - /** - * The mixer factory that prepares all readers for superposition. - */ - AUD_SDLMixerFactory* m_factory; - - /** - * The list of buffers to superpose. - */ - std::list<AUD_SDLMixerBuffer> m_buffers; - - /** - * The size of an output sample. - */ - int m_samplesize; - -public: - /** - * Creates the mixer. - */ - AUD_SDLMixer(); - - virtual ~AUD_SDLMixer(); - - virtual AUD_IReader* prepare(AUD_IReader* reader); - virtual void setSpecs(AUD_Specs specs); - virtual void add(sample_t* buffer, AUD_Specs specs, int length, - float volume); - virtual void superpose(sample_t* buffer, int length, float volume); -}; - -#endif //AUD_SDLMIXER diff --git a/intern/audaspace/SDL/AUD_SDLMixerFactory.cpp b/intern/audaspace/SDL/AUD_SDLMixerFactory.cpp deleted file mode 100644 index e0b0c7d3603..00000000000 --- a/intern/audaspace/SDL/AUD_SDLMixerFactory.cpp +++ /dev/null @@ -1,65 +0,0 @@ -/* - * $Id$ - * - * ***** BEGIN LGPL LICENSE BLOCK ***** - * - * Copyright 2009 Jörg Hermann Müller - * - * This file is part of AudaSpace. - * - * AudaSpace is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * AudaSpace is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with AudaSpace. If not, see <http://www.gnu.org/licenses/>. - * - * ***** END LGPL LICENSE BLOCK ***** - */ - -#include "AUD_SDLMixerFactory.h" -#include "AUD_SDLMixerReader.h" - -#include <cstring> - -AUD_SDLMixerFactory::AUD_SDLMixerFactory(AUD_IReader* reader, AUD_Specs specs) : - AUD_MixerFactory(reader, specs) {} - -AUD_SDLMixerFactory::AUD_SDLMixerFactory(AUD_IFactory* factory, AUD_Specs specs) : - AUD_MixerFactory(factory, specs) {} - -AUD_SDLMixerFactory::AUD_SDLMixerFactory(AUD_Specs specs) : - AUD_MixerFactory(specs) {} - -AUD_IReader* AUD_SDLMixerFactory::createReader() -{ - AUD_IReader* reader = getReader(); - - if(reader != 0) - { - AUD_Specs specs = reader->getSpecs(); - if(memcmp(&m_specs, &specs, sizeof(AUD_Specs)) != 0) - { - try - { - reader = new AUD_SDLMixerReader(reader, m_specs); - AUD_NEW("reader") - } - catch(AUD_Exception e) - { - // return 0 in case SDL cannot mix the source - if(e.error != AUD_ERROR_SDL) - throw; - else - reader = NULL; - } - } - } - return reader; -} diff --git a/intern/audaspace/SDL/AUD_SDLMixerFactory.h b/intern/audaspace/SDL/AUD_SDLMixerFactory.h deleted file mode 100644 index 44b36d06859..00000000000 --- a/intern/audaspace/SDL/AUD_SDLMixerFactory.h +++ /dev/null @@ -1,45 +0,0 @@ -/* - * $Id$ - * - * ***** BEGIN LGPL LICENSE BLOCK ***** - * - * Copyright 2009 Jörg Hermann Müller - * - * This file is part of AudaSpace. - * - * AudaSpace is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * AudaSpace is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with AudaSpace. If not, see <http://www.gnu.org/licenses/>. - * - * ***** END LGPL LICENSE BLOCK ***** - */ - -#ifndef AUD_SDLMIXERFACTORY -#define AUD_SDLMIXERFACTORY - -#include "AUD_MixerFactory.h" - -/** - * This factory creates a resampling reader that uses SDL's resampling - * functionality which unfortunately is very very very limited. - */ -class AUD_SDLMixerFactory : public AUD_MixerFactory -{ -public: - AUD_SDLMixerFactory(AUD_IReader* reader, AUD_Specs specs); - AUD_SDLMixerFactory(AUD_IFactory* factory, AUD_Specs specs); - AUD_SDLMixerFactory(AUD_Specs specs); - - virtual AUD_IReader* createReader(); -}; - -#endif //AUD_SDLMIXERFACTORY diff --git a/intern/audaspace/SDL/AUD_SDLMixerReader.cpp b/intern/audaspace/SDL/AUD_SDLMixerReader.cpp deleted file mode 100644 index 0a47e36533a..00000000000 --- a/intern/audaspace/SDL/AUD_SDLMixerReader.cpp +++ /dev/null @@ -1,216 +0,0 @@ -/* - * $Id$ - * - * ***** BEGIN LGPL LICENSE BLOCK ***** - * - * Copyright 2009 Jörg Hermann Müller - * - * This file is part of AudaSpace. - * - * AudaSpace is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * AudaSpace is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with AudaSpace. If not, see <http://www.gnu.org/licenses/>. - * - * ***** END LGPL LICENSE BLOCK ***** - */ - -#include "AUD_SDLMixerReader.h" -#include "AUD_Buffer.h" - -#include <cstring> - -inline Uint16 AUD_TO_SDL(AUD_SampleFormat format) -{ - // SDL only supports 8 and 16 bit audio - switch(format) - { - case AUD_FORMAT_U8: - return AUDIO_U8; - case AUD_FORMAT_S16: - return AUDIO_S16SYS; - default: - AUD_THROW(AUD_ERROR_SDL); - } -} - -// greatest common divisor -inline int gcd(int a, int b) -{ - int c; - - // make sure a is the bigger - if(b > a) - { - c = b; - b = a; - a = c; - } - - // greetings from Euclides - while(b != 0) - { - c = a % b; - a = b; - b = c; - } - return a; -} - -AUD_SDLMixerReader::AUD_SDLMixerReader(AUD_IReader* reader, - AUD_Specs specs) -{ - if(reader == NULL) - AUD_THROW(AUD_ERROR_READER); - - m_reader = reader; - m_tspecs = specs; - m_sspecs = reader->getSpecs(); - - try - { - // SDL only supports 8 and 16 bit sample formats - if(SDL_BuildAudioCVT(&m_cvt, - AUD_TO_SDL(m_sspecs.format), - m_sspecs.channels, - m_sspecs.rate, - AUD_TO_SDL(specs.format), - specs.channels, - specs.rate) == -1) - AUD_THROW(AUD_ERROR_SDL); - } - catch(AUD_Exception) - { - delete m_reader; AUD_DELETE("reader") - throw; - } - - m_eor = false; - m_rsposition = 0; - m_rssize = 0; - m_ssize = m_sspecs.rate / gcd(specs.rate, m_sspecs.rate); - m_tsize = m_tspecs.rate * m_ssize / m_sspecs.rate; - - m_buffer = new AUD_Buffer(); AUD_NEW("buffer") - m_rsbuffer = new AUD_Buffer(); AUD_NEW("buffer") -} - -AUD_SDLMixerReader::~AUD_SDLMixerReader() -{ - delete m_reader; AUD_DELETE("reader") - delete m_buffer; AUD_DELETE("buffer") - delete m_rsbuffer; AUD_DELETE("buffer") -} - -bool AUD_SDLMixerReader::isSeekable() -{ - return m_reader->isSeekable(); -} - -void AUD_SDLMixerReader::seek(int position) -{ - m_reader->seek(position * m_ssize / m_tsize); - m_eor = false; -} - -int AUD_SDLMixerReader::getLength() -{ - return m_reader->getLength() * m_tsize / m_ssize; -} - -int AUD_SDLMixerReader::getPosition() -{ - return m_reader->getPosition() * m_tsize / m_ssize; -} - -AUD_Specs AUD_SDLMixerReader::getSpecs() -{ - return m_tspecs; -} - -AUD_ReaderType AUD_SDLMixerReader::getType() -{ - return m_reader->getType(); -} - -bool AUD_SDLMixerReader::notify(AUD_Message &message) -{ - return m_reader->notify(message); -} - -void AUD_SDLMixerReader::read(int & length, sample_t* & buffer) -{ - // sample count for the target buffer without getting a shift - int tns = length + m_tsize - length % m_tsize; - // sample count for the source buffer without getting a shift - int sns = tns * m_ssize / m_tsize; - // target sample size - int tss = AUD_SAMPLE_SIZE(m_tspecs); - // source sample size - int sss = AUD_SAMPLE_SIZE(m_sspecs); - - // input is output buffer - int buf_size = AUD_MAX(tns*tss, sns*sss); - - // resize if necessary - if(m_rsbuffer->getSize() < buf_size) - m_rsbuffer->resize(buf_size, true); - - if(m_buffer->getSize() < length*tss) - m_buffer->resize(length*tss); - - buffer = m_buffer->getBuffer(); - int size; - int index = 0; - sample_t* buf; - - while(index < length) - { - if(m_rsposition == m_rssize) - { - // no more data - if(m_eor) - length = index; - // mix - else - { - // read from source - size = sns; - m_reader->read(size, buf); - - // prepare - m_cvt.buf = m_rsbuffer->getBuffer(); - m_cvt.len = size*sss; - memcpy(m_cvt.buf, buf, size*sss); - - // convert - SDL_ConvertAudio(&m_cvt); - - // end of reader - if(size < sns) - m_eor = true; - - m_rsposition = 0; - m_rssize = size * m_tsize / m_ssize; - } - } - - // size to copy - size = AUD_MIN(m_rssize-m_rsposition, length-index); - - // copy - memcpy(m_buffer->getBuffer() + index * tss, - m_rsbuffer->getBuffer() + m_rsposition * tss, - size*tss); - m_rsposition += size; - index += size; - } -} diff --git a/intern/audaspace/SDL/AUD_SDLMixerReader.h b/intern/audaspace/SDL/AUD_SDLMixerReader.h deleted file mode 100644 index 56668d02171..00000000000 --- a/intern/audaspace/SDL/AUD_SDLMixerReader.h +++ /dev/null @@ -1,128 +0,0 @@ -/* - * $Id$ - * - * ***** BEGIN LGPL LICENSE BLOCK ***** - * - * Copyright 2009 Jörg Hermann Müller - * - * This file is part of AudaSpace. - * - * AudaSpace is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * AudaSpace is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with AudaSpace. If not, see <http://www.gnu.org/licenses/>. - * - * ***** END LGPL LICENSE BLOCK ***** - */ - -#ifndef AUD_SDLMIXERREADER -#define AUD_SDLMIXERREADER - -#include "AUD_IReader.h" -class AUD_Buffer; - -#include <SDL.h> - -/** - * This class mixes a sound source with help of the SDL library. - * Unfortunately SDL is only capable of 8 and 16 bit audio, mono and stereo, as - * well as resampling only 2^n sample rate relationships where n is a natural - * number. - * \warning Although SDL can only resample 2^n sample rate relationships, this - * class doesn't check for compliance, so in case of other factors, - * the behaviour is undefined. - */ -class AUD_SDLMixerReader : public AUD_IReader -{ -private: - /** - * The reader that is being mixed. - */ - AUD_IReader* m_reader; - - /** - * The current reading position in the resampling buffer. - */ - int m_rsposition; - - /** - * The count of mixed samples in the resampling buffer. - */ - int m_rssize; - - /** - * The smallest count of source samples to get a fractionless resampling - * factor. - */ - int m_ssize; - - /** - * The smallest count of target samples to get a fractionless resampling - * factor. - */ - int m_tsize; - - /** - * The sound output buffer. - */ - AUD_Buffer *m_buffer; - - /** - * The resampling buffer. - */ - AUD_Buffer *m_rsbuffer; - - /** - * The target specification. - */ - AUD_Specs m_tspecs; - - /** - * The sample specification of the source. - */ - AUD_Specs m_sspecs; - - /** - * Saves whether the end of the source has been reached. - */ - bool m_eor; - - /** - * The SDL_AudioCVT structure used for resampling. - */ - SDL_AudioCVT m_cvt; - -public: - /** - * Creates a resampling reader. - * \param reader The reader to mix. - * \param specs The target specification. - * \exception AUD_Exception Thrown if the source specification cannot be - * mixed to the target specification or if the reader is - * NULL. - */ - AUD_SDLMixerReader(AUD_IReader* reader, AUD_Specs specs); - /** - * Destroys the reader. - */ - ~AUD_SDLMixerReader(); - - virtual bool isSeekable(); - virtual void seek(int position); - virtual int getLength(); - virtual int getPosition(); - virtual AUD_Specs getSpecs(); - virtual AUD_ReaderType getType(); - virtual bool notify(AUD_Message &message); - virtual void read(int & length, sample_t* & buffer); -}; - -#endif //AUD_SDLMIXERREADER |