From 2d3d025e8cf8776361e6397502f4e240ae9a5ccc Mon Sep 17 00:00:00 2001 From: Joerg Mueller Date: Tue, 21 Jun 2011 20:39:41 +0000 Subject: 3D Audio GSoC: - Sequencer dynamics: Now it's possible to change the output channels and the resampling quality also increased (previously maximum quality was 44,1 kHz) - Changed two buffers to use ffmpeg allocation, not sure if that helps somehow. --- intern/audaspace/intern/AUD_C-API.cpp | 17 ++++++---- intern/audaspace/intern/AUD_C-API.h | 4 +++ .../audaspace/intern/AUD_ChannelMapperReader.cpp | 6 ++++ intern/audaspace/intern/AUD_ChannelMapperReader.h | 2 ++ intern/audaspace/intern/AUD_Mixer.cpp | 5 +++ intern/audaspace/intern/AUD_Mixer.h | 8 ++++- intern/audaspace/intern/AUD_SequencerFactory.cpp | 9 ++++-- intern/audaspace/intern/AUD_SequencerFactory.h | 3 +- intern/audaspace/intern/AUD_SequencerReader.cpp | 36 +++++++++++++++++----- intern/audaspace/intern/AUD_SequencerReader.h | 7 ++++- 10 files changed, 77 insertions(+), 20 deletions(-) (limited to 'intern/audaspace') diff --git a/intern/audaspace/intern/AUD_C-API.cpp b/intern/audaspace/intern/AUD_C-API.cpp index b52243c3fe0..db76b9b4faf 100644 --- a/intern/audaspace/intern/AUD_C-API.cpp +++ b/intern/audaspace/intern/AUD_C-API.cpp @@ -882,16 +882,11 @@ AUD_Handle* AUD_pauseAfter(AUD_Handle* handle, float seconds) AUD_Sound* AUD_createSequencer(int muted, void* data, AUD_volumeFunction volume) { -/* AUD_XXX should be this: but AUD_createSequencer is called before the device - * is initialized. - - return new AUD_SequencerFactory(AUD_device->getSpecs().specs, data, volume); -*/ + // specs are changed at a later point! AUD_Specs specs; specs.channels = AUD_CHANNELS_STEREO; specs.rate = AUD_RATE_44100; AUD_Reference* sequencer = new AUD_Reference(new AUD_SequencerFactory(specs, muted, data, volume)); - (*sequencer)->setThis(sequencer); return reinterpret_cast(sequencer); } @@ -928,6 +923,16 @@ void AUD_muteSequencer(AUD_Sound* sequencer, AUD_Reference* ((AUD_SequencerFactory*)sequencer->get())->mute(*entry, mute); } +void AUD_setSequencerDeviceSpecs(AUD_Sound* sequencer) +{ + ((AUD_SequencerFactory*)sequencer->get())->setSpecs(AUD_device->getSpecs().specs); +} + +void AUD_setSequencerSpecs(AUD_Sound* sequencer, AUD_Specs specs) +{ + ((AUD_SequencerFactory*)sequencer->get())->setSpecs(specs); +} + int AUD_readSound(AUD_Sound* sound, sample_t* buffer, int length) { AUD_DeviceSpecs specs; diff --git a/intern/audaspace/intern/AUD_C-API.h b/intern/audaspace/intern/AUD_C-API.h index b818140a571..72d423e847b 100644 --- a/intern/audaspace/intern/AUD_C-API.h +++ b/intern/audaspace/intern/AUD_C-API.h @@ -469,6 +469,10 @@ extern void AUD_moveSequencer(AUD_Sound* sequencer, AUD_SEntry* entry, extern void AUD_muteSequencer(AUD_Sound* sequencer, AUD_SEntry* entry, char mute); +extern void AUD_setSequencerDeviceSpecs(AUD_Sound* sequencer); + +extern void AUD_setSequencerSpecs(AUD_Sound* sequencer, AUD_Specs specs); + extern int AUD_readSound(AUD_Sound* sound, sample_t* buffer, int length); extern void AUD_startPlayback(void); diff --git a/intern/audaspace/intern/AUD_ChannelMapperReader.cpp b/intern/audaspace/intern/AUD_ChannelMapperReader.cpp index ab7b5317be1..4ac1982e32c 100644 --- a/intern/audaspace/intern/AUD_ChannelMapperReader.cpp +++ b/intern/audaspace/intern/AUD_ChannelMapperReader.cpp @@ -44,6 +44,12 @@ AUD_ChannelMapperReader::~AUD_ChannelMapperReader() delete[] m_mapping; } +void AUD_ChannelMapperReader::setChannels(AUD_Channels channels) +{ + m_target_channels = channels; + calculateMapping(); +} + float AUD_ChannelMapperReader::angleDistance(float alpha, float beta) { alpha = fabs(alpha - beta); diff --git a/intern/audaspace/intern/AUD_ChannelMapperReader.h b/intern/audaspace/intern/AUD_ChannelMapperReader.h index 949bb4427e2..3da34ed85ce 100644 --- a/intern/audaspace/intern/AUD_ChannelMapperReader.h +++ b/intern/audaspace/intern/AUD_ChannelMapperReader.h @@ -109,6 +109,8 @@ public: */ ~AUD_ChannelMapperReader(); + void setChannels(AUD_Channels channels); + virtual AUD_Specs getSpecs() const; virtual void read(int& length, bool& eos, sample_t* buffer); }; diff --git a/intern/audaspace/intern/AUD_Mixer.cpp b/intern/audaspace/intern/AUD_Mixer.cpp index e6699811344..cfdf2b0e60a 100644 --- a/intern/audaspace/intern/AUD_Mixer.cpp +++ b/intern/audaspace/intern/AUD_Mixer.cpp @@ -73,6 +73,11 @@ AUD_DeviceSpecs AUD_Mixer::getSpecs() const return m_specs; } +void AUD_Mixer::setSpecs(AUD_Specs specs) +{ + m_specs.specs = specs; +} + void AUD_Mixer::clear(int length) { m_buffer.assureSize(length * m_specs.channels * AUD_SAMPLE_SIZE(m_specs)); diff --git a/intern/audaspace/intern/AUD_Mixer.h b/intern/audaspace/intern/AUD_Mixer.h index a68d86dcb83..5ca801b1690 100644 --- a/intern/audaspace/intern/AUD_Mixer.h +++ b/intern/audaspace/intern/AUD_Mixer.h @@ -47,7 +47,7 @@ protected: /** * The output specification. */ - const AUD_DeviceSpecs m_specs; + AUD_DeviceSpecs m_specs; /** * The length of the mixing buffer. @@ -81,6 +81,12 @@ public: */ AUD_DeviceSpecs getSpecs() const; + /** + * Sets the target specification for superposing. + * \param specs The target specification. + */ + void setSpecs(AUD_Specs specs); + /** * Mixes a buffer. * \param buffer The buffer to superpose. diff --git a/intern/audaspace/intern/AUD_SequencerFactory.cpp b/intern/audaspace/intern/AUD_SequencerFactory.cpp index 1787dea0ebb..6907d7683c9 100644 --- a/intern/audaspace/intern/AUD_SequencerFactory.cpp +++ b/intern/audaspace/intern/AUD_SequencerFactory.cpp @@ -48,9 +48,12 @@ AUD_SequencerFactory::~AUD_SequencerFactory() { } -void AUD_SequencerFactory::setThis(AUD_Reference* self) +void AUD_SequencerFactory::setSpecs(AUD_Specs specs) { - m_this = self; + m_specs = specs; + + for(AUD_ReaderIterator i = m_readers.begin(); i != m_readers.end(); i++) + (*i)->setSpecs(m_specs); } void AUD_SequencerFactory::mute(bool muted) @@ -103,7 +106,7 @@ void AUD_SequencerFactory::mute(AUD_Reference entry, bool mu AUD_Reference AUD_SequencerFactory::createReader() { - AUD_Reference reader = new AUD_SequencerReader(*m_this, m_entries, + AUD_Reference reader = new AUD_SequencerReader(this, m_entries, m_specs, m_data, m_volume); m_readers.push_front(reader); diff --git a/intern/audaspace/intern/AUD_SequencerFactory.h b/intern/audaspace/intern/AUD_SequencerFactory.h index 37a332bc9ff..4e57a224c65 100644 --- a/intern/audaspace/intern/AUD_SequencerFactory.h +++ b/intern/audaspace/intern/AUD_SequencerFactory.h @@ -66,7 +66,6 @@ private: bool m_muted; void* m_data; AUD_volumeFunction m_volume; - AUD_Reference* m_this; // hide copy constructor and operator= AUD_SequencerFactory(const AUD_SequencerFactory&); @@ -76,7 +75,7 @@ public: AUD_SequencerFactory(AUD_Specs specs, bool muted, void* data, AUD_volumeFunction volume); ~AUD_SequencerFactory(); - void setThis(AUD_Reference* self); + void setSpecs(AUD_Specs specs); void mute(bool muted); bool getMute() const; diff --git a/intern/audaspace/intern/AUD_SequencerReader.cpp b/intern/audaspace/intern/AUD_SequencerReader.cpp index 9ee0b39c50d..a9309311d6a 100644 --- a/intern/audaspace/intern/AUD_SequencerReader.cpp +++ b/intern/audaspace/intern/AUD_SequencerReader.cpp @@ -95,6 +95,22 @@ void AUD_SequencerReader::remove(AUD_Reference entry) } } +void AUD_SequencerReader::setSpecs(AUD_Specs specs) +{ + m_mixer->setSpecs(specs); + + AUD_Reference strip; + for(AUD_StripIterator i = m_strips.begin(); i != m_strips.end(); i++) + { + strip = *i; + if(!strip->mapper.isNull()) + { + strip->mapper->setChannels(specs.channels); + strip->resampler->setRate(specs.rate); + } + } +} + bool AUD_SequencerReader::isSeekable() const { return true; @@ -149,24 +165,30 @@ void AUD_SequencerReader::read(int& length, bool& eos, sample_t* buffer) strip->reader = (*strip->old_sound)->createReader(); // resample #ifdef WITH_SAMPLERATE - strip->reader = new AUD_SRCResampleReader(strip->reader, m_mixer->getSpecs().specs); + strip->resampler = new AUD_SRCResampleReader(strip->reader, m_mixer->getSpecs().specs); #else - strip->reader = new AUD_LinearResampleReader(strip->reader, m_mixer->getSpecs().specs); + strip->resampler = new AUD_LinearResampleReader(strip->reader, m_mixer->getSpecs().specs); #endif // rechannel - strip->reader = new AUD_ChannelMapperReader(strip->reader, m_mixer->getSpecs().channels); + strip->mapper = new AUD_ChannelMapperReader(AUD_Reference(strip->resampler), m_mixer->getSpecs().channels); } catch(AUD_Exception) { strip->reader = NULL; + strip->resampler = NULL; + strip->mapper = NULL; } } else + { strip->reader = NULL; + strip->resampler = NULL; + strip->mapper = NULL; + } } - if(!strip->reader.isNull()) + if(!strip->mapper.isNull()) { end = floor(strip->entry->end * rate); if(m_position < end) @@ -185,9 +207,9 @@ void AUD_SequencerReader::read(int& length, bool& eos, sample_t* buffer) current += strip->entry->skip * rate; len = length > end - m_position ? end - m_position : length; len -= skip; - if(strip->reader->getPosition() != current) - strip->reader->seek(current); - strip->reader->read(len, eos, m_buffer.getBuffer()); + if(strip->mapper->getPosition() != current) + strip->mapper->seek(current); + strip->mapper->read(len, eos, m_buffer.getBuffer()); m_mixer->mix(m_buffer.getBuffer(), skip, len, m_volume(m_data, strip->entry->data, (float)m_position / (float)rate)); } } diff --git a/intern/audaspace/intern/AUD_SequencerReader.h b/intern/audaspace/intern/AUD_SequencerReader.h index e769b342d1b..625bad3c3ae 100644 --- a/intern/audaspace/intern/AUD_SequencerReader.h +++ b/intern/audaspace/intern/AUD_SequencerReader.h @@ -35,11 +35,15 @@ #include "AUD_IReader.h" #include "AUD_SequencerFactory.h" #include "AUD_Buffer.h" -class AUD_Mixer; +#include "AUD_Mixer.h" +#include "AUD_ResampleReader.h" +#include "AUD_ChannelMapperReader.h" struct AUD_SequencerStrip { AUD_Reference reader; + AUD_Reference resampler; + AUD_Reference mapper; AUD_Reference entry; AUD_Reference* old_sound; }; @@ -94,6 +98,7 @@ public: void add(AUD_Reference entry); void remove(AUD_Reference entry); + void setSpecs(AUD_Specs specs); virtual bool isSeekable() const; virtual void seek(int position); -- cgit v1.2.3