From 3cf1718ef63b5758de782b2702de5ac7c23df811 Mon Sep 17 00:00:00 2001 From: Thomas Goyne Date: Fri, 18 Nov 2011 22:58:02 +0000 Subject: [PATCH] Add support for the inactive color scheme to the audio renderers Originally committed to SVN as r5886. --- .../aegisub_vs2008/aegisub_vs2008.vcproj | 4 + aegisub/src/audio_renderer.h | 37 +----- aegisub/src/audio_renderer_spectrum.cpp | 115 +++++++----------- aegisub/src/audio_renderer_spectrum.h | 40 +++--- aegisub/src/audio_renderer_waveform.cpp | 24 ++-- aegisub/src/audio_renderer_waveform.h | 19 +-- 6 files changed, 106 insertions(+), 133 deletions(-) diff --git a/aegisub/build/aegisub_vs2008/aegisub_vs2008.vcproj b/aegisub/build/aegisub_vs2008/aegisub_vs2008.vcproj index c718375b2..3b392ac25 100644 --- a/aegisub/build/aegisub_vs2008/aegisub_vs2008.vcproj +++ b/aegisub/build/aegisub_vs2008/aegisub_vs2008.vcproj @@ -1763,6 +1763,10 @@ RelativePath="..\..\src\audio_renderer_waveform.h" > + + diff --git a/aegisub/src/audio_renderer.h b/aegisub/src/audio_renderer.h index 2a8a31a01..9c63a91d9 100644 --- a/aegisub/src/audio_renderer.h +++ b/aegisub/src/audio_renderer.h @@ -35,6 +35,7 @@ /// /// Base classes for audio renderers (spectrum, waveform, ...) +#pragma once #ifndef AGI_PRE #include @@ -44,6 +45,7 @@ #include #endif +#include "audio_rendering_style.h" #include "block_cache.h" // Some forward declarations for outside stuff @@ -53,41 +55,6 @@ class AudioProvider; class AudioRendererBitmapProvider; class AudioRenderer; -/// @brief Styles audio may be rendered in -/// -/// The constants are ordered by priority: -/// Selected has highest priority and should overlap active, which should -/// overlap inactive, which should overlap normal regions. -enum AudioRenderingStyle { - /// Regular audio with no special properties - AudioStyle_Normal, - /// Audio belonging to objects that can not be manipulated currently - AudioStyle_Inactive, - /// Audio that may be manipulated indirectly, usually part of selected lines - AudioStyle_Active, - /// Primary selection for work, usually coinciding with the primary playback range - AudioStyle_Selected, - /// Number of audio styles - AudioStyle_MAX -}; - - -/// @class AudioRenderingStyleRanges -/// @brief Abstract container for ranges of audio rendering styles -/// -/// Interface for producers of audio rendering ranges, consumers should implement -/// this interface for objects to pass to producers. -class AudioRenderingStyleRanges { -public: - /// @brief Add a range to the line - /// @param start First sample index in range - /// @param end One past last sample index in range - /// @param style Style of the range added - virtual void AddRange(int64_t start, int64_t end, AudioRenderingStyle style) = 0; -}; - - - /// @class AudioRendererBitmapCacheBitmapFactory /// @brief Produces wxBitmap objects for DataBlockCache storage for the audio renderer struct AudioRendererBitmapCacheBitmapFactory { diff --git a/aegisub/src/audio_renderer_spectrum.cpp b/aegisub/src/audio_renderer_spectrum.cpp index 020d634d7..99f18c88d 100644 --- a/aegisub/src/audio_renderer_spectrum.cpp +++ b/aegisub/src/audio_renderer_spectrum.cpp @@ -36,6 +36,18 @@ #include "config.h" +#include "audio_renderer_spectrum.h" + +#include "audio_colorscheme.h" +#ifndef WITH_FFTW +#include "fft.h" +#endif +#include "include/aegisub/audio_provider.h" +#include "main.h" +#include "utils.h" + +#include + #ifndef AGI_PRE #include @@ -44,22 +56,6 @@ #include #endif -#include - -#include "block_cache.h" -#include "include/aegisub/audio_provider.h" -#include "audio_colorscheme.h" -#include "audio_renderer.h" -#include "audio_renderer_spectrum.h" - -#ifdef WITH_FFTW -#include -#else -#include "fft.h" -#endif -#include "main.h" -#include "utils.h" - /// Allocates blocks of derived data for the audio spectrum struct AudioSpectrumCacheBlockFactory { /// Pointer back to the owning spectrum renderer @@ -99,36 +95,31 @@ struct AudioSpectrumCacheBlockFactory { /// @brief Cache for audio spectrum frequency-power data class AudioSpectrumCache - : public DataBlockCache { +: public DataBlockCache { public: AudioSpectrumCache(size_t block_count, AudioSpectrumRenderer *renderer) - : DataBlockCache( + : DataBlockCache( block_count, AudioSpectrumCacheBlockFactory(renderer)) { } }; - - AudioSpectrumRenderer::AudioSpectrumRenderer() -: AudioRendererBitmapProvider() -, cache(0) -, colors_normal(12) -, colors_selected(12) +: colors_normal(new AudioColorScheme(12)) +, colors_selected(new AudioColorScheme(12)) +, colors_inactive(new AudioColorScheme(12)) , derivation_size(8) , derivation_dist(8) #ifdef WITH_FFTW , dft_plan(0) , dft_input(0) , dft_output(0) -#else -, fft_scratch(0) #endif -, audio_scratch(0) { - colors_normal.InitIcyBlue(AudioStyle_Normal); - colors_selected.InitIcyBlue(AudioStyle_Selected); + colors_normal->InitIcyBlue(AudioStyle_Normal); + colors_selected->InitIcyBlue(AudioStyle_Selected); + colors_inactive->InitIcyBlue(AudioStyle_Inactive); } AudioSpectrumRenderer::~AudioSpectrumRenderer() @@ -138,14 +129,8 @@ AudioSpectrumRenderer::~AudioSpectrumRenderer() RecreateCache(); } - void AudioSpectrumRenderer::RecreateCache() { - delete cache; - delete[] audio_scratch; - cache = 0; - audio_scratch = 0; - #ifdef WITH_FFTW if (dft_plan) { @@ -156,15 +141,12 @@ void AudioSpectrumRenderer::RecreateCache() dft_input = 0; dft_output = 0; } -#else - delete[] fft_scratch; - fft_scratch = 0; #endif if (provider) { size_t block_count = (size_t)((provider->GetNumSamples() + (size_t)(1<> derivation_dist); - cache = new AudioSpectrumCache(block_count, this); + cache.reset(new AudioSpectrumCache(block_count, this)); #ifdef WITH_FFTW dft_input = (double*)fftw_malloc(sizeof(double) * (2< +void AudioSpectrumRenderer::ConvertToFloat(size_t count, T &dest) { + for (size_t si = 0; si < count; ++si) + { + dest[si] = (float)(audio_scratch[si]) / 32768.f; + } +} void AudioSpectrumRenderer::FillBlock(size_t block_index, float *block) { @@ -215,14 +202,10 @@ void AudioSpectrumRenderer::FillBlock(size_t block_index, float *block) assert(block); int64_t first_sample = ((int64_t)block_index) << derivation_dist; - provider->GetAudio(audio_scratch, first_sample, 2 << derivation_size); + provider->GetAudio(&audio_scratch[0], first_sample, 2 << derivation_size); #ifdef WITH_FFTW - // Convert audio data to float range [-1;+1) - for (size_t si = 0; si < (size_t)(2<map(0.0, color_raw); - wxColour col(color_raw[0], color_raw[1], color_raw[2]); - + wxColour col = GetColorScheme(style)->get(0.0f); dc.SetBrush(wxBrush(col)); dc.SetPen(wxPen(col)); dc.DrawRectangle(rect); } - void AudioSpectrumRenderer::AgeCache(size_t max_size) { if (cache) cache->Age(max_size); } - +const AudioColorScheme *AudioSpectrumRenderer::GetColorScheme(AudioRenderingStyle style) const +{ + switch (style) + { + case AudioStyle_Selected: return colors_selected.get(); + case AudioStyle_Inactive: return colors_inactive.get(); + default: return colors_normal.get(); + } +} diff --git a/aegisub/src/audio_renderer_spectrum.h b/aegisub/src/audio_renderer_spectrum.h index ba6722a1c..93bfd3b5a 100644 --- a/aegisub/src/audio_renderer_spectrum.h +++ b/aegisub/src/audio_renderer_spectrum.h @@ -37,21 +37,21 @@ #ifndef AGI_PRE #include +#include #endif +#include "audio_renderer.h" + +#include + #ifdef WITH_FFTW #include #endif - - -// Specified and implemented in cpp file, to avoid pulling in too much -// complex template code in this header. +class AudioColorScheme; class AudioSpectrumCache; struct AudioSpectrumCacheBlockFactory; - - /// @class AudioSpectrumRenderer /// @brief Render frequency-power spectrum graphs for audio data. /// @@ -61,13 +61,16 @@ class AudioSpectrumRenderer : public AudioRendererBitmapProvider { friend struct AudioSpectrumCacheBlockFactory; /// Internal cache management for the spectrum - AudioSpectrumCache *cache; + agi::scoped_ptr cache; /// Colour table used for regular rendering - AudioColorScheme colors_normal; + agi::scoped_ptr colors_normal; /// Colour table used for rendering the audio selection - AudioColorScheme colors_selected; + agi::scoped_ptr colors_selected; + + /// Colour table used for rendering inactive lines + agi::scoped_ptr colors_inactive; /// Binary logarithm of number of samples to use in deriving frequency-power data size_t derivation_size; @@ -84,7 +87,7 @@ class AudioSpectrumRenderer : public AudioRendererBitmapProvider { /// @brief Recreates the cache /// /// To be called when the number of blocks in cache might have changed, - // eg. new audio provider or new resolution. + /// e.g. new audio provider or new resolution. void RecreateCache(); /// @brief Fill a block with frequency-power data for a time range @@ -92,6 +95,12 @@ class AudioSpectrumRenderer : public AudioRendererBitmapProvider { /// @param[out] block Address to write the data to void FillBlock(size_t block_index, float *block); + /// @brief Convert audio data to float range [-1;+1) + /// @param count Samples to convert + /// @param dest Buffer to fill + template + void ConvertToFloat(size_t count, T &dest); + #ifdef WITH_FFTW /// FFTW plan data fftw_plan dft_plan; @@ -101,21 +110,24 @@ class AudioSpectrumRenderer : public AudioRendererBitmapProvider { fftw_complex *dft_output; #else /// Pre-allocated scratch area for doing FFT derivations - float *fft_scratch; + std::vector fft_scratch; #endif /// Pre-allocated scratch area for storing raw audio data - int16_t *audio_scratch; + std::vector audio_scratch; + + /// Get the color scheme for a rendering style + const AudioColorScheme *GetColorScheme(AudioRenderingStyle style) const; public: /// @brief Constructor AudioSpectrumRenderer(); /// @brief Destructor - virtual ~AudioSpectrumRenderer(); + ~AudioSpectrumRenderer(); /// @brief Render a range of audio spectrum - /// @param bmp [in,out] Bitmap to render into, also carries lenght information + /// @param bmp [in,out] Bitmap to render into, also carries length information /// @param start First column of pixel data in display to render /// @param style Style to render audio in void Render(wxBitmap &bmp, int start, AudioRenderingStyle style); diff --git a/aegisub/src/audio_renderer_waveform.cpp b/aegisub/src/audio_renderer_waveform.cpp index bdc944ae3..3df7facd7 100644 --- a/aegisub/src/audio_renderer_waveform.cpp +++ b/aegisub/src/audio_renderer_waveform.cpp @@ -53,10 +53,12 @@ AudioWaveformRenderer::AudioWaveformRenderer() : AudioRendererBitmapProvider() , colors_normal(6) , colors_selected(6) +, colors_inactive(6) , audio_buffer(0) { - colors_normal.InitIcyBlue_Normal(); - colors_selected.InitIcyBlue_Selected(); + colors_normal.InitIcyBlue(AudioStyle_Normal); + colors_selected.InitIcyBlue(AudioStyle_Selected); + colors_inactive.InitIcyBlue(AudioStyle_Inactive); } @@ -72,7 +74,7 @@ void AudioWaveformRenderer::Render(wxBitmap &bmp, int start, AudioRenderingStyle wxRect rect(wxPoint(0, 0), bmp.GetSize()); int midpoint = rect.height / 2; - AudioColorScheme *pal = style == AudioStyle_Selected ? &colors_selected : &colors_normal; + const AudioColorScheme *pal = GetColorScheme(style); // Fill the background dc.SetBrush(wxBrush(pal->get(0.0f))); @@ -137,8 +139,7 @@ void AudioWaveformRenderer::Render(wxBitmap &bmp, int start, AudioRenderingStyle void AudioWaveformRenderer::RenderBlank(wxDC &dc, const wxRect &rect, AudioRenderingStyle style) { - AudioColorScheme *pal = style == AudioStyle_Selected ? &colors_selected : &colors_normal; - + const AudioColorScheme *pal = GetColorScheme(style); wxColor line(pal->get(1.0)); wxColor bg(pal->get(0.0)); @@ -155,19 +156,24 @@ void AudioWaveformRenderer::RenderBlank(wxDC &dc, const wxRect &rect, AudioRende dc.DrawLine(rect.x, rect.y+halfheight, rect.x+rect.width, rect.y+halfheight); } - - void AudioWaveformRenderer::OnSetProvider() { delete[] audio_buffer; audio_buffer = 0; } - void AudioWaveformRenderer::OnSetSamplesPerPixel() { delete[] audio_buffer; audio_buffer = 0; } - +const AudioColorScheme *AudioWaveformRenderer::GetColorScheme(AudioRenderingStyle style) const +{ + switch (style) + { + case AudioStyle_Selected: return &colors_selected; + case AudioStyle_Inactive: return &colors_inactive; + default: return &colors_normal; + } +} diff --git a/aegisub/src/audio_renderer_waveform.h b/aegisub/src/audio_renderer_waveform.h index 7b7cc24e0..6d91ce533 100644 --- a/aegisub/src/audio_renderer_waveform.h +++ b/aegisub/src/audio_renderer_waveform.h @@ -35,9 +35,9 @@ /// /// Render a waveform display of PCM audio data +#ifndef AGI_PRE #include - - +#endif class AudioWaveformRenderer : public AudioRendererBitmapProvider { /// Colour table used for regular rendering @@ -46,22 +46,27 @@ class AudioWaveformRenderer : public AudioRendererBitmapProvider { /// Colour table used for rendering the audio selection AudioColorScheme colors_selected; + /// Colour table used for rendering inactive lines + AudioColorScheme colors_inactive; + /// Pre-allocated buffer for audio fetched from provider char *audio_buffer; -protected: - virtual void OnSetProvider(); - virtual void OnSetSamplesPerPixel(); + /// Get the color scheme for a rendering style + const AudioColorScheme *GetColorScheme(AudioRenderingStyle style) const; + + void OnSetProvider(); + void OnSetSamplesPerPixel(); public: /// @brief Constructor AudioWaveformRenderer(); /// @brief Destructor - virtual ~AudioWaveformRenderer(); + ~AudioWaveformRenderer(); /// @brief Render a range of audio waveform - /// @param bmp [in,out] Bitmap to render into, also carries lenght information + /// @param bmp [in,out] Bitmap to render into, also carries length information /// @param start First column of pixel data in display to render /// @param style Style to render audio in void Render(wxBitmap &bmp, int start, AudioRenderingStyle style);