added: parse JSON coming from kodi, if there is a notification that playback has started, switch on the amplifier

This commit is contained in:
Bob 2021-09-26 22:11:22 +02:00
parent 413f5ecf9d
commit d23b42c1b3
5 changed files with 62 additions and 19 deletions

View file

@ -52,6 +52,7 @@ CAmpSwitch::CAmpSwitch(int argc, char *argv[])
m_switchedon = false;
m_samplecounter = 0;
m_usekodi = false;
m_playstart = false;
struct option longoptions[] =
{
@ -138,7 +139,7 @@ bool CAmpSwitch::Setup()
printf("off command: \"%s\"\n", m_offcommand);
if (m_usekodi)
m_kodiclient.Start(); //start a thread that connects to Kodi's JSONRPC
m_kodiclient.Start(this); //start a thread that connects to Kodi's JSONRPC
return true;
}
@ -321,6 +322,14 @@ int CAmpSwitch::PJackProcessCallback(jack_nframes_t nframes)
{
//if the absolute sample value is higher than the trigger level, set the switch state to on and reset the sample counter
bool trigger = fabsf(*(in++)) > m_triggerlevel;
//Consider a playback start as a trigger.
if (m_playstart)
{
trigger = true;
m_playstart = false;
}
if (trigger)
{
m_samplecounter = std::max((int)lround(m_switchtime * m_samplerate), 1);
@ -381,3 +390,8 @@ void CAmpSwitch::SignalHandler(int signum)
g_stop = true;
}
void CAmpSwitch::SignalPlayStart()
{
//Signal the jack client thread that playback has started.
m_playstart = true;
}

View file

@ -28,27 +28,29 @@ class CAmpSwitch
CAmpSwitch(int argc, char *argv[]);
~CAmpSwitch();
bool Setup();
void Process();
void Cleanup();
bool Setup();
void Process();
void Cleanup();
void SignalPlayStart();
private:
void PrintHelpMessage();
void PrintHelpMessage();
void Connect();
bool JackConnect();
void JackDisconnect();
void Connect();
bool JackConnect();
void JackDisconnect();
static int SJackProcessCallback(jack_nframes_t nframes, void *arg);
int PJackProcessCallback(jack_nframes_t nframes);
static int SJackProcessCallback(jack_nframes_t nframes, void *arg);
int PJackProcessCallback(jack_nframes_t nframes);
static int SJackSamplerateCallback(jack_nframes_t nframes, void *arg);
int PJackSamplerateCallback(jack_nframes_t nframes);
static int SJackSamplerateCallback(jack_nframes_t nframes, void *arg);
int PJackSamplerateCallback(jack_nframes_t nframes);
static void SJackInfoShutdownCallback(jack_status_t code, const char *reason, void *arg);
void PJackInfoShutdownCallback(jack_status_t code, const char *reason);
static void SJackInfoShutdownCallback(jack_status_t code, const char *reason, void *arg);
void PJackInfoShutdownCallback(jack_status_t code, const char *reason);
static void SignalHandler(int signum);
static void SignalHandler(int signum);
float m_triggerlevel;
float m_switchtime;
@ -68,6 +70,7 @@ class CAmpSwitch
bool m_usekodi;
CKodiClient m_kodiclient;
bool m_playstart;
};
#endif //AMPSWITCH_H

View file

@ -17,6 +17,7 @@
*/
#include "kodiclient.h"
#include "ampswitch.h"
#include <cstdio>
#include <unistd.h>
@ -24,14 +25,18 @@
#include <iostream>
#include <boost/asio.hpp>
#include <nlohmann/json.hpp>
using namespace boost::asio;
using ip::tcp;
using std::string;
using std::cout;
using std::endl;
using namespace nlohmann;
void CKodiClient::Start()
void CKodiClient::Start(CAmpSwitch* ampswitch)
{
m_ampswitch = ampswitch;
m_thread = std::thread(SProcess, this);
}
@ -56,6 +61,8 @@ void CKodiClient::Process()
//Connect to Kodi's JSONRPC, this will thrown an exception on failure.
socket.connect(tcp::endpoint(address, 9090));
printf("Connected to Kodi\n");
//Keep reading data from Kodi, when the tcp socket is closed an exception is thrown.
for(;;)
{
@ -63,8 +70,18 @@ void CKodiClient::Process()
size_t readbytes = boost::asio::read(socket, receive_buffer, boost::asio::transfer_at_least(1));
const char* data = boost::asio::buffer_cast<const char*>(receive_buffer.data());
printf("Received %i bytes: %s\n", (int)readbytes, data);
printf("Data length: %i\n", (int)strlen(data));
//TODO: because of TCP, one read does not exactly equal one JSON object.
json jsondata = json::parse(data);
//If Kodi signals a Player.OnPlay notification, the amplifier should be turned on.
if (jsondata.contains("method"))
{
if (jsondata["method"] == "Player.OnPlay")
{
printf("Player started\n");
m_ampswitch->SignalPlayStart();
}
}
}
}
catch(boost::system::system_error& error)

View file

@ -16,16 +16,24 @@
* with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef KODICLIENT_H
#define KODICLIENT_H
#include <thread>
class CAmpSwitch;
class CKodiClient
{
public:
void Start();
void Start(CAmpSwitch* ampswitch);
private:
static void SProcess(CKodiClient* kodiclient);
void Process();
std::thread m_thread;
CAmpSwitch* m_ampswitch;
};
#endif //KODICLIENT_H

View file

@ -17,6 +17,7 @@ def configure(conf):
conf.check(header_name='jack/jack.h')
conf.check(header_name='boost/asio.hpp')
conf.check(header_name='nlohmann/json.hpp')
conf.check(lib='jack', uselib_store='jack', mandatory=True)
conf.check(lib='pthread', uselib_store='pthread', mandatory=False)