Basic support for ProjectM visualisations
This commit is contained in:
parent
fe39d99923
commit
1895582eb9
|
@ -55,6 +55,9 @@ endif(WIN32)
|
|||
find_library(LASTFM_LIBRARY_DIRS lastfm)
|
||||
find_path(LASTFM_INCLUDE_DIRS lastfm/ws.h)
|
||||
|
||||
find_library(PROJECTM_LIBRARIES projectM)
|
||||
find_path(PROJECTM_INCLUDE_DIRS libprojectM/projectM.hpp)
|
||||
|
||||
if (APPLE)
|
||||
find_library(GROWL Growl)
|
||||
find_library(SPARKLE Sparkle)
|
||||
|
|
|
@ -36,6 +36,7 @@ add_subdirectory(playlistparsers)
|
|||
add_subdirectory(radio)
|
||||
add_subdirectory(transcoder)
|
||||
add_subdirectory(ui)
|
||||
add_subdirectory(visualisations)
|
||||
add_subdirectory(widgets)
|
||||
add_subdirectory(translations)
|
||||
|
||||
|
|
|
@ -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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef BUFFERCONSUMER_H
|
||||
#define BUFFERCONSUMER_H
|
||||
|
||||
#include <gst/gstbuffer.h>
|
||||
|
||||
class GstEnginePipeline;
|
||||
|
||||
class BufferConsumer {
|
||||
public:
|
||||
virtual ~BufferConsumer() {}
|
||||
|
||||
// This is called in some unspecified GStreamer thread.
|
||||
// Ownership of the buffer is transferred to the BufferConsumer and it should
|
||||
// gst_buffer_unref it.
|
||||
virtual void ConsumeBuffer(GstBuffer* buffer, GstEnginePipeline* pipeline) = 0;
|
||||
};
|
||||
|
||||
#endif // BUFFERCONSUMER_H
|
|
@ -259,9 +259,18 @@ Engine::State GstEngine::state() const {
|
|||
}
|
||||
}
|
||||
|
||||
void GstEngine::AddBufferToScope(GstBuffer* buf) {
|
||||
GstEnginePipeline* pipeline = qobject_cast<GstEnginePipeline*>(sender());
|
||||
if (!pipeline || pipeline != current_pipeline_.get()) {
|
||||
void GstEngine::ConsumeBuffer(GstBuffer *buffer, GstEnginePipeline* pipeline) {
|
||||
// Schedule this to run in the GUI thread. The buffer gets added to the
|
||||
// queue and unreffed by UpdateScope.
|
||||
if (!QMetaObject::invokeMethod(this, "AddBufferToScope",
|
||||
Q_ARG(GstBuffer*, buffer),
|
||||
Q_ARG(GstEnginePipeline*, pipeline))) {
|
||||
qWarning() << "Failed to invoke AddBufferToScope on GstEngine";
|
||||
}
|
||||
}
|
||||
|
||||
void GstEngine::AddBufferToScope(GstBuffer* buf, GstEnginePipeline* pipeline) {
|
||||
if (current_pipeline_.get() != pipeline) {
|
||||
gst_buffer_unref(buf);
|
||||
return;
|
||||
}
|
||||
|
@ -442,7 +451,7 @@ bool GstEngine::Load(const QUrl& url, Engine::TrackChangeType change) {
|
|||
void GstEngine::StartFadeout() {
|
||||
fadeout_pipeline_ = current_pipeline_;
|
||||
disconnect(fadeout_pipeline_.get(), 0, 0, 0);
|
||||
fadeout_pipeline_->set_forwards_buffers(false);
|
||||
fadeout_pipeline_->RemoveAllBufferConsumers();
|
||||
ClearScopeBuffers();
|
||||
|
||||
fadeout_pipeline_->StartFader(fadeout_duration_, QTimeLine::Backward);
|
||||
|
@ -642,12 +651,14 @@ GstEngine::PluginDetailsList
|
|||
|
||||
shared_ptr<GstEnginePipeline> GstEngine::CreatePipeline(const QUrl& url) {
|
||||
shared_ptr<GstEnginePipeline> ret(new GstEnginePipeline(this));
|
||||
ret->set_forwards_buffers(true);
|
||||
ret->set_output_device(sink_, device_);
|
||||
ret->set_replaygain(rg_enabled_, rg_mode_, rg_preamp_, rg_compression_);
|
||||
|
||||
ret->AddBufferConsumer(this);
|
||||
foreach (BufferConsumer* consumer, buffer_consumers_)
|
||||
ret->AddBufferConsumer(consumer);
|
||||
|
||||
connect(ret.get(), SIGNAL(EndOfStreamReached(bool)), SLOT(EndOfStreamReached(bool)));
|
||||
connect(ret.get(), SIGNAL(BufferFound(GstBuffer*)), SLOT(AddBufferToScope(GstBuffer*)));
|
||||
connect(ret.get(), SIGNAL(Error(QString)), SLOT(HandlePipelineError(QString)));
|
||||
connect(ret.get(), SIGNAL(MetadataFound(Engine::SimpleMetaBundle)),
|
||||
SLOT(NewMetaData(Engine::SimpleMetaBundle)));
|
||||
|
@ -703,3 +714,15 @@ void GstEngine::ClearScopeBuffers() {
|
|||
bool GstEngine::DoesThisSinkSupportChangingTheOutputDeviceToAUserEditableString(const QString &name) {
|
||||
return (name == "alsasink" || name == "osssink" || name == "pulsesink");
|
||||
}
|
||||
|
||||
void GstEngine::AddBufferConsumer(BufferConsumer *consumer) {
|
||||
buffer_consumers_ << consumer;
|
||||
if (current_pipeline_)
|
||||
current_pipeline_->AddBufferConsumer(consumer);
|
||||
}
|
||||
|
||||
void GstEngine::RemoveBufferConsumer(BufferConsumer *consumer) {
|
||||
buffer_consumers_.removeAll(consumer);
|
||||
if (current_pipeline_)
|
||||
current_pipeline_->RemoveBufferConsumer(consumer);
|
||||
}
|
||||
|
|
|
@ -23,6 +23,7 @@
|
|||
#define AMAROK_GSTENGINE_H
|
||||
|
||||
#include "enginebase.h"
|
||||
#include "bufferconsumer.h"
|
||||
|
||||
#include <QString>
|
||||
#include <QTimerEvent>
|
||||
|
@ -42,7 +43,7 @@ class GstEnginePipeline;
|
|||
* @short GStreamer engine plugin
|
||||
* @author Mark Kretschmann <markey@web.de>
|
||||
*/
|
||||
class GstEngine : public Engine::Base {
|
||||
class GstEngine : public Engine::Base, public BufferConsumer {
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
|
@ -75,6 +76,9 @@ class GstEngine : public Engine::Base {
|
|||
GstElement* CreateElement(
|
||||
const QString& factoryName, GstElement* bin = 0, const QString& name = 0);
|
||||
|
||||
// BufferConsumer
|
||||
void ConsumeBuffer(GstBuffer *buffer, GstEnginePipeline* pipeline);
|
||||
|
||||
public slots:
|
||||
void StartPreloading(const QUrl &);
|
||||
bool Load(const QUrl&, Engine::TrackChangeType change);
|
||||
|
@ -92,6 +96,9 @@ class GstEngine : public Engine::Base {
|
|||
|
||||
void ReloadSettings();
|
||||
|
||||
void AddBufferConsumer(BufferConsumer* consumer);
|
||||
void RemoveBufferConsumer(BufferConsumer* consumer);
|
||||
|
||||
protected:
|
||||
void SetVolumeSW(uint percent);
|
||||
void timerEvent(QTimerEvent*);
|
||||
|
@ -100,8 +107,8 @@ class GstEngine : public Engine::Base {
|
|||
void EndOfStreamReached(bool has_next_track);
|
||||
void HandlePipelineError(const QString& message);
|
||||
void NewMetaData(const Engine::SimpleMetaBundle& bundle);
|
||||
void AddBufferToScope(GstBuffer* buf);
|
||||
void ClearScopeBuffers();
|
||||
void AddBufferToScope(GstBuffer* buf, GstEnginePipeline* pipeline);
|
||||
void FadeoutFinished();
|
||||
void SeekNow();
|
||||
|
||||
|
@ -137,6 +144,8 @@ class GstEngine : public Engine::Base {
|
|||
boost::shared_ptr<GstEnginePipeline> preload_pipeline_;
|
||||
QUrl preloaded_url_;
|
||||
|
||||
QList<BufferConsumer*> buffer_consumers_;
|
||||
|
||||
GQueue* delayq_;
|
||||
float current_scope_[kScopeSize];
|
||||
int current_sample_;
|
||||
|
|
|
@ -17,6 +17,7 @@
|
|||
#include "gstenginepipeline.h"
|
||||
#include "gstequalizer.h"
|
||||
#include "gstengine.h"
|
||||
#include "bufferconsumer.h"
|
||||
|
||||
#include <QDebug>
|
||||
|
||||
|
@ -28,7 +29,6 @@ GstEnginePipeline::GstEnginePipeline(GstEngine* engine)
|
|||
engine_(engine),
|
||||
valid_(false),
|
||||
sink_(GstEngine::kAutoSink),
|
||||
forwards_buffers_(false),
|
||||
rg_enabled_(false),
|
||||
rg_mode_(0),
|
||||
rg_preamp_(0.0),
|
||||
|
@ -268,7 +268,7 @@ void GstEnginePipeline::NewPadCallback(GstElement*, GstPad* pad, gpointer self)
|
|||
GstPad* const audiopad = gst_element_get_pad(instance->audiobin_, "sink");
|
||||
|
||||
if (GST_PAD_IS_LINKED(audiopad)) {
|
||||
qDebug() << "audiopad is already linked. Unlinking old pad." ;
|
||||
qDebug() << "audiopad is already linked. Unlinking old pad.";
|
||||
gst_pad_unlink(audiopad, GST_PAD_PEER(audiopad));
|
||||
}
|
||||
|
||||
|
@ -281,9 +281,15 @@ void GstEnginePipeline::NewPadCallback(GstElement*, GstPad* pad, gpointer self)
|
|||
bool GstEnginePipeline::HandoffCallback(GstPad*, GstBuffer* buf, gpointer self) {
|
||||
GstEnginePipeline* instance = reinterpret_cast<GstEnginePipeline*>(self);
|
||||
|
||||
if (instance->forwards_buffers_) {
|
||||
QList<BufferConsumer*> consumers;
|
||||
{
|
||||
QMutexLocker l(&instance->buffer_consumers_mutex_);
|
||||
consumers = instance->buffer_consumers_;
|
||||
}
|
||||
|
||||
foreach (BufferConsumer* consumer, consumers) {
|
||||
gst_buffer_ref(buf);
|
||||
emit instance->BufferFound(buf);
|
||||
consumer->ConsumeBuffer(buf, instance);
|
||||
}
|
||||
|
||||
return true;
|
||||
|
@ -426,3 +432,18 @@ void GstEnginePipeline::timerEvent(QTimerEvent* e) {
|
|||
|
||||
QObject::timerEvent(e);
|
||||
}
|
||||
|
||||
void GstEnginePipeline::AddBufferConsumer(BufferConsumer *consumer) {
|
||||
QMutexLocker l(&buffer_consumers_mutex_);
|
||||
buffer_consumers_ << consumer;
|
||||
}
|
||||
|
||||
void GstEnginePipeline::RemoveBufferConsumer(BufferConsumer *consumer) {
|
||||
QMutexLocker l(&buffer_consumers_mutex_);
|
||||
buffer_consumers_.removeAll(consumer);
|
||||
}
|
||||
|
||||
void GstEnginePipeline::RemoveAllBufferConsumers() {
|
||||
QMutexLocker l(&buffer_consumers_mutex_);
|
||||
buffer_consumers_.clear();
|
||||
}
|
||||
|
|
|
@ -21,6 +21,7 @@
|
|||
#include <QUrl>
|
||||
#include <QTimeLine>
|
||||
#include <QBasicTimer>
|
||||
#include <QMutex>
|
||||
|
||||
#include <gst/gst.h>
|
||||
#include <boost/scoped_ptr.hpp>
|
||||
|
@ -28,6 +29,7 @@
|
|||
#include "engine_fwd.h"
|
||||
|
||||
class GstEngine;
|
||||
class BufferConsumer;
|
||||
|
||||
struct GstURIDecodeBin;
|
||||
|
||||
|
@ -40,12 +42,16 @@ class GstEnginePipeline : public QObject {
|
|||
|
||||
// Call these setters before Init
|
||||
void set_output_device(const QString& sink, const QString& device);
|
||||
void set_forwards_buffers(bool v) { forwards_buffers_ = v; }
|
||||
void set_replaygain(bool enabled, int mode, float preamp, bool compression);
|
||||
|
||||
// Creates the pipeline, returns false on error
|
||||
bool Init(const QUrl& url);
|
||||
|
||||
// BufferConsumers get fed audio data. Thread-safe.
|
||||
void AddBufferConsumer(BufferConsumer* consumer);
|
||||
void RemoveBufferConsumer(BufferConsumer* consumer);
|
||||
void RemoveAllBufferConsumers();
|
||||
|
||||
// Control the music playback
|
||||
bool SetState(GstState state);
|
||||
bool Seek(qint64 nanosec);
|
||||
|
@ -73,7 +79,6 @@ class GstEnginePipeline : public QObject {
|
|||
signals:
|
||||
void EndOfStreamReached(bool has_next_track);
|
||||
void MetadataFound(const Engine::SimpleMetaBundle& bundle);
|
||||
void BufferFound(GstBuffer* buf);
|
||||
void Error(const QString& message);
|
||||
void FaderFinished();
|
||||
|
||||
|
@ -106,16 +111,23 @@ class GstEnginePipeline : public QObject {
|
|||
|
||||
GstEngine* engine_;
|
||||
|
||||
// General settings for the pipeline
|
||||
bool valid_;
|
||||
QString sink_;
|
||||
QString device_;
|
||||
bool forwards_buffers_;
|
||||
|
||||
// These get called when there is a new audio buffer available
|
||||
QList<BufferConsumer*> buffer_consumers_;
|
||||
QMutex buffer_consumers_mutex_;
|
||||
|
||||
// ReplayGain
|
||||
bool rg_enabled_;
|
||||
int rg_mode_;
|
||||
float rg_preamp_;
|
||||
bool rg_compression_;
|
||||
|
||||
// The URL that is currently playing, and the URL that is to be preloaded
|
||||
// when the current track is close to finishing.
|
||||
QUrl url_;
|
||||
QUrl next_url_;
|
||||
|
||||
|
|
10
src/main.cpp
10
src/main.cpp
|
@ -49,6 +49,11 @@
|
|||
# include "widgets/osd.h"
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_GSTREAMER
|
||||
# include <gst/gstbuffer.h>
|
||||
class GstEnginePipeline;
|
||||
#endif
|
||||
|
||||
// Load sqlite plugin on windows and mac.
|
||||
#ifndef Q_WS_X11
|
||||
# include <QtPlugin>
|
||||
|
@ -100,6 +105,11 @@ int main(int argc, char *argv[]) {
|
|||
qRegisterMetaType<const char*>("const char*");
|
||||
qRegisterMetaType<QNetworkReply*>("QNetworkReply*");
|
||||
|
||||
#ifdef HAVE_GSTREAMER
|
||||
qRegisterMetaType<GstBuffer*>("GstBuffer*");
|
||||
qRegisterMetaType<GstEnginePipeline*>("GstEnginePipeline*");
|
||||
#endif
|
||||
|
||||
|
||||
lastfm::ws::ApiKey = LastFMService::kApiKey;
|
||||
lastfm::ws::SharedSecret = LastFMService::kSecret;
|
||||
|
|
|
@ -1053,6 +1053,9 @@ msgstr ""
|
|||
msgid "Update Library"
|
||||
msgstr ""
|
||||
|
||||
msgid "Visualisations"
|
||||
msgstr ""
|
||||
|
||||
msgid "Library"
|
||||
msgstr ""
|
||||
|
||||
|
@ -1206,6 +1209,9 @@ msgstr ""
|
|||
msgid "Choose color..."
|
||||
msgstr ""
|
||||
|
||||
msgid "Clementine Visualisation"
|
||||
msgstr ""
|
||||
|
||||
msgid "Copy to library..."
|
||||
msgstr ""
|
||||
|
||||
|
|
|
@ -1059,6 +1059,9 @@ msgstr ""
|
|||
msgid "Update Library"
|
||||
msgstr ""
|
||||
|
||||
msgid "Visualisations"
|
||||
msgstr ""
|
||||
|
||||
msgid "Library"
|
||||
msgstr "Knihovna"
|
||||
|
||||
|
@ -1212,6 +1215,9 @@ msgstr "Barva textu"
|
|||
msgid "Choose color..."
|
||||
msgstr "Vyber barvu..."
|
||||
|
||||
msgid "Clementine Visualisation"
|
||||
msgstr ""
|
||||
|
||||
msgid "Copy to library..."
|
||||
msgstr "Zkopírovat do knihovny..."
|
||||
|
||||
|
|
|
@ -1062,6 +1062,9 @@ msgstr ""
|
|||
msgid "Update Library"
|
||||
msgstr ""
|
||||
|
||||
msgid "Visualisations"
|
||||
msgstr ""
|
||||
|
||||
msgid "Library"
|
||||
msgstr "Bibliotek"
|
||||
|
||||
|
@ -1215,6 +1218,9 @@ msgstr "Tekstfarve"
|
|||
msgid "Choose color..."
|
||||
msgstr "Vælg farve..."
|
||||
|
||||
msgid "Clementine Visualisation"
|
||||
msgstr ""
|
||||
|
||||
msgid "Copy to library..."
|
||||
msgstr "Kopiér til bibliotek..."
|
||||
|
||||
|
|
|
@ -1060,6 +1060,9 @@ msgstr ""
|
|||
msgid "Update Library"
|
||||
msgstr ""
|
||||
|
||||
msgid "Visualisations"
|
||||
msgstr ""
|
||||
|
||||
msgid "Library"
|
||||
msgstr "Musiksammlung"
|
||||
|
||||
|
@ -1215,6 +1218,9 @@ msgstr "Text"
|
|||
msgid "Choose color..."
|
||||
msgstr "Farbe wählen..."
|
||||
|
||||
msgid "Clementine Visualisation"
|
||||
msgstr ""
|
||||
|
||||
msgid "Copy to library..."
|
||||
msgstr "In die Musiksammlung kopieren..."
|
||||
|
||||
|
|
|
@ -1063,6 +1063,9 @@ msgstr ""
|
|||
msgid "Update Library"
|
||||
msgstr ""
|
||||
|
||||
msgid "Visualisations"
|
||||
msgstr ""
|
||||
|
||||
msgid "Library"
|
||||
msgstr "Βιβλιοθήκη"
|
||||
|
||||
|
@ -1216,6 +1219,9 @@ msgstr "Χρώμα κειμένου"
|
|||
msgid "Choose color..."
|
||||
msgstr "Επέλεξε χρώμα..."
|
||||
|
||||
msgid "Clementine Visualisation"
|
||||
msgstr ""
|
||||
|
||||
msgid "Copy to library..."
|
||||
msgstr "Αντιγραφή στην βιβλιοθήκη..."
|
||||
|
||||
|
|
|
@ -1057,6 +1057,9 @@ msgstr ""
|
|||
msgid "Update Library"
|
||||
msgstr ""
|
||||
|
||||
msgid "Visualisations"
|
||||
msgstr ""
|
||||
|
||||
msgid "Library"
|
||||
msgstr "Library"
|
||||
|
||||
|
@ -1210,6 +1213,9 @@ msgstr "Text colour"
|
|||
msgid "Choose color..."
|
||||
msgstr "Choose colour..."
|
||||
|
||||
msgid "Clementine Visualisation"
|
||||
msgstr ""
|
||||
|
||||
msgid "Copy to library..."
|
||||
msgstr "Copy to library..."
|
||||
|
||||
|
|
|
@ -1067,6 +1067,9 @@ msgstr ""
|
|||
msgid "Update Library"
|
||||
msgstr ""
|
||||
|
||||
msgid "Visualisations"
|
||||
msgstr ""
|
||||
|
||||
msgid "Library"
|
||||
msgstr "Colección"
|
||||
|
||||
|
@ -1222,6 +1225,9 @@ msgstr "Color del texto"
|
|||
msgid "Choose color..."
|
||||
msgstr "Elegir color..."
|
||||
|
||||
msgid "Clementine Visualisation"
|
||||
msgstr ""
|
||||
|
||||
msgid "Copy to library..."
|
||||
msgstr "Copiar a la colección..."
|
||||
|
||||
|
|
|
@ -1053,6 +1053,9 @@ msgstr ""
|
|||
msgid "Update Library"
|
||||
msgstr ""
|
||||
|
||||
msgid "Visualisations"
|
||||
msgstr ""
|
||||
|
||||
msgid "Library"
|
||||
msgstr ""
|
||||
|
||||
|
@ -1206,6 +1209,9 @@ msgstr ""
|
|||
msgid "Choose color..."
|
||||
msgstr ""
|
||||
|
||||
msgid "Clementine Visualisation"
|
||||
msgstr ""
|
||||
|
||||
msgid "Copy to library..."
|
||||
msgstr "Kopioi kirjastoon"
|
||||
|
||||
|
|
|
@ -1065,6 +1065,9 @@ msgstr ""
|
|||
msgid "Update Library"
|
||||
msgstr ""
|
||||
|
||||
msgid "Visualisations"
|
||||
msgstr ""
|
||||
|
||||
msgid "Library"
|
||||
msgstr "Bibliothèque"
|
||||
|
||||
|
@ -1220,6 +1223,9 @@ msgstr "Couleur du texte"
|
|||
msgid "Choose color..."
|
||||
msgstr "Choisir une couleur..."
|
||||
|
||||
msgid "Clementine Visualisation"
|
||||
msgstr ""
|
||||
|
||||
msgid "Copy to library..."
|
||||
msgstr "Copier dans la bilbiothèque..."
|
||||
|
||||
|
|
|
@ -1055,6 +1055,9 @@ msgstr ""
|
|||
msgid "Update Library"
|
||||
msgstr ""
|
||||
|
||||
msgid "Visualisations"
|
||||
msgstr ""
|
||||
|
||||
msgid "Library"
|
||||
msgstr ""
|
||||
|
||||
|
@ -1208,6 +1211,9 @@ msgstr ""
|
|||
msgid "Choose color..."
|
||||
msgstr ""
|
||||
|
||||
msgid "Clementine Visualisation"
|
||||
msgstr ""
|
||||
|
||||
msgid "Copy to library..."
|
||||
msgstr "Copiar para a biblioteca"
|
||||
|
||||
|
|
|
@ -1064,6 +1064,9 @@ msgstr ""
|
|||
msgid "Update Library"
|
||||
msgstr ""
|
||||
|
||||
msgid "Visualisations"
|
||||
msgstr ""
|
||||
|
||||
msgid "Library"
|
||||
msgstr "Raccolta"
|
||||
|
||||
|
@ -1219,6 +1222,9 @@ msgstr "Colore del testo"
|
|||
msgid "Choose color..."
|
||||
msgstr "Scegli colore..."
|
||||
|
||||
msgid "Clementine Visualisation"
|
||||
msgstr ""
|
||||
|
||||
msgid "Copy to library..."
|
||||
msgstr "Copia nella raccolta..."
|
||||
|
||||
|
|
|
@ -1055,6 +1055,9 @@ msgstr ""
|
|||
msgid "Update Library"
|
||||
msgstr ""
|
||||
|
||||
msgid "Visualisations"
|
||||
msgstr ""
|
||||
|
||||
msgid "Library"
|
||||
msgstr ""
|
||||
|
||||
|
@ -1208,6 +1211,9 @@ msgstr ""
|
|||
msgid "Choose color..."
|
||||
msgstr ""
|
||||
|
||||
msgid "Clementine Visualisation"
|
||||
msgstr ""
|
||||
|
||||
msgid "Copy to library..."
|
||||
msgstr ""
|
||||
|
||||
|
|
|
@ -1059,6 +1059,9 @@ msgstr ""
|
|||
msgid "Update Library"
|
||||
msgstr ""
|
||||
|
||||
msgid "Visualisations"
|
||||
msgstr ""
|
||||
|
||||
msgid "Library"
|
||||
msgstr "Bibliotek"
|
||||
|
||||
|
@ -1212,6 +1215,9 @@ msgstr "Tekstfarge"
|
|||
msgid "Choose color..."
|
||||
msgstr "Velg farge..."
|
||||
|
||||
msgid "Clementine Visualisation"
|
||||
msgstr ""
|
||||
|
||||
msgid "Copy to library..."
|
||||
msgstr "Kopier til bibliotek..."
|
||||
|
||||
|
|
|
@ -1053,6 +1053,9 @@ msgstr ""
|
|||
msgid "Update Library"
|
||||
msgstr ""
|
||||
|
||||
msgid "Visualisations"
|
||||
msgstr ""
|
||||
|
||||
msgid "Library"
|
||||
msgstr "Bibliotèca"
|
||||
|
||||
|
@ -1206,6 +1209,9 @@ msgstr "Color del tèxte"
|
|||
msgid "Choose color..."
|
||||
msgstr ""
|
||||
|
||||
msgid "Clementine Visualisation"
|
||||
msgstr ""
|
||||
|
||||
msgid "Copy to library..."
|
||||
msgstr ""
|
||||
|
||||
|
|
|
@ -1057,6 +1057,9 @@ msgstr ""
|
|||
msgid "Update Library"
|
||||
msgstr ""
|
||||
|
||||
msgid "Visualisations"
|
||||
msgstr ""
|
||||
|
||||
msgid "Library"
|
||||
msgstr "Biblioteka"
|
||||
|
||||
|
@ -1210,6 +1213,9 @@ msgstr "Kolor tekstu"
|
|||
msgid "Choose color..."
|
||||
msgstr "Wybierz kolor..."
|
||||
|
||||
msgid "Clementine Visualisation"
|
||||
msgstr ""
|
||||
|
||||
msgid "Copy to library..."
|
||||
msgstr "Skopiuj do biblioteki..."
|
||||
|
||||
|
|
|
@ -1060,6 +1060,9 @@ msgstr ""
|
|||
msgid "Update Library"
|
||||
msgstr ""
|
||||
|
||||
msgid "Visualisations"
|
||||
msgstr ""
|
||||
|
||||
msgid "Library"
|
||||
msgstr "Biblioteca"
|
||||
|
||||
|
@ -1213,6 +1216,9 @@ msgstr "Cor do Texto"
|
|||
msgid "Choose color..."
|
||||
msgstr "Escolher a cor.."
|
||||
|
||||
msgid "Clementine Visualisation"
|
||||
msgstr ""
|
||||
|
||||
msgid "Copy to library..."
|
||||
msgstr "Copiar para a biblioteca"
|
||||
|
||||
|
|
|
@ -1053,6 +1053,9 @@ msgstr ""
|
|||
msgid "Update Library"
|
||||
msgstr ""
|
||||
|
||||
msgid "Visualisations"
|
||||
msgstr ""
|
||||
|
||||
msgid "Library"
|
||||
msgstr ""
|
||||
|
||||
|
@ -1206,6 +1209,9 @@ msgstr ""
|
|||
msgid "Choose color..."
|
||||
msgstr ""
|
||||
|
||||
msgid "Clementine Visualisation"
|
||||
msgstr ""
|
||||
|
||||
msgid "Copy to library..."
|
||||
msgstr ""
|
||||
|
||||
|
|
|
@ -1054,6 +1054,9 @@ msgstr ""
|
|||
msgid "Update Library"
|
||||
msgstr ""
|
||||
|
||||
msgid "Visualisations"
|
||||
msgstr ""
|
||||
|
||||
msgid "Library"
|
||||
msgstr "Bibliotecă"
|
||||
|
||||
|
@ -1207,6 +1210,9 @@ msgstr "Culoare text"
|
|||
msgid "Choose color..."
|
||||
msgstr "Alege culoare..."
|
||||
|
||||
msgid "Clementine Visualisation"
|
||||
msgstr ""
|
||||
|
||||
msgid "Copy to library..."
|
||||
msgstr "Copiază în bibliotecă..."
|
||||
|
||||
|
|
|
@ -1059,6 +1059,9 @@ msgstr ""
|
|||
msgid "Update Library"
|
||||
msgstr ""
|
||||
|
||||
msgid "Visualisations"
|
||||
msgstr ""
|
||||
|
||||
msgid "Library"
|
||||
msgstr "Коллекция"
|
||||
|
||||
|
@ -1213,6 +1216,9 @@ msgstr "Цвет текста"
|
|||
msgid "Choose color..."
|
||||
msgstr "Выберете цвет"
|
||||
|
||||
msgid "Clementine Visualisation"
|
||||
msgstr ""
|
||||
|
||||
msgid "Copy to library..."
|
||||
msgstr "Копировать в коллекцию..."
|
||||
|
||||
|
|
|
@ -1061,6 +1061,9 @@ msgstr ""
|
|||
msgid "Update Library"
|
||||
msgstr ""
|
||||
|
||||
msgid "Visualisations"
|
||||
msgstr ""
|
||||
|
||||
msgid "Library"
|
||||
msgstr "Zbierka"
|
||||
|
||||
|
@ -1214,6 +1217,9 @@ msgstr "Farba písma"
|
|||
msgid "Choose color..."
|
||||
msgstr "Vybrať farbu..."
|
||||
|
||||
msgid "Clementine Visualisation"
|
||||
msgstr ""
|
||||
|
||||
msgid "Copy to library..."
|
||||
msgstr "Skopírovať do zbierky..."
|
||||
|
||||
|
|
|
@ -1062,6 +1062,9 @@ msgstr ""
|
|||
msgid "Update Library"
|
||||
msgstr ""
|
||||
|
||||
msgid "Visualisations"
|
||||
msgstr ""
|
||||
|
||||
msgid "Library"
|
||||
msgstr "Bibliotek"
|
||||
|
||||
|
@ -1215,6 +1218,9 @@ msgstr "Textfärg"
|
|||
msgid "Choose color..."
|
||||
msgstr "Välj färg..."
|
||||
|
||||
msgid "Clementine Visualisation"
|
||||
msgstr ""
|
||||
|
||||
msgid "Copy to library..."
|
||||
msgstr "Kopiera till bibliotek..."
|
||||
|
||||
|
|
|
@ -1053,6 +1053,9 @@ msgstr ""
|
|||
msgid "Update Library"
|
||||
msgstr ""
|
||||
|
||||
msgid "Visualisations"
|
||||
msgstr ""
|
||||
|
||||
msgid "Library"
|
||||
msgstr ""
|
||||
|
||||
|
@ -1206,6 +1209,9 @@ msgstr ""
|
|||
msgid "Choose color..."
|
||||
msgstr ""
|
||||
|
||||
msgid "Clementine Visualisation"
|
||||
msgstr ""
|
||||
|
||||
msgid "Copy to library..."
|
||||
msgstr ""
|
||||
|
||||
|
|
|
@ -1044,6 +1044,9 @@ msgstr ""
|
|||
msgid "Update Library"
|
||||
msgstr ""
|
||||
|
||||
msgid "Visualisations"
|
||||
msgstr ""
|
||||
|
||||
msgid "Library"
|
||||
msgstr ""
|
||||
|
||||
|
@ -1197,6 +1200,9 @@ msgstr ""
|
|||
msgid "Choose color..."
|
||||
msgstr ""
|
||||
|
||||
msgid "Clementine Visualisation"
|
||||
msgstr ""
|
||||
|
||||
msgid "Copy to library..."
|
||||
msgstr ""
|
||||
|
||||
|
|
|
@ -1053,6 +1053,9 @@ msgstr ""
|
|||
msgid "Update Library"
|
||||
msgstr ""
|
||||
|
||||
msgid "Visualisations"
|
||||
msgstr ""
|
||||
|
||||
msgid "Library"
|
||||
msgstr ""
|
||||
|
||||
|
@ -1206,6 +1209,9 @@ msgstr ""
|
|||
msgid "Choose color..."
|
||||
msgstr ""
|
||||
|
||||
msgid "Clementine Visualisation"
|
||||
msgstr ""
|
||||
|
||||
msgid "Copy to library..."
|
||||
msgstr ""
|
||||
|
||||
|
|
|
@ -59,6 +59,7 @@ target_link_libraries(clementine_ui
|
|||
clementine_playlistparsers
|
||||
clementine_radio
|
||||
clementine_transcoder
|
||||
clementine_visualisations
|
||||
)
|
||||
|
||||
add_translation_source(ui ${SOURCES} ${MOC} ${UIC})
|
||||
|
|
|
@ -51,6 +51,7 @@
|
|||
#include "ui/iconloader.h"
|
||||
#include "ui/settingsdialog.h"
|
||||
#include "ui/systemtrayicon.h"
|
||||
#include "visualisations/visualisationcontainer.h"
|
||||
#include "widgets/errordialog.h"
|
||||
#include "widgets/multiloadingindicator.h"
|
||||
#include "widgets/osd.h"
|
||||
|
@ -118,6 +119,7 @@ MainWindow::MainWindow(NetworkAccessManager* network, Engine::Type engine, QWidg
|
|||
transcode_dialog_(new TranscodeDialog),
|
||||
global_shortcuts_dialog_(new GlobalShortcutsDialog(global_shortcuts_)),
|
||||
error_dialog_(new ErrorDialog),
|
||||
visualisation_(new VisualisationContainer),
|
||||
playlist_menu_(new QMenu(this)),
|
||||
library_sort_model_(new QSortFilterProxyModel(this)),
|
||||
track_position_timer_(new QTimer(this)),
|
||||
|
@ -151,8 +153,10 @@ MainWindow::MainWindow(NetworkAccessManager* network, Engine::Type engine, QWidg
|
|||
player_->Init();
|
||||
|
||||
#ifdef HAVE_GSTREAMER
|
||||
if (GstEngine* engine = qobject_cast<GstEngine*>(player_->GetEngine()))
|
||||
if (GstEngine* engine = qobject_cast<GstEngine*>(player_->GetEngine())) {
|
||||
settings_dialog_->SetGstEngine(engine);
|
||||
visualisation_->SetEngine(engine);
|
||||
}
|
||||
#endif
|
||||
|
||||
// Models
|
||||
|
@ -233,6 +237,7 @@ MainWindow::MainWindow(NetworkAccessManager* network, Engine::Type engine, QWidg
|
|||
connect(ui_->action_configure_global_shortcuts, SIGNAL(triggered()), global_shortcuts_dialog_.get(), SLOT(show()));
|
||||
connect(ui_->action_jump, SIGNAL(triggered()), ui_->playlist->view(), SLOT(JumpToCurrentlyPlayingTrack()));
|
||||
connect(ui_->action_update_library, SIGNAL(triggered()), library_, SLOT(IncrementalScan()));
|
||||
connect(ui_->action_visualisations, SIGNAL(triggered()), visualisation_.get(), SLOT(show()));
|
||||
|
||||
// Give actions to buttons
|
||||
ui_->forward_button->setDefaultAction(ui_->action_next_track);
|
||||
|
|
|
@ -54,6 +54,7 @@ class Song;
|
|||
class SystemTrayIcon;
|
||||
class TrackSlider;
|
||||
class TranscodeDialog;
|
||||
class VisualisationContainer;
|
||||
class Ui_MainWindow;
|
||||
|
||||
class QSortFilterProxyModel;
|
||||
|
@ -175,6 +176,7 @@ class MainWindow : public QMainWindow {
|
|||
boost::scoped_ptr<TranscodeDialog> transcode_dialog_;
|
||||
boost::scoped_ptr<GlobalShortcutsDialog> global_shortcuts_dialog_;
|
||||
boost::scoped_ptr<ErrorDialog> error_dialog_;
|
||||
boost::scoped_ptr<VisualisationContainer> visualisation_;
|
||||
|
||||
QMenu* playlist_menu_;
|
||||
QAction* playlist_play_pause_;
|
||||
|
|
|
@ -341,7 +341,7 @@
|
|||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>804</width>
|
||||
<height>25</height>
|
||||
<height>23</height>
|
||||
</rect>
|
||||
</property>
|
||||
<widget class="QMenu" name="menuMusic">
|
||||
|
@ -398,6 +398,7 @@
|
|||
</property>
|
||||
<addaction name="action_cover_manager"/>
|
||||
<addaction name="action_equalizer"/>
|
||||
<addaction name="action_visualisations"/>
|
||||
<addaction name="action_transcode"/>
|
||||
<addaction name="separator"/>
|
||||
<addaction name="action_update_library"/>
|
||||
|
@ -597,6 +598,11 @@
|
|||
<string>Update Library</string>
|
||||
</property>
|
||||
</action>
|
||||
<action name="action_visualisations">
|
||||
<property name="text">
|
||||
<string>Visualisations</string>
|
||||
</property>
|
||||
</action>
|
||||
</widget>
|
||||
<layoutdefault spacing="6" margin="11"/>
|
||||
<customwidgets>
|
||||
|
|
|
@ -0,0 +1,29 @@
|
|||
cmake_minimum_required(VERSION 2.6)
|
||||
|
||||
include_directories(${CMAKE_CURRENT_BINARY_DIR} ${CMAKE_CURRENT_SOURCE_DIR})
|
||||
include_directories(${PROJECTM_INCLUDE_DIRS})
|
||||
|
||||
set(SOURCES
|
||||
projectmvisualisation.cpp
|
||||
visualisationcontainer.cpp
|
||||
)
|
||||
|
||||
set(HEADERS
|
||||
projectmvisualisation.h
|
||||
visualisationcontainer.h
|
||||
)
|
||||
|
||||
qt4_wrap_cpp(MOC ${HEADERS})
|
||||
|
||||
add_library(clementine_visualisations
|
||||
${SOURCES}
|
||||
${MOC}
|
||||
)
|
||||
|
||||
target_link_libraries(clementine_visualisations
|
||||
clementine_core
|
||||
clementine_engines
|
||||
${PROJECTM_LIBRARIES}
|
||||
)
|
||||
|
||||
add_translation_source(visualisations ${SOURCES} ${MOC})
|
|
@ -0,0 +1,67 @@
|
|||
/* 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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "projectmvisualisation.h"
|
||||
|
||||
#include <QTimerEvent>
|
||||
#include <QtDebug>
|
||||
|
||||
#include <libprojectM/projectM.hpp>
|
||||
|
||||
ProjectMVisualisation::ProjectMVisualisation(QWidget *parent)
|
||||
: QGLWidget(parent),
|
||||
projectm_(NULL)
|
||||
{
|
||||
}
|
||||
|
||||
ProjectMVisualisation::~ProjectMVisualisation() {
|
||||
}
|
||||
|
||||
void ProjectMVisualisation::showEvent(QShowEvent *) {
|
||||
redraw_timer_.start(1000/25, this);
|
||||
}
|
||||
|
||||
void ProjectMVisualisation::hideEvent(QHideEvent *) {
|
||||
redraw_timer_.stop();
|
||||
}
|
||||
|
||||
void ProjectMVisualisation::timerEvent(QTimerEvent* e) {
|
||||
if (e->timerId() == redraw_timer_.timerId())
|
||||
update();
|
||||
}
|
||||
|
||||
void ProjectMVisualisation::initializeGL() {
|
||||
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
||||
|
||||
projectm_.reset(new projectM("/usr/share/projectM/config.inp"));
|
||||
projectm_->selectPreset(100);
|
||||
}
|
||||
|
||||
void ProjectMVisualisation::paintGL() {
|
||||
projectm_->renderFrame();
|
||||
}
|
||||
|
||||
void ProjectMVisualisation::resizeGL(int w, int h) {
|
||||
|
||||
}
|
||||
|
||||
void ProjectMVisualisation::ConsumeBuffer(GstBuffer *buffer, GstEnginePipeline*) {
|
||||
const int samples = GST_BUFFER_SIZE(buffer) / sizeof(short);
|
||||
const short* data = reinterpret_cast<short*>(GST_BUFFER_DATA(buffer));
|
||||
|
||||
projectm_->pcm()->addPCM16Data(data, samples);
|
||||
gst_buffer_unref(buffer);
|
||||
}
|
|
@ -0,0 +1,54 @@
|
|||
/* 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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef PROJECTMVISUALISATION_H
|
||||
#define PROJECTMVISUALISATION_H
|
||||
|
||||
#include <QGLWidget>
|
||||
#include <QBasicTimer>
|
||||
|
||||
#include <boost/scoped_ptr.hpp>
|
||||
|
||||
#include "engines/bufferconsumer.h"
|
||||
|
||||
class projectM;
|
||||
|
||||
class ProjectMVisualisation : public QGLWidget, public BufferConsumer {
|
||||
Q_OBJECT
|
||||
public:
|
||||
ProjectMVisualisation(QWidget *parent = 0);
|
||||
~ProjectMVisualisation();
|
||||
|
||||
// QGLWidget
|
||||
void paintGL();
|
||||
void resizeGL(int w, int h);
|
||||
void initializeGL();
|
||||
|
||||
// BufferConsumer
|
||||
void ConsumeBuffer(GstBuffer *buffer, GstEnginePipeline*);
|
||||
|
||||
protected:
|
||||
// QWidget
|
||||
void hideEvent(QHideEvent *);
|
||||
void showEvent(QShowEvent *);
|
||||
void timerEvent(QTimerEvent *);
|
||||
|
||||
private:
|
||||
boost::scoped_ptr<projectM> projectm_;
|
||||
QBasicTimer redraw_timer_;
|
||||
};
|
||||
|
||||
#endif // PROJECTMVISUALISATION_H
|
|
@ -0,0 +1,52 @@
|
|||
/* 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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "visualisationcontainer.h"
|
||||
#include "projectmvisualisation.h"
|
||||
#include "engines/gstengine.h"
|
||||
|
||||
#include <QHBoxLayout>
|
||||
|
||||
VisualisationContainer::VisualisationContainer(QWidget *parent)
|
||||
: QWidget(parent),
|
||||
engine_(NULL),
|
||||
vis_(new ProjectMVisualisation(this))
|
||||
{
|
||||
setWindowTitle(tr("Clementine Visualisation"));
|
||||
resize(512, 512);
|
||||
|
||||
QHBoxLayout* layout = new QHBoxLayout(this);
|
||||
layout->setMargin(0);
|
||||
layout->setSpacing(0);
|
||||
layout->addWidget(vis_);
|
||||
setLayout(layout);
|
||||
}
|
||||
|
||||
void VisualisationContainer::SetEngine(GstEngine* engine) {
|
||||
engine_ = engine;
|
||||
if (isVisible())
|
||||
engine_->AddBufferConsumer(vis_);
|
||||
}
|
||||
|
||||
void VisualisationContainer::showEvent(QShowEvent*) {
|
||||
if (engine_)
|
||||
engine_->AddBufferConsumer(vis_);
|
||||
}
|
||||
|
||||
void VisualisationContainer::hideEvent(QHideEvent*) {
|
||||
if (engine_)
|
||||
engine_->RemoveBufferConsumer(vis_);
|
||||
}
|
|
@ -0,0 +1,43 @@
|
|||
/* 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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef VISUALISATIONCONTAINER_H
|
||||
#define VISUALISATIONCONTAINER_H
|
||||
|
||||
#include <QWidget>
|
||||
|
||||
class ProjectMVisualisation;
|
||||
class GstEngine;
|
||||
|
||||
class VisualisationContainer : public QWidget {
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
VisualisationContainer(QWidget* parent = 0);
|
||||
|
||||
void SetEngine(GstEngine* engine);
|
||||
|
||||
protected:
|
||||
// QWidget
|
||||
void showEvent(QShowEvent*);
|
||||
void hideEvent(QHideEvent*);
|
||||
|
||||
private:
|
||||
GstEngine* engine_;
|
||||
ProjectMVisualisation* vis_;
|
||||
};
|
||||
|
||||
#endif // VISUALISATIONCONTAINER_H
|
Loading…
Reference in New Issue