mirror of
https://github.com/tomahawk-player/tomahawk.git
synced 2025-07-31 19:30:21 +02:00
First attempt to add DSP support
This commit is contained in:
@@ -215,6 +215,7 @@ list(APPEND libSources
|
||||
|
||||
audio/AudioEngine.cpp
|
||||
audio/AudioOutput.cpp
|
||||
audio/VlcDspHack.cpp
|
||||
|
||||
collection/Collection.cpp
|
||||
collection/ArtistsRequest.cpp
|
||||
@@ -506,6 +507,7 @@ TARGET_LINK_LIBRARIES( tomahawklib
|
||||
LINK_PRIVATE
|
||||
${PHONON_LIBRARY}
|
||||
${LIBVLC_LIBRARY}
|
||||
${LIBVLCCORE_LIBRARY}
|
||||
|
||||
# Thirdparty shipped with tomahawk
|
||||
${LIBPORTFWD_LIBRARIES}
|
||||
|
@@ -1341,7 +1341,7 @@ AudioEngine::setCurrentTrackPlaylist( const playlistinterface_ptr& playlist )
|
||||
|
||||
|
||||
void
|
||||
AudioEngine::setDspCallback( void ( *cb ) ( signed short*, int, int ) )
|
||||
AudioEngine::setDspCallback( void ( *cb ) ( float*, int, int ) )
|
||||
{
|
||||
Q_D( AudioEngine );
|
||||
|
||||
|
@@ -109,7 +109,7 @@ public:
|
||||
*/
|
||||
qint64 currentTrackTotalTime() const;
|
||||
|
||||
void setDspCallback( void ( *cb ) ( signed short* samples, int nb_channels, int nb_samples ) );
|
||||
void setDspCallback( void ( *cb ) ( float* samples, int nb_channels, int nb_samples ) );
|
||||
|
||||
public slots:
|
||||
void playPause();
|
||||
|
@@ -20,6 +20,7 @@
|
||||
|
||||
#include "AudioEngine.h"
|
||||
#include "AudioOutput.h"
|
||||
#include "VlcDspHack.h"
|
||||
|
||||
#include "utils/Logger.h"
|
||||
|
||||
@@ -85,10 +86,11 @@ AudioOutput::AudioOutput( QObject* parent )
|
||||
args << "--no-snapshot-preview";
|
||||
args << "--no-xlib";
|
||||
args << "--services-discovery=''";
|
||||
// args << "--no-one-instance";
|
||||
args << "--no-video";
|
||||
// args << "--audio-filter=dsp";
|
||||
// args << QString("--dsp-callback=%1").arg((quint64)&AudioOutput::s_dspCallback, 0, 16).toAscii();
|
||||
#ifdef VLC_DSP_PLUGIN_ENABLED
|
||||
args << "--audio-filter=dsp";
|
||||
args << QString("--dsp-callback=%1").arg((quint64)&AudioOutput::s_dspCallback, 0, 16).toAscii();
|
||||
#endif
|
||||
|
||||
QVarLengthArray< const char * , 64 > vlcArgs( args.size() );
|
||||
for ( int i = 0 ; i < args.size() ; ++i ) {
|
||||
@@ -138,6 +140,8 @@ AudioOutput::AudioOutput( QObject* parent )
|
||||
AudioOutput::~AudioOutput()
|
||||
{
|
||||
tDebug() << Q_FUNC_INFO;
|
||||
|
||||
// TODO
|
||||
}
|
||||
|
||||
|
||||
@@ -218,6 +222,10 @@ AudioOutput::setCurrentSource(MediaStream* stream)
|
||||
|
||||
libvlc_media_player_set_media( vlcPlayer, vlcMedia );
|
||||
|
||||
#ifdef VLC_DSP_PLUGIN_ENABLED
|
||||
// This is very, very tricky
|
||||
VlcDspHackInstall( vlcPlayer );
|
||||
#endif
|
||||
|
||||
if ( stream->type() == MediaStream::Url ) {
|
||||
m_totalTime = libvlc_media_get_duration( vlcMedia );
|
||||
@@ -479,9 +487,9 @@ AudioOutput::vlcEventCallback( const libvlc_event_t* event, void* opaque )
|
||||
|
||||
|
||||
void
|
||||
AudioOutput::s_dspCallback( signed short* samples, int nb_channels, int nb_samples )
|
||||
AudioOutput::s_dspCallback( float* samples, int nb_channels, int nb_samples )
|
||||
{
|
||||
tDebug() << Q_FUNC_INFO;
|
||||
// tDebug() << Q_FUNC_INFO;
|
||||
|
||||
if ( AudioOutput::instance()->dspPluginCallback ) {
|
||||
AudioOutput::instance()->dspPluginCallback( samples, nb_channels, nb_samples );
|
||||
@@ -490,7 +498,7 @@ AudioOutput::s_dspCallback( signed short* samples, int nb_channels, int nb_sampl
|
||||
|
||||
|
||||
void
|
||||
AudioOutput::setDspCallback( void ( *cb ) ( signed short*, int, int ) )
|
||||
AudioOutput::setDspCallback( void ( *cb ) ( float*, int, int ) )
|
||||
{
|
||||
dspPluginCallback = cb;
|
||||
}
|
||||
|
@@ -61,7 +61,7 @@ public:
|
||||
qint64 totalTime();
|
||||
void setAutoDelete ( bool ad );
|
||||
|
||||
void setDspCallback( void ( *cb ) ( signed short*, int, int ) );
|
||||
void setDspCallback( void ( *cb ) ( float*, int, int ) );
|
||||
|
||||
static AudioOutput* instance();
|
||||
|
||||
@@ -78,7 +78,7 @@ private:
|
||||
void setTotalTime( qint64 time );
|
||||
|
||||
static void vlcEventCallback( const libvlc_event_t *event, void *opaque );
|
||||
static void s_dspCallback( signed short* samples, int nb_channels, int nb_samples );
|
||||
static void s_dspCallback( float* samples, int nb_channels, int nb_samples );
|
||||
|
||||
static AudioOutput* s_instance;
|
||||
AudioState currentState;
|
||||
@@ -91,7 +91,7 @@ private:
|
||||
qint64 m_totalTime;
|
||||
bool m_aboutToFinish;
|
||||
|
||||
void ( *dspPluginCallback ) ( signed short* samples, int nb_channels, int nb_samples );
|
||||
void ( *dspPluginCallback ) ( float* samples, int nb_channels, int nb_samples );
|
||||
|
||||
libvlc_instance_t* vlcInstance;
|
||||
libvlc_media_player_t* vlcPlayer;
|
||||
|
24
src/libtomahawk/audio/VlcDspHack.cpp
Normal file
24
src/libtomahawk/audio/VlcDspHack.cpp
Normal file
@@ -0,0 +1,24 @@
|
||||
#include "VlcDspHack_p.h"
|
||||
|
||||
#ifdef VLC_DSP_PLUGIN_ENABLED
|
||||
|
||||
void
|
||||
VlcDspHackInstall( libvlc_media_player_t* vlcPlayer )
|
||||
{
|
||||
if ( vlcPlayer->input.p_resource != 0 ) {
|
||||
audio_output_t *aout = input_resource_GetAout( vlcPlayer->input.p_resource );
|
||||
if ( aout != 0 ) {
|
||||
var_Create( (vlc_object_t*)aout, "audio-filter", 0x0040 /*VLC_VAR_STRING*/ );
|
||||
|
||||
vlc_value_t val;
|
||||
val.psz_string = (char*)"dsp";
|
||||
var_SetChecked( (vlc_object_t*)aout, "audio-filter", 0x0040 /*VLC_VAR_STRING*/, val );
|
||||
|
||||
aout->event.restart_request( aout, 1 /*AOUT_RESTART_FILTERS*/ );
|
||||
|
||||
input_resource_PutAout( vlcPlayer->input.p_resource, aout );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endif // VLC_DSP_PLUGIN_ENABLED
|
28
src/libtomahawk/audio/VlcDspHack.h
Normal file
28
src/libtomahawk/audio/VlcDspHack.h
Normal file
@@ -0,0 +1,28 @@
|
||||
#ifndef VLCDSPHACK_H
|
||||
#define VLCDSPHACK_H
|
||||
|
||||
/*
|
||||
* Very tricky technique to enable DSP plugin support
|
||||
* There is no other way to do this with libvlc for the moment
|
||||
*
|
||||
* A VLC audio filter plugin specificaly made for Tomahawk
|
||||
* is necessary to get it functionning
|
||||
*
|
||||
* TODO : Check thoroughly if both libvlc_media_player_t and audio_output
|
||||
* structures are identical to those in the running libvlccore.so
|
||||
* (checking if libVLC version is >= than the one used to compile Tomahawk
|
||||
* and verifying pointers integrity should be enough.
|
||||
* + check if audio filter "dsp" is present in libVLC plugins list)
|
||||
*/
|
||||
|
||||
//#define VLC_DSP_PLUGIN_ENABLED
|
||||
|
||||
#ifdef VLC_DSP_PLUGIN_ENABLED
|
||||
|
||||
struct libvlc_media_player_t;
|
||||
|
||||
void VlcDspHackInstall( libvlc_media_player_t* vlcPlayer );
|
||||
|
||||
#endif // VLC_DSP_PLUGIN_ENABLED
|
||||
|
||||
#endif // VLCDSPHACK_H
|
107
src/libtomahawk/audio/VlcDspHack_p.h
Normal file
107
src/libtomahawk/audio/VlcDspHack_p.h
Normal file
@@ -0,0 +1,107 @@
|
||||
#ifndef VLCDSPHACK_P_H
|
||||
#define VLCDSPHACK_P_H
|
||||
|
||||
#include "VlcDspHack.h"
|
||||
|
||||
#ifdef VLC_DSP_PLUGIN_ENABLED
|
||||
|
||||
#include <pthread.h>
|
||||
|
||||
#include <vlc/libvlc.h>
|
||||
#include <vlc/libvlc_media.h>
|
||||
#include <vlc/libvlc_media_player.h>
|
||||
#include <vlc/libvlc_events.h>
|
||||
#include <vlc/libvlc_version.h>
|
||||
|
||||
// TODO : Replace all these copy-pasted strutures by vlc/plugins/?.h includes
|
||||
|
||||
typedef struct audio_output audio_output_t;
|
||||
typedef struct input_resource_t input_resource_t;
|
||||
typedef struct vlc_object_t vlc_object_t;
|
||||
typedef struct vlc_list_t vlc_list_t;
|
||||
typedef int64_t mtime_t;
|
||||
typedef pthread_mutex_t vlc_mutex_t;
|
||||
|
||||
typedef union
|
||||
{
|
||||
int64_t i_int;
|
||||
bool b_bool;
|
||||
float f_float;
|
||||
char * psz_string;
|
||||
void * p_address;
|
||||
vlc_object_t * p_object;
|
||||
vlc_list_t * p_list;
|
||||
mtime_t i_time;
|
||||
struct { int32_t x; int32_t y; } coords;
|
||||
|
||||
} vlc_value_t;
|
||||
|
||||
struct audio_output
|
||||
{
|
||||
const char *psz_object_type;
|
||||
char *psz_header;
|
||||
int i_flags;
|
||||
bool b_force;
|
||||
void *p_libvlc;
|
||||
void * p_parent;
|
||||
|
||||
void *sys;
|
||||
int (*start)(audio_output_t *, void *fmt);
|
||||
void (*stop)(audio_output_t *);
|
||||
int (*time_get)(audio_output_t *, void *delay);
|
||||
void (*play)(audio_output_t *, void *);
|
||||
void (*pause)( audio_output_t *, bool pause, mtime_t date);
|
||||
void (*flush)( audio_output_t *, bool wait);
|
||||
int (*volume_set)(audio_output_t *, float volume);
|
||||
int (*mute_set)(audio_output_t *, bool mute);
|
||||
int (*device_select)(audio_output_t *, const char *id);
|
||||
struct {
|
||||
void (*volume_report)(audio_output_t *, float);
|
||||
void (*mute_report)(audio_output_t *, bool);
|
||||
void (*policy_report)(audio_output_t *, bool);
|
||||
void (*device_report)(audio_output_t *, const char *);
|
||||
void (*hotplug_report)(audio_output_t *, const char *, const char *);
|
||||
int (*gain_request)(audio_output_t *, float);
|
||||
void (*restart_request)(audio_output_t *, unsigned);
|
||||
} event;
|
||||
};
|
||||
|
||||
|
||||
struct libvlc_media_player_t
|
||||
{
|
||||
const char *psz_object_type;
|
||||
char *psz_header;
|
||||
int i_flags;
|
||||
bool b_force;
|
||||
void *p_libvlc;
|
||||
void *p_parent;
|
||||
|
||||
int i_refcount;
|
||||
vlc_mutex_t object_lock;
|
||||
|
||||
struct
|
||||
{
|
||||
void *p_thread;
|
||||
input_resource_t *p_resource;
|
||||
vlc_mutex_t lock;
|
||||
} input;
|
||||
|
||||
void *p_libvlc_instance;
|
||||
void *p_md;
|
||||
void *p_event_manager;
|
||||
int state;
|
||||
};
|
||||
|
||||
extern "C" {
|
||||
audio_output_t* input_resource_GetAout(input_resource_t*);
|
||||
void input_resource_PutAout(input_resource_t*, audio_output_t*);
|
||||
int var_Create(vlc_object_t *, const char *, int );
|
||||
int var_SetChecked( vlc_object_t *, const char *, int, vlc_value_t );
|
||||
static inline void aout_RestartRequest(audio_output_t *aout, unsigned mode){
|
||||
aout->event.restart_request(aout, mode);
|
||||
}
|
||||
};
|
||||
|
||||
#endif // VLC_DSP_PLUGIN_ENABLED
|
||||
|
||||
#endif // VLCDSPHACK_P_H
|
Reference in New Issue
Block a user