2007-01-07 05:44:11 +01:00
|
|
|
// Copyright (c) 2005, 2006, Rodrigo Braz Monteiro
|
|
|
|
// Copyright (c) 2006, 2007, Niels Martin Hansen
|
|
|
|
// All rights reserved.
|
|
|
|
//
|
|
|
|
// Redistribution and use in source and binary forms, with or without
|
|
|
|
// modification, are permitted provided that the following conditions are met:
|
|
|
|
//
|
|
|
|
// * Redistributions of source code must retain the above copyright notice,
|
|
|
|
// this list of conditions and the following disclaimer.
|
|
|
|
// * Redistributions in binary form must reproduce the above copyright notice,
|
|
|
|
// this list of conditions and the following disclaimer in the documentation
|
|
|
|
// and/or other materials provided with the distribution.
|
|
|
|
// * Neither the name of the Aegisub Group nor the names of its contributors
|
|
|
|
// may be used to endorse or promote products derived from this software
|
|
|
|
// without specific prior written permission.
|
|
|
|
//
|
|
|
|
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
|
|
|
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
|
|
|
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
|
|
|
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
|
|
|
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
|
|
|
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
|
|
|
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
|
|
|
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
|
|
|
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
|
|
|
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
|
|
|
// POSSIBILITY OF SUCH DAMAGE.
|
|
|
|
//
|
2009-07-29 07:43:02 +02:00
|
|
|
// Aegisub Project http://www.aegisub.org/
|
2007-01-07 05:44:11 +01:00
|
|
|
//
|
2009-07-29 07:43:02 +02:00
|
|
|
// $Id$
|
|
|
|
|
2009-08-13 19:28:12 +02:00
|
|
|
/// @file audio_renderer_spectrum.cpp
|
2009-07-29 07:43:02 +02:00
|
|
|
/// @brief Caching frequency-power spectrum renderer for audio display
|
|
|
|
/// @ingroup audio_ui
|
|
|
|
///
|
2007-01-07 05:44:11 +01:00
|
|
|
|
2009-01-04 07:31:48 +01:00
|
|
|
#include "config.h"
|
|
|
|
|
2009-09-10 15:06:40 +02:00
|
|
|
#ifndef AGI_PRE
|
2007-01-07 05:44:11 +01:00
|
|
|
#include <assert.h>
|
2008-01-15 23:18:54 +01:00
|
|
|
#ifdef _OPENMP
|
|
|
|
#include <omp.h>
|
|
|
|
#endif
|
2009-09-10 15:06:40 +02:00
|
|
|
|
|
|
|
#include <algorithm>
|
|
|
|
#include <list>
|
|
|
|
#include <utility>
|
|
|
|
#include <vector>
|
|
|
|
|
|
|
|
#include <wx/log.h>
|
|
|
|
#endif
|
|
|
|
|
2010-06-09 01:21:39 +02:00
|
|
|
#include <libaegisub/log.h>
|
|
|
|
|
2009-08-13 18:04:45 +02:00
|
|
|
#include "audio_renderer_spectrum.h"
|
2007-01-07 05:44:11 +01:00
|
|
|
#include "colorspace.h"
|
2009-09-10 15:06:40 +02:00
|
|
|
#include "fft.h"
|
2010-05-21 03:13:36 +02:00
|
|
|
#include "main.h"
|
2007-04-29 01:43:58 +02:00
|
|
|
#include "utils.h"
|
2007-01-07 05:44:11 +01:00
|
|
|
|
|
|
|
|
Note: This was done using a script! it's far from perfect but 95% of the work has been done already formatting-wise.
Document all functions, class, struct, union, enum, macro, variable, typedefs. This isn't the actual document in itself but empty documentation using any old documentation if it was there.
This was done using exuberant ctags to get tag info, then a TCL script to parse/remove old comments and convert them into Doxygen-style.
Some notes:
* Anything labeled 'DOCME' needs to be documented, @param and @return have been left blank as it would be annoying to delete the 'DOCME' from every one of those.
* Some multiline comments may have been munged into single line comments
* Leave the /// comments above global variables with a space, if they're harder to read then we'll be less likey to use them.
* Enum comments can go after the enumeration itself '[value] /// comment'
* include/aegisub/*.h haven't been converted yet, this will be done in a later commit
* Some documentation blocks are in the wrong place, in the .h when it should be in the .cpp, or vice versa.
See http://devel.aegisub.org/wiki/Doxygen for some details on Doxygen and a 'style guide'.
Originally committed to SVN as r3312.
2009-07-30 00:59:22 +02:00
|
|
|
/// @class AudioSpectrumCache
|
2009-08-01 03:55:17 +02:00
|
|
|
/// @brief Base class for the frequency-power cache tree.
|
|
|
|
///
|
|
|
|
/// The cached frequency-power are kept in a shallow tree-structure composed of
|
|
|
|
/// intermediate branches and final leaves, both accessed through a common
|
|
|
|
/// interface, which is this class.
|
Note: This was done using a script! it's far from perfect but 95% of the work has been done already formatting-wise.
Document all functions, class, struct, union, enum, macro, variable, typedefs. This isn't the actual document in itself but empty documentation using any old documentation if it was there.
This was done using exuberant ctags to get tag info, then a TCL script to parse/remove old comments and convert them into Doxygen-style.
Some notes:
* Anything labeled 'DOCME' needs to be documented, @param and @return have been left blank as it would be annoying to delete the 'DOCME' from every one of those.
* Some multiline comments may have been munged into single line comments
* Leave the /// comments above global variables with a space, if they're harder to read then we'll be less likey to use them.
* Enum comments can go after the enumeration itself '[value] /// comment'
* include/aegisub/*.h haven't been converted yet, this will be done in a later commit
* Some documentation blocks are in the wrong place, in the .h when it should be in the .cpp, or vice versa.
See http://devel.aegisub.org/wiki/Doxygen for some details on Doxygen and a 'style guide'.
Originally committed to SVN as r3312.
2009-07-30 00:59:22 +02:00
|
|
|
///
|
2009-08-01 03:55:17 +02:00
|
|
|
/// The term "cache line" here means the frequency-power data derived from
|
|
|
|
/// some range of audio samples, calculated by a single FFT.
|
2007-06-30 16:40:52 +02:00
|
|
|
class AudioSpectrumCache {
|
|
|
|
public:
|
Note: This was done using a script! it's far from perfect but 95% of the work has been done already formatting-wise.
Document all functions, class, struct, union, enum, macro, variable, typedefs. This isn't the actual document in itself but empty documentation using any old documentation if it was there.
This was done using exuberant ctags to get tag info, then a TCL script to parse/remove old comments and convert them into Doxygen-style.
Some notes:
* Anything labeled 'DOCME' needs to be documented, @param and @return have been left blank as it would be annoying to delete the 'DOCME' from every one of those.
* Some multiline comments may have been munged into single line comments
* Leave the /// comments above global variables with a space, if they're harder to read then we'll be less likey to use them.
* Enum comments can go after the enumeration itself '[value] /// comment'
* include/aegisub/*.h haven't been converted yet, this will be done in a later commit
* Some documentation blocks are in the wrong place, in the .h when it should be in the .cpp, or vice versa.
See http://devel.aegisub.org/wiki/Doxygen for some details on Doxygen and a 'style guide'.
Originally committed to SVN as r3312.
2009-07-30 00:59:22 +02:00
|
|
|
|
2009-08-01 03:55:17 +02:00
|
|
|
/// The type of frequency-power data at one point in time.
|
2007-06-30 16:40:52 +02:00
|
|
|
typedef std::vector<float> CacheLine;
|
|
|
|
|
Note: This was done using a script! it's far from perfect but 95% of the work has been done already formatting-wise.
Document all functions, class, struct, union, enum, macro, variable, typedefs. This isn't the actual document in itself but empty documentation using any old documentation if it was there.
This was done using exuberant ctags to get tag info, then a TCL script to parse/remove old comments and convert them into Doxygen-style.
Some notes:
* Anything labeled 'DOCME' needs to be documented, @param and @return have been left blank as it would be annoying to delete the 'DOCME' from every one of those.
* Some multiline comments may have been munged into single line comments
* Leave the /// comments above global variables with a space, if they're harder to read then we'll be less likey to use them.
* Enum comments can go after the enumeration itself '[value] /// comment'
* include/aegisub/*.h haven't been converted yet, this will be done in a later commit
* Some documentation blocks are in the wrong place, in the .h when it should be in the .cpp, or vice versa.
See http://devel.aegisub.org/wiki/Doxygen for some details on Doxygen and a 'style guide'.
Originally committed to SVN as r3312.
2009-07-30 00:59:22 +02:00
|
|
|
|
2009-08-01 03:55:17 +02:00
|
|
|
/// The type of timestamps for last access.
|
2007-06-30 16:40:52 +02:00
|
|
|
typedef unsigned int CacheAccessTime;
|
Note: This was done using a script! it's far from perfect but 95% of the work has been done already formatting-wise.
Document all functions, class, struct, union, enum, macro, variable, typedefs. This isn't the actual document in itself but empty documentation using any old documentation if it was there.
This was done using exuberant ctags to get tag info, then a TCL script to parse/remove old comments and convert them into Doxygen-style.
Some notes:
* Anything labeled 'DOCME' needs to be documented, @param and @return have been left blank as it would be annoying to delete the 'DOCME' from every one of those.
* Some multiline comments may have been munged into single line comments
* Leave the /// comments above global variables with a space, if they're harder to read then we'll be less likey to use them.
* Enum comments can go after the enumeration itself '[value] /// comment'
* include/aegisub/*.h haven't been converted yet, this will be done in a later commit
* Some documentation blocks are in the wrong place, in the .h when it should be in the .cpp, or vice versa.
See http://devel.aegisub.org/wiki/Doxygen for some details on Doxygen and a 'style guide'.
Originally committed to SVN as r3312.
2009-07-30 00:59:22 +02:00
|
|
|
|
2009-08-01 03:55:17 +02:00
|
|
|
/// Holds last-access data for a range of range of cache lines.
|
|
|
|
/// Ranges can overlap, in case overlapping FFT's are used to increase precision.
|
2007-06-30 16:40:52 +02:00
|
|
|
struct CacheAgeData {
|
2009-08-01 03:55:17 +02:00
|
|
|
/// Last time this range of cache lines were accessed.
|
2007-06-30 16:40:52 +02:00
|
|
|
CacheAccessTime access_time;
|
2009-08-01 03:55:17 +02:00
|
|
|
/// First line in the range.
|
2007-06-30 16:40:52 +02:00
|
|
|
unsigned long first_line;
|
2009-08-01 03:55:17 +02:00
|
|
|
/// Number of lines in the range.
|
|
|
|
unsigned long num_lines;
|
Note: This was done using a script! it's far from perfect but 95% of the work has been done already formatting-wise.
Document all functions, class, struct, union, enum, macro, variable, typedefs. This isn't the actual document in itself but empty documentation using any old documentation if it was there.
This was done using exuberant ctags to get tag info, then a TCL script to parse/remove old comments and convert them into Doxygen-style.
Some notes:
* Anything labeled 'DOCME' needs to be documented, @param and @return have been left blank as it would be annoying to delete the 'DOCME' from every one of those.
* Some multiline comments may have been munged into single line comments
* Leave the /// comments above global variables with a space, if they're harder to read then we'll be less likey to use them.
* Enum comments can go after the enumeration itself '[value] /// comment'
* include/aegisub/*.h haven't been converted yet, this will be done in a later commit
* Some documentation blocks are in the wrong place, in the .h when it should be in the .cpp, or vice versa.
See http://devel.aegisub.org/wiki/Doxygen for some details on Doxygen and a 'style guide'.
Originally committed to SVN as r3312.
2009-07-30 00:59:22 +02:00
|
|
|
|
2009-08-01 03:55:17 +02:00
|
|
|
/// @brief Comparison operator for sorting age data by last access time.
|
|
|
|
/// @param second The age data structure to compare against.
|
|
|
|
/// @return Returns true if last access time of this range is less than that of the other.
|
2007-09-12 01:22:26 +02:00
|
|
|
bool operator< (const CacheAgeData& second) const { return access_time < second.access_time; }
|
Note: This was done using a script! it's far from perfect but 95% of the work has been done already formatting-wise.
Document all functions, class, struct, union, enum, macro, variable, typedefs. This isn't the actual document in itself but empty documentation using any old documentation if it was there.
This was done using exuberant ctags to get tag info, then a TCL script to parse/remove old comments and convert them into Doxygen-style.
Some notes:
* Anything labeled 'DOCME' needs to be documented, @param and @return have been left blank as it would be annoying to delete the 'DOCME' from every one of those.
* Some multiline comments may have been munged into single line comments
* Leave the /// comments above global variables with a space, if they're harder to read then we'll be less likey to use them.
* Enum comments can go after the enumeration itself '[value] /// comment'
* include/aegisub/*.h haven't been converted yet, this will be done in a later commit
* Some documentation blocks are in the wrong place, in the .h when it should be in the .cpp, or vice versa.
See http://devel.aegisub.org/wiki/Doxygen for some details on Doxygen and a 'style guide'.
Originally committed to SVN as r3312.
2009-07-30 00:59:22 +02:00
|
|
|
|
2009-08-01 03:55:17 +02:00
|
|
|
/// @brief Constructor.
|
|
|
|
/// @param t Initial access time to set.
|
|
|
|
/// @param first First line in the range.
|
|
|
|
/// @param num Number of lines in the range.
|
Note: This was done using a script! it's far from perfect but 95% of the work has been done already formatting-wise.
Document all functions, class, struct, union, enum, macro, variable, typedefs. This isn't the actual document in itself but empty documentation using any old documentation if it was there.
This was done using exuberant ctags to get tag info, then a TCL script to parse/remove old comments and convert them into Doxygen-style.
Some notes:
* Anything labeled 'DOCME' needs to be documented, @param and @return have been left blank as it would be annoying to delete the 'DOCME' from every one of those.
* Some multiline comments may have been munged into single line comments
* Leave the /// comments above global variables with a space, if they're harder to read then we'll be less likey to use them.
* Enum comments can go after the enumeration itself '[value] /// comment'
* include/aegisub/*.h haven't been converted yet, this will be done in a later commit
* Some documentation blocks are in the wrong place, in the .h when it should be in the .cpp, or vice versa.
See http://devel.aegisub.org/wiki/Doxygen for some details on Doxygen and a 'style guide'.
Originally committed to SVN as r3312.
2009-07-30 00:59:22 +02:00
|
|
|
///
|
2007-06-30 16:40:52 +02:00
|
|
|
CacheAgeData(CacheAccessTime t, unsigned long first, unsigned long num) : access_time(t), first_line(first), num_lines(num) { }
|
|
|
|
};
|
Note: This was done using a script! it's far from perfect but 95% of the work has been done already formatting-wise.
Document all functions, class, struct, union, enum, macro, variable, typedefs. This isn't the actual document in itself but empty documentation using any old documentation if it was there.
This was done using exuberant ctags to get tag info, then a TCL script to parse/remove old comments and convert them into Doxygen-style.
Some notes:
* Anything labeled 'DOCME' needs to be documented, @param and @return have been left blank as it would be annoying to delete the 'DOCME' from every one of those.
* Some multiline comments may have been munged into single line comments
* Leave the /// comments above global variables with a space, if they're harder to read then we'll be less likey to use them.
* Enum comments can go after the enumeration itself '[value] /// comment'
* include/aegisub/*.h haven't been converted yet, this will be done in a later commit
* Some documentation blocks are in the wrong place, in the .h when it should be in the .cpp, or vice versa.
See http://devel.aegisub.org/wiki/Doxygen for some details on Doxygen and a 'style guide'.
Originally committed to SVN as r3312.
2009-07-30 00:59:22 +02:00
|
|
|
|
2009-08-01 03:55:17 +02:00
|
|
|
/// Type of a list of cache age data.
|
2007-06-30 16:40:52 +02:00
|
|
|
typedef std::vector<CacheAgeData> CacheAgeList;
|
|
|
|
|
2009-08-01 03:55:17 +02:00
|
|
|
/// @brief Retrieve frequency-power data.
|
|
|
|
/// @param i Index of the block to get the line from.
|
|
|
|
/// @param overlap Index of the overlap in the block to get the line for.
|
|
|
|
/// @param created [out] Set to true if the data had to be calculated, false if the data
|
|
|
|
/// was found in cache.
|
|
|
|
/// @param access_time Timestamp to mark the cache data as accessed at.
|
|
|
|
/// @return Returns a reference to the frequency-power data requested.
|
|
|
|
///
|
|
|
|
/// The data are fetched from the cache if they are cached, otherwise the required
|
|
|
|
/// audio data are retrieved, the FFT derived, and power data calculated.
|
2007-06-30 16:40:52 +02:00
|
|
|
virtual CacheLine& GetLine(unsigned long i, unsigned int overlap, bool &created, CacheAccessTime access_time) = 0;
|
|
|
|
|
2009-08-01 03:55:17 +02:00
|
|
|
/// @brief Get the size of the cache subtree.
|
|
|
|
/// @return Number of lines stored in all nodes below this one in the tree.
|
2007-06-30 16:40:52 +02:00
|
|
|
virtual size_t GetManagedLineCount() = 0;
|
|
|
|
|
2009-08-01 03:55:17 +02:00
|
|
|
/// @brief Retrieve cache access times.
|
|
|
|
/// @param ages [in,out] List to append age data of managed lines to.
|
|
|
|
///
|
|
|
|
/// Existing contents of the list is kept, new entries are added to the end.
|
2007-06-30 16:40:52 +02:00
|
|
|
virtual void GetLineAccessTimes(CacheAgeList &ages) = 0;
|
|
|
|
|
2009-08-01 03:55:17 +02:00
|
|
|
/// @brief Remove data from the cache.
|
|
|
|
/// @param line_id Index of the block the cache node to remove starts at.
|
|
|
|
/// @return Returns true if the object the method was called on no longer manages
|
|
|
|
// any cache lines and can safely be deleted.
|
2007-06-30 16:40:52 +02:00
|
|
|
virtual bool KillLine(unsigned long line_id) = 0;
|
|
|
|
|
Note: This was done using a script! it's far from perfect but 95% of the work has been done already formatting-wise.
Document all functions, class, struct, union, enum, macro, variable, typedefs. This isn't the actual document in itself but empty documentation using any old documentation if it was there.
This was done using exuberant ctags to get tag info, then a TCL script to parse/remove old comments and convert them into Doxygen-style.
Some notes:
* Anything labeled 'DOCME' needs to be documented, @param and @return have been left blank as it would be annoying to delete the 'DOCME' from every one of those.
* Some multiline comments may have been munged into single line comments
* Leave the /// comments above global variables with a space, if they're harder to read then we'll be less likey to use them.
* Enum comments can go after the enumeration itself '[value] /// comment'
* include/aegisub/*.h haven't been converted yet, this will be done in a later commit
* Some documentation blocks are in the wrong place, in the .h when it should be in the .cpp, or vice versa.
See http://devel.aegisub.org/wiki/Doxygen for some details on Doxygen and a 'style guide'.
Originally committed to SVN as r3312.
2009-07-30 00:59:22 +02:00
|
|
|
|
2009-08-01 03:55:17 +02:00
|
|
|
/// @brief Set the FFT size used globally.
|
|
|
|
/// @param new_length Number of audio samples to use in calculation.
|
2007-06-30 16:40:52 +02:00
|
|
|
static void SetLineLength(unsigned long new_length)
|
|
|
|
{
|
|
|
|
line_length = new_length;
|
|
|
|
null_line.resize(new_length, 0);
|
|
|
|
}
|
|
|
|
|
Note: This was done using a script! it's far from perfect but 95% of the work has been done already formatting-wise.
Document all functions, class, struct, union, enum, macro, variable, typedefs. This isn't the actual document in itself but empty documentation using any old documentation if it was there.
This was done using exuberant ctags to get tag info, then a TCL script to parse/remove old comments and convert them into Doxygen-style.
Some notes:
* Anything labeled 'DOCME' needs to be documented, @param and @return have been left blank as it would be annoying to delete the 'DOCME' from every one of those.
* Some multiline comments may have been munged into single line comments
* Leave the /// comments above global variables with a space, if they're harder to read then we'll be less likey to use them.
* Enum comments can go after the enumeration itself '[value] /// comment'
* include/aegisub/*.h haven't been converted yet, this will be done in a later commit
* Some documentation blocks are in the wrong place, in the .h when it should be in the .cpp, or vice versa.
See http://devel.aegisub.org/wiki/Doxygen for some details on Doxygen and a 'style guide'.
Originally committed to SVN as r3312.
2009-07-30 00:59:22 +02:00
|
|
|
|
2009-08-01 03:55:17 +02:00
|
|
|
/// @brief Destructor, does nothing in base class.
|
2007-06-30 16:40:52 +02:00
|
|
|
virtual ~AudioSpectrumCache() {};
|
|
|
|
|
|
|
|
protected:
|
Note: This was done using a script! it's far from perfect but 95% of the work has been done already formatting-wise.
Document all functions, class, struct, union, enum, macro, variable, typedefs. This isn't the actual document in itself but empty documentation using any old documentation if it was there.
This was done using exuberant ctags to get tag info, then a TCL script to parse/remove old comments and convert them into Doxygen-style.
Some notes:
* Anything labeled 'DOCME' needs to be documented, @param and @return have been left blank as it would be annoying to delete the 'DOCME' from every one of those.
* Some multiline comments may have been munged into single line comments
* Leave the /// comments above global variables with a space, if they're harder to read then we'll be less likey to use them.
* Enum comments can go after the enumeration itself '[value] /// comment'
* include/aegisub/*.h haven't been converted yet, this will be done in a later commit
* Some documentation blocks are in the wrong place, in the .h when it should be in the .cpp, or vice versa.
See http://devel.aegisub.org/wiki/Doxygen for some details on Doxygen and a 'style guide'.
Originally committed to SVN as r3312.
2009-07-30 00:59:22 +02:00
|
|
|
|
2009-08-01 03:55:17 +02:00
|
|
|
/// Global template for cache lines.
|
2007-06-30 16:40:52 +02:00
|
|
|
static CacheLine null_line;
|
2009-08-01 03:55:17 +02:00
|
|
|
/// Number of audio samples used for power calculation, determining the
|
|
|
|
/// frequency resolution of the frequency-power data.
|
2007-06-30 16:40:52 +02:00
|
|
|
static unsigned long line_length;
|
|
|
|
};
|
|
|
|
|
2009-08-01 03:55:17 +02:00
|
|
|
// Actual variables allocating memory for the static class members
|
2007-01-07 05:44:11 +01:00
|
|
|
AudioSpectrumCache::CacheLine AudioSpectrumCache::null_line;
|
|
|
|
unsigned long AudioSpectrumCache::line_length;
|
|
|
|
|
|
|
|
|
|
|
|
|
Note: This was done using a script! it's far from perfect but 95% of the work has been done already formatting-wise.
Document all functions, class, struct, union, enum, macro, variable, typedefs. This isn't the actual document in itself but empty documentation using any old documentation if it was there.
This was done using exuberant ctags to get tag info, then a TCL script to parse/remove old comments and convert them into Doxygen-style.
Some notes:
* Anything labeled 'DOCME' needs to be documented, @param and @return have been left blank as it would be annoying to delete the 'DOCME' from every one of those.
* Some multiline comments may have been munged into single line comments
* Leave the /// comments above global variables with a space, if they're harder to read then we'll be less likey to use them.
* Enum comments can go after the enumeration itself '[value] /// comment'
* include/aegisub/*.h haven't been converted yet, this will be done in a later commit
* Some documentation blocks are in the wrong place, in the .h when it should be in the .cpp, or vice versa.
See http://devel.aegisub.org/wiki/Doxygen for some details on Doxygen and a 'style guide'.
Originally committed to SVN as r3312.
2009-07-30 00:59:22 +02:00
|
|
|
/// @class FinalSpectrumCache
|
2009-08-01 03:55:17 +02:00
|
|
|
/// @brief Leaf node in frequency-power cache tree, holds actual data.
|
Note: This was done using a script! it's far from perfect but 95% of the work has been done already formatting-wise.
Document all functions, class, struct, union, enum, macro, variable, typedefs. This isn't the actual document in itself but empty documentation using any old documentation if it was there.
This was done using exuberant ctags to get tag info, then a TCL script to parse/remove old comments and convert them into Doxygen-style.
Some notes:
* Anything labeled 'DOCME' needs to be documented, @param and @return have been left blank as it would be annoying to delete the 'DOCME' from every one of those.
* Some multiline comments may have been munged into single line comments
* Leave the /// comments above global variables with a space, if they're harder to read then we'll be less likey to use them.
* Enum comments can go after the enumeration itself '[value] /// comment'
* include/aegisub/*.h haven't been converted yet, this will be done in a later commit
* Some documentation blocks are in the wrong place, in the .h when it should be in the .cpp, or vice versa.
See http://devel.aegisub.org/wiki/Doxygen for some details on Doxygen and a 'style guide'.
Originally committed to SVN as r3312.
2009-07-30 00:59:22 +02:00
|
|
|
///
|
2009-08-01 03:55:17 +02:00
|
|
|
/// This class stores frequency-power data and is responsible for calculating it as well.
|
2007-01-07 05:44:11 +01:00
|
|
|
class FinalSpectrumCache : public AudioSpectrumCache {
|
|
|
|
private:
|
Note: This was done using a script! it's far from perfect but 95% of the work has been done already formatting-wise.
Document all functions, class, struct, union, enum, macro, variable, typedefs. This isn't the actual document in itself but empty documentation using any old documentation if it was there.
This was done using exuberant ctags to get tag info, then a TCL script to parse/remove old comments and convert them into Doxygen-style.
Some notes:
* Anything labeled 'DOCME' needs to be documented, @param and @return have been left blank as it would be annoying to delete the 'DOCME' from every one of those.
* Some multiline comments may have been munged into single line comments
* Leave the /// comments above global variables with a space, if they're harder to read then we'll be less likey to use them.
* Enum comments can go after the enumeration itself '[value] /// comment'
* include/aegisub/*.h haven't been converted yet, this will be done in a later commit
* Some documentation blocks are in the wrong place, in the .h when it should be in the .cpp, or vice versa.
See http://devel.aegisub.org/wiki/Doxygen for some details on Doxygen and a 'style guide'.
Originally committed to SVN as r3312.
2009-07-30 00:59:22 +02:00
|
|
|
|
2009-08-01 03:55:17 +02:00
|
|
|
/// The stored data.
|
2007-01-07 05:44:11 +01:00
|
|
|
std::vector<CacheLine> data;
|
Note: This was done using a script! it's far from perfect but 95% of the work has been done already formatting-wise.
Document all functions, class, struct, union, enum, macro, variable, typedefs. This isn't the actual document in itself but empty documentation using any old documentation if it was there.
This was done using exuberant ctags to get tag info, then a TCL script to parse/remove old comments and convert them into Doxygen-style.
Some notes:
* Anything labeled 'DOCME' needs to be documented, @param and @return have been left blank as it would be annoying to delete the 'DOCME' from every one of those.
* Some multiline comments may have been munged into single line comments
* Leave the /// comments above global variables with a space, if they're harder to read then we'll be less likey to use them.
* Enum comments can go after the enumeration itself '[value] /// comment'
* include/aegisub/*.h haven't been converted yet, this will be done in a later commit
* Some documentation blocks are in the wrong place, in the .h when it should be in the .cpp, or vice versa.
See http://devel.aegisub.org/wiki/Doxygen for some details on Doxygen and a 'style guide'.
Originally committed to SVN as r3312.
2009-07-30 00:59:22 +02:00
|
|
|
|
2009-08-01 03:55:17 +02:00
|
|
|
unsigned long start, ///< Start of block range
|
|
|
|
length; ///< Number of blocks
|
|
|
|
unsigned int overlaps; ///< How many lines per block
|
2007-01-07 05:44:11 +01:00
|
|
|
|
2009-08-01 03:55:17 +02:00
|
|
|
/// Last access time for cache management.
|
2007-06-30 16:40:52 +02:00
|
|
|
CacheAccessTime last_access;
|
|
|
|
|
2007-01-07 05:44:11 +01:00
|
|
|
public:
|
Note: This was done using a script! it's far from perfect but 95% of the work has been done already formatting-wise.
Document all functions, class, struct, union, enum, macro, variable, typedefs. This isn't the actual document in itself but empty documentation using any old documentation if it was there.
This was done using exuberant ctags to get tag info, then a TCL script to parse/remove old comments and convert them into Doxygen-style.
Some notes:
* Anything labeled 'DOCME' needs to be documented, @param and @return have been left blank as it would be annoying to delete the 'DOCME' from every one of those.
* Some multiline comments may have been munged into single line comments
* Leave the /// comments above global variables with a space, if they're harder to read then we'll be less likey to use them.
* Enum comments can go after the enumeration itself '[value] /// comment'
* include/aegisub/*.h haven't been converted yet, this will be done in a later commit
* Some documentation blocks are in the wrong place, in the .h when it should be in the .cpp, or vice versa.
See http://devel.aegisub.org/wiki/Doxygen for some details on Doxygen and a 'style guide'.
Originally committed to SVN as r3312.
2009-07-30 00:59:22 +02:00
|
|
|
|
2009-08-01 03:55:17 +02:00
|
|
|
/// @brief Returns stored frequency-power data.
|
|
|
|
/// @param i Index of the block to get the line from.
|
|
|
|
/// @param overlap Index of the overlap in the block to get the line for.
|
|
|
|
/// @param created [out] Set to true if the data had to be calculated, false if the data
|
|
|
|
/// was found in cache.
|
|
|
|
/// @param access_time Timestamp to mark the cache data as accessed at.
|
|
|
|
/// @return Returns a reference to the frequency-power data requested.
|
2007-06-30 16:40:52 +02:00
|
|
|
CacheLine& GetLine(unsigned long i, unsigned int overlap, bool &created, CacheAccessTime access_time)
|
2007-01-07 05:44:11 +01:00
|
|
|
{
|
2007-06-30 16:40:52 +02:00
|
|
|
last_access = access_time;
|
|
|
|
|
2007-01-07 05:44:11 +01:00
|
|
|
// This check ought to be redundant
|
|
|
|
if (i >= start && i-start < length)
|
2007-06-24 21:53:41 +02:00
|
|
|
return data[i - start + overlap*length];
|
2007-01-07 05:44:11 +01:00
|
|
|
else
|
|
|
|
return null_line;
|
|
|
|
}
|
|
|
|
|
Note: This was done using a script! it's far from perfect but 95% of the work has been done already formatting-wise.
Document all functions, class, struct, union, enum, macro, variable, typedefs. This isn't the actual document in itself but empty documentation using any old documentation if it was there.
This was done using exuberant ctags to get tag info, then a TCL script to parse/remove old comments and convert them into Doxygen-style.
Some notes:
* Anything labeled 'DOCME' needs to be documented, @param and @return have been left blank as it would be annoying to delete the 'DOCME' from every one of those.
* Some multiline comments may have been munged into single line comments
* Leave the /// comments above global variables with a space, if they're harder to read then we'll be less likey to use them.
* Enum comments can go after the enumeration itself '[value] /// comment'
* include/aegisub/*.h haven't been converted yet, this will be done in a later commit
* Some documentation blocks are in the wrong place, in the .h when it should be in the .cpp, or vice versa.
See http://devel.aegisub.org/wiki/Doxygen for some details on Doxygen and a 'style guide'.
Originally committed to SVN as r3312.
2009-07-30 00:59:22 +02:00
|
|
|
|
2009-08-01 03:55:17 +02:00
|
|
|
/// @brief Get number of lines in cache.
|
|
|
|
/// @return Number of lines stored at this leaf.
|
2007-06-30 16:40:52 +02:00
|
|
|
size_t GetManagedLineCount()
|
|
|
|
{
|
|
|
|
return data.size();
|
|
|
|
}
|
|
|
|
|
Note: This was done using a script! it's far from perfect but 95% of the work has been done already formatting-wise.
Document all functions, class, struct, union, enum, macro, variable, typedefs. This isn't the actual document in itself but empty documentation using any old documentation if it was there.
This was done using exuberant ctags to get tag info, then a TCL script to parse/remove old comments and convert them into Doxygen-style.
Some notes:
* Anything labeled 'DOCME' needs to be documented, @param and @return have been left blank as it would be annoying to delete the 'DOCME' from every one of those.
* Some multiline comments may have been munged into single line comments
* Leave the /// comments above global variables with a space, if they're harder to read then we'll be less likey to use them.
* Enum comments can go after the enumeration itself '[value] /// comment'
* include/aegisub/*.h haven't been converted yet, this will be done in a later commit
* Some documentation blocks are in the wrong place, in the .h when it should be in the .cpp, or vice versa.
See http://devel.aegisub.org/wiki/Doxygen for some details on Doxygen and a 'style guide'.
Originally committed to SVN as r3312.
2009-07-30 00:59:22 +02:00
|
|
|
|
2009-08-01 03:55:17 +02:00
|
|
|
/// @brief Add own cache age data to list of age data.
|
|
|
|
/// @param ages [in,out] List to add cache age data to.
|
Note: This was done using a script! it's far from perfect but 95% of the work has been done already formatting-wise.
Document all functions, class, struct, union, enum, macro, variable, typedefs. This isn't the actual document in itself but empty documentation using any old documentation if it was there.
This was done using exuberant ctags to get tag info, then a TCL script to parse/remove old comments and convert them into Doxygen-style.
Some notes:
* Anything labeled 'DOCME' needs to be documented, @param and @return have been left blank as it would be annoying to delete the 'DOCME' from every one of those.
* Some multiline comments may have been munged into single line comments
* Leave the /// comments above global variables with a space, if they're harder to read then we'll be less likey to use them.
* Enum comments can go after the enumeration itself '[value] /// comment'
* include/aegisub/*.h haven't been converted yet, this will be done in a later commit
* Some documentation blocks are in the wrong place, in the .h when it should be in the .cpp, or vice versa.
See http://devel.aegisub.org/wiki/Doxygen for some details on Doxygen and a 'style guide'.
Originally committed to SVN as r3312.
2009-07-30 00:59:22 +02:00
|
|
|
///
|
2009-08-01 03:55:17 +02:00
|
|
|
/// Produces a single cache age data object, representing the entire node,
|
|
|
|
/// and adds it to the list.
|
2007-06-30 16:40:52 +02:00
|
|
|
void GetLineAccessTimes(CacheAgeList &ages)
|
|
|
|
{
|
|
|
|
ages.push_back(CacheAgeData(last_access, start, data.size()));
|
|
|
|
}
|
|
|
|
|
Note: This was done using a script! it's far from perfect but 95% of the work has been done already formatting-wise.
Document all functions, class, struct, union, enum, macro, variable, typedefs. This isn't the actual document in itself but empty documentation using any old documentation if it was there.
This was done using exuberant ctags to get tag info, then a TCL script to parse/remove old comments and convert them into Doxygen-style.
Some notes:
* Anything labeled 'DOCME' needs to be documented, @param and @return have been left blank as it would be annoying to delete the 'DOCME' from every one of those.
* Some multiline comments may have been munged into single line comments
* Leave the /// comments above global variables with a space, if they're harder to read then we'll be less likey to use them.
* Enum comments can go after the enumeration itself '[value] /// comment'
* include/aegisub/*.h haven't been converted yet, this will be done in a later commit
* Some documentation blocks are in the wrong place, in the .h when it should be in the .cpp, or vice versa.
See http://devel.aegisub.org/wiki/Doxygen for some details on Doxygen and a 'style guide'.
Originally committed to SVN as r3312.
2009-07-30 00:59:22 +02:00
|
|
|
|
2009-08-01 03:55:17 +02:00
|
|
|
/// @brief Return true if this is the line to remove.
|
|
|
|
/// @param line_id Index of the block the cache node to remove starts at.
|
|
|
|
/// @return Returns true if this is the cache block to remove.
|
Note: This was done using a script! it's far from perfect but 95% of the work has been done already formatting-wise.
Document all functions, class, struct, union, enum, macro, variable, typedefs. This isn't the actual document in itself but empty documentation using any old documentation if it was there.
This was done using exuberant ctags to get tag info, then a TCL script to parse/remove old comments and convert them into Doxygen-style.
Some notes:
* Anything labeled 'DOCME' needs to be documented, @param and @return have been left blank as it would be annoying to delete the 'DOCME' from every one of those.
* Some multiline comments may have been munged into single line comments
* Leave the /// comments above global variables with a space, if they're harder to read then we'll be less likey to use them.
* Enum comments can go after the enumeration itself '[value] /// comment'
* include/aegisub/*.h haven't been converted yet, this will be done in a later commit
* Some documentation blocks are in the wrong place, in the .h when it should be in the .cpp, or vice versa.
See http://devel.aegisub.org/wiki/Doxygen for some details on Doxygen and a 'style guide'.
Originally committed to SVN as r3312.
2009-07-30 00:59:22 +02:00
|
|
|
///
|
2009-08-01 03:55:17 +02:00
|
|
|
/// This function won't actually delete anything, instead it is the responsibility
|
|
|
|
/// of the caller to delete the cache node if this function returns true.
|
2007-06-30 16:40:52 +02:00
|
|
|
bool KillLine(unsigned long line_id)
|
|
|
|
{
|
|
|
|
return start == line_id;
|
|
|
|
}
|
|
|
|
|
Note: This was done using a script! it's far from perfect but 95% of the work has been done already formatting-wise.
Document all functions, class, struct, union, enum, macro, variable, typedefs. This isn't the actual document in itself but empty documentation using any old documentation if it was there.
This was done using exuberant ctags to get tag info, then a TCL script to parse/remove old comments and convert them into Doxygen-style.
Some notes:
* Anything labeled 'DOCME' needs to be documented, @param and @return have been left blank as it would be annoying to delete the 'DOCME' from every one of those.
* Some multiline comments may have been munged into single line comments
* Leave the /// comments above global variables with a space, if they're harder to read then we'll be less likey to use them.
* Enum comments can go after the enumeration itself '[value] /// comment'
* include/aegisub/*.h haven't been converted yet, this will be done in a later commit
* Some documentation blocks are in the wrong place, in the .h when it should be in the .cpp, or vice versa.
See http://devel.aegisub.org/wiki/Doxygen for some details on Doxygen and a 'style guide'.
Originally committed to SVN as r3312.
2009-07-30 00:59:22 +02:00
|
|
|
|
2009-08-01 03:55:17 +02:00
|
|
|
/// @brief Constructor, derives FFT and calculates frequency-power data.
|
|
|
|
/// @param provider Audio provider to get audio from.
|
|
|
|
/// @param _start Index of first block to calculate data for.
|
|
|
|
/// @param _length Number of blocks to calculate data for.
|
|
|
|
/// @param _overlaps Number of lines to calculate per block.
|
2007-06-24 21:53:41 +02:00
|
|
|
FinalSpectrumCache(AudioProvider *provider, unsigned long _start, unsigned long _length, unsigned int _overlaps)
|
2007-01-07 05:44:11 +01:00
|
|
|
{
|
|
|
|
start = _start;
|
|
|
|
length = _length;
|
2007-06-24 21:53:41 +02:00
|
|
|
overlaps = _overlaps;
|
|
|
|
|
|
|
|
if (overlaps < 1) overlaps = 1;
|
|
|
|
// Add an upper limit to number of overlaps or trust user to do sane things?
|
|
|
|
// Any limit should probably be a function of length
|
2007-01-07 05:44:11 +01:00
|
|
|
|
|
|
|
assert(length > 2);
|
|
|
|
|
|
|
|
// First fill the data vector with blanks
|
|
|
|
// Both start and end are included in the range stored, so we have end-start+1 elements
|
2007-06-24 21:53:41 +02:00
|
|
|
data.resize(length*overlaps, null_line);
|
2007-01-07 05:44:11 +01:00
|
|
|
|
2007-06-24 22:09:18 +02:00
|
|
|
unsigned int overlap_offset = line_length / overlaps * 2; // FIXME: the result seems weird/wrong without this factor 2, but why?
|
2007-01-07 05:44:11 +01:00
|
|
|
|
2007-06-24 21:53:41 +02:00
|
|
|
FFT fft; // Use FFTW instead? A wavelet?
|
2007-01-07 05:44:11 +01:00
|
|
|
|
2007-06-24 21:53:41 +02:00
|
|
|
for (unsigned int overlap = 0; overlap < overlaps; ++overlap) {
|
|
|
|
// Start sample number of the next line calculated
|
|
|
|
// line_length is half of the number of samples used to calculate a line, since half of the output from
|
|
|
|
// a Fourier transform of real data is redundant, and not interesting for the purpose of creating
|
|
|
|
// a frequenmcy/power spectrum.
|
2007-08-31 16:11:35 +02:00
|
|
|
int64_t sample = start * line_length*2 + overlap*overlap_offset;
|
2007-01-07 05:44:11 +01:00
|
|
|
|
2008-01-15 23:18:54 +01:00
|
|
|
long len = length;
|
|
|
|
#ifdef _OPENMP
|
2008-03-21 04:02:39 +01:00
|
|
|
#pragma omp parallel shared(overlap,len)
|
2008-01-15 23:18:54 +01:00
|
|
|
#endif
|
|
|
|
{
|
|
|
|
short *raw_sample_data = new short[line_length*2];
|
|
|
|
float *sample_data = new float[line_length*2];
|
|
|
|
float *out_r = new float[line_length*2];
|
|
|
|
float *out_i = new float[line_length*2];
|
|
|
|
|
|
|
|
#ifdef _OPENMP
|
|
|
|
#pragma omp for
|
|
|
|
#endif
|
|
|
|
for (long i = 0; i < len; ++i) {
|
|
|
|
// Initialize
|
|
|
|
sample = start * line_length*2 + overlap*overlap_offset + i*line_length*2;
|
|
|
|
|
|
|
|
provider->GetAudio(raw_sample_data, sample, line_length*2);
|
|
|
|
for (size_t j = 0; j < line_length; ++j) {
|
|
|
|
sample_data[j*2] = (float)raw_sample_data[j*2];
|
|
|
|
sample_data[j*2+1] = (float)raw_sample_data[j*2+1];
|
|
|
|
}
|
|
|
|
|
|
|
|
fft.Transform(line_length*2, sample_data, out_r, out_i);
|
|
|
|
|
|
|
|
CacheLine &line = data[i + length*overlap];
|
|
|
|
for (size_t j = 0; j < line_length; ++j) {
|
|
|
|
line[j] = sqrt(out_r[j]*out_r[j] + out_i[j]*out_i[j]);
|
|
|
|
}
|
|
|
|
|
|
|
|
//sample += line_length*2;
|
2007-06-24 21:53:41 +02:00
|
|
|
}
|
2007-01-07 05:44:11 +01:00
|
|
|
|
2008-01-15 23:18:54 +01:00
|
|
|
delete[] raw_sample_data;
|
|
|
|
delete[] sample_data;
|
|
|
|
delete[] out_r;
|
|
|
|
delete[] out_i;
|
2007-06-24 21:53:41 +02:00
|
|
|
}
|
2007-01-07 05:44:11 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
Note: This was done using a script! it's far from perfect but 95% of the work has been done already formatting-wise.
Document all functions, class, struct, union, enum, macro, variable, typedefs. This isn't the actual document in itself but empty documentation using any old documentation if it was there.
This was done using exuberant ctags to get tag info, then a TCL script to parse/remove old comments and convert them into Doxygen-style.
Some notes:
* Anything labeled 'DOCME' needs to be documented, @param and @return have been left blank as it would be annoying to delete the 'DOCME' from every one of those.
* Some multiline comments may have been munged into single line comments
* Leave the /// comments above global variables with a space, if they're harder to read then we'll be less likey to use them.
* Enum comments can go after the enumeration itself '[value] /// comment'
* include/aegisub/*.h haven't been converted yet, this will be done in a later commit
* Some documentation blocks are in the wrong place, in the .h when it should be in the .cpp, or vice versa.
See http://devel.aegisub.org/wiki/Doxygen for some details on Doxygen and a 'style guide'.
Originally committed to SVN as r3312.
2009-07-30 00:59:22 +02:00
|
|
|
|
2009-08-01 03:55:17 +02:00
|
|
|
/// @brief Destructor, does nothing.
|
Note: This was done using a script! it's far from perfect but 95% of the work has been done already formatting-wise.
Document all functions, class, struct, union, enum, macro, variable, typedefs. This isn't the actual document in itself but empty documentation using any old documentation if it was there.
This was done using exuberant ctags to get tag info, then a TCL script to parse/remove old comments and convert them into Doxygen-style.
Some notes:
* Anything labeled 'DOCME' needs to be documented, @param and @return have been left blank as it would be annoying to delete the 'DOCME' from every one of those.
* Some multiline comments may have been munged into single line comments
* Leave the /// comments above global variables with a space, if they're harder to read then we'll be less likey to use them.
* Enum comments can go after the enumeration itself '[value] /// comment'
* include/aegisub/*.h haven't been converted yet, this will be done in a later commit
* Some documentation blocks are in the wrong place, in the .h when it should be in the .cpp, or vice versa.
See http://devel.aegisub.org/wiki/Doxygen for some details on Doxygen and a 'style guide'.
Originally committed to SVN as r3312.
2009-07-30 00:59:22 +02:00
|
|
|
///
|
2009-08-01 03:55:17 +02:00
|
|
|
/// All data is managed by C++ types and gets deleted when those types'
|
|
|
|
/// destructors are implicitly run.
|
2007-01-07 05:44:11 +01:00
|
|
|
virtual ~FinalSpectrumCache()
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
Note: This was done using a script! it's far from perfect but 95% of the work has been done already formatting-wise.
Document all functions, class, struct, union, enum, macro, variable, typedefs. This isn't the actual document in itself but empty documentation using any old documentation if it was there.
This was done using exuberant ctags to get tag info, then a TCL script to parse/remove old comments and convert them into Doxygen-style.
Some notes:
* Anything labeled 'DOCME' needs to be documented, @param and @return have been left blank as it would be annoying to delete the 'DOCME' from every one of those.
* Some multiline comments may have been munged into single line comments
* Leave the /// comments above global variables with a space, if they're harder to read then we'll be less likey to use them.
* Enum comments can go after the enumeration itself '[value] /// comment'
* include/aegisub/*.h haven't been converted yet, this will be done in a later commit
* Some documentation blocks are in the wrong place, in the .h when it should be in the .cpp, or vice versa.
See http://devel.aegisub.org/wiki/Doxygen for some details on Doxygen and a 'style guide'.
Originally committed to SVN as r3312.
2009-07-30 00:59:22 +02:00
|
|
|
/// @class IntermediateSpectrumCache
|
2009-08-01 03:55:17 +02:00
|
|
|
/// @brief Intermediate node in the spectrum cache tree.
|
Note: This was done using a script! it's far from perfect but 95% of the work has been done already formatting-wise.
Document all functions, class, struct, union, enum, macro, variable, typedefs. This isn't the actual document in itself but empty documentation using any old documentation if it was there.
This was done using exuberant ctags to get tag info, then a TCL script to parse/remove old comments and convert them into Doxygen-style.
Some notes:
* Anything labeled 'DOCME' needs to be documented, @param and @return have been left blank as it would be annoying to delete the 'DOCME' from every one of those.
* Some multiline comments may have been munged into single line comments
* Leave the /// comments above global variables with a space, if they're harder to read then we'll be less likey to use them.
* Enum comments can go after the enumeration itself '[value] /// comment'
* include/aegisub/*.h haven't been converted yet, this will be done in a later commit
* Some documentation blocks are in the wrong place, in the .h when it should be in the .cpp, or vice versa.
See http://devel.aegisub.org/wiki/Doxygen for some details on Doxygen and a 'style guide'.
Originally committed to SVN as r3312.
2009-07-30 00:59:22 +02:00
|
|
|
///
|
2009-08-01 03:55:17 +02:00
|
|
|
/// References further nodes in the spectrum cache tree and delegates operations to them.
|
2007-01-07 05:44:11 +01:00
|
|
|
class IntermediateSpectrumCache : public AudioSpectrumCache {
|
|
|
|
private:
|
Note: This was done using a script! it's far from perfect but 95% of the work has been done already formatting-wise.
Document all functions, class, struct, union, enum, macro, variable, typedefs. This isn't the actual document in itself but empty documentation using any old documentation if it was there.
This was done using exuberant ctags to get tag info, then a TCL script to parse/remove old comments and convert them into Doxygen-style.
Some notes:
* Anything labeled 'DOCME' needs to be documented, @param and @return have been left blank as it would be annoying to delete the 'DOCME' from every one of those.
* Some multiline comments may have been munged into single line comments
* Leave the /// comments above global variables with a space, if they're harder to read then we'll be less likey to use them.
* Enum comments can go after the enumeration itself '[value] /// comment'
* include/aegisub/*.h haven't been converted yet, this will be done in a later commit
* Some documentation blocks are in the wrong place, in the .h when it should be in the .cpp, or vice versa.
See http://devel.aegisub.org/wiki/Doxygen for some details on Doxygen and a 'style guide'.
Originally committed to SVN as r3312.
2009-07-30 00:59:22 +02:00
|
|
|
|
2009-08-01 03:55:17 +02:00
|
|
|
/// The child-nodes in the cache tree.
|
2007-01-07 05:44:11 +01:00
|
|
|
std::vector<AudioSpectrumCache*> sub_caches;
|
Note: This was done using a script! it's far from perfect but 95% of the work has been done already formatting-wise.
Document all functions, class, struct, union, enum, macro, variable, typedefs. This isn't the actual document in itself but empty documentation using any old documentation if it was there.
This was done using exuberant ctags to get tag info, then a TCL script to parse/remove old comments and convert them into Doxygen-style.
Some notes:
* Anything labeled 'DOCME' needs to be documented, @param and @return have been left blank as it would be annoying to delete the 'DOCME' from every one of those.
* Some multiline comments may have been munged into single line comments
* Leave the /// comments above global variables with a space, if they're harder to read then we'll be less likey to use them.
* Enum comments can go after the enumeration itself '[value] /// comment'
* include/aegisub/*.h haven't been converted yet, this will be done in a later commit
* Some documentation blocks are in the wrong place, in the .h when it should be in the .cpp, or vice versa.
See http://devel.aegisub.org/wiki/Doxygen for some details on Doxygen and a 'style guide'.
Originally committed to SVN as r3312.
2009-07-30 00:59:22 +02:00
|
|
|
|
2009-08-01 03:55:17 +02:00
|
|
|
unsigned long start, ///< DOCME
|
|
|
|
length, ///< DOCME
|
|
|
|
subcache_length; ///< DOCME
|
|
|
|
unsigned int overlaps; ///< Number of overlaps used.
|
|
|
|
bool subcaches_are_final; ///< Are the children leaf nodes?
|
|
|
|
int depth; ///< How deep is this in the tree.
|
Note: This was done using a script! it's far from perfect but 95% of the work has been done already formatting-wise.
Document all functions, class, struct, union, enum, macro, variable, typedefs. This isn't the actual document in itself but empty documentation using any old documentation if it was there.
This was done using exuberant ctags to get tag info, then a TCL script to parse/remove old comments and convert them into Doxygen-style.
Some notes:
* Anything labeled 'DOCME' needs to be documented, @param and @return have been left blank as it would be annoying to delete the 'DOCME' from every one of those.
* Some multiline comments may have been munged into single line comments
* Leave the /// comments above global variables with a space, if they're harder to read then we'll be less likey to use them.
* Enum comments can go after the enumeration itself '[value] /// comment'
* include/aegisub/*.h haven't been converted yet, this will be done in a later commit
* Some documentation blocks are in the wrong place, in the .h when it should be in the .cpp, or vice versa.
See http://devel.aegisub.org/wiki/Doxygen for some details on Doxygen and a 'style guide'.
Originally committed to SVN as r3312.
2009-07-30 00:59:22 +02:00
|
|
|
|
2009-08-01 03:55:17 +02:00
|
|
|
/// Audio provider to pass on to child nodes.
|
2007-01-07 05:44:11 +01:00
|
|
|
AudioProvider *provider;
|
|
|
|
|
|
|
|
public:
|
Note: This was done using a script! it's far from perfect but 95% of the work has been done already formatting-wise.
Document all functions, class, struct, union, enum, macro, variable, typedefs. This isn't the actual document in itself but empty documentation using any old documentation if it was there.
This was done using exuberant ctags to get tag info, then a TCL script to parse/remove old comments and convert them into Doxygen-style.
Some notes:
* Anything labeled 'DOCME' needs to be documented, @param and @return have been left blank as it would be annoying to delete the 'DOCME' from every one of those.
* Some multiline comments may have been munged into single line comments
* Leave the /// comments above global variables with a space, if they're harder to read then we'll be less likey to use them.
* Enum comments can go after the enumeration itself '[value] /// comment'
* include/aegisub/*.h haven't been converted yet, this will be done in a later commit
* Some documentation blocks are in the wrong place, in the .h when it should be in the .cpp, or vice versa.
See http://devel.aegisub.org/wiki/Doxygen for some details on Doxygen and a 'style guide'.
Originally committed to SVN as r3312.
2009-07-30 00:59:22 +02:00
|
|
|
|
2009-08-01 03:55:17 +02:00
|
|
|
/// @brief Delegate line retrieval to a child node.
|
|
|
|
/// @param i Index of the block to get the line from.
|
|
|
|
/// @param overlap Index of the overlap in the block to get the line for.
|
|
|
|
/// @param created [out] Set to true if the data had to be calculated, false if the data
|
|
|
|
/// was found in cache.
|
|
|
|
/// @param access_time Timestamp to mark the cache data as accessed at.
|
|
|
|
/// @return Returns a reference to the frequency-power data requested.
|
Note: This was done using a script! it's far from perfect but 95% of the work has been done already formatting-wise.
Document all functions, class, struct, union, enum, macro, variable, typedefs. This isn't the actual document in itself but empty documentation using any old documentation if it was there.
This was done using exuberant ctags to get tag info, then a TCL script to parse/remove old comments and convert them into Doxygen-style.
Some notes:
* Anything labeled 'DOCME' needs to be documented, @param and @return have been left blank as it would be annoying to delete the 'DOCME' from every one of those.
* Some multiline comments may have been munged into single line comments
* Leave the /// comments above global variables with a space, if they're harder to read then we'll be less likey to use them.
* Enum comments can go after the enumeration itself '[value] /// comment'
* include/aegisub/*.h haven't been converted yet, this will be done in a later commit
* Some documentation blocks are in the wrong place, in the .h when it should be in the .cpp, or vice versa.
See http://devel.aegisub.org/wiki/Doxygen for some details on Doxygen and a 'style guide'.
Originally committed to SVN as r3312.
2009-07-30 00:59:22 +02:00
|
|
|
///
|
2009-08-01 03:55:17 +02:00
|
|
|
/// Will create the required child node if it doesn't exist yet.
|
2007-06-30 16:40:52 +02:00
|
|
|
CacheLine &GetLine(unsigned long i, unsigned int overlap, bool &created, CacheAccessTime access_time)
|
2007-01-07 05:44:11 +01:00
|
|
|
{
|
|
|
|
if (i >= start && i-start <= length) {
|
|
|
|
// Determine which sub-cache this line resides in
|
2007-01-07 07:36:10 +01:00
|
|
|
size_t subcache = (i-start) / subcache_length;
|
2007-04-04 22:42:44 +02:00
|
|
|
assert(subcache < sub_caches.size());
|
2007-01-07 05:44:11 +01:00
|
|
|
|
|
|
|
if (!sub_caches[subcache]) {
|
2007-06-24 22:46:52 +02:00
|
|
|
created = true;
|
2007-01-07 05:44:11 +01:00
|
|
|
if (subcaches_are_final) {
|
2007-06-24 21:53:41 +02:00
|
|
|
sub_caches[subcache] = new FinalSpectrumCache(provider, start+subcache*subcache_length, subcache_length, overlaps);
|
2007-01-07 05:44:11 +01:00
|
|
|
} else {
|
2007-06-24 21:53:41 +02:00
|
|
|
sub_caches[subcache] = new IntermediateSpectrumCache(provider, start+subcache*subcache_length, subcache_length, overlaps, depth+1);
|
2007-01-07 05:44:11 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2007-06-30 16:40:52 +02:00
|
|
|
return sub_caches[subcache]->GetLine(i, overlap, created, access_time);
|
2007-01-07 05:44:11 +01:00
|
|
|
} else {
|
|
|
|
return null_line;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
Note: This was done using a script! it's far from perfect but 95% of the work has been done already formatting-wise.
Document all functions, class, struct, union, enum, macro, variable, typedefs. This isn't the actual document in itself but empty documentation using any old documentation if it was there.
This was done using exuberant ctags to get tag info, then a TCL script to parse/remove old comments and convert them into Doxygen-style.
Some notes:
* Anything labeled 'DOCME' needs to be documented, @param and @return have been left blank as it would be annoying to delete the 'DOCME' from every one of those.
* Some multiline comments may have been munged into single line comments
* Leave the /// comments above global variables with a space, if they're harder to read then we'll be less likey to use them.
* Enum comments can go after the enumeration itself '[value] /// comment'
* include/aegisub/*.h haven't been converted yet, this will be done in a later commit
* Some documentation blocks are in the wrong place, in the .h when it should be in the .cpp, or vice versa.
See http://devel.aegisub.org/wiki/Doxygen for some details on Doxygen and a 'style guide'.
Originally committed to SVN as r3312.
2009-07-30 00:59:22 +02:00
|
|
|
|
2009-08-01 03:55:17 +02:00
|
|
|
/// @brief Iterate all direct children and return the sum of their managed line count.
|
|
|
|
/// @return Returns the sum of the managed line count of all children.
|
2007-06-30 16:40:52 +02:00
|
|
|
size_t GetManagedLineCount()
|
|
|
|
{
|
|
|
|
size_t res = 0;
|
|
|
|
for (size_t i = 0; i < sub_caches.size(); ++i) {
|
|
|
|
if (sub_caches[i])
|
|
|
|
res += sub_caches[i]->GetManagedLineCount();
|
|
|
|
}
|
|
|
|
return res;
|
|
|
|
}
|
|
|
|
|
Note: This was done using a script! it's far from perfect but 95% of the work has been done already formatting-wise.
Document all functions, class, struct, union, enum, macro, variable, typedefs. This isn't the actual document in itself but empty documentation using any old documentation if it was there.
This was done using exuberant ctags to get tag info, then a TCL script to parse/remove old comments and convert them into Doxygen-style.
Some notes:
* Anything labeled 'DOCME' needs to be documented, @param and @return have been left blank as it would be annoying to delete the 'DOCME' from every one of those.
* Some multiline comments may have been munged into single line comments
* Leave the /// comments above global variables with a space, if they're harder to read then we'll be less likey to use them.
* Enum comments can go after the enumeration itself '[value] /// comment'
* include/aegisub/*.h haven't been converted yet, this will be done in a later commit
* Some documentation blocks are in the wrong place, in the .h when it should be in the .cpp, or vice versa.
See http://devel.aegisub.org/wiki/Doxygen for some details on Doxygen and a 'style guide'.
Originally committed to SVN as r3312.
2009-07-30 00:59:22 +02:00
|
|
|
|
2009-08-01 03:55:17 +02:00
|
|
|
/// @brief Get access time data for all child nodes in cache tree.
|
|
|
|
/// @param ages [in,out] List for child nodes to add their data to.
|
2007-06-30 16:40:52 +02:00
|
|
|
void GetLineAccessTimes(CacheAgeList &ages)
|
|
|
|
{
|
|
|
|
for (size_t i = 0; i < sub_caches.size(); ++i) {
|
|
|
|
if (sub_caches[i])
|
|
|
|
sub_caches[i]->GetLineAccessTimes(ages);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
Note: This was done using a script! it's far from perfect but 95% of the work has been done already formatting-wise.
Document all functions, class, struct, union, enum, macro, variable, typedefs. This isn't the actual document in itself but empty documentation using any old documentation if it was there.
This was done using exuberant ctags to get tag info, then a TCL script to parse/remove old comments and convert them into Doxygen-style.
Some notes:
* Anything labeled 'DOCME' needs to be documented, @param and @return have been left blank as it would be annoying to delete the 'DOCME' from every one of those.
* Some multiline comments may have been munged into single line comments
* Leave the /// comments above global variables with a space, if they're harder to read then we'll be less likey to use them.
* Enum comments can go after the enumeration itself '[value] /// comment'
* include/aegisub/*.h haven't been converted yet, this will be done in a later commit
* Some documentation blocks are in the wrong place, in the .h when it should be in the .cpp, or vice versa.
See http://devel.aegisub.org/wiki/Doxygen for some details on Doxygen and a 'style guide'.
Originally committed to SVN as r3312.
2009-07-30 00:59:22 +02:00
|
|
|
|
2009-08-01 03:55:17 +02:00
|
|
|
/// @brief Remove block with given index from cache.
|
|
|
|
/// @param line_id Index of the block the cache node to remove starts at.
|
|
|
|
/// @return Returns true if this node has no more live childs, false if
|
|
|
|
/// there is a least one line child.
|
Note: This was done using a script! it's far from perfect but 95% of the work has been done already formatting-wise.
Document all functions, class, struct, union, enum, macro, variable, typedefs. This isn't the actual document in itself but empty documentation using any old documentation if it was there.
This was done using exuberant ctags to get tag info, then a TCL script to parse/remove old comments and convert them into Doxygen-style.
Some notes:
* Anything labeled 'DOCME' needs to be documented, @param and @return have been left blank as it would be annoying to delete the 'DOCME' from every one of those.
* Some multiline comments may have been munged into single line comments
* Leave the /// comments above global variables with a space, if they're harder to read then we'll be less likey to use them.
* Enum comments can go after the enumeration itself '[value] /// comment'
* include/aegisub/*.h haven't been converted yet, this will be done in a later commit
* Some documentation blocks are in the wrong place, in the .h when it should be in the .cpp, or vice versa.
See http://devel.aegisub.org/wiki/Doxygen for some details on Doxygen and a 'style guide'.
Originally committed to SVN as r3312.
2009-07-30 00:59:22 +02:00
|
|
|
///
|
2009-08-01 03:55:17 +02:00
|
|
|
/// Iterates the child nodes, calls the method recursively on all live
|
|
|
|
/// nodes, deletes any node returning true, and counts number of nodes
|
|
|
|
/// still alive, returning true if any are alive.
|
2007-06-30 16:40:52 +02:00
|
|
|
bool KillLine(unsigned long line_id)
|
|
|
|
{
|
|
|
|
int sub_caches_left = 0;
|
|
|
|
for (size_t i = 0; i < sub_caches.size(); ++i) {
|
|
|
|
if (sub_caches[i]) {
|
|
|
|
if (sub_caches[i]->KillLine(line_id)) {
|
|
|
|
delete sub_caches[i];
|
|
|
|
sub_caches[i] = 0;
|
|
|
|
} else {
|
|
|
|
sub_caches_left++;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return sub_caches_left == 0;
|
|
|
|
}
|
|
|
|
|
Note: This was done using a script! it's far from perfect but 95% of the work has been done already formatting-wise.
Document all functions, class, struct, union, enum, macro, variable, typedefs. This isn't the actual document in itself but empty documentation using any old documentation if it was there.
This was done using exuberant ctags to get tag info, then a TCL script to parse/remove old comments and convert them into Doxygen-style.
Some notes:
* Anything labeled 'DOCME' needs to be documented, @param and @return have been left blank as it would be annoying to delete the 'DOCME' from every one of those.
* Some multiline comments may have been munged into single line comments
* Leave the /// comments above global variables with a space, if they're harder to read then we'll be less likey to use them.
* Enum comments can go after the enumeration itself '[value] /// comment'
* include/aegisub/*.h haven't been converted yet, this will be done in a later commit
* Some documentation blocks are in the wrong place, in the .h when it should be in the .cpp, or vice versa.
See http://devel.aegisub.org/wiki/Doxygen for some details on Doxygen and a 'style guide'.
Originally committed to SVN as r3312.
2009-07-30 00:59:22 +02:00
|
|
|
|
2009-08-01 03:55:17 +02:00
|
|
|
/// @brief Constructor.
|
|
|
|
/// @param _provider Audio provider to pass to child nodes.
|
|
|
|
/// @param _start Index of first block to manage.
|
|
|
|
/// @param _length Number of blocks to manage.
|
|
|
|
/// @param _overlaps Number of lines per block.
|
|
|
|
/// @param _depth Number of levels in the tree above this node.
|
Note: This was done using a script! it's far from perfect but 95% of the work has been done already formatting-wise.
Document all functions, class, struct, union, enum, macro, variable, typedefs. This isn't the actual document in itself but empty documentation using any old documentation if it was there.
This was done using exuberant ctags to get tag info, then a TCL script to parse/remove old comments and convert them into Doxygen-style.
Some notes:
* Anything labeled 'DOCME' needs to be documented, @param and @return have been left blank as it would be annoying to delete the 'DOCME' from every one of those.
* Some multiline comments may have been munged into single line comments
* Leave the /// comments above global variables with a space, if they're harder to read then we'll be less likey to use them.
* Enum comments can go after the enumeration itself '[value] /// comment'
* include/aegisub/*.h haven't been converted yet, this will be done in a later commit
* Some documentation blocks are in the wrong place, in the .h when it should be in the .cpp, or vice versa.
See http://devel.aegisub.org/wiki/Doxygen for some details on Doxygen and a 'style guide'.
Originally committed to SVN as r3312.
2009-07-30 00:59:22 +02:00
|
|
|
///
|
2009-08-01 03:55:17 +02:00
|
|
|
/// Determine how many sub-caches are required, how big they
|
|
|
|
/// should be and allocates memory to store their pointers.
|
2007-06-24 21:53:41 +02:00
|
|
|
IntermediateSpectrumCache(AudioProvider *_provider, unsigned long _start, unsigned long _length, unsigned int _overlaps, int _depth)
|
2007-01-07 05:44:11 +01:00
|
|
|
{
|
|
|
|
provider = _provider;
|
|
|
|
start = _start;
|
|
|
|
length = _length;
|
2007-06-24 21:53:41 +02:00
|
|
|
overlaps = _overlaps;
|
2007-01-07 05:44:11 +01:00
|
|
|
depth = _depth;
|
|
|
|
|
|
|
|
// FIXME: this calculation probably needs tweaking
|
|
|
|
int num_subcaches = 1;
|
|
|
|
unsigned long tmp = length;
|
|
|
|
while (tmp > 0) {
|
|
|
|
tmp /= 16;
|
|
|
|
num_subcaches *= 2;
|
|
|
|
}
|
|
|
|
subcache_length = length / (num_subcaches-1);
|
|
|
|
|
|
|
|
subcaches_are_final = num_subcaches <= 4;
|
|
|
|
|
|
|
|
sub_caches.resize(num_subcaches, 0);
|
|
|
|
}
|
|
|
|
|
Note: This was done using a script! it's far from perfect but 95% of the work has been done already formatting-wise.
Document all functions, class, struct, union, enum, macro, variable, typedefs. This isn't the actual document in itself but empty documentation using any old documentation if it was there.
This was done using exuberant ctags to get tag info, then a TCL script to parse/remove old comments and convert them into Doxygen-style.
Some notes:
* Anything labeled 'DOCME' needs to be documented, @param and @return have been left blank as it would be annoying to delete the 'DOCME' from every one of those.
* Some multiline comments may have been munged into single line comments
* Leave the /// comments above global variables with a space, if they're harder to read then we'll be less likey to use them.
* Enum comments can go after the enumeration itself '[value] /// comment'
* include/aegisub/*.h haven't been converted yet, this will be done in a later commit
* Some documentation blocks are in the wrong place, in the .h when it should be in the .cpp, or vice versa.
See http://devel.aegisub.org/wiki/Doxygen for some details on Doxygen and a 'style guide'.
Originally committed to SVN as r3312.
2009-07-30 00:59:22 +02:00
|
|
|
|
2009-08-01 03:55:17 +02:00
|
|
|
/// @brief Destructor, deletes all still-live sub caches.
|
2007-01-07 05:44:11 +01:00
|
|
|
virtual ~IntermediateSpectrumCache()
|
|
|
|
{
|
|
|
|
for (size_t i = 0; i < sub_caches.size(); ++i)
|
|
|
|
if (sub_caches[i])
|
|
|
|
delete sub_caches[i];
|
|
|
|
}
|
|
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
2007-06-30 16:40:52 +02:00
|
|
|
|
Note: This was done using a script! it's far from perfect but 95% of the work has been done already formatting-wise.
Document all functions, class, struct, union, enum, macro, variable, typedefs. This isn't the actual document in itself but empty documentation using any old documentation if it was there.
This was done using exuberant ctags to get tag info, then a TCL script to parse/remove old comments and convert them into Doxygen-style.
Some notes:
* Anything labeled 'DOCME' needs to be documented, @param and @return have been left blank as it would be annoying to delete the 'DOCME' from every one of those.
* Some multiline comments may have been munged into single line comments
* Leave the /// comments above global variables with a space, if they're harder to read then we'll be less likey to use them.
* Enum comments can go after the enumeration itself '[value] /// comment'
* include/aegisub/*.h haven't been converted yet, this will be done in a later commit
* Some documentation blocks are in the wrong place, in the .h when it should be in the .cpp, or vice versa.
See http://devel.aegisub.org/wiki/Doxygen for some details on Doxygen and a 'style guide'.
Originally committed to SVN as r3312.
2009-07-30 00:59:22 +02:00
|
|
|
|
|
|
|
/// @class AudioSpectrumCacheManager
|
2009-08-01 03:55:17 +02:00
|
|
|
/// @brief Manages a frequency-power cache tree.
|
Note: This was done using a script! it's far from perfect but 95% of the work has been done already formatting-wise.
Document all functions, class, struct, union, enum, macro, variable, typedefs. This isn't the actual document in itself but empty documentation using any old documentation if it was there.
This was done using exuberant ctags to get tag info, then a TCL script to parse/remove old comments and convert them into Doxygen-style.
Some notes:
* Anything labeled 'DOCME' needs to be documented, @param and @return have been left blank as it would be annoying to delete the 'DOCME' from every one of those.
* Some multiline comments may have been munged into single line comments
* Leave the /// comments above global variables with a space, if they're harder to read then we'll be less likey to use them.
* Enum comments can go after the enumeration itself '[value] /// comment'
* include/aegisub/*.h haven't been converted yet, this will be done in a later commit
* Some documentation blocks are in the wrong place, in the .h when it should be in the .cpp, or vice versa.
See http://devel.aegisub.org/wiki/Doxygen for some details on Doxygen and a 'style guide'.
Originally committed to SVN as r3312.
2009-07-30 00:59:22 +02:00
|
|
|
///
|
2009-08-01 03:55:17 +02:00
|
|
|
/// The primary task of this class is to manage the amount of memory consumed by
|
|
|
|
/// the cache and delete items when it grows too large.
|
2007-06-30 16:40:52 +02:00
|
|
|
class AudioSpectrumCacheManager {
|
|
|
|
private:
|
Note: This was done using a script! it's far from perfect but 95% of the work has been done already formatting-wise.
Document all functions, class, struct, union, enum, macro, variable, typedefs. This isn't the actual document in itself but empty documentation using any old documentation if it was there.
This was done using exuberant ctags to get tag info, then a TCL script to parse/remove old comments and convert them into Doxygen-style.
Some notes:
* Anything labeled 'DOCME' needs to be documented, @param and @return have been left blank as it would be annoying to delete the 'DOCME' from every one of those.
* Some multiline comments may have been munged into single line comments
* Leave the /// comments above global variables with a space, if they're harder to read then we'll be less likey to use them.
* Enum comments can go after the enumeration itself '[value] /// comment'
* include/aegisub/*.h haven't been converted yet, this will be done in a later commit
* Some documentation blocks are in the wrong place, in the .h when it should be in the .cpp, or vice versa.
See http://devel.aegisub.org/wiki/Doxygen for some details on Doxygen and a 'style guide'.
Originally committed to SVN as r3312.
2009-07-30 00:59:22 +02:00
|
|
|
|
2009-08-01 03:55:17 +02:00
|
|
|
/// Root node of the cache tree.
|
2007-06-30 16:40:52 +02:00
|
|
|
IntermediateSpectrumCache *cache_root;
|
Note: This was done using a script! it's far from perfect but 95% of the work has been done already formatting-wise.
Document all functions, class, struct, union, enum, macro, variable, typedefs. This isn't the actual document in itself but empty documentation using any old documentation if it was there.
This was done using exuberant ctags to get tag info, then a TCL script to parse/remove old comments and convert them into Doxygen-style.
Some notes:
* Anything labeled 'DOCME' needs to be documented, @param and @return have been left blank as it would be annoying to delete the 'DOCME' from every one of those.
* Some multiline comments may have been munged into single line comments
* Leave the /// comments above global variables with a space, if they're harder to read then we'll be less likey to use them.
* Enum comments can go after the enumeration itself '[value] /// comment'
* include/aegisub/*.h haven't been converted yet, this will be done in a later commit
* Some documentation blocks are in the wrong place, in the .h when it should be in the .cpp, or vice versa.
See http://devel.aegisub.org/wiki/Doxygen for some details on Doxygen and a 'style guide'.
Originally committed to SVN as r3312.
2009-07-30 00:59:22 +02:00
|
|
|
|
2009-08-01 03:55:17 +02:00
|
|
|
unsigned long cache_hits, ///< Number of times the cache was used to retrieve data
|
|
|
|
cache_misses; ///< Number of times data had to be calculated
|
Note: This was done using a script! it's far from perfect but 95% of the work has been done already formatting-wise.
Document all functions, class, struct, union, enum, macro, variable, typedefs. This isn't the actual document in itself but empty documentation using any old documentation if it was there.
This was done using exuberant ctags to get tag info, then a TCL script to parse/remove old comments and convert them into Doxygen-style.
Some notes:
* Anything labeled 'DOCME' needs to be documented, @param and @return have been left blank as it would be annoying to delete the 'DOCME' from every one of those.
* Some multiline comments may have been munged into single line comments
* Leave the /// comments above global variables with a space, if they're harder to read then we'll be less likey to use them.
* Enum comments can go after the enumeration itself '[value] /// comment'
* include/aegisub/*.h haven't been converted yet, this will be done in a later commit
* Some documentation blocks are in the wrong place, in the .h when it should be in the .cpp, or vice versa.
See http://devel.aegisub.org/wiki/Doxygen for some details on Doxygen and a 'style guide'.
Originally committed to SVN as r3312.
2009-07-30 00:59:22 +02:00
|
|
|
|
2009-08-01 03:55:17 +02:00
|
|
|
/// Current time, used for cache aging purposes.
|
2007-06-30 16:40:52 +02:00
|
|
|
AudioSpectrumCache::CacheAccessTime cur_time;
|
|
|
|
|
2009-08-01 03:55:17 +02:00
|
|
|
/// Maximum number of lines to keep in cache.
|
2007-06-30 16:40:52 +02:00
|
|
|
unsigned long max_lines_cached;
|
|
|
|
|
|
|
|
public:
|
Note: This was done using a script! it's far from perfect but 95% of the work has been done already formatting-wise.
Document all functions, class, struct, union, enum, macro, variable, typedefs. This isn't the actual document in itself but empty documentation using any old documentation if it was there.
This was done using exuberant ctags to get tag info, then a TCL script to parse/remove old comments and convert them into Doxygen-style.
Some notes:
* Anything labeled 'DOCME' needs to be documented, @param and @return have been left blank as it would be annoying to delete the 'DOCME' from every one of those.
* Some multiline comments may have been munged into single line comments
* Leave the /// comments above global variables with a space, if they're harder to read then we'll be less likey to use them.
* Enum comments can go after the enumeration itself '[value] /// comment'
* include/aegisub/*.h haven't been converted yet, this will be done in a later commit
* Some documentation blocks are in the wrong place, in the .h when it should be in the .cpp, or vice versa.
See http://devel.aegisub.org/wiki/Doxygen for some details on Doxygen and a 'style guide'.
Originally committed to SVN as r3312.
2009-07-30 00:59:22 +02:00
|
|
|
|
2009-08-01 03:55:17 +02:00
|
|
|
/// @brief Wrapper around cache tree, to get frequency-power data
|
|
|
|
/// @param i Block to get data from.
|
|
|
|
/// @param overlap Line in block to get data from.
|
|
|
|
/// @return Returns a reference to the requested line.
|
Note: This was done using a script! it's far from perfect but 95% of the work has been done already formatting-wise.
Document all functions, class, struct, union, enum, macro, variable, typedefs. This isn't the actual document in itself but empty documentation using any old documentation if it was there.
This was done using exuberant ctags to get tag info, then a TCL script to parse/remove old comments and convert them into Doxygen-style.
Some notes:
* Anything labeled 'DOCME' needs to be documented, @param and @return have been left blank as it would be annoying to delete the 'DOCME' from every one of those.
* Some multiline comments may have been munged into single line comments
* Leave the /// comments above global variables with a space, if they're harder to read then we'll be less likey to use them.
* Enum comments can go after the enumeration itself '[value] /// comment'
* include/aegisub/*.h haven't been converted yet, this will be done in a later commit
* Some documentation blocks are in the wrong place, in the .h when it should be in the .cpp, or vice versa.
See http://devel.aegisub.org/wiki/Doxygen for some details on Doxygen and a 'style guide'.
Originally committed to SVN as r3312.
2009-07-30 00:59:22 +02:00
|
|
|
///
|
2007-06-30 16:40:52 +02:00
|
|
|
AudioSpectrumCache::CacheLine &GetLine(unsigned long i, unsigned int overlap)
|
|
|
|
{
|
|
|
|
bool created = false;
|
|
|
|
AudioSpectrumCache::CacheLine &res = cache_root->GetLine(i, overlap, created, cur_time++);
|
|
|
|
if (created)
|
|
|
|
cache_misses++;
|
|
|
|
else
|
|
|
|
cache_hits++;
|
|
|
|
return res;
|
|
|
|
}
|
|
|
|
|
Note: This was done using a script! it's far from perfect but 95% of the work has been done already formatting-wise.
Document all functions, class, struct, union, enum, macro, variable, typedefs. This isn't the actual document in itself but empty documentation using any old documentation if it was there.
This was done using exuberant ctags to get tag info, then a TCL script to parse/remove old comments and convert them into Doxygen-style.
Some notes:
* Anything labeled 'DOCME' needs to be documented, @param and @return have been left blank as it would be annoying to delete the 'DOCME' from every one of those.
* Some multiline comments may have been munged into single line comments
* Leave the /// comments above global variables with a space, if they're harder to read then we'll be less likey to use them.
* Enum comments can go after the enumeration itself '[value] /// comment'
* include/aegisub/*.h haven't been converted yet, this will be done in a later commit
* Some documentation blocks are in the wrong place, in the .h when it should be in the .cpp, or vice versa.
See http://devel.aegisub.org/wiki/Doxygen for some details on Doxygen and a 'style guide'.
Originally committed to SVN as r3312.
2009-07-30 00:59:22 +02:00
|
|
|
|
2009-08-01 03:55:17 +02:00
|
|
|
/// @brief Remove old data from the cache.
|
Note: This was done using a script! it's far from perfect but 95% of the work has been done already formatting-wise.
Document all functions, class, struct, union, enum, macro, variable, typedefs. This isn't the actual document in itself but empty documentation using any old documentation if it was there.
This was done using exuberant ctags to get tag info, then a TCL script to parse/remove old comments and convert them into Doxygen-style.
Some notes:
* Anything labeled 'DOCME' needs to be documented, @param and @return have been left blank as it would be annoying to delete the 'DOCME' from every one of those.
* Some multiline comments may have been munged into single line comments
* Leave the /// comments above global variables with a space, if they're harder to read then we'll be less likey to use them.
* Enum comments can go after the enumeration itself '[value] /// comment'
* include/aegisub/*.h haven't been converted yet, this will be done in a later commit
* Some documentation blocks are in the wrong place, in the .h when it should be in the .cpp, or vice versa.
See http://devel.aegisub.org/wiki/Doxygen for some details on Doxygen and a 'style guide'.
Originally committed to SVN as r3312.
2009-07-30 00:59:22 +02:00
|
|
|
///
|
2009-08-01 03:55:17 +02:00
|
|
|
/// Ages the cache by finding the least recently accessed data and removing cache data
|
|
|
|
/// until the total number of lines stored in the tree is less than the maximum.
|
2007-06-30 16:40:52 +02:00
|
|
|
void Age()
|
|
|
|
{
|
2010-06-09 01:21:39 +02:00
|
|
|
LOG_D("audio/renderer/spectrum/cache") << "stats: hits=" << cache_hits << " misses=" << cache_misses << " misses%=" << cache_misses/float(cache_hits+cache_misses)*100 << " managed lines=" << cache_root->GetManagedLineCount() << "(max=" << max_lines_cached << ")";
|
2007-06-30 16:40:52 +02:00
|
|
|
|
|
|
|
// 0 means no limit
|
|
|
|
if (max_lines_cached == 0)
|
|
|
|
return;
|
|
|
|
// No reason to proceed with complicated stuff if the count is too small
|
|
|
|
// (FIXME: does this really pay off?)
|
|
|
|
if (cache_root->GetManagedLineCount() < max_lines_cached)
|
|
|
|
return;
|
|
|
|
|
|
|
|
// Get and sort ages
|
|
|
|
AudioSpectrumCache::CacheAgeList ages;
|
|
|
|
cache_root->GetLineAccessTimes(ages);
|
|
|
|
std::sort(ages.begin(), ages.end());
|
|
|
|
|
|
|
|
// Number of lines we have found used so far
|
|
|
|
// When this exceeds max_lines_caches go into kill-mode
|
|
|
|
unsigned long cumulative_lines = 0;
|
|
|
|
// Run backwards through the line age list (the most recently accessed items are at end)
|
|
|
|
AudioSpectrumCache::CacheAgeList::reverse_iterator it = ages.rbegin();
|
|
|
|
|
|
|
|
// Find the point where we have too many lines cached
|
|
|
|
while (cumulative_lines < max_lines_cached) {
|
|
|
|
if (it == ages.rend()) {
|
2010-06-09 01:21:39 +02:00
|
|
|
LOG_D("audio/renderer/spectrum/") << "done aging did not exeed max_lines_cached";
|
2007-06-30 16:40:52 +02:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
cumulative_lines += it->num_lines;
|
|
|
|
++it;
|
|
|
|
}
|
|
|
|
|
|
|
|
// By here, we have exceeded max_lines_cached so backtrack one
|
|
|
|
--it;
|
|
|
|
|
|
|
|
// And now start cleaning up
|
|
|
|
for (; it != ages.rend(); ++it) {
|
|
|
|
cache_root->KillLine(it->first_line);
|
|
|
|
}
|
|
|
|
|
2010-06-09 01:21:39 +02:00
|
|
|
LOG_D("audio/renderer/spectrum/") << "done aging, managed lines now=" << cache_root->GetManagedLineCount() << " (max=" << max_lines_cached << ")";
|
2007-06-30 16:40:52 +02:00
|
|
|
assert(cache_root->GetManagedLineCount() < max_lines_cached);
|
|
|
|
}
|
|
|
|
|
Note: This was done using a script! it's far from perfect but 95% of the work has been done already formatting-wise.
Document all functions, class, struct, union, enum, macro, variable, typedefs. This isn't the actual document in itself but empty documentation using any old documentation if it was there.
This was done using exuberant ctags to get tag info, then a TCL script to parse/remove old comments and convert them into Doxygen-style.
Some notes:
* Anything labeled 'DOCME' needs to be documented, @param and @return have been left blank as it would be annoying to delete the 'DOCME' from every one of those.
* Some multiline comments may have been munged into single line comments
* Leave the /// comments above global variables with a space, if they're harder to read then we'll be less likey to use them.
* Enum comments can go after the enumeration itself '[value] /// comment'
* include/aegisub/*.h haven't been converted yet, this will be done in a later commit
* Some documentation blocks are in the wrong place, in the .h when it should be in the .cpp, or vice versa.
See http://devel.aegisub.org/wiki/Doxygen for some details on Doxygen and a 'style guide'.
Originally committed to SVN as r3312.
2009-07-30 00:59:22 +02:00
|
|
|
|
2009-08-01 03:55:17 +02:00
|
|
|
/// @brief Constructor
|
|
|
|
/// @param provider Audio provider to pass to cache tree nodes.
|
|
|
|
/// @param line_length Number of audio samples to use per block.
|
|
|
|
/// @param num_lines Number of blocks to produce in total from the audio.
|
|
|
|
/// @param num_overlaps Number of overlaps per block.
|
Note: This was done using a script! it's far from perfect but 95% of the work has been done already formatting-wise.
Document all functions, class, struct, union, enum, macro, variable, typedefs. This isn't the actual document in itself but empty documentation using any old documentation if it was there.
This was done using exuberant ctags to get tag info, then a TCL script to parse/remove old comments and convert them into Doxygen-style.
Some notes:
* Anything labeled 'DOCME' needs to be documented, @param and @return have been left blank as it would be annoying to delete the 'DOCME' from every one of those.
* Some multiline comments may have been munged into single line comments
* Leave the /// comments above global variables with a space, if they're harder to read then we'll be less likey to use them.
* Enum comments can go after the enumeration itself '[value] /// comment'
* include/aegisub/*.h haven't been converted yet, this will be done in a later commit
* Some documentation blocks are in the wrong place, in the .h when it should be in the .cpp, or vice versa.
See http://devel.aegisub.org/wiki/Doxygen for some details on Doxygen and a 'style guide'.
Originally committed to SVN as r3312.
2009-07-30 00:59:22 +02:00
|
|
|
///
|
2009-08-01 03:55:17 +02:00
|
|
|
/// Initialises the cache tree root and calculates the maximum number of cache lines
|
|
|
|
/// to keep based on the Audio Spectrum Memory Max configuration setting.
|
2007-06-30 16:40:52 +02:00
|
|
|
AudioSpectrumCacheManager(AudioProvider *provider, unsigned long line_length, unsigned long num_lines, unsigned int num_overlaps)
|
|
|
|
{
|
|
|
|
cache_hits = cache_misses = 0;
|
|
|
|
cur_time = 0;
|
|
|
|
cache_root = new IntermediateSpectrumCache(provider, 0, num_lines, num_overlaps, 0);
|
|
|
|
|
|
|
|
// option is stored in megabytes, but we want number of bytes
|
2010-05-21 03:13:36 +02:00
|
|
|
unsigned long max_cache_size = OPT_GET("Audio/Renderer/Spectrum/Memory Max")->GetInt();
|
2007-10-19 05:32:53 +02:00
|
|
|
// It can't go too low
|
|
|
|
if (max_cache_size < 5) max_cache_size = 128;
|
|
|
|
max_cache_size *= 1024 * 1024;
|
2007-06-30 16:40:52 +02:00
|
|
|
unsigned long line_size = sizeof(AudioSpectrumCache::CacheLine::value_type) * line_length;
|
|
|
|
max_lines_cached = max_cache_size / line_size;
|
|
|
|
}
|
|
|
|
|
Note: This was done using a script! it's far from perfect but 95% of the work has been done already formatting-wise.
Document all functions, class, struct, union, enum, macro, variable, typedefs. This isn't the actual document in itself but empty documentation using any old documentation if it was there.
This was done using exuberant ctags to get tag info, then a TCL script to parse/remove old comments and convert them into Doxygen-style.
Some notes:
* Anything labeled 'DOCME' needs to be documented, @param and @return have been left blank as it would be annoying to delete the 'DOCME' from every one of those.
* Some multiline comments may have been munged into single line comments
* Leave the /// comments above global variables with a space, if they're harder to read then we'll be less likey to use them.
* Enum comments can go after the enumeration itself '[value] /// comment'
* include/aegisub/*.h haven't been converted yet, this will be done in a later commit
* Some documentation blocks are in the wrong place, in the .h when it should be in the .cpp, or vice versa.
See http://devel.aegisub.org/wiki/Doxygen for some details on Doxygen and a 'style guide'.
Originally committed to SVN as r3312.
2009-07-30 00:59:22 +02:00
|
|
|
|
2009-08-01 03:55:17 +02:00
|
|
|
/// @brief Destructor, deletes the cache tree root node.
|
2007-06-30 16:40:52 +02:00
|
|
|
~AudioSpectrumCacheManager()
|
|
|
|
{
|
|
|
|
delete cache_root;
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
|
2009-08-01 03:55:17 +02:00
|
|
|
// AudioSpectrum, documented in .h file
|
2007-01-07 05:44:11 +01:00
|
|
|
|
Note: This was done using a script! it's far from perfect but 95% of the work has been done already formatting-wise.
Document all functions, class, struct, union, enum, macro, variable, typedefs. This isn't the actual document in itself but empty documentation using any old documentation if it was there.
This was done using exuberant ctags to get tag info, then a TCL script to parse/remove old comments and convert them into Doxygen-style.
Some notes:
* Anything labeled 'DOCME' needs to be documented, @param and @return have been left blank as it would be annoying to delete the 'DOCME' from every one of those.
* Some multiline comments may have been munged into single line comments
* Leave the /// comments above global variables with a space, if they're harder to read then we'll be less likey to use them.
* Enum comments can go after the enumeration itself '[value] /// comment'
* include/aegisub/*.h haven't been converted yet, this will be done in a later commit
* Some documentation blocks are in the wrong place, in the .h when it should be in the .cpp, or vice versa.
See http://devel.aegisub.org/wiki/Doxygen for some details on Doxygen and a 'style guide'.
Originally committed to SVN as r3312.
2009-07-30 00:59:22 +02:00
|
|
|
|
2007-06-24 22:46:52 +02:00
|
|
|
AudioSpectrum::AudioSpectrum(AudioProvider *_provider)
|
2007-01-07 05:44:11 +01:00
|
|
|
{
|
|
|
|
provider = _provider;
|
2007-06-24 22:46:52 +02:00
|
|
|
|
2007-10-19 05:32:53 +02:00
|
|
|
// Determine the quality of the spectrum rendering based on an index
|
2010-05-21 03:13:36 +02:00
|
|
|
int quality_index = OPT_GET("Audio/Renderer/Spectrum/Quality")->GetInt();
|
2007-06-24 22:46:52 +02:00
|
|
|
if (quality_index < 0) quality_index = 0;
|
|
|
|
if (quality_index > 5) quality_index = 5; // no need to go freaking insane
|
2007-10-19 05:32:53 +02:00
|
|
|
|
|
|
|
// Line length determines the balance between resolution in the time and frequency domains.
|
|
|
|
// Larger line length gives better resolution in frequency domain,
|
|
|
|
// smaller gives better resolution in time domain.
|
|
|
|
// Any values uses the same amount of memory, but larger values takes (slightly) more CPU.
|
|
|
|
// Line lengths must be powers of 2 due to the FFT algorithm.
|
|
|
|
// 2^8 is a good compromise between time and frequency domain resolution, any smaller
|
|
|
|
// gives an unreasonably low resolution in the frequency domain.
|
|
|
|
|
|
|
|
// Increasing the number of overlaps gives better resolution in the time domain.
|
|
|
|
// Doubling the number of overlaps doubles memory and CPU use, and also
|
|
|
|
// doubles resolution in the time domain.
|
|
|
|
|
|
|
|
switch (quality_index) {
|
|
|
|
case 0:
|
|
|
|
// No overlaps, good comprimise between time/frequency resolution.
|
|
|
|
// 4 bytes used per sample.
|
|
|
|
line_length = 1<<8;
|
|
|
|
fft_overlaps = 1;
|
|
|
|
break;
|
|
|
|
case 1:
|
|
|
|
// Double frequency resolution, the resulting half time resolution
|
|
|
|
// is countered with an overlap.
|
|
|
|
// 8 bytes per sample.
|
|
|
|
line_length = 1<<9;
|
|
|
|
fft_overlaps = 2;
|
|
|
|
break;
|
|
|
|
case 2:
|
|
|
|
// Resulting double resolution in both domains.
|
|
|
|
// 16 bytes per sample.
|
|
|
|
line_length = 1<<9;
|
|
|
|
fft_overlaps = 4;
|
|
|
|
break;
|
|
|
|
case 3:
|
|
|
|
// Double frequency and quadrouble time resolution.
|
|
|
|
// 32 bytes per sample.
|
|
|
|
line_length = 1<<9;
|
|
|
|
fft_overlaps = 8;
|
|
|
|
break;
|
|
|
|
case 4:
|
|
|
|
// Quadrouble resolution in both domains.
|
|
|
|
// 64 bytes per sample.
|
|
|
|
line_length = 1<<10;
|
|
|
|
fft_overlaps = 16;
|
|
|
|
break;
|
|
|
|
case 5:
|
|
|
|
// Eight-double resolution in both domains.
|
|
|
|
// 256 bytes per sample.
|
|
|
|
line_length = 1<<11;
|
|
|
|
fft_overlaps = 64;
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
throw _T("Internal error in AudioSpectrum class - impossible quality index");
|
|
|
|
}
|
2007-01-07 05:44:11 +01:00
|
|
|
|
2007-08-31 16:11:35 +02:00
|
|
|
int64_t _num_lines = provider->GetNumSamples() / line_length / 2;
|
2007-01-07 05:44:11 +01:00
|
|
|
num_lines = (unsigned long)_num_lines;
|
|
|
|
|
|
|
|
AudioSpectrumCache::SetLineLength(line_length);
|
2007-06-30 16:40:52 +02:00
|
|
|
cache = new AudioSpectrumCacheManager(provider, line_length, num_lines, fft_overlaps);
|
2007-01-07 05:44:11 +01:00
|
|
|
|
|
|
|
power_scale = 1;
|
2010-05-21 03:13:36 +02:00
|
|
|
minband = OPT_GET("Audio/Renderer/Spectrum/Cutoff")->GetInt();
|
2007-01-07 05:44:11 +01:00
|
|
|
maxband = line_length - minband * 2/3; // TODO: make this customisable?
|
|
|
|
|
|
|
|
// Generate colour maps
|
|
|
|
unsigned char *palptr = colours_normal;
|
|
|
|
for (int i = 0; i < 256; i++) {
|
2007-04-29 01:43:58 +02:00
|
|
|
//hsl_to_rgb(170 + i * 2/3, 128 + i/2, i, palptr+0, palptr+1, palptr+2); // Previous
|
|
|
|
hsl_to_rgb((255+128-i)/2, 128 + i/2, MIN(255,2*i), palptr+0, palptr+1, palptr+2); // Icy blue
|
2007-01-07 05:44:11 +01:00
|
|
|
palptr += 3;
|
|
|
|
}
|
|
|
|
palptr = colours_selected;
|
|
|
|
for (int i = 0; i < 256; i++) {
|
2007-04-29 01:43:58 +02:00
|
|
|
//hsl_to_rgb(170 + i * 2/3, 128 + i/2, i*3/4+64, palptr+0, palptr+1, palptr+2);
|
|
|
|
hsl_to_rgb((255+128-i)/2, 128 + i/2, MIN(255,3*i/2+64), palptr+0, palptr+1, palptr+2); // Icy blue
|
2007-01-07 05:44:11 +01:00
|
|
|
palptr += 3;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
AudioSpectrum::~AudioSpectrum()
|
|
|
|
{
|
|
|
|
delete cache;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2007-08-31 16:11:35 +02:00
|
|
|
void AudioSpectrum::RenderRange(int64_t range_start, int64_t range_end, bool selected, unsigned char *img, int imgleft, int imgwidth, int imgpitch, int imgheight)
|
2007-01-07 05:44:11 +01:00
|
|
|
{
|
2007-06-24 21:53:41 +02:00
|
|
|
unsigned long first_line = (unsigned long)(fft_overlaps * range_start / line_length / 2);
|
|
|
|
unsigned long last_line = (unsigned long)(fft_overlaps * range_end / line_length / 2);
|
2007-01-07 05:44:11 +01:00
|
|
|
|
|
|
|
float *power = new float[line_length];
|
|
|
|
|
|
|
|
int last_imgcol_rendered = -1;
|
|
|
|
|
|
|
|
unsigned char *palette;
|
|
|
|
if (selected)
|
|
|
|
palette = colours_selected;
|
|
|
|
else
|
|
|
|
palette = colours_normal;
|
|
|
|
|
2007-01-07 07:36:10 +01:00
|
|
|
// Some scaling constants
|
|
|
|
const int maxpower = (1 << (16 - 1))*256;
|
|
|
|
|
|
|
|
const double upscale = power_scale * 16384 / line_length;
|
|
|
|
const double onethirdmaxpower = maxpower / 3, twothirdmaxpower = maxpower * 2/3;
|
|
|
|
const double logoverscale = log(maxpower*upscale - twothirdmaxpower);
|
|
|
|
|
2007-06-24 21:53:41 +02:00
|
|
|
// Note that here "lines" are actually bands of power data
|
|
|
|
unsigned long baseline = first_line / fft_overlaps;
|
|
|
|
unsigned int overlap = first_line % fft_overlaps;
|
2007-01-07 05:44:11 +01:00
|
|
|
for (unsigned long i = first_line; i <= last_line; ++i) {
|
|
|
|
// Handle horizontal compression and don't unneededly re-render columns
|
|
|
|
int imgcol = imgleft + imgwidth * (i - first_line) / (last_line - first_line + 1);
|
|
|
|
if (imgcol <= last_imgcol_rendered)
|
|
|
|
continue;
|
|
|
|
|
2007-06-30 16:40:52 +02:00
|
|
|
AudioSpectrumCache::CacheLine &line = cache->GetLine(baseline, overlap);
|
2007-06-24 21:53:41 +02:00
|
|
|
++overlap;
|
|
|
|
if (overlap >= fft_overlaps) {
|
|
|
|
overlap = 0;
|
|
|
|
++baseline;
|
|
|
|
}
|
2007-01-07 05:44:11 +01:00
|
|
|
|
2007-06-24 21:53:41 +02:00
|
|
|
// Apply a "compressed" scaling to the signal power
|
2007-01-07 07:36:10 +01:00
|
|
|
for (unsigned int j = 0; j < line_length; j++) {
|
2007-01-07 05:44:11 +01:00
|
|
|
// First do a simple linear scale power calculation -- 8 gives a reasonable default scaling
|
2007-01-07 07:36:10 +01:00
|
|
|
power[j] = line[j] * upscale;
|
2007-01-07 05:44:11 +01:00
|
|
|
if (power[j] > maxpower * 2/3) {
|
|
|
|
double p = power[j] - twothirdmaxpower;
|
|
|
|
p = log(p) * onethirdmaxpower / logoverscale;
|
|
|
|
power[j] = p + twothirdmaxpower;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2009-08-01 03:55:17 +02:00
|
|
|
/// @internal Macro that stores pixel data, depends on local variables in AudioSpectrum::RenderRange
|
2007-01-07 05:44:11 +01:00
|
|
|
#define WRITE_PIXEL \
|
2007-01-07 08:28:39 +01:00
|
|
|
if (intensity < 0) intensity = 0; \
|
|
|
|
if (intensity > 255) intensity = 255; \
|
2007-01-07 05:44:11 +01:00
|
|
|
img[((imgheight-y-1)*imgpitch+x)*3 + 0] = palette[intensity*3+0]; \
|
|
|
|
img[((imgheight-y-1)*imgpitch+x)*3 + 1] = palette[intensity*3+1]; \
|
|
|
|
img[((imgheight-y-1)*imgpitch+x)*3 + 2] = palette[intensity*3+2];
|
|
|
|
|
2007-01-07 07:36:10 +01:00
|
|
|
// Handle horizontal expansion
|
2007-01-07 05:44:11 +01:00
|
|
|
int next_line_imgcol = imgleft + imgwidth * (i - first_line + 1) / (last_line - first_line + 1);
|
|
|
|
if (next_line_imgcol >= imgpitch)
|
|
|
|
next_line_imgcol = imgpitch-1;
|
|
|
|
|
|
|
|
for (int x = imgcol; x <= next_line_imgcol; ++x) {
|
|
|
|
|
|
|
|
// Decide which rendering algo to use
|
|
|
|
if (maxband - minband > imgheight) {
|
|
|
|
// more than one frequency sample per pixel (vertically compress data)
|
|
|
|
// pick the largest value per pixel for display
|
|
|
|
|
|
|
|
// Iterate over pixels, picking a range of samples for each
|
|
|
|
for (int y = 0; y < imgheight; ++y) {
|
2008-01-18 19:35:55 +01:00
|
|
|
int sample1 = MAX(0,maxband * y/imgheight + minband);
|
2008-01-18 19:36:52 +01:00
|
|
|
int sample2 = MIN(signed(line_length-1),maxband * (y+1)/imgheight + minband);
|
2007-01-07 05:44:11 +01:00
|
|
|
float maxval = 0;
|
|
|
|
for (int samp = sample1; samp <= sample2; samp++) {
|
|
|
|
if (power[samp] > maxval) maxval = power[samp];
|
|
|
|
}
|
|
|
|
int intensity = int(256 * maxval / maxpower);
|
|
|
|
WRITE_PIXEL
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
// less than one frequency sample per pixel (vertically expand data)
|
|
|
|
// interpolate between pixels
|
|
|
|
// can also happen with exactly one sample per pixel, but how often is that?
|
|
|
|
|
|
|
|
// Iterate over pixels, picking the nearest power values
|
|
|
|
for (int y = 0; y < imgheight; ++y) {
|
|
|
|
float ideal = (float)(y+1.)/imgheight * maxband;
|
|
|
|
float sample1 = power[(int)floor(ideal)+minband];
|
|
|
|
float sample2 = power[(int)ceil(ideal)+minband];
|
|
|
|
float frac = ideal - floor(ideal);
|
|
|
|
int intensity = int(((1-frac)*sample1 + frac*sample2) / maxpower * 256);
|
|
|
|
WRITE_PIXEL
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2009-08-01 03:55:17 +02:00
|
|
|
/// @internal The WRITE_PIXEL macro is only defined inside AudioSpectrum::RenderRange
|
2007-01-07 05:44:11 +01:00
|
|
|
#undef WRITE_PIXEL
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
delete[] power;
|
2007-06-24 22:46:52 +02:00
|
|
|
|
2007-06-30 16:40:52 +02:00
|
|
|
cache->Age();
|
2007-01-07 05:44:11 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void AudioSpectrum::SetScaling(float _power_scale)
|
|
|
|
{
|
|
|
|
power_scale = _power_scale;
|
|
|
|
}
|
|
|
|
|
2007-09-12 01:22:26 +02:00
|
|
|
|
2009-07-29 07:43:02 +02:00
|
|
|
|
Note: This was done using a script! it's far from perfect but 95% of the work has been done already formatting-wise.
Document all functions, class, struct, union, enum, macro, variable, typedefs. This isn't the actual document in itself but empty documentation using any old documentation if it was there.
This was done using exuberant ctags to get tag info, then a TCL script to parse/remove old comments and convert them into Doxygen-style.
Some notes:
* Anything labeled 'DOCME' needs to be documented, @param and @return have been left blank as it would be annoying to delete the 'DOCME' from every one of those.
* Some multiline comments may have been munged into single line comments
* Leave the /// comments above global variables with a space, if they're harder to read then we'll be less likey to use them.
* Enum comments can go after the enumeration itself '[value] /// comment'
* include/aegisub/*.h haven't been converted yet, this will be done in a later commit
* Some documentation blocks are in the wrong place, in the .h when it should be in the .cpp, or vice versa.
See http://devel.aegisub.org/wiki/Doxygen for some details on Doxygen and a 'style guide'.
Originally committed to SVN as r3312.
2009-07-30 00:59:22 +02:00
|
|
|
|