From a4982bb4d3fd9908aa01c824ac6202ac8618ac24 Mon Sep 17 00:00:00 2001 From: Mikko Rasa Date: Sat, 17 Oct 2015 02:48:59 +0300 Subject: [PATCH] Support changing audio and SPU channels --- source/client.cpp | 42 +++++++++++++++++++++++++++++ source/client.h | 3 +++ source/xinestream.cpp | 63 ++++++++++++++++++++++++++++++++++++++++++- source/xinestream.h | 13 +++++++++ 4 files changed, 120 insertions(+), 1 deletion(-) diff --git a/source/client.cpp b/source/client.cpp index 8c84e26..6047796 100644 --- a/source/client.cpp +++ b/source/client.cpp @@ -94,6 +94,10 @@ void Client::process_command(const string &cmd) get_stream().pause(); else if(keyword=="stop") get_stream().stop(); + else if(keyword=="select_audio") + set_audio_channel(args); + else if(keyword=="select_spu") + set_spu_channel(args); else throw runtime_error("Invalid command"); } @@ -126,12 +130,31 @@ void Client::list_directory(const FS::Path &dn) } } +void Client::set_audio_channel(const string &arg) +{ + XineStream &stream = get_stream(); + if(arg=="off") + stream.set_audio_off(); + else + stream.set_audio_channel(lexical_cast(arg)); +} + +void Client::set_spu_channel(const string &arg) +{ + XineStream &stream = get_stream(); + if(arg=="off") + stream.set_spu_off(); + else + stream.set_spu_channel(lexical_cast(arg)); +} + void Client::stream_created(XineStream &stream) { stream.signal_state_changed.connect(sigc::mem_fun(this, &Client::stream_state_changed)); stream.signal_title_changed.connect(sigc::mem_fun(this, &Client::stream_title_changed)); stream.signal_duration_changed.connect(sigc::mem_fun(this, &Client::stream_duration_changed)); stream.signal_position_changed.connect(sigc::mem_fun(this, &Client::stream_position_changed)); + stream.signal_channels_changed.connect(sigc::mem_fun(this, &Client::stream_channels_changed)); MutexLock lock(stream.get_mutex()); stream_state_changed(stream.get_state()); @@ -142,6 +165,8 @@ void Client::stream_created(XineStream &stream) if(const Time::TimeDelta &dur = stream.get_duration()) stream_duration_changed(dur); + + stream_channels_changed(); } void Client::stream_destroyed() @@ -172,3 +197,20 @@ void Client::stream_position_changed(const Time::TimeDelta &pos) last_position = pos; } } + +void Client::stream_channels_changed() +{ + XineStream &stream = get_stream(); + + const vector &audio_channels = stream.get_audio_channels(); + send_reply(format("audio_count %d", audio_channels.size())); + for(unsigned i=0; i &spu_channels = stream.get_spu_channels(); + send_reply(format("spu_count %d", spu_channels.size())); + for(unsigned i=0; i=audio_channels.size()) + throw out_of_range("XineStream::set_audio_channel"); + + xine_set_param(stream, XINE_PARAM_AUDIO_CHANNEL_LOGICAL, i); +} + +void XineStream::set_audio_off() +{ + xine_set_param(stream, XINE_PARAM_AUDIO_CHANNEL_LOGICAL, -2); +} + +void XineStream::set_spu_channel(unsigned i) +{ + if(i>=spu_channels.size()) + throw out_of_range("XineStream::set_spu_channel"); + + xine_set_param(stream, XINE_PARAM_SPU_CHANNEL, i); +} + +void XineStream::set_spu_off() +{ + xine_set_param(stream, XINE_PARAM_SPU_CHANNEL, -2); +} + void XineStream::play() { if(state==STOPPED) @@ -82,6 +110,12 @@ void XineStream::tick() } update_info(); + + if(channels_changed) + { + channels_changed = false; + update_channels(); + } } void XineStream::update_info() @@ -112,6 +146,30 @@ void XineStream::update_info() } } +void XineStream::update_channels() +{ + MutexLock lock(mutex); + char langbuf[XINE_LANG_MAX]; + + unsigned n_audio = xine_get_stream_info(stream, XINE_STREAM_INFO_MAX_AUDIO_CHANNEL); + audio_channels.resize(n_audio); + for(unsigned i=0; i +#include #include #include #include @@ -23,6 +24,8 @@ public: sigc::signal signal_title_changed; sigc::signal signal_duration_changed; sigc::signal signal_position_changed; + sigc::signal signal_channels_changed; + sigc::signal signal_finished; private: XineEngine &engine; @@ -33,6 +36,9 @@ private: std::string title; Msp::Time::TimeDelta duration; Msp::Time::TimeDelta position; + std::vector audio_channels; + std::vector spu_channels; + bool channels_changed; public: XineStream(XineEngine &, const std::string &); @@ -43,6 +49,12 @@ public: const Msp::Time::TimeDelta &get_duration() const { return duration; } const Msp::Time::TimeDelta &get_position() const { return position; } const std::string &get_title() const { return title; } + const std::vector &get_audio_channels() const { return audio_channels; } + const std::vector &get_spu_channels() const { return spu_channels; } + void set_audio_channel(unsigned); + void set_audio_off(); + void set_spu_channel(unsigned); + void set_spu_off(); void play(); void seek(const Msp::Time::TimeDelta &); @@ -55,6 +67,7 @@ public: void tick(); private: void update_info(); + void update_channels(); void handle_event(const xine_event_t &); }; -- 2.43.0