From 68af6f6836a965ff61fb92702eae5cd756150294 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B6rg=20M=C3=BCller?= Date: Sat, 8 Apr 2023 10:36:40 +0200 Subject: [PATCH] Audaspace: porting changes from upstream. --- extern/audaspace/AUTHORS | 10 ++ extern/audaspace/CHANGES | 105 ++++++++++++++++++ extern/audaspace/CMakeLists.txt | 2 +- extern/audaspace/INSTALL | 2 +- extern/audaspace/README.md | 2 +- extern/audaspace/bindings/C/AUD_Sequence.cpp | 6 + extern/audaspace/bindings/C/AUD_Sequence.h | 10 ++ .../include/sequence/AnimateableProperty.h | 8 ++ .../audaspace/include/sequence/SequenceData.h | 3 +- .../include/sequence/SequenceEntry.h | 7 +- .../src/sequence/AnimateableProperty.cpp | 13 +++ extern/audaspace/src/sequence/Sequence.cpp | 2 +- .../audaspace/src/sequence/SequenceData.cpp | 4 +- .../audaspace/src/sequence/SequenceEntry.cpp | 3 +- .../audaspace/src/sequence/SequenceHandle.cpp | 36 +++++- 15 files changed, 200 insertions(+), 13 deletions(-) diff --git a/extern/audaspace/AUTHORS b/extern/audaspace/AUTHORS index 08007912102..d54d14bf3ac 100644 --- a/extern/audaspace/AUTHORS +++ b/extern/audaspace/AUTHORS @@ -14,3 +14,13 @@ The first three of them were employed by the Blender Foundation during that time Some features (random sounds, dynamic music, playback manager, convolution and HRTFs support) were added as part of the VALS (Virtual Alliances for Learning Society) project by - Juan Francisco Crespo Galán + +The Equalizer sound effect has been added by + +- Marcos Perez + +Several people provided fixes: + +- Aaron Carlisle +- Sebastian Parborg +- Leon Zandman diff --git a/extern/audaspace/CHANGES b/extern/audaspace/CHANGES index bd5acaa88fb..9682e1388a2 100644 --- a/extern/audaspace/CHANGES +++ b/extern/audaspace/CHANGES @@ -1,3 +1,104 @@ +Audaspace 1.4 + +- Support for OS specific/native audio devices/backends has been added, that is PulseAudio (Linux), WASAPI (Windows) and CoreAudio (MacOS). +- New sound effects have been added, namely Modulator and Equalizer. Thanks to Marcos Perez for contributing the Equalizer. +- File stream info: if an audio file contains multiple streams you can choose which one to process instead of taking the first one (this feature is only supported by ffmpeg, not libsndfile). +- API Change: double instead of float for time values for more precise timing control. +- There have been lots of bugfixes, which are basically the majority of all changes. +- And some other minor improvements were implemented as well. + +Detailed list of changes: + +d4042d9 Port changes in Blender to upstream. +b60fb45 Equalizer +ab04e84 Fixes +8f0c305 Fix build error with MSVC 17.4+ ported from Blender. +ce44342 Minor documentation update. +cdcb3f4 Migrate from distuils to setuptools for python module. +21eccef Fix FindFFTW to find the float version fftw3f. +ab15e2f Bugfix: API change in new ffmpeg version. +a097be8 Clang format file added, valid from now on. +2fc9fb7 Porting bugfix from Blender upstream. +bb655b7 Bugfix: wrong sample size computation for PulseAudio. +a150495 Bugfix: Buffer did not support buffers > 2 GB. +034645c Update for ffmpeg 5. +932739c Bugfix: WASAPI hangs. +4fcd47c WASAPI: fix bug when switching the default device while there is no playback. +a16fbd2 Python API: fix to get convolution in the python API. +27ac5c1 WASAPI: always switch to default audio device. +1b03e6c Bugfix: catch exception if file cannot be read. +369ff6e PulseAudio: remove unused underflow callback. +2d8bf3a PulseAudio: improve synchronization accuracy. +4868e14 Revert PulseAudioDevice back from ThreadedDevice to threaded mainloop. +6a04446 Adding a jack style mixing thread with a ring buffer for pulseaudio. +5d4b57b Implement RingBuffer class. +e02d3aa FFMPEG: fix seeking and duration calculation. +07b9fa0 Adding file stream functionality. +5a8ad27 Porting changes from Blender. +fa47258 Bugfix: PulseAudio writing to little data on request. +ca3edb5 PulseAudio: increase buffersize. +6d36f3e Pulseaudio: may fix crackling playback start bug. +dbeac4b WASAPI: reinitialize device when lost. +0cba4d3 Bugfix Pulseaudio: might hang. +b73dc6d Bugfix: ffmpeg 4.4 requires channels to be set. +f1ecbe0 Fixed typo. +09e4f27 Rewrite PulseAudioDevice to use ThreadedDevice. +9516924 WASAPI: refactor to simplify and use ThreadedDevice. +749c974 Add ThreadedDevice. +e68b355 Fix some locks in SoftwareDevice. +44b57af Bugfix for deadlock in WASAPIDevice. +8c4b266 CMake: fix ERROR to FATAL_ERROR in MESSAGE. +5a17338 Rename NullDevice's reported name to None. +cd138d7 PulseAudio: add dynamic loading and threading fixes. +6e0250f CoreAudio: add CoreAudioClock as synchronizer. +43aff35 Fix leakage in CoreAudioDevice.cpp +7f6f059 Remove unnecessary cmake code. +a5c1a02 Add CoreAudio device for Apple. +af96f67 Indentation fix. +eec8fd5 WASAPI: use padding also for first buffer submission. +c63bd9b WASAPI: deal with IsFormatSupported case. +079cccb Hide WITH_PULSEAUDIO when not on Linux. +67b5013 Add mingw64 cross compilation toolchain on Linux. +a7bfa58 Add WASAPI backend for Windows. +be1cb25 Allow AUD_init with nullptr to use default device. +fc68868 Compilation fix for mingw. +bb79d25 Add a PulseAudio output device. +a11f593 Bugfix for unwanted volume fading at the beginning of sounds. +8510acf Bugfix: more accurate positioning of sequences. +cb816c1 Fix API docs for python playback manager play function +d125fa2 Add callback for mixing down audio. +789832e Fix numpy import. +9a6a802 Bugfix: JOS resampling type bugfix caused integer underflow. +ece0842 Fix corrupted document in python bindings +28b2ea2 SDL 2: support more audio formats. +a39b7e3 Trying to fix Travis CI build for OS X. +c924007 Some more changes of times from flaot to double. +659afd4 Porting fixes from blender. +8e5e2e6 Fix documentation warnings. +7a6054f API: All times are now double instead of float. +452a724 Mixer sample buffer added channels twice +8ddb6c1 Docs: Cleanup Line Wrapping for python examples +a0c37b2 Docs: Use class methods for api docs +2f8b2e3 Bugfix for invalid offsets provided by ffmpeg's seeking code. +20a7a28 Bug fixes for files with more than 8 channels. +94dc527 Bugfix: Fading from full volume. +2fb9862 Fix: Missing include in FileManager.h. +afadb94 Minor CMakeLists.txt formatting fixes. +734ef03 Add sample rate parameter to silence generation. +ed50f3b Bugfix: Return correct length for modulator and superpose. +cb7a314 Adding a modulator sound effect. +101c714 Bugfix: don't add non-existing devices to the device manager. +7ad99df OpenAL: recreate device if disconnected. +a2ff4e8 Bugfix: memory leak in python API. +5fb21bb Silence some warnings. +9b38605 Some fixes backported from Blender. +40a0a34 Udpate for travis.ci. +212b4b6 Support newer ffmpeg versions. +d27746c Build option: configure whether to build versioned plugins. +19c8d9f Make fftw3 optional. +aa11968 Bugfix for building with gcc7. +10413c5 Fix for seeking with modified pitch. + Audaspace 1.3 ============= @@ -10,6 +111,8 @@ Audaspace 1.3 - filter python API parameter check - finding ffmpeg with pkgconfig + Detailed list of changes: + 64884a7 Windows fixes. 53ba3e6 Implemented JACK dynamic loading. 5ee0ee1 Continues last commit. @@ -46,6 +149,8 @@ Audaspace 1.2 - assuring numpy is installed - building the Python module on Mac OS X with CMake + Detailed list of changes: + a6b6e70 Changing default sample rate from 44.1 to 48 kHz. 20f0164 Bugfix: CMake custom command for python module on OS X. 98679a2 Bugfix: using standard library (s)rand. diff --git a/extern/audaspace/CMakeLists.txt b/extern/audaspace/CMakeLists.txt index 1ae2fbfba10..ed48d4533a1 100644 --- a/extern/audaspace/CMakeLists.txt +++ b/extern/audaspace/CMakeLists.txt @@ -23,7 +23,7 @@ endif() project(audaspace) -set(AUDASPACE_VERSION 1.3) +set(AUDASPACE_VERSION 1.4) set(AUDASPACE_LONG_VERSION ${AUDASPACE_VERSION}.0) if(DEFINED AUDASPACE_CMAKE_CFG) diff --git a/extern/audaspace/INSTALL b/extern/audaspace/INSTALL index c63206fb949..d7180e6727e 100644 --- a/extern/audaspace/INSTALL +++ b/extern/audaspace/INSTALL @@ -15,7 +15,7 @@ Audaspace is written in C++ 11 so a fairly recent compiler (g++ 4.8.2, clang 3.3 - Jack (output device) - libsndfile (file access) - ffmpeg (file access) -- Python (language binding) +- Python (language binding, needs NumPy as well) Getting the Code ---------------- diff --git a/extern/audaspace/README.md b/extern/audaspace/README.md index 7fdd515ab67..bfc343e2b49 100644 --- a/extern/audaspace/README.md +++ b/extern/audaspace/README.md @@ -32,7 +32,7 @@ The following (probably incomplete) features are supported by audaspace: License ------- -> Copyright © 2009-2015 Jörg Müller. All rights reserved. +> Copyright © 2009-2023 Jörg Müller. All rights reserved. > > Licensed under the Apache License, Version 2.0 (the "License"); > you may not use this file except in compliance with the License. diff --git a/extern/audaspace/bindings/C/AUD_Sequence.cpp b/extern/audaspace/bindings/C/AUD_Sequence.cpp index e3f88629657..4e60a2902f2 100644 --- a/extern/audaspace/bindings/C/AUD_Sequence.cpp +++ b/extern/audaspace/bindings/C/AUD_Sequence.cpp @@ -165,6 +165,12 @@ AUD_API void AUD_SequenceEntry_move(AUD_SequenceEntry* entry, double begin, doub (*entry)->move(begin, end, skip); } +AUD_API void AUD_SequenceEntry_setConstantRangeAnimationData(AUD_SequenceEntry* entry, AUD_AnimateablePropertyType type, int frame_start, int frame_end, float* data) +{ + AnimateableProperty* prop = (*entry)->getAnimProperty(static_cast(type)); + prop->writeConstantRange(data, frame_start, frame_end); +} + AUD_API void AUD_SequenceEntry_setAnimationData(AUD_SequenceEntry* entry, AUD_AnimateablePropertyType type, int frame, float* data, char animated) { AnimateableProperty* prop = (*entry)->getAnimProperty(static_cast(type)); diff --git a/extern/audaspace/bindings/C/AUD_Sequence.h b/extern/audaspace/bindings/C/AUD_Sequence.h index bdf1a61a2de..57075f3a1cb 100644 --- a/extern/audaspace/bindings/C/AUD_Sequence.h +++ b/extern/audaspace/bindings/C/AUD_Sequence.h @@ -68,6 +68,16 @@ extern AUD_API void AUD_Sequence_remove(AUD_Sound* sequence, AUD_SequenceEntry* * Writes animation data to a sequence. * \param sequence The sound scene. * \param type The type of animation data. + * \param frame_start Start of the frame range. + * \param frame_end End of the frame range. + * \param data The data to write. + */ +AUD_API void AUD_SequenceEntry_setConstantRangeAnimationData(AUD_SequenceEntry* entry, AUD_AnimateablePropertyType type, int frame_start, int frame_end, float* data); + +/** + * Writes animation data to a sequenced entry. + * \param entry The sequenced entry. + * \param type The type of animation data. * \param frame The frame this data is for. * \param data The data to write. * \param animated Whether the attribute is animated. diff --git a/extern/audaspace/include/sequence/AnimateableProperty.h b/extern/audaspace/include/sequence/AnimateableProperty.h index 2c3fcf23f8b..d14990b6867 100644 --- a/extern/audaspace/include/sequence/AnimateableProperty.h +++ b/extern/audaspace/include/sequence/AnimateableProperty.h @@ -112,6 +112,14 @@ public: */ void write(const float* data, int position, int count); + /** + * Fills the properties frame range with constant value and marks it animated. + * \param data The new value. + * \param position_start The start position in the animation in frames. + * \param position_end The end position in the animation in frames. + */ + void writeConstantRange(const float* data, int position_start, int position_end); + /** * Reads the properties value. * \param position The position in the animation in frames. diff --git a/extern/audaspace/include/sequence/SequenceData.h b/extern/audaspace/include/sequence/SequenceData.h index c3380e66924..c19c82c090e 100644 --- a/extern/audaspace/include/sequence/SequenceData.h +++ b/extern/audaspace/include/sequence/SequenceData.h @@ -198,12 +198,13 @@ public: /** * Adds a new entry to the scene. * \param sound The sound this entry should play. + * \param sequence_data Reference to sequence_data. Mainly needed to get the FPS of the scene. * \param begin The start time. * \param end The end time or a negative value if determined by the sound. * \param skip How much seconds should be skipped at the beginning. * \return The entry added. */ - std::shared_ptr add(std::shared_ptr sound, double begin, double end, double skip); + std::shared_ptr add(std::shared_ptr sound, std::shared_ptr sequence_data, double begin, double end, double skip); /** * Removes an entry from the scene. diff --git a/extern/audaspace/include/sequence/SequenceEntry.h b/extern/audaspace/include/sequence/SequenceEntry.h index b8e9f116ee4..47b900405d9 100644 --- a/extern/audaspace/include/sequence/SequenceEntry.h +++ b/extern/audaspace/include/sequence/SequenceEntry.h @@ -23,6 +23,7 @@ */ #include "sequence/AnimateableProperty.h" +#include "sequence/SequenceData.h" #include "util/ILockable.h" #include @@ -63,6 +64,9 @@ private: /// How many seconds are skipped at the beginning. double m_skip; + /// reference to sequence_data. Mainly needed to get the FPS of the scene. + std::shared_ptr m_sequence_data; + /// Whether the entry is muted. bool m_muted; @@ -122,9 +126,10 @@ public: * \param begin The start time. * \param end The end time or a negative value if determined by the sound. * \param skip How much seconds should be skipped at the beginning. + * \param sequence_data Reference to sequence_data. Mainly needed to get the FPS of the scene. * \param id The ID of the entry. */ - SequenceEntry(std::shared_ptr sound, double begin, double end, double skip, int id); + SequenceEntry(std::shared_ptr sound, double begin, double end, double skip, std::shared_ptr sequence_data, int id); virtual ~SequenceEntry(); /** diff --git a/extern/audaspace/src/sequence/AnimateableProperty.cpp b/extern/audaspace/src/sequence/AnimateableProperty.cpp index 306ba8e07f5..c9c2a358219 100644 --- a/extern/audaspace/src/sequence/AnimateableProperty.cpp +++ b/extern/audaspace/src/sequence/AnimateableProperty.cpp @@ -65,6 +65,19 @@ void AnimateableProperty::write(const float* data) std::memcpy(getBuffer(), data, m_count * sizeof(float)); } +void AnimateableProperty::writeConstantRange(const float* data, int position_start, int position_end) +{ + assureSize(position_end * m_count * sizeof(float), true); + float* buffer = getBuffer(); + + for(int i = position_start; i < position_end; i++) + { + std::memcpy(buffer + i * m_count, data, m_count * sizeof(float)); + } + + m_isAnimated = true; +} + void AnimateableProperty::write(const float* data, int position, int count) { std::lock_guard lock(m_mutex); diff --git a/extern/audaspace/src/sequence/Sequence.cpp b/extern/audaspace/src/sequence/Sequence.cpp index ab7e6e77857..3beb225d4ee 100644 --- a/extern/audaspace/src/sequence/Sequence.cpp +++ b/extern/audaspace/src/sequence/Sequence.cpp @@ -92,7 +92,7 @@ AnimateableProperty* Sequence::getAnimProperty(AnimateablePropertyType type) std::shared_ptr Sequence::add(std::shared_ptr sound, double begin, double end, double skip) { - return m_sequence->add(sound, begin, end, skip); + return m_sequence->add(sound, m_sequence, begin, end, skip); } void Sequence::remove(std::shared_ptr entry) diff --git a/extern/audaspace/src/sequence/SequenceData.cpp b/extern/audaspace/src/sequence/SequenceData.cpp index 288f0bd225d..47d57da3b92 100644 --- a/extern/audaspace/src/sequence/SequenceData.cpp +++ b/extern/audaspace/src/sequence/SequenceData.cpp @@ -149,11 +149,11 @@ AnimateableProperty* SequenceData::getAnimProperty(AnimateablePropertyType type) } } -std::shared_ptr SequenceData::add(std::shared_ptr sound, double begin, double end, double skip) +std::shared_ptr SequenceData::add(std::shared_ptr sound, std::shared_ptr sequence_data, double begin, double end, double skip) { std::lock_guard lock(m_mutex); - std::shared_ptr entry = std::shared_ptr(new SequenceEntry(sound, begin, end, skip, m_id++)); + std::shared_ptr entry = std::shared_ptr(new SequenceEntry(sound, begin, end, skip, sequence_data, m_id++)); m_entries.push_back(entry); m_entry_status++; diff --git a/extern/audaspace/src/sequence/SequenceEntry.cpp b/extern/audaspace/src/sequence/SequenceEntry.cpp index b63bdd2ffca..0fbab21cfc8 100644 --- a/extern/audaspace/src/sequence/SequenceEntry.cpp +++ b/extern/audaspace/src/sequence/SequenceEntry.cpp @@ -22,7 +22,7 @@ AUD_NAMESPACE_BEGIN -SequenceEntry::SequenceEntry(std::shared_ptr sound, double begin, double end, double skip, int id) : +SequenceEntry::SequenceEntry(std::shared_ptr sound, double begin, double end, double skip, std::shared_ptr sequence_data, int id) : m_status(0), m_pos_status(1), m_sound_status(0), @@ -31,6 +31,7 @@ SequenceEntry::SequenceEntry(std::shared_ptr sound, double begin, double m_begin(begin), m_end(end), m_skip(skip), + m_sequence_data(sequence_data), m_muted(false), m_relative(true), m_volume_max(1.0f), diff --git a/extern/audaspace/src/sequence/SequenceHandle.cpp b/extern/audaspace/src/sequence/SequenceHandle.cpp index fca4e805df2..55384ba5f35 100644 --- a/extern/audaspace/src/sequence/SequenceHandle.cpp +++ b/extern/audaspace/src/sequence/SequenceHandle.cpp @@ -241,10 +241,38 @@ bool SequenceHandle::seek(double position) return false; std::lock_guard lock(*m_entry); - double seekpos = position - m_entry->m_begin; - if(seekpos < 0) - seekpos = 0; - seekpos += m_entry->m_skip; + + double seek_frame = (position - m_entry->m_begin) * m_entry->m_sequence_data->getFPS(); + + if(seek_frame < 0) + seek_frame = 0; + + seek_frame += m_entry->m_skip * m_entry->m_sequence_data->getFPS(); + + AnimateableProperty* pitch_property = m_entry->getAnimProperty(AP_PITCH); + + double target_frame = 0; + + if(pitch_property != nullptr) + { + int frame_start = (m_entry->m_begin - m_entry->m_skip) * m_entry->m_sequence_data->getFPS(); + + for(int i = 0; seek_frame > 0; i++) + { + float pitch; + pitch_property->read(frame_start + i, &pitch); + const double factor = seek_frame > 1.0 ? 1.0 : seek_frame; + target_frame += pitch * factor; + seek_frame--; + } + } + else + { + target_frame = seek_frame; + } + + double seekpos = target_frame / m_entry->m_sequence_data->getFPS(); + m_handle->setPitch(1.0f); m_handle->seek(seekpos);