diff --git a/CMakeLists.txt b/CMakeLists.txt index 50cd1cd3b..0c2273acc 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -31,11 +31,13 @@ if(WIN32) find_path(LIBXML_INCLUDE_DIRS libxml/parser.h PATH_SUFFIXES libxml libxml2) find_library(GSTREAMER_LIBRARIES gstreamer-0.10) + find_library(GSTREAMER_BASE_LIBRARIES gstbase-0.10) find_library(GLIB_LIBRARIES glib-2.0) find_library(GOBJECT_LIBRARIES gobject-2.0) else(WIN32) pkg_check_modules(TAGLIB taglib) pkg_check_modules(GSTREAMER gstreamer-0.10) + pkg_check_modules(GSTREAMER_BASE gstreamer-base-0.10) if (TAGLIB_VERSION VERSION_LESS 1.6) message(FATAL_ERROR "Taglib version 1.6 or greater is required") diff --git a/data/data.qrc b/data/data.qrc index 35e8ee9c9..5a7f9ce0f 100644 --- a/data/data.qrc +++ b/data/data.qrc @@ -76,5 +76,6 @@ osd_shadow_corner.png osd_shadow_edge.png schema-6.sql + list-add.png diff --git a/data/list-add.png b/data/list-add.png new file mode 100644 index 000000000..e029787c7 Binary files /dev/null and b/data/list-add.png differ diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index c3833a2fc..48b415074 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -13,6 +13,7 @@ set(CLEMENTINE-SOURCES playlistitem.cpp engines/enginebase.cpp engines/gstengine.cpp + engines/gstequalizer.cpp analyzers/baranalyzer.cpp analyzers/analyzerbase.cpp fht.cpp @@ -68,6 +69,8 @@ set(CLEMENTINE-SOURCES osdpretty.cpp playlistdelegates.cpp groupbydialog.cpp + equalizer.cpp + equalizerslider.cpp ) # Header files that have Q_OBJECT in @@ -128,6 +131,8 @@ set(CLEMENTINE-MOC-HEADERS osdpretty.h playlistdelegates.h groupbydialog.h + equalizer.h + equalizerslider.h ) # UI files @@ -149,6 +154,8 @@ set(CLEMENTINE-UI playlistsequence.ui osdpretty.ui groupbydialog.ui + equalizer.ui + equalizerslider.ui ) # Resource files @@ -296,6 +303,7 @@ target_link_libraries(clementine_lib ${GOBJECT_LIBRARIES} ${GLIB_LIBRARIES} ${GSTREAMER_LIBRARIES} + ${GSTREAMER_BASE_LIBRARIES} ${TAGLIB_LIBRARIES} ${QT_LIBRARIES} ) diff --git a/src/engines/enginebase.h b/src/engines/enginebase.h index a75137484..da423c6b6 100644 --- a/src/engines/enginebase.h +++ b/src/engines/enginebase.h @@ -204,20 +204,6 @@ namespace Engine */ void setXFadeNextTrack( bool enable ) { m_xfadeNextTrack = enable; } - /** Set whether equalizer is enabled - * You don't need to cache the parameters, setEqualizerParameters is called straight after this - * function, _always_. - */ - virtual void setEqualizerEnabled( bool ) {}; - - /** Set equalizer parameters, all in range -100..100, where 0 = no adjustment - * @param preamp the preamplification value - * @param bandGains a list of 10 integers, ascending in frequency, the exact frequencies you amplify - * are not too-important at this time - */ - virtual void setEqualizerParameters( int /*preamp*/, const QList &/*bandGains*/ ) {}; - - /** Tries to retrieve metadata for the given url (called only if url * is not in the collection). The intended usage is to retrieve * information for AudiCD tracks when they are added to the playlist @@ -260,6 +246,19 @@ namespace Engine public slots: virtual void ReloadSettings() {} + /** Set whether equalizer is enabled + * You don't need to cache the parameters, setEqualizerParameters is called straight after this + * function, _always_. + */ + virtual void setEqualizerEnabled( bool ) {}; + + /** Set equalizer parameters, all in range -100..100, where 0 = no adjustment + * @param preamp the preamplification value + * @param bandGains a list of 10 integers, ascending in frequency, the exact frequencies you amplify + * are not too-important at this time + */ + virtual void setEqualizerParameters( int /*preamp*/, const QList &/*bandGains*/ ) {}; + protected: Base(); diff --git a/src/engines/gstengine.cpp b/src/engines/gstengine.cpp index 027318a6a..8bcd5d66e 100644 --- a/src/engines/gstengine.cpp +++ b/src/engines/gstengine.cpp @@ -21,8 +21,8 @@ #define DEBUG_PREFIX "Gst-Engine" -#include "enginebase.h" #include "gstengine.h" +#include "gstequalizer.h" #include #include @@ -536,8 +536,7 @@ bool GstEngine::load(const QUrl& url, bool stream) { setVolume(m_volume); setEqualizerEnabled(equalizer_enabled_); - if (equalizer_enabled_) - setEqualizerParameters(equalizer_preamp_, equalizer_gains_); + setEqualizerParameters(equalizer_preamp_, equalizer_gains_); return true; } @@ -602,33 +601,31 @@ void GstEngine::seek( uint ms ) { gst_element_get_state(gst_pipeline_, NULL, NULL, 100*GST_MSECOND); } -void GstEngine::setEqualizerEnabled( bool enabled ) { +void GstEngine::setEqualizerEnabled(bool enabled) { equalizer_enabled_= enabled; RETURN_IF_PIPELINE_EMPTY; - //g_object_set( G_OBJECT( m_gst_equalizer ), "active", enabled, NULL ); + g_object_set(G_OBJECT(gst_equalizer_), "active", enabled, NULL); } -void GstEngine::setEqualizerParameters( int preamp, const QList& bandGains ) { +void GstEngine::setEqualizerParameters( int preamp, const QList& band_gains ) { equalizer_preamp_ = preamp; - equalizer_gains_ = bandGains; + equalizer_gains_ = band_gains; RETURN_IF_PIPELINE_EMPTY; - // BEGIN Preamp - //g_object_set( G_OBJECT( m_gst_equalizer ) , "preamp", ( preamp + 100 ) / 2 , NULL ); - // END + // Preamp + g_object_set(G_OBJECT(gst_equalizer_), "preamp", ( preamp + 100 ) / 2, NULL); - // BEGIN Gains + // Gains vector gains_temp; - gains_temp.resize( bandGains.count() ); - for ( int i = 0; i < bandGains.count(); i++ ) - gains_temp[i] = ( bandGains.at( i ) + 100 ) / 2; + gains_temp.resize( band_gains.count() ); + for ( int i = 0; i < band_gains.count(); i++ ) + gains_temp[i] = band_gains.at( i ) + 100; - //g_object_set( G_OBJECT( m_gst_equalizer ), "gain", &gainsTemp, NULL ); - // END + g_object_set(G_OBJECT(gst_equalizer_), "gain", &gains_temp, NULL); } void GstEngine::setVolumeSW( uint percent ) { @@ -763,8 +760,9 @@ bool GstEngine::CreatePipeline() { return false; } - /*m_gst_equalizer = GST_ELEMENT( gst_equalizer_new() ); - gst_bin_add( GST_BIN( gst_audiobin_ ), m_gst_equalizer );*/ + gst_equalizer_ = GST_ELEMENT(gst_equalizer_new()); + gst_bin_add(GST_BIN(gst_audiobin_), gst_equalizer_); + if ( !( gst_audioconvert_ = CreateElement( "audioconvert", gst_audiobin_ ) ) ) { return false; } if ( !( gst_identity_ = CreateElement( "identity", gst_audiobin_ ) ) ) { return false; } if ( !( gst_volume_ = CreateElement( "volume", gst_audiobin_ ) ) ) { return false; } @@ -787,12 +785,12 @@ bool GstEngine::CreatePipeline() { "width", G_TYPE_INT, 16, "signed", G_TYPE_BOOLEAN, true, NULL); - gst_element_link_filtered(gst_audioconvert_, gst_identity_, caps); + gst_element_link_filtered(gst_audioconvert_, gst_equalizer_, caps); gst_caps_unref(caps); /* link elements */ - gst_element_link_many( gst_identity_, gst_volume_, gst_audioscale_, - gst_audiosink_, NULL ); + gst_element_link_many( gst_equalizer_, gst_identity_, gst_volume_, + gst_audioscale_, gst_audiosink_, NULL ); gst_bin_add( GST_BIN(gst_pipeline_), gst_audiobin_); //gst_bus_set_sync_handler(gst_pipeline_get_bus(GST_PIPELINE(gst_pipeline_)), bus_cb, NULL); diff --git a/src/engines/gstengine.h b/src/engines/gstengine.h index ec5f23ebb..a1c3bca22 100644 --- a/src/engines/gstengine.h +++ b/src/engines/gstengine.h @@ -169,7 +169,7 @@ class GstEngine : public Engine::Base { GstElement* gst_audiobin_; GstElement* gst_audioconvert_; - //GstElement* gst_equalizer_; + GstElement* gst_equalizer_; GstElement* gst_identity_; GstElement* gst_volume_; GstElement* gst_audioscale_; diff --git a/src/engines/gstequalizer.cpp b/src/engines/gstequalizer.cpp new file mode 100644 index 000000000..2da70b6ae --- /dev/null +++ b/src/engines/gstequalizer.cpp @@ -0,0 +1,340 @@ +// PCM time-domain equalizer +// (c) 2002 Felipe Rivera +// (c) 2004 Mark Kretschmann +// (c) 2006 Jakub Stachowski +// License: GPL V2 + + +#include "gstequalizer.h" +#include "iir_cf.h" // IIR filter coefficients + +#include +#include +#include + +#include + + +GST_DEBUG_CATEGORY_STATIC ( gst_equalizer_debug ); +#define GST_CAT_DEFAULT gst_equalizer_debug + +/* signals and args */ +enum { + LAST_SIGNAL +}; + +enum { + ARG_0, + ARG_ACTIVE, + ARG_PREAMP, + ARG_GAIN +}; + +static GstElementDetails gst_equalizer_details = { + const_cast("Equalizer"), + const_cast("Filter/Effect/Audio"), + const_cast("Parametric Equalizer"), + const_cast("Mark Kretschmann ") }; + +GstStaticPadTemplate sink_template = + GST_STATIC_PAD_TEMPLATE ( (gchar*) "sink", + GST_PAD_SINK, + GST_PAD_ALWAYS, + GST_STATIC_CAPS ( + "audio/x-raw-int, " \ + "rate = (int) [ 1, MAX ], " \ + "channels = (int) [ 1, MAX ], " \ + "endianness = (int) { LITTLE_ENDIAN, BIG_ENDIAN }, " \ + "width = (int) 16, " \ + "depth = (int) 16, " \ + "signed = (bool) TRUE " + ) + ); + +GstStaticPadTemplate src_template = + GST_STATIC_PAD_TEMPLATE ( (gchar*) "src", + GST_PAD_SRC, + GST_PAD_ALWAYS, + GST_STATIC_CAPS ( + "audio/x-raw-int, " \ + "rate = (int) [ 1, MAX ], " \ + "channels = (int) [ 1, MAX ], " \ + "endianness = (int) { LITTLE_ENDIAN, BIG_ENDIAN }, " \ + "width = (int) 16, " \ + "depth = (int) 16, " \ + "signed = (bool) TRUE" + ) + ); + +// static guint gst_equalizer_signals[ LAST_SIGNAL ] = { 0 }; + +#define _do_init(bla) \ + GST_DEBUG_CATEGORY_INIT (gst_equalizer_debug, "equalizer", 0, "equalizer element"); + +GST_BOILERPLATE_FULL ( GstEqualizer, gst_equalizer, GstBaseTransform, GST_TYPE_BASE_TRANSFORM, _do_init ); + +static gboolean gst_equalizer_set_caps (GstBaseTransform * base, GstCaps * incaps, GstCaps * outcaps); +static GstFlowReturn gst_equalizer_transform_ip (GstBaseTransform * base, GstBuffer * outbuf); + +///////////////////////////////////////////////////////////////////////////////////// +// INIT +///////////////////////////////////////////////////////////////////////////////////// + +void +gst_equalizer_base_init ( gpointer g_class ) +{ + qDebug() << __PRETTY_FUNCTION__; + + GstElementClass * gstelement_class = GST_ELEMENT_CLASS ( g_class ); + gst_element_class_add_pad_template (gstelement_class, + gst_static_pad_template_get (&src_template)); + gst_element_class_add_pad_template (gstelement_class, + gst_static_pad_template_get (&sink_template)); + gst_element_class_set_details ( gstelement_class, &gst_equalizer_details ); +} + + +void +gst_equalizer_class_init ( GstEqualizerClass * klass ) +{ + qDebug() << __PRETTY_FUNCTION__; + + GObjectClass* gobject_class; + gobject_class = G_OBJECT_CLASS( klass ); + + gobject_class->set_property = gst_equalizer_set_property; + gobject_class->get_property = gst_equalizer_get_property; + + g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_ACTIVE, g_param_spec_boolean ("active", "active", "active", false, (GParamFlags)G_PARAM_READWRITE)); + g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_PREAMP, g_param_spec_int ("preamp", "preamp", "preamp", 0, 100, 0, (GParamFlags)G_PARAM_READWRITE)); + g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_GAIN, g_param_spec_pointer ("gain", "gain", "gain", (GParamFlags)G_PARAM_WRITABLE)); + GST_BASE_TRANSFORM_CLASS (klass)->transform_ip = + GST_DEBUG_FUNCPTR (gst_equalizer_transform_ip); + GST_BASE_TRANSFORM_CLASS (klass)->set_caps = + GST_DEBUG_FUNCPTR (gst_equalizer_set_caps); +} + + +void +gst_equalizer_init ( GstEqualizer* obj, GstEqualizerClass * klass ) +{ + qDebug() << __PRETTY_FUNCTION__; + + // Properties + obj->active = false; +} + + +///////////////////////////////////////////////////////////////////////////////////// +// PUBLIC METHODS +///////////////////////////////////////////////////////////////////////////////////// + +static gboolean +gst_equalizer_set_caps (GstBaseTransform * base, GstCaps * incaps, GstCaps * outcaps) +{ + GstEqualizer* obj = GST_EQUALIZER (base); + GstStructure* structure = gst_caps_get_structure (incaps, 0); + + /* Since we're an audio filter, we want to handle raw audio + * and from that audio type, we need to get the samplerate and + * number of channels. */ + + gst_structure_get_int (structure, "rate", &obj->samplerate); + gst_structure_get_int (structure, "channels", &obj->channels); + // Load the correct filter table according to the sampling rate + set_filters( obj ); + /* Zero the history arrays */ + memset(obj->data_history, 0, sizeof(sXYData) * EQ_MAX_BANDS * EQ_CHANNELS); + qDebug() << "Samplerate " << obj->samplerate << ", channels: " << obj->channels; + return TRUE; +} + + + +void +gst_equalizer_set_property ( GObject * object, guint prop_id, const GValue * value, + GParamSpec * pspec ) +{ + /* it's not null if we got it, but it might not be ours */ + g_return_if_fail ( GST_IS_EQUALIZER ( object ) ); + + GstEqualizer* obj = GST_EQUALIZER ( object ); + std::vector* gains; + + switch ( prop_id ) + { + case ARG_ACTIVE: + obj->active = g_value_get_boolean (value); + break; + + case ARG_PREAMP: + for ( int chan = 0; chan < EQ_CHANNELS; chan++ ) + obj->preamp[chan] = (float)g_value_get_int(value) * 0.01; + break; + + case ARG_GAIN: + gains = (std::vector*) g_value_get_pointer(value); + for ( int band = 0; band < BAND_NUM; band++ ) + for ( int chan = 0; chan < EQ_CHANNELS; chan++ ) + obj->gain[band][chan] = (float)(*gains)[band] * 0.012 - 0.2; + break; + + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID ( object, prop_id, pspec ); + break; + } +} + + +void +gst_equalizer_get_property ( GObject * object, guint prop_id, GValue * value, GParamSpec * pspec ) +{ + /* it's not null if we got it, but it might not be ours */ + g_return_if_fail ( GST_IS_EQUALIZER ( object ) ); + + GstEqualizer* obj = GST_EQUALIZER ( object ); + + switch ( prop_id ) + { + case ARG_ACTIVE: + g_value_set_boolean (value, obj->active); + break; + + case ARG_PREAMP: + g_value_set_int(value, obj->preamp[0] * 100); + break; + + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID ( object, prop_id, pspec ); + break; + } +} + + +void +set_filters( GstEqualizer* obj ) +{ + switch(obj->samplerate) + { + case 11025: + obj->iir_cf = iir_cf10_11k_11025; + break; + + case 22050: + obj->iir_cf = iir_cf10_22k_22050; + break; + + case 48000: + obj->iir_cf = iir_cf10_48000; + break; + + default: + obj->iir_cf = iir_cf10_44100; + break; + } +} + +static GstFlowReturn +gst_equalizer_transform_ip (GstBaseTransform * base, GstBuffer * outbuf) +{ + GstEqualizer* obj = GST_EQUALIZER ( base ); + + if ( !obj->active ) return GST_FLOW_OK; + + gint16 *data = (gint16*)GST_BUFFER_DATA ( outbuf ); + gint length = GST_BUFFER_SIZE( outbuf ); + + /* Indexes for the history arrays + * These have to be kept between calls to this function + * hence they are static */ + static gint i = 0, j = 2, k = 1; + + gint index, band, channel; + gint halflength; + float out[EQ_CHANNELS], pcm[EQ_CHANNELS]; + float tempfloat; + + /** + * IIR filter equation is + * y[n] = 2 * (alpha*(x[n]-x[n-2]) + gamma*y[n-1] - beta*y[n-2]) + * + * NOTE: The 2 factor was introduced in the coefficients to save + * a multiplication + * + * This algorithm cascades two filters to get nice filtering + * at the expense of extra CPU cycles + */ + /* 16bit, 2 bytes per sample, so divide by two the length of + * the buffer (length is in bytes) + */ + halflength = (length >> 1); + for (index = 0; index < halflength; index+=2) + { + /* For each channel */ + for (channel = 0; channel < obj->channels; channel++) + { + pcm[channel] = data[index+channel]; + /* Preamp gain */ + pcm[channel] *= obj->preamp[channel]; + + out[channel] = 0.; + /* For each band */ + for (band = 0; band < BAND_NUM; band++) + { + /* Store Xi(n) */ + obj->data_history[band][channel].x[i] = pcm[channel]; + /* Calculate and store Yi(n) */ + obj->data_history[band][channel].y[i] = + ( + /* = alpha * [x(n)-x(n-2)] */ + obj->iir_cf[band].alpha * ( obj->data_history[band][channel].x[i] + - obj->data_history[band][channel].x[k]) + /* + gamma * y(n-1) */ + + obj->iir_cf[band].gamma * obj->data_history[band][channel].y[j] + /* - beta * y(n-2) */ + - obj->iir_cf[band].beta * obj->data_history[band][channel].y[k] + ); + /* + * The multiplication by 2.0 was 'moved' into the coefficients to save + * CPU cycles here */ + /* Apply the gain */ + out[channel] += obj->data_history[band][channel].y[i]*obj->gain[band][channel]; // * 2.0; + } /* For each band */ + + /* Volume stuff + Scale down original PCM sample and add it to the filters + output. This substitutes the multiplication by 0.25 + Go back to use the floating point multiplication before the + conversion to give more dynamic range + */ + out[channel] += pcm[channel]*0.25; + + /* Round and convert to integer and limit the output */ + tempfloat = out[channel] < -32768.0 ? -32768.0 : out[channel]; + tempfloat = tempfloat > 32767.0 ? 32767.0 : tempfloat; + data[index+channel] = (gint)rintf(tempfloat); + + } /* For each channel */ + + i++; j++; k++; + + /* Wrap around the indexes */ + if (i == 3) i = 0; + else if (j == 3) j = 0; + else k = 0; + }/* For each pair of samples */ + + return GST_FLOW_OK; +} + + + +GstEqualizer* +gst_equalizer_new () +{ + GstEqualizer* obj = GST_EQUALIZER ( g_object_new ( GST_TYPE_EQUALIZER, NULL ) ); + gst_object_set_name( (GstObject*) obj, "Equalizer" ); + + return obj; +} + diff --git a/src/engines/gstequalizer.h b/src/engines/gstequalizer.h new file mode 100644 index 000000000..f4325451f --- /dev/null +++ b/src/engines/gstequalizer.h @@ -0,0 +1,91 @@ +// PCM time-domain equalizer +// (c) 2002 Felipe Rivera +// (c) 2004 Mark Kretschmann +// License: GPL V2 + +#ifndef AMAROK_GST_EQUALIZER_H +#define AMAROK_GST_EQUALIZER_H + +#include +#include + +G_BEGIN_DECLS + +#define BAND_NUM 10 +#define EQ_MAX_BANDS 10 +#define EQ_CHANNELS 2 + +#define GST_TYPE_EQUALIZER \ + (gst_equalizer_get_type()) +#define GST_EQUALIZER(obj) \ + (G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_EQUALIZER,GstEqualizer)) +#define GST_EQUALIZER_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_EQUALIZER,GstEqualizerClass)) +#define GST_IS_EQUALIZER(obj) \ + (G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_EQUALIZER)) +#define GST_IS_EQUALIZER_CLASS(obj) \ + (G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_EQUALIZER)) + +typedef struct _GstEqualizer GstEqualizer; +typedef struct _GstEqualizerClass GstEqualizerClass; + +// Floating point +typedef struct +{ + float beta; + float alpha; + float gamma; +} sIIRCoefficients; + +/* Coefficient history for the IIR filter */ +typedef struct +{ + float x[3]; /* x[n], x[n-1], x[n-2] */ + float y[3]; /* y[n], y[n-1], y[n-2] */ +} sXYData; + + +struct _GstEqualizer +{ + // Do not remove + GstBaseTransform element; + + GstPad *srcpad; + GstPad *sinkpad; + + int samplerate; + int channels; + + // Properties + bool active; + // Gain for each band + // values should be between -0.2 and 1.0 + float gain[EQ_MAX_BANDS][EQ_CHANNELS] __attribute__((aligned)); + // Volume gain + // values should be between 0.0 and 1.0 + float preamp[EQ_CHANNELS] __attribute__((aligned)); + + // Coefficients + sIIRCoefficients* iir_cf; + + sXYData data_history[EQ_MAX_BANDS][EQ_CHANNELS] __attribute__((aligned)); +}; + +struct _GstEqualizerClass +{ + GstBaseTransformClass parent_class; + + /* signals */ +}; + +void gst_equalizer_set_property( GObject * object, guint prop_id, const GValue * value, GParamSpec * pspec ); +void gst_equalizer_get_property( GObject * object, guint prop_id, GValue * value, GParamSpec * pspec ); +void set_filters( GstEqualizer* obj ); +GType gst_equalizer_get_type( void ); +GstEqualizer* gst_equalizer_new(); + + +G_END_DECLS + + +#endif /* AMAROK_GST_EQUALIZER_H */ diff --git a/src/engines/iir_cf.h b/src/engines/iir_cf.h new file mode 100644 index 000000000..ef3341e7b --- /dev/null +++ b/src/engines/iir_cf.h @@ -0,0 +1,433 @@ +// IIR filter coefficient tables + + +/* BETA, ALPHA, GAMMA */ +static sIIRCoefficients iir_cf10_11k_11025[] __attribute__((aligned)) = { + /* 31 Hz*/ +{ 9.8758524689e-01, 6.2073765555e-03, 1.9872750693e+00 }, + /* 62 Hz*/ +{ 9.7532461998e-01, 1.2337690008e-02, 1.9740916593e+00 }, + /* 125 Hz*/ +{ 9.5087485437e-01, 2.4562572817e-02, 1.9459267562e+00 }, + /* 250 Hz*/ +{ 9.0416308662e-01, 4.7918456688e-02, 1.8848691023e+00 }, + /* 500 Hz*/ +{ 8.1751373987e-01, 9.1243130064e-02, 1.7442229115e+00 }, + /* 1k Hz*/ +{ 6.6840529852e-01, 1.6579735074e-01, 1.4047189863e+00 }, + /* 2k Hz*/ +{ 4.4858358977e-01, 2.7570820511e-01, 6.0517475334e-01 }, + /* 3k Hz*/ +{ 3.1012671838e-01, 3.4493664081e-01, -1.8141012760e-01 }, + /* 4k Hz*/ +{ 2.4198119087e-01, 3.7900940457e-01, -8.0845085113e-01 }, + /* 5.5k Hz*/ +{ 3.3453245058e-01, 3.3273377471e-01, -1.3344985880e+00 }, +}; +static sIIRCoefficients iir_cf10_22k_22050[] __attribute__((aligned)) = { + /* 31 Hz*/ +{ 9.9377323686e-01, 3.1133815717e-03, 1.9936954495e+00 }, + /* 62 Hz*/ +{ 9.8758524689e-01, 6.2073765555e-03, 1.9872750693e+00 }, + /* 125 Hz*/ +{ 9.7512812040e-01, 1.2435939802e-02, 1.9738753198e+00 }, + /* 250 Hz*/ +{ 9.5087485437e-01, 2.4562572817e-02, 1.9459267562e+00 }, + /* 500 Hz*/ +{ 9.0416308662e-01, 4.7918456688e-02, 1.8848691023e+00 }, + /* 1k Hz*/ +{ 8.1751373987e-01, 9.1243130064e-02, 1.7442229115e+00 }, + /* 2k Hz*/ +{ 6.6840529852e-01, 1.6579735074e-01, 1.4047189863e+00 }, + /* 4k Hz*/ +{ 4.4858358977e-01, 2.7570820511e-01, 6.0517475334e-01 }, + /* 8k Hz*/ +{ 2.4198119087e-01, 3.7900940457e-01, -8.0845085113e-01 }, + /* 11k Hz*/ +{ 3.3453245058e-01, 3.3273377471e-01, -1.3344985880e+00 }, +}; +static sIIRCoefficients iir_cforiginal10_44100[] __attribute__((aligned)) = { + /* 60 Hz*/ +{ 9.9397349481e-01, 3.0132525945e-03, 1.9939006377e+00 }, + /* 170 Hz*/ +{ 9.8301906957e-01, 8.4904652142e-03, 1.9824374272e+00 }, + /* 310 Hz*/ +{ 9.6925150511e-01, 1.5374247445e-02, 1.9673310395e+00 }, + /* 600 Hz*/ +{ 9.4134330314e-01, 2.9328348430e-02, 1.9342541736e+00 }, + /* 1k Hz*/ +{ 9.0416308662e-01, 4.7918456688e-02, 1.8848691023e+00 }, + /* 3k Hz*/ +{ 7.3918401009e-01, 1.3040799496e-01, 1.5827185140e+00 }, + /* 6k Hz*/ +{ 5.4688945509e-01, 2.2655527245e-01, 1.0152665639e+00 }, + /* 12k Hz*/ +{ 3.1012671838e-01, 3.4493664081e-01, -1.8141012760e-01 }, + /* 14k Hz*/ +{ 2.6712322292e-01, 3.6643838854e-01, -5.2115143966e-01 }, + /* 16k Hz*/ +{ 2.4198119087e-01, 3.7900940457e-01, -8.0845085113e-01 }, +}; +static sIIRCoefficients iir_cforiginal10_48000[] __attribute__((aligned)) = { + /* 60 Hz*/ +{ 9.9446178985e-01, 2.7691050731e-03, 1.9944002760e+00 }, + /* 170 Hz*/ +{ 9.8438794122e-01, 7.8060293913e-03, 1.9838966333e+00 }, + /* 310 Hz*/ +{ 9.7171413384e-01, 1.4142933081e-02, 1.9700909975e+00 }, + /* 600 Hz*/ +{ 9.4597793866e-01, 2.7011030668e-02, 1.9399791381e+00 }, + /* 1k Hz*/ +{ 9.1159452679e-01, 4.4202736607e-02, 1.8952405706e+00 }, + /* 3k Hz*/ +{ 7.5755317065e-01, 1.2122341468e-01, 1.6237674017e+00 }, + /* 6k Hz*/ +{ 5.7422402554e-01, 2.1288798723e-01, 1.1131444836e+00 }, + /* 12k Hz*/ +{ 3.3730698905e-01, 3.3134650547e-01, 8.1883731790e-17 }, + /* 14k Hz*/ +{ 2.8947322018e-01, 3.5526338991e-01, -3.3374022753e-01 }, + /* 16k Hz*/ +{ 2.5620076154e-01, 3.7189961923e-01, -6.2810038077e-01 }, +}; +static sIIRCoefficients iir_cf10_44100[] __attribute__((aligned)) = { + /* 31 Hz*/ +{ 9.9688176273e-01, 1.5591186337e-03, 1.9968622855e+00 }, + /* 62 Hz*/ +{ 9.9377323686e-01, 3.1133815717e-03, 1.9936954495e+00 }, + /* 125 Hz*/ +{ 9.8748575691e-01, 6.2571215431e-03, 1.9871705722e+00 }, + /* 250 Hz*/ +{ 9.7512812040e-01, 1.2435939802e-02, 1.9738753198e+00 }, + /* 500 Hz*/ +{ 9.5087485437e-01, 2.4562572817e-02, 1.9459267562e+00 }, + /* 1k Hz*/ +{ 9.0416308662e-01, 4.7918456688e-02, 1.8848691023e+00 }, + /* 2k Hz*/ +{ 8.1751373987e-01, 9.1243130064e-02, 1.7442229115e+00 }, + /* 4k Hz*/ +{ 6.6840529852e-01, 1.6579735074e-01, 1.4047189863e+00 }, + /* 8k Hz*/ +{ 4.4858358977e-01, 2.7570820511e-01, 6.0517475334e-01 }, + /* 16k Hz*/ +{ 2.4198119087e-01, 3.7900940457e-01, -8.0845085113e-01 }, +}; +static sIIRCoefficients iir_cf10_48000[] __attribute__((aligned)) = { + /* 31 Hz*/ +{ 9.9713475915e-01, 1.4326204244e-03, 1.9971183163e+00 }, + /* 62 Hz*/ +{ 9.9427771143e-01, 2.8611442874e-03, 1.9942120343e+00 }, + /* 125 Hz*/ +{ 9.8849666727e-01, 5.7516663664e-03, 1.9882304829e+00 }, + /* 250 Hz*/ +{ 9.7712566171e-01, 1.1437169144e-02, 1.9760670839e+00 }, + /* 500 Hz*/ +{ 9.5477456091e-01, 2.2612719547e-02, 1.9505892385e+00 }, + /* 1k Hz*/ +{ 9.1159452679e-01, 4.4202736607e-02, 1.8952405706e+00 }, + /* 2k Hz*/ +{ 8.3100647694e-01, 8.4496761532e-02, 1.7686164442e+00 }, + /* 4k Hz*/ +{ 6.9062328809e-01, 1.5468835596e-01, 1.4641227157e+00 }, + /* 8k Hz*/ +{ 4.7820368352e-01, 2.6089815824e-01, 7.3910184176e-01 }, + /* 16k Hz*/ +{ 2.5620076154e-01, 3.7189961923e-01, -6.2810038077e-01 }, +}; +static sIIRCoefficients iir_cf15_44100[] __attribute__((aligned)) = { + /* 25 Hz*/ +{ 9.9834072702e-01, 8.2963648917e-04, 1.9983280505e+00 }, + /* 40 Hz*/ +{ 9.9734652663e-01, 1.3267366865e-03, 1.9973140908e+00 }, + /* 63 Hz*/ +{ 9.9582396353e-01, 2.0880182333e-03, 1.9957435641e+00 }, + /* 100 Hz*/ +{ 9.9337951306e-01, 3.3102434709e-03, 1.9931771947e+00 }, + /* 160 Hz*/ +{ 9.8942832039e-01, 5.2858398053e-03, 1.9889114258e+00 }, + /* 250 Hz*/ +{ 9.8353109588e-01, 8.2344520610e-03, 1.9822729654e+00 }, + /* 400 Hz*/ +{ 9.7378088082e-01, 1.3109559588e-02, 1.9705764276e+00 }, + /* 630 Hz*/ +{ 9.5901979676e-01, 2.0490101620e-02, 1.9511333590e+00 }, + /* 1k Hz*/ +{ 9.3574903986e-01, 3.2125480071e-02, 1.9161350100e+00 }, + /* 1.6k Hz*/ +{ 8.9923630641e-01, 5.0381846793e-02, 1.8501014162e+00 }, + /* 2.5k Hz*/ +{ 8.4722457681e-01, 7.6387711593e-02, 1.7312785699e+00 }, + /* 4k Hz*/ +{ 7.6755471307e-01, 1.1622264346e-01, 1.4881981417e+00 }, + /* 6.3k Hz*/ +{ 6.6125377473e-01, 1.6937311263e-01, 1.0357747868e+00 }, + /* 10k Hz*/ +{ 5.2683267950e-01, 2.3658366025e-01, 2.2218349322e-01 }, + /* 16k Hz*/ +{ 4.0179628792e-01, 2.9910185604e-01, -9.1248032613e-01 }, +}; +static sIIRCoefficients iir_cf15_48000[] __attribute__((aligned)) = { + /* 25 Hz*/ +{ 9.9847546664e-01, 7.6226668143e-04, 1.9984647656e+00 }, + /* 40 Hz*/ +{ 9.9756184654e-01, 1.2190767289e-03, 1.9975344645e+00 }, + /* 63 Hz*/ +{ 9.9616261379e-01, 1.9186931041e-03, 1.9960947369e+00 }, + /* 100 Hz*/ +{ 9.9391578543e-01, 3.0421072865e-03, 1.9937449618e+00 }, + /* 160 Hz*/ +{ 9.9028307215e-01, 4.8584639242e-03, 1.9898465702e+00 }, + /* 250 Hz*/ +{ 9.8485897264e-01, 7.5705136795e-03, 1.9837962543e+00 }, + /* 400 Hz*/ +{ 9.7588512657e-01, 1.2057436715e-02, 1.9731772447e+00 }, + /* 630 Hz*/ +{ 9.6228521814e-01, 1.8857390928e-02, 1.9556164694e+00 }, + /* 1k Hz*/ +{ 9.4080933132e-01, 2.9595334338e-02, 1.9242054384e+00 }, + /* 1.6k Hz*/ +{ 9.0702059196e-01, 4.6489704022e-02, 1.8653476166e+00 }, + /* 2.5k Hz*/ +{ 8.5868004289e-01, 7.0659978553e-02, 1.7600401337e+00 }, + /* 4k Hz*/ +{ 7.8409610788e-01, 1.0795194606e-01, 1.5450725522e+00 }, + /* 6.3k Hz*/ +{ 6.8332861002e-01, 1.5833569499e-01, 1.1426447155e+00 }, + /* 10k Hz*/ +{ 5.5267518228e-01, 2.2366240886e-01, 4.0186190803e-01 }, + /* 16k Hz*/ +{ 4.1811888447e-01, 2.9094055777e-01, -7.0905944223e-01 }, +}; +static sIIRCoefficients iir_cf25_44100[] __attribute__((aligned)) = { + /* 20 Hz*/ +{ 9.9934037157e-01, 3.2981421662e-04, 1.9993322545e+00 }, + /* 31.5 Hz*/ +{ 9.9896129025e-01, 5.1935487310e-04, 1.9989411587e+00 }, + /* 40 Hz*/ +{ 9.9868118265e-01, 6.5940867495e-04, 1.9986487252e+00 }, + /* 50 Hz*/ +{ 9.9835175161e-01, 8.2412419683e-04, 1.9983010452e+00 }, + /* 80 Hz*/ +{ 9.9736411067e-01, 1.3179446674e-03, 1.9972343673e+00 }, + /* 100 Hz*/ +{ 9.9670622662e-01, 1.6468866919e-03, 1.9965035707e+00 }, + /* 125 Hz*/ +{ 9.9588448566e-01, 2.0577571681e-03, 1.9955679690e+00 }, + /* 160 Hz*/ +{ 9.9473519326e-01, 2.6324033689e-03, 1.9942169198e+00 }, + /* 250 Hz*/ +{ 9.9178600786e-01, 4.1069960678e-03, 1.9905226414e+00 }, + /* 315 Hz*/ +{ 9.8966154150e-01, 5.1692292513e-03, 1.9876580847e+00 }, + /* 400 Hz*/ +{ 9.8689036168e-01, 6.5548191616e-03, 1.9836646251e+00 }, + /* 500 Hz*/ +{ 9.8364027156e-01, 8.1798642207e-03, 1.9786090689e+00 }, + /* 800 Hz*/ +{ 9.7395577681e-01, 1.3022111597e-02, 1.9611472340e+00 }, + /* 1k Hz*/ +{ 9.6755437936e-01, 1.6222810321e-02, 1.9476180811e+00 }, + /* 1.25k Hz*/ +{ 9.5961458750e-01, 2.0192706249e-02, 1.9286193446e+00 }, + /* 1.6k Hz*/ +{ 9.4861481164e-01, 2.5692594182e-02, 1.8982024567e+00 }, + /* 2.5k Hz*/ +{ 9.2095325455e-01, 3.9523372724e-02, 1.8003794694e+00 }, + /* 3.15k Hz*/ +{ 9.0153642498e-01, 4.9231787512e-02, 1.7132251201e+00 }, + /* 4k Hz*/ +{ 8.7685876255e-01, 6.1570618727e-02, 1.5802270232e+00 }, + /* 5k Hz*/ +{ 8.4886734822e-01, 7.5566325889e-02, 1.3992391376e+00 }, + /* 8k Hz*/ +{ 7.7175298860e-01, 1.1412350570e-01, 7.4018523020e-01 }, + /* 10k Hz*/ +{ 7.2627049462e-01, 1.3686475269e-01, 2.5120552756e-01 }, + /* 12.5k Hz*/ +{ 6.7674787974e-01, 1.6162606013e-01, -3.4978377639e-01 }, + /* 16k Hz*/ +{ 6.2482197550e-01, 1.8758901225e-01, -1.0576558797e+00 }, + /* 20k Hz*/ +{ 6.1776148240e-01, 1.9111925880e-01, -1.5492465594e+00 }, +}; +static sIIRCoefficients iir_cf25_48000[] __attribute__((aligned)) = { + /* 20 Hz*/ +{ 9.9939388451e-01, 3.0305774630e-04, 1.9993870327e+00 }, + /* 31.5 Hz*/ +{ 9.9904564663e-01, 4.7717668529e-04, 1.9990286528e+00 }, + /* 40 Hz*/ +{ 9.9878827195e-01, 6.0586402557e-04, 1.9987608731e+00 }, + /* 50 Hz*/ +{ 9.9848556942e-01, 7.5721528829e-04, 1.9984427652e+00 }, + /* 80 Hz*/ +{ 9.9757801538e-01, 1.2109923088e-03, 1.9974684869e+00 }, + /* 100 Hz*/ +{ 9.9697343933e-01, 1.5132803374e-03, 1.9968023538e+00 }, + /* 125 Hz*/ +{ 9.9621823598e-01, 1.8908820086e-03, 1.9959510180e+00 }, + /* 160 Hz*/ +{ 9.9516191728e-01, 2.4190413595e-03, 1.9947243453e+00 }, + /* 250 Hz*/ +{ 9.9245085008e-01, 3.7745749576e-03, 1.9913840669e+00 }, + /* 315 Hz*/ +{ 9.9049749914e-01, 4.7512504310e-03, 1.9888056233e+00 }, + /* 400 Hz*/ +{ 9.8794899744e-01, 6.0255012789e-03, 1.9852245824e+00 }, + /* 500 Hz*/ +{ 9.8495930023e-01, 7.5203498850e-03, 1.9807093500e+00 }, + /* 800 Hz*/ +{ 9.7604570090e-01, 1.1977149551e-02, 1.9652207158e+00 }, + /* 1k Hz*/ +{ 9.7014963927e-01, 1.4925180364e-02, 1.9532947360e+00 }, + /* 1.25k Hz*/ +{ 9.6283181641e-01, 1.8584091793e-02, 1.9366149237e+00 }, + /* 1.6k Hz*/ +{ 9.5268463224e-01, 2.3657683878e-02, 1.9100137880e+00 }, + /* 2.5k Hz*/ +{ 9.2711765003e-01, 3.6441174983e-02, 1.8248457659e+00 }, + /* 3.15k Hz*/ +{ 9.0912548757e-01, 4.5437256213e-02, 1.7491177803e+00 }, + /* 4k Hz*/ +{ 8.8619860800e-01, 5.6900696000e-02, 1.6334959111e+00 }, + /* 5k Hz*/ +{ 8.6010264114e-01, 6.9948679430e-02, 1.4757186436e+00 }, + /* 8k Hz*/ +{ 7.8757448309e-01, 1.0621275845e-01, 8.9378724155e-01 }, + /* 10k Hz*/ +{ 7.4415362476e-01, 1.2792318762e-01, 4.5142017567e-01 }, + /* 12.5k Hz*/ +{ 6.9581428034e-01, 1.5209285983e-01, -1.1091156053e-01 }, + /* 16k Hz*/ +{ 6.4120506488e-01, 1.7939746756e-01, -8.2060253244e-01 }, + /* 20k Hz*/ +{ 6.0884213704e-01, 1.9557893148e-01, -1.3932981614e+00 }, +}; +static sIIRCoefficients iir_cf31_44100[] __attribute__((aligned)) = { + /* 20 Hz*/ +{ 9.9934037157e-01, 3.2981421662e-04, 1.9993322545e+00 }, + /* 25 Hz*/ +{ 9.9917555233e-01, 4.1222383516e-04, 1.9991628705e+00 }, + /* 31.5 Hz*/ +{ 9.9896129025e-01, 5.1935487310e-04, 1.9989411587e+00 }, + /* 40 Hz*/ +{ 9.9868118265e-01, 6.5940867495e-04, 1.9986487252e+00 }, + /* 50 Hz*/ +{ 9.9835175161e-01, 8.2412419683e-04, 1.9983010452e+00 }, + /* 63 Hz*/ +{ 9.9792365217e-01, 1.0381739160e-03, 1.9978431682e+00 }, + /* 80 Hz*/ +{ 9.9736411067e-01, 1.3179446674e-03, 1.9972343673e+00 }, + /* 100 Hz*/ +{ 9.9670622662e-01, 1.6468866919e-03, 1.9965035707e+00 }, + /* 125 Hz*/ +{ 9.9588448566e-01, 2.0577571681e-03, 1.9955679690e+00 }, + /* 160 Hz*/ +{ 9.9473519326e-01, 2.6324033689e-03, 1.9942169198e+00 }, + /* 200 Hz*/ +{ 9.9342335280e-01, 3.2883236020e-03, 1.9926141028e+00 }, + /* 250 Hz*/ +{ 9.9178600786e-01, 4.1069960678e-03, 1.9905226414e+00 }, + /* 315 Hz*/ +{ 9.8966154150e-01, 5.1692292513e-03, 1.9876580847e+00 }, + /* 400 Hz*/ +{ 9.8689036168e-01, 6.5548191616e-03, 1.9836646251e+00 }, + /* 500 Hz*/ +{ 9.8364027156e-01, 8.1798642207e-03, 1.9786090689e+00 }, + /* 630 Hz*/ +{ 9.7943153305e-01, 1.0284233476e-02, 1.9714629236e+00 }, + /* 800 Hz*/ +{ 9.7395577681e-01, 1.3022111597e-02, 1.9611472340e+00 }, + /* 1k Hz*/ +{ 9.6755437936e-01, 1.6222810321e-02, 1.9476180811e+00 }, + /* 1.25k Hz*/ +{ 9.5961458750e-01, 2.0192706249e-02, 1.9286193446e+00 }, + /* 1.6k Hz*/ +{ 9.4861481164e-01, 2.5692594182e-02, 1.8982024567e+00 }, + /* 2k Hz*/ +{ 9.3620971896e-01, 3.1895140519e-02, 1.8581325022e+00 }, + /* 2.5k Hz*/ +{ 9.2095325455e-01, 3.9523372724e-02, 1.8003794694e+00 }, + /* 3.15k Hz*/ +{ 9.0153642498e-01, 4.9231787512e-02, 1.7132251201e+00 }, + /* 4k Hz*/ +{ 8.7685876255e-01, 6.1570618727e-02, 1.5802270232e+00 }, + /* 5k Hz*/ +{ 8.4886734822e-01, 7.5566325889e-02, 1.3992391376e+00 }, + /* 6.3k Hz*/ +{ 8.1417575446e-01, 9.2912122771e-02, 1.1311200817e+00 }, + /* 8k Hz*/ +{ 7.7175298860e-01, 1.1412350570e-01, 7.4018523020e-01 }, + /* 10k Hz*/ +{ 7.2627049462e-01, 1.3686475269e-01, 2.5120552756e-01 }, + /* 12.5k Hz*/ +{ 6.7674787974e-01, 1.6162606013e-01, -3.4978377639e-01 }, + /* 16k Hz*/ +{ 6.2482197550e-01, 1.8758901225e-01, -1.0576558797e+00 }, + /* 20k Hz*/ +{ 6.1776148240e-01, 1.9111925880e-01, -1.5492465594e+00 }, +}; +static sIIRCoefficients iir_cf31_48000[] __attribute__((aligned)) = { + /* 20 Hz*/ +{ 9.9939388451e-01, 3.0305774630e-04, 1.9993870327e+00 }, + /* 25 Hz*/ +{ 9.9924247917e-01, 3.7876041632e-04, 1.9992317740e+00 }, + /* 31.5 Hz*/ +{ 9.9904564663e-01, 4.7717668529e-04, 1.9990286528e+00 }, + /* 40 Hz*/ +{ 9.9878827195e-01, 6.0586402557e-04, 1.9987608731e+00 }, + /* 50 Hz*/ +{ 9.9848556942e-01, 7.5721528829e-04, 1.9984427652e+00 }, + /* 63 Hz*/ +{ 9.9809219264e-01, 9.5390367779e-04, 1.9980242502e+00 }, + /* 80 Hz*/ +{ 9.9757801538e-01, 1.2109923088e-03, 1.9974684869e+00 }, + /* 100 Hz*/ +{ 9.9697343933e-01, 1.5132803374e-03, 1.9968023538e+00 }, + /* 125 Hz*/ +{ 9.9621823598e-01, 1.8908820086e-03, 1.9959510180e+00 }, + /* 160 Hz*/ +{ 9.9516191728e-01, 2.4190413595e-03, 1.9947243453e+00 }, + /* 200 Hz*/ +{ 9.9395607757e-01, 3.0219612131e-03, 1.9932727986e+00 }, + /* 250 Hz*/ +{ 9.9245085008e-01, 3.7745749576e-03, 1.9913840669e+00 }, + /* 315 Hz*/ +{ 9.9049749914e-01, 4.7512504310e-03, 1.9888056233e+00 }, + /* 400 Hz*/ +{ 9.8794899744e-01, 6.0255012789e-03, 1.9852245824e+00 }, + /* 500 Hz*/ +{ 9.8495930023e-01, 7.5203498850e-03, 1.9807093500e+00 }, + /* 630 Hz*/ +{ 9.8108651246e-01, 9.4567437704e-03, 1.9743538683e+00 }, + /* 800 Hz*/ +{ 9.7604570090e-01, 1.1977149551e-02, 1.9652207158e+00 }, + /* 1k Hz*/ +{ 9.7014963927e-01, 1.4925180364e-02, 1.9532947360e+00 }, + /* 1.25k Hz*/ +{ 9.6283181641e-01, 1.8584091793e-02, 1.9366149237e+00 }, + /* 1.6k Hz*/ +{ 9.5268463224e-01, 2.3657683878e-02, 1.9100137880e+00 }, + /* 2k Hz*/ +{ 9.4122788957e-01, 2.9386055213e-02, 1.8750821533e+00 }, + /* 2.5k Hz*/ +{ 9.2711765003e-01, 3.6441174983e-02, 1.8248457659e+00 }, + /* 3.15k Hz*/ +{ 9.0912548757e-01, 4.5437256213e-02, 1.7491177803e+00 }, + /* 4k Hz*/ +{ 8.8619860800e-01, 5.6900696000e-02, 1.6334959111e+00 }, + /* 5k Hz*/ +{ 8.6010264114e-01, 6.9948679430e-02, 1.4757186436e+00 }, + /* 6.3k Hz*/ +{ 8.2760520925e-01, 8.6197395374e-02, 1.2405797786e+00 }, + /* 8k Hz*/ +{ 7.8757448309e-01, 1.0621275845e-01, 8.9378724155e-01 }, + /* 10k Hz*/ +{ 7.4415362476e-01, 1.2792318762e-01, 4.5142017567e-01 }, + /* 12.5k Hz*/ +{ 6.9581428034e-01, 1.5209285983e-01, -1.1091156053e-01 }, + /* 16k Hz*/ +{ 6.4120506488e-01, 1.7939746756e-01, -8.2060253244e-01 }, + /* 20k Hz*/ +{ 6.0884213704e-01, 1.9557893148e-01, -1.3932981614e+00 }, +}; + diff --git a/src/equalizer.cpp b/src/equalizer.cpp new file mode 100644 index 000000000..a163c2dc9 --- /dev/null +++ b/src/equalizer.cpp @@ -0,0 +1,86 @@ +/* This file is part of Clementine. + + Clementine is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + Clementine is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with Clementine. If not, see . +*/ + +#include "equalizer.h" +#include "equalizerslider.h" + +#include +#include + +// We probably don't need to translate these, right? +const char* Equalizer::kGainText[] = { + "30", "60", "125", "250", "500", "1k", "2k", "4k", "8k", "16k"}; + +const char* Equalizer::kSettingsGroup = "Equalizer"; + +Equalizer::Equalizer(QWidget *parent) + : QDialog(parent) +{ + ui_.setupUi(this); + connect(ui_.enable, SIGNAL(toggled(bool)), SIGNAL(EnabledChanged(bool))); + connect(ui_.enable, SIGNAL(toggled(bool)), ui_.slider_container, SLOT(setEnabled(bool))); + + preamp_ = AddSlider(tr("Pre-amp")); + + QFrame* line = new QFrame(ui_.slider_container); + line->setFrameShape(QFrame::VLine); + line->setFrameShadow(QFrame::Sunken); + ui_.slider_container->layout()->addWidget(line); + + for (int i=0 ; isetChecked(s.value("enabled", false).toBool()); + + preamp_->set_value(s.value("preamp", 0).toInt()); + for (int i=0 ; iset_value(s.value("gain_" + QString::number(i+1), 0).toInt()); + } + + emit EnabledChanged(ui_.enable->isChecked()); + ParametersChanged(); +} + +EqualizerSlider* Equalizer::AddSlider(const QString &label) { + EqualizerSlider* ret = new EqualizerSlider(label, ui_.slider_container); + ui_.slider_container->layout()->addWidget(ret); + connect(ret, SIGNAL(ValueChanged(int)), SLOT(ParametersChanged())); + + return ret; +} + +int Equalizer::preamp_value() const { + return preamp_->value(); +} + +QList Equalizer::gain_values() const { + QList ret; + for (int i=0 ; ivalue(); + } + return ret; +} + +void Equalizer::ParametersChanged() { + emit ParametersChanged(preamp_value(), gain_values()); +} + + diff --git a/src/equalizer.h b/src/equalizer.h new file mode 100644 index 000000000..890876561 --- /dev/null +++ b/src/equalizer.h @@ -0,0 +1,59 @@ +/* This file is part of Clementine. + + Clementine is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + Clementine is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with Clementine. If not, see . +*/ + +#ifndef EQUALIZER_H +#define EQUALIZER_H + +#include + +#include "ui_equalizer.h" + +class EqualizerSlider; + +class Equalizer : public QDialog { + Q_OBJECT + + public: + Equalizer(QWidget *parent = 0); + + static const int kBands = 10; + static const char* kGainText[kBands]; + static const char* kSettingsGroup; + + int preamp_value() const; + QList gain_values() const; + + public slots: + void ReloadSettings(); + + signals: + void EnabledChanged(bool enabled); + void ParametersChanged(int preamp, const QList& band_gains); + + private slots: + void ParametersChanged(); + + private: + EqualizerSlider* AddSlider(const QString& label); + + private: + Ui::Equalizer ui_; + + EqualizerSlider* preamp_; + EqualizerSlider* gain_[kBands]; +}; + +#endif // EQUALIZER_H diff --git a/src/equalizer.ui b/src/equalizer.ui new file mode 100644 index 000000000..381db5f47 --- /dev/null +++ b/src/equalizer.ui @@ -0,0 +1,90 @@ + + + Equalizer + + + + 0 + 0 + 435 + 265 + + + + Equalizer + + + + + + + + Preset: + + + + + + + + 0 + 0 + + + + + + + + + :/list-add.png:/list-add.png + + + + 16 + 16 + + + + + + + + + + Qt::Horizontal + + + + + + + Enable equalizer + + + + + + + false + + + + 0 + 0 + + + + + + + + + preset + preset_add + + + + + + diff --git a/src/equalizerslider.cpp b/src/equalizerslider.cpp new file mode 100644 index 000000000..79140e803 --- /dev/null +++ b/src/equalizerslider.cpp @@ -0,0 +1,34 @@ +/* This file is part of Clementine. + + Clementine is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + Clementine is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with Clementine. If not, see . +*/ + +#include "equalizerslider.h" + +EqualizerSlider::EqualizerSlider(const QString& label, QWidget *parent) + : QWidget(parent) +{ + ui_.setupUi(this); + ui_.label->setText(label); + + connect(ui_.slider, SIGNAL(valueChanged(int)), SIGNAL(ValueChanged(int))); +} + +int EqualizerSlider::value() const { + return ui_.slider->value(); +} + +void EqualizerSlider::set_value(int value) { + ui_.slider->setValue(value); +} diff --git a/src/equalizerslider.h b/src/equalizerslider.h new file mode 100644 index 000000000..6be5a2104 --- /dev/null +++ b/src/equalizerslider.h @@ -0,0 +1,40 @@ +/* This file is part of Clementine. + + Clementine is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + Clementine is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with Clementine. If not, see . +*/ + +#ifndef EQUALISERSLIDER_H +#define EQUALISERSLIDER_H + +#include + +#include "ui_equalizerslider.h" + +class EqualizerSlider : public QWidget { + Q_OBJECT + + public: + EqualizerSlider(const QString& label, QWidget *parent = 0); + + int value() const; + void set_value(int value); + + signals: + void ValueChanged(int value); + + private: + Ui::EqualizerSlider ui_; +}; + +#endif // EQUALISERSLIDER_H diff --git a/src/equalizerslider.ui b/src/equalizerslider.ui new file mode 100644 index 000000000..1ad9338bd --- /dev/null +++ b/src/equalizerslider.ui @@ -0,0 +1,74 @@ + + + EqualizerSlider + + + + 0 + 0 + 33 + 224 + + + + Form + + + + 0 + + + + + + + Qt::Horizontal + + + + 0 + 0 + + + + + + + + -100 + + + 100 + + + Qt::Vertical + + + + + + + Qt::Horizontal + + + + 0 + 0 + + + + + + + + + + Qt::AlignCenter + + + + + + + + diff --git a/src/main.cpp b/src/main.cpp index 64a55e26c..c125034ec 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -81,6 +81,7 @@ int main(int argc, char *argv[]) { lastfm::ws::SharedSecret = LastFMService::kSecret; QtSingleApplication a(argc, argv); + a.setQuitOnLastWindowClosed(false); if (a.isRunning()) { qDebug() << "Clementine is already running - activating existing window"; diff --git a/src/mainwindow.cpp b/src/mainwindow.cpp index 1a2251030..074cdbded 100644 --- a/src/mainwindow.cpp +++ b/src/mainwindow.cpp @@ -39,6 +39,7 @@ #include "playlistsequence.h" #include "groupbydialog.h" #include "engines/gstengine.h" +#include "equalizer.h" #include "globalshortcuts/globalshortcuts.h" @@ -81,6 +82,7 @@ MainWindow::MainWindow(QNetworkAccessManager* network, QWidget *parent) add_stream_dialog_(new AddStreamDialog(this)), cover_manager_(new AlbumCoverManager(network, this)), group_by_dialog_(new GroupByDialog(this)), + equalizer_(new Equalizer(this)), playlist_menu_(new QMenu(this)), library_sort_model_(new QSortFilterProxyModel(this)), track_position_timer_(new QTimer(this)) @@ -149,6 +151,7 @@ MainWindow::MainWindow(QNetworkAccessManager* network, QWidget *parent) connect(ui_.action_add_media, SIGNAL(triggered()), SLOT(AddMedia())); connect(ui_.action_add_stream, SIGNAL(triggered()), SLOT(AddStream())); connect(ui_.action_cover_manager, SIGNAL(triggered()), cover_manager_, SLOT(show())); + connect(ui_.action_equalizer, SIGNAL(triggered()), equalizer_, SLOT(show())); // Give actions to buttons ui_.forward_button->setDefaultAction(ui_.action_next_track); @@ -339,6 +342,13 @@ MainWindow::MainWindow(QNetworkAccessManager* network, QWidget *parent) // Analyzer ui_.analyzer->set_engine(player_->GetEngine()); + // Equalizer + connect(equalizer_, SIGNAL(ParametersChanged(int,QList)), + player_->GetEngine(), SLOT(setEqualizerParameters(int,QList))); + connect(equalizer_, SIGNAL(EnabledChanged(bool)), + player_->GetEngine(), SLOT(setEqualizerEnabled(bool))); + equalizer_->ReloadSettings(); + // Statusbar widgets playlist_->set_sequence(playlist_sequence_); ui_.statusBar->addPermanentWidget(playlist_sequence_); @@ -536,9 +546,8 @@ void MainWindow::closeEvent(QCloseEvent* event) { if (tray_icon_->isVisible()) { event->ignore(); SetHiddenInTray(true); - } - else { - settings_.setValue("showtray", tray_icon_->isVisible()); + } else { + QApplication::quit(); } } diff --git a/src/mainwindow.h b/src/mainwindow.h index dcbbcd373..1b50139c6 100644 --- a/src/mainwindow.h +++ b/src/mainwindow.h @@ -41,6 +41,7 @@ class AlbumCoverManager; class PlaylistSequence; class GlobalShortcuts; class GroupByDialog; +class Equalizer; class QSortFilterProxyModel; class SystemTrayIcon; @@ -141,6 +142,7 @@ class MainWindow : public QMainWindow { AddStreamDialog* add_stream_dialog_; AlbumCoverManager* cover_manager_; GroupByDialog* group_by_dialog_; + Equalizer* equalizer_; QMenu* playlist_menu_; QAction* playlist_play_pause_; diff --git a/src/mainwindow.ui b/src/mainwindow.ui index a98155d8f..c0b7bb5cd 100644 --- a/src/mainwindow.ui +++ b/src/mainwindow.ui @@ -14,7 +14,7 @@ Clementine - + :/icon.png:/icon.png @@ -298,7 +298,7 @@ - + :/clear.png:/clear.png @@ -322,7 +322,7 @@ - + :/configure.png:/configure.png @@ -492,6 +492,7 @@ Tools + @@ -501,7 +502,7 @@ - + :/media-skip-backward.png:/media-skip-backward.png @@ -510,7 +511,7 @@ - + :/media-playback-start.png:/media-playback-start.png @@ -522,7 +523,7 @@ false - + :/media-playback-stop.png:/media-playback-stop.png @@ -531,7 +532,7 @@ - + :/media-skip-forward.png:/media-skip-forward.png @@ -540,7 +541,7 @@ - + :/exit.png:/exit.png @@ -552,7 +553,7 @@ - + :/media-playback-stop.png:/media-playback-stop.png @@ -618,7 +619,7 @@ false - + :/last.fm/love.png:/last.fm/love.png @@ -630,7 +631,7 @@ false - + :/last.fm/ban.png:/last.fm/ban.png @@ -639,7 +640,7 @@ - + :/clear-list.png:/clear-list.png @@ -651,7 +652,7 @@ - + :/edit-track.png:/edit-track.png @@ -675,7 +676,7 @@ - + :/configure.png:/configure.png @@ -689,7 +690,7 @@ - + :/shuffle.png:/shuffle.png @@ -698,7 +699,7 @@ - + :/open_media.png:/open_media.png @@ -707,7 +708,7 @@ - + :/open_stream.png:/open_stream.png @@ -716,7 +717,7 @@ - + :/open_media.png:/open_media.png @@ -725,7 +726,7 @@ - + :/download.png:/download.png @@ -734,7 +735,7 @@ - + :/media-playlist-shuffle.png:/media-playlist-shuffle.png @@ -743,7 +744,7 @@ - + :/media-playlist-repeat.png:/media-playlist-repeat.png @@ -752,7 +753,7 @@ - + :/list-remove.png:/list-remove.png @@ -815,6 +816,11 @@ Advanced grouping... + + + Equalizer + + @@ -856,8 +862,6 @@ 1 - - - + diff --git a/src/translations/cs.po b/src/translations/cs.po index 4d685c340..d7ab25cc0 100644 --- a/src/translations/cs.po +++ b/src/translations/cs.po @@ -400,6 +400,10 @@ msgstr "TrueAudio" msgid "Stream" msgstr "Proud" +#, fuzzy +msgid "Pre-amp" +msgstr "Proud" + msgid "Clementine" msgstr "Clementine" @@ -508,6 +512,9 @@ msgstr "" msgid "Advanced grouping..." msgstr "" +msgid "Equalizer" +msgstr "" + msgid "Library" msgstr "Knihovna" @@ -871,6 +878,12 @@ msgstr "" msgid "Third level" msgstr "" +msgid "Preset:" +msgstr "" + +msgid "Enable equalizer" +msgstr "" + #~ msgid "&Hide tray icon" #~ msgstr "S&krýt ikonu v systémovém panelu" diff --git a/src/translations/el.po b/src/translations/el.po index 6d1a1add3..8ab5df67a 100644 --- a/src/translations/el.po +++ b/src/translations/el.po @@ -401,6 +401,10 @@ msgstr "TrueAudio" msgid "Stream" msgstr "Stream" +#, fuzzy +msgid "Pre-amp" +msgstr "Stream" + msgid "Clementine" msgstr "Clementine" @@ -509,6 +513,9 @@ msgstr "Ομαδοποίηση κατά Είδος/Καλλιντέχνη/Άλμ msgid "Advanced grouping..." msgstr "Προχωρημένη ομαδοποίηση..." +msgid "Equalizer" +msgstr "" + msgid "Library" msgstr "Βιβλιοθήκη" @@ -836,6 +843,12 @@ msgstr "Δεύτερο επίπεδο" msgid "Third level" msgstr "Τρίτο επίπεδο" +msgid "Preset:" +msgstr "" + +msgid "Enable equalizer" +msgstr "" + #~ msgid "&Hide tray icon" #~ msgstr "&Απόκρυψη εικονιδίου συστήματος" diff --git a/src/translations/es.po b/src/translations/es.po index def5f71ff..43bf62881 100644 --- a/src/translations/es.po +++ b/src/translations/es.po @@ -401,6 +401,9 @@ msgstr "" msgid "Stream" msgstr "" +msgid "Pre-amp" +msgstr "" + msgid "Clementine" msgstr "Clementine" @@ -509,6 +512,9 @@ msgstr "Agrupar por Género/Artista/Álbum" msgid "Advanced grouping..." msgstr "Agrupamiento avanzado..." +msgid "Equalizer" +msgstr "" + msgid "Library" msgstr "Colección" @@ -879,6 +885,12 @@ msgstr "Segundo nivel" msgid "Third level" msgstr "Tercer nivel" +msgid "Preset:" +msgstr "" + +msgid "Enable equalizer" +msgstr "" + #~ msgid "&Hide tray icon" #~ msgstr "&Ocultar icono de la bandeja" diff --git a/src/translations/fr.po b/src/translations/fr.po index 78794356c..6baf64fd3 100644 --- a/src/translations/fr.po +++ b/src/translations/fr.po @@ -402,6 +402,10 @@ msgstr "TrueAudio" msgid "Stream" msgstr "Flux" +#, fuzzy +msgid "Pre-amp" +msgstr "Flux" + msgid "Clementine" msgstr "Clementine" @@ -510,6 +514,9 @@ msgstr "" msgid "Advanced grouping..." msgstr "" +msgid "Equalizer" +msgstr "" + msgid "Library" msgstr "Bibliothèque" @@ -876,6 +883,12 @@ msgstr "" msgid "Third level" msgstr "" +msgid "Preset:" +msgstr "" + +msgid "Enable equalizer" +msgstr "" + #~ msgid "&Hide tray icon" #~ msgstr "&Masquer l'icône" diff --git a/src/translations/pl.po b/src/translations/pl.po index 0f4f2aa7b..392e1d297 100644 --- a/src/translations/pl.po +++ b/src/translations/pl.po @@ -399,6 +399,9 @@ msgstr "" msgid "Stream" msgstr "" +msgid "Pre-amp" +msgstr "" + msgid "Clementine" msgstr "" @@ -507,6 +510,9 @@ msgstr "Grupuj według Gatunek/Artysta/Album" msgid "Advanced grouping..." msgstr "Zaawansowane grupowanie..." +msgid "Equalizer" +msgstr "" + msgid "Library" msgstr "Biblioteka" @@ -869,5 +875,11 @@ msgstr "Drugi poziom" msgid "Third level" msgstr "Trzeci poziom" +msgid "Preset:" +msgstr "" + +msgid "Enable equalizer" +msgstr "" + #~ msgid "&Hide tray icon" #~ msgstr "&Ukryj ikonę w trayu" diff --git a/src/translations/ru.po b/src/translations/ru.po index 37955ee18..0daaeb7e1 100644 --- a/src/translations/ru.po +++ b/src/translations/ru.po @@ -400,6 +400,9 @@ msgstr "" msgid "Stream" msgstr "" +msgid "Pre-amp" +msgstr "" + msgid "Clementine" msgstr "Clementine" @@ -508,6 +511,9 @@ msgstr "" msgid "Advanced grouping..." msgstr "" +msgid "Equalizer" +msgstr "" + msgid "Library" msgstr "Коллекция" @@ -869,5 +875,11 @@ msgstr "" msgid "Third level" msgstr "" +msgid "Preset:" +msgstr "" + +msgid "Enable equalizer" +msgstr "" + #~ msgid "Don't show notifications" #~ msgstr "Не показывать" diff --git a/src/translations/sk.po b/src/translations/sk.po index cf72483ab..b72dcac5e 100644 --- a/src/translations/sk.po +++ b/src/translations/sk.po @@ -400,6 +400,9 @@ msgstr "" msgid "Stream" msgstr "" +msgid "Pre-amp" +msgstr "" + msgid "Clementine" msgstr "" @@ -508,6 +511,9 @@ msgstr "Zoradiť podľa žáner/interprét/album" msgid "Advanced grouping..." msgstr "Pokročilé zoraďovanie..." +msgid "Equalizer" +msgstr "" + msgid "Library" msgstr "Zbierka" @@ -872,6 +878,12 @@ msgstr "Druhá úroveň" msgid "Third level" msgstr "Tretia úroveň" +msgid "Preset:" +msgstr "" + +msgid "Enable equalizer" +msgstr "" + #~ msgid "&Hide tray icon" #~ msgstr "&Skryť tray ikonu" diff --git a/src/translations/translations.pot b/src/translations/translations.pot index 7c496a986..e1dd85a94 100644 --- a/src/translations/translations.pot +++ b/src/translations/translations.pot @@ -398,6 +398,9 @@ msgstr "" msgid "Stream" msgstr "" +msgid "Pre-amp" +msgstr "" + msgid "Clementine" msgstr "" @@ -506,6 +509,9 @@ msgstr "" msgid "Advanced grouping..." msgstr "" +msgid "Equalizer" +msgstr "" + msgid "Library" msgstr "" @@ -822,3 +828,9 @@ msgstr "" msgid "Third level" msgstr "" + +msgid "Preset:" +msgstr "" + +msgid "Enable equalizer" +msgstr ""