Compare commits

..

No commits in common. "master" and "main" have entirely different histories.
master ... main

13 changed files with 4 additions and 1078 deletions

View file

@ -1,48 +0,0 @@
name: Build
on:
push:
branches:
- master
jobs:
build:
runs-on: debian-latest
steps:
- run: |-
apt update
apt install -y \
python3 git curl make gcc g++ pkg-config \
libboost-dev libjack-dev nlohmann-json3-dev
- uses: actions/checkout@v4
- run: ./waf configure
- run: ./waf
- name: Build Debian package
run: |-
mkdir -p deb/DEBIAN
cat <<EOF | tee deb/DEBIAN/control
Package: ampswitch
Version: 0.$(date --date="@$(git show -s --format='%ct' HEAD)" '+%4Y%m%d.%H%M%S')
Section: base
Priority: optional
Architecture: amd64
Maintainer: polyfloyd <floy@polyfloyd.net>, Bob <bob-nospam-@xbmc.org>
Description: Executes a command triggered by jack audio
Depends: libboost-dev, libjack0
EOF
install -D -m 0755 build/ampswitch deb/usr/bin/ampswitch
dpkg-deb --build deb ampswitch.deb
- name: Deploy Debian package
run: |-
curl \
--fail \
--user ${{ secrets.PKG_RELEASE_CREDENTIALS }} \
--upload-file ampswitch.deb \
$GITHUB_SERVER_URL/api/packages/$GITHUB_REPOSITORY_OWNER/debian/pool/stable/main/upload

View file

@ -1,7 +1,7 @@
GNU GENERAL PUBLIC LICENSE
Version 3, 29 June 2007
Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/>
Copyright (C) 2007 Free Software Foundation, Inc. <https://fsf.org/>
Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.
@ -645,7 +645,7 @@ the "copyright" line and a pointer to where the full notice is found.
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
along with this program. If not, see <https://www.gnu.org/licenses/>.
Also add information on how to contact you by electronic and paper mail.
@ -664,12 +664,11 @@ might be different; for a GUI interface, you would use an "about box".
You should also get your employer (if you work as a programmer) or school,
if any, to sign a "copyright disclaimer" for the program, if necessary.
For more information on this, and how to apply and follow the GNU GPL, see
<http://www.gnu.org/licenses/>.
<https://www.gnu.org/licenses/>.
The GNU General Public License does not permit incorporating your program
into proprietary programs. If your program is a subroutine library, you
may consider it more useful to permit linking proprietary applications with
the library. If this is what you want to do, use the GNU Lesser General
Public License instead of this License. But first, please read
<http://www.gnu.org/philosophy/why-not-lgpl.html>.
<https://www.gnu.org/licenses/why-not-lgpl.html>.

View file

@ -1,87 +0,0 @@
Original description from the relay board in chinlish:
Below item is powered by Canton-electronics Ltd .
Product Name: 12V 2Ch RS232 Relay Remote Control USB PC UART TTL COM Serial Ports Smart Home
Module No.: TB252
Qty:
1 pcs Dual Function Manual control and PC UART Control Relay ;
1 pcs RS232 to TTL;
4 pcs female to 4 pins female dupont wire;
Descripion :
12V 2 Channel Relay Module;
Dual Function : Manual control & PC RS232 Control Relay;
Input and output optical isolation;
With 5V TTL 232 interface, which is convenient to achieve USB to PC by USB to TTL232 serial to control relay, you can also use 8051 AVR Arduino MCU to control relay ;
Power indicator: LED lights ;
Output indication: relay output with LED indicators, easy to see working status of the relay ;
Communication protocol: UART protocol communication, baud rate 9600kpbs, 8 data bits, one stop bit, no parity. Each data frame contains eight bytes. Two-way data transmission.
Baud rate 9600kbps, 8 data bits, one stop bit, no parity. Each data frame contains eight bytes..
1 Control commands
1. Reading statusreading the satus of the relay (on/off)
0x55 0x56 0x00 0x00 0x00 0x00 0x00 0xAB
2. Relay open (issue this command Relay open , COM connect to NO
Channel 1 0x55 0x56 0x00 0x00 0x00 0x01 0x01 0xAD
Channel 2 0x55 0x56 0x00 0x00 0x00 0x02 0x01 0xAE
3. Relay close (issue this command Relay close , COM disconnect NO , and COM connect to NC
Channel 1 0x55 0x56 0x00 0x00 0x00 0x01 0x02 0xAE
Channel 2 0x55 0x56 0x00 0x00 0x00 0x02 0x02 0xAF
4. Relay toggleRelay status reversalif COM connect to NOthis commands will Disconnect COM to NO and Reverse COM connect to NCand vice versa
Channel 1 0x55 0x56 0x00 0x00 0x00 0x01 0x03 0xAF
Channel 2 0x55 0x56 0x00 0x00 0x00 0x02 0x03 0xB0
5. Relay momentaryRelay COM connect to NOdisconnect after 200MS
Channel 1 0x55 0x56 0x00 0x00 0x00 0x01 0x04 0xB0
Channel 2 0x55 0x56 0x00 0x00 0x00 0x02 0x04 0xB1
Once issue a command, will have a return fame , 7th byte of return fame mean the satus of realy .
2 return command
1、Return relay openreturn this commandmean COM connect to NO
Channel 1 : 0x33 0x3C 0x00 0x00 0x00 0x01 0x01 0x71
Channel 2 : 0x33 0x3C 0x00 0x00 0x00 0x02 0x01 0x72
2、Return relay closereturn this commandmean COM disconnect NO , and COM connect to NC
Channel 1 : 0x33 0x3C 0x00 0x00 0x00 0x01 0x02 0x72
Channel 2 : 0x33 0x3C 0x00 0x00 0x00 0x02 0x02 0x73

Binary file not shown.

Before

Width:  |  Height:  |  Size: 91 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 122 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 120 KiB

View file

@ -1,401 +0,0 @@
/*
* ampswitch
* Copyright (C) Bob 2014
*
* ampswitch 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.
*
* ampswitch 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 this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "ampswitch.h"
#ifndef _GNU_SOURCE
#define _GNU_SOURCE //for pipe2
#endif //_GNU_SOURCE
#include <unistd.h>
#include <stdlib.h>
#include <unistd.h>
#include <stdio.h>
#include <signal.h>
#include <errno.h>
#include <math.h>
#include <string.h>
#include <fcntl.h>
#include <sys/select.h>
#include <getopt.h>
#include <algorithm>
volatile bool g_stop = false;
CAmpSwitch::CAmpSwitch(int argc, char *argv[])
{
m_triggerlevel = 0.1f;
m_switchtime = 10.0f;
m_oncommand = NULL;
m_offcommand = NULL;
m_pipe[0] = -1;
m_pipe[1] = -1;
m_connected = false;
m_jackname = "Ampswitch";
m_client = NULL;
m_port = NULL;
m_samplerate = 0;
m_jackshutdown = false;
m_switchedon = false;
m_samplecounter = 0;
m_usekodi = false;
m_playing = false;
struct option longoptions[] =
{
{"jack-name", required_argument, NULL, 'j'},
{"on-command", required_argument, NULL, 'n'},
{"off-command", required_argument, NULL, 'f'},
{"switch-time", required_argument, NULL, 's'},
{"trigger-level", required_argument, NULL, 't'},
{"kodi", no_argument, NULL, 'k'},
{"help", no_argument, NULL, 'h'},
{0, 0, 0, 0}
};
const char* shortoptions = "j:n:f:s:t:kh";
int c;
int optionindex = 0;
while ((c = getopt_long(argc, argv, shortoptions, longoptions, &optionindex)) != -1)
{
if (c == 'j')
{
m_jackname = optarg;
}
else if (c == 'n')
{
m_oncommand = optarg;
}
else if (c == 'f')
{
m_offcommand = optarg;
}
else if (c == 'h')
{
PrintHelpMessage();
exit(1);
}
else if (c == 's')
{
float switchtime;
if (sscanf(optarg, "%f", &switchtime) != 1)
{
printf("ERROR: Wrong value for switch-time: \"%s\"\n", optarg);
exit(1);
}
m_switchtime = switchtime;
}
else if (c == 't')
{
float triggerlevel;
if (sscanf(optarg, "%f", &triggerlevel) != 1)
{
printf("ERROR: Wrong value for trigger-level: \"%s\"\n", optarg);
exit(1);
}
m_triggerlevel = triggerlevel;
}
else if (c == 'k')
{
m_usekodi = true;
}
else if (c == '?')
{
exit(1);
}
}
}
CAmpSwitch::~CAmpSwitch()
{
}
bool CAmpSwitch::Setup()
{
//install signal handlers for exiting
signal(SIGINT, SignalHandler);
signal(SIGTERM, SignalHandler);
//create a non blocking pipe which the jack thread will use to communicate with the main thread
if (pipe2(m_pipe, O_NONBLOCK) == -1)
{
printf("ERROR: Creating pipe: %s\n", strerror(errno));
return false;
}
if (m_oncommand)
printf("on command: \"%s\"\n", m_oncommand);
if (m_offcommand)
printf("off command: \"%s\"\n", m_offcommand);
if (m_usekodi)
m_kodiclient.Start(this); //start a thread that connects to Kodi's JSONRPC
return true;
}
void CAmpSwitch::Process()
{
//if the off command is passed on the command line, execute that first
if (m_offcommand)
{
printf("switching off, executing \"%s\"\n", m_offcommand);
system(m_offcommand);
}
//local switch state
bool switchedon = false;
while (!g_stop)
{
//if the jack daemon has shut down, clean up the jack client
if (m_jackshutdown)
JackDisconnect();
//try to connect to jackd if not connected yet
if (!m_connected)
Connect();
//wait for one second on the readable end of the pipe
fd_set pipeset;
FD_ZERO(&pipeset);
FD_SET(m_pipe[0], &pipeset);
struct timeval tv;
tv.tv_sec = 1;
tv.tv_usec = 0;
select(m_pipe[0] + 1, &pipeset, NULL, NULL, &tv);
//clear the readable end of the pipe
uint8_t byte;
read(m_pipe[0], &byte, 1);
//if the jack thread has written a byte to the pipe, the switch state has changed
//execute the switch on or switch off command if necessary
if (switchedon != m_switchedon)
{
switchedon = m_switchedon;
if (switchedon && m_oncommand)
{
printf("switching on, executing \"%s\"\n", m_oncommand);
system(m_oncommand);
}
else if (!switchedon && m_offcommand)
{
printf("switching off, executing \"%s\"\n", m_offcommand);
system(m_offcommand);
}
}
}
//if the off command is passed on the command line, execute that before exiting
if (m_offcommand)
{
printf("switching off, executing \"%s\"\n", m_offcommand);
system(m_offcommand);
}
}
void CAmpSwitch::Cleanup()
{
JackDisconnect();
}
void CAmpSwitch::PrintHelpMessage()
{
printf(
"\n"
"usage: ampswitch [OPTION]\n"
"\n"
" options:\n"
"\n"
" -j, --jack-name name of the jack client\n"
" -n, --on-command command to execute when switching on\n"
" -f, --off-command command to execute when switching off\n"
" -s, --switch-time minimum number of seconds between switches\n"
" -t, --trigger-level absolute value of trigger level\n"
" -k, --kodi use Kodi's JSONRPC to switch on when playback starts\n"
" -h, --help print this message\n"
"\n"
);
}
void CAmpSwitch::Connect()
{
m_connected = JackConnect();
if (!m_connected)
{
JackDisconnect();
printf("Waiting 10 seconds before trying again\n");
sleep(10);
}
}
bool CAmpSwitch::JackConnect()
{
//try to connect to jackd
m_client = jack_client_open(m_jackname, JackNoStartServer, NULL);
if (m_client == NULL)
{
printf("ERROR: Unable to connect to jack\n");
return false;
}
int returnv;
//get the sample rate for timing calculations
m_samplerate = jack_get_sample_rate(m_client);
//install a callback which gets called when jackd shuts down
jack_on_info_shutdown(m_client, SJackInfoShutdownCallback, this);
//install the process callback, this will be called when a new audio frame is passed
returnv = jack_set_process_callback(m_client, SJackProcessCallback, this);
if (returnv != 0)
{
printf("ERROR: Unable to set process callback\n");
return false;
}
//install a callback for when the sample rate changes
returnv = jack_set_sample_rate_callback(m_client, SJackSamplerateCallback, this);
if (returnv != 0)
printf("ERROR: Unable to set sample rate callback\n");
//register a jack audio port
m_port = jack_port_register(m_client, "Input", JACK_DEFAULT_AUDIO_TYPE, JackPortIsInput, 0);
if (m_port == NULL)
{
printf("ERROR: Unable to register jack port\n");
return false;
}
//activate the jack client
returnv = jack_activate(m_client);
if (returnv != 0)
{
printf("ERROR: Unable to activate jack client\n");
return false;
}
printf("Connected to jack with name %s\n", m_jackname);
return true;
}
void CAmpSwitch::JackDisconnect()
{
if (m_client)
{
printf("Disconnecting from jack\n");
jack_client_close(m_client);
m_port = NULL;
m_client = NULL;
}
m_jackshutdown = false;
m_connected = false;
}
int CAmpSwitch::SJackProcessCallback(jack_nframes_t nframes, void *arg)
{
return ((CAmpSwitch*)arg)->PJackProcessCallback(nframes);
}
int CAmpSwitch::PJackProcessCallback(jack_nframes_t nframes)
{
float* jackptr = (float*)jack_port_get_buffer(m_port, nframes);
//iterate over all samples
float* in = jackptr;
float* inend = in + nframes;
while (in != inend)
{
//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 kodi playing as a trigger
if (m_playing)
trigger = true;
if (trigger)
{
m_samplecounter = std::max((int)lround(m_switchtime * m_samplerate), 1);
if (!m_switchedon)
{
m_switchedon = true;
uint8_t msgbyte = 0;
write(m_pipe[1], &msgbyte, 1);
}
}
else if (m_samplecounter > 0)
{
//if the sample counter expires, set the switch state to off
m_samplecounter--;
if (m_samplecounter == 0)
{
m_switchedon = false;
uint8_t msgbyte = 0;
write(m_pipe[1], &msgbyte, 1);
}
}
}
return 0;
}
int CAmpSwitch::SJackSamplerateCallback(jack_nframes_t nframes, void *arg)
{
return ((CAmpSwitch*)arg)->PJackSamplerateCallback(nframes);
}
int CAmpSwitch::PJackSamplerateCallback(jack_nframes_t nframes)
{
//when the sample rate changes, update the sample counter so that it will represent the same amount of time
m_samplecounter = lround((double)m_samplecounter / (double)m_samplerate * (double)nframes);
m_samplerate = nframes;
return 0;
}
void CAmpSwitch::SJackInfoShutdownCallback(jack_status_t code, const char *reason, void *arg)
{
((CAmpSwitch*)arg)->PJackInfoShutdownCallback(code, reason);
}
void CAmpSwitch::PJackInfoShutdownCallback(jack_status_t code, const char *reason)
{
//signal the main thread that the jack server has shut down
m_jackshutdown = true;
uint8_t msgbyte = 0;
write(m_pipe[1], &msgbyte, 1);
}
void CAmpSwitch::SignalHandler(int signum)
{
//signal the main thread that the process should exit
if (signum == SIGINT || signum == SIGTERM)
g_stop = true;
}
void CAmpSwitch::SetPlayingState(bool playing)
{
//Inform the switch thread about the play state of kodi
m_playing = playing;
}

View file

@ -1,77 +0,0 @@
/*
* ampswitch
* Copyright (C) Bob 2014
*
* ampswitch 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.
*
* ampswitch 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 this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef AMPSWITCH_H
#define AMPSWITCH_H
#include <jack/jack.h>
#include "kodiclient.h"
class CAmpSwitch
{
public:
CAmpSwitch(int argc, char *argv[]);
~CAmpSwitch();
bool Setup();
void Process();
void Cleanup();
void SetPlayingState(bool playing);
private:
void PrintHelpMessage();
void Connect();
bool JackConnect();
void JackDisconnect();
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 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);
float m_triggerlevel;
float m_switchtime;
char* m_oncommand;
char* m_offcommand;
int m_pipe[2];
bool m_connected;
const char* m_jackname;
jack_client_t* m_client;
jack_port_t* m_port;
int m_samplerate;
bool m_jackshutdown;
bool m_switchedon;
int m_samplecounter;
bool m_usekodi;
CKodiClient m_kodiclient;
bool m_playing;
};
#endif //AMPSWITCH_H

View file

@ -1,167 +0,0 @@
/*
* ampswitch
* Copyright (C) Bob 2021
*
* ampswitch 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.
*
* ampswitch 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 this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "kodiclient.h"
#include "ampswitch.h"
#include <cstdio>
#include <unistd.h>
#include <cstdint>
#include <iostream>
#include <boost/asio.hpp>
#include <nlohmann/json.hpp>
using namespace boost::asio;
using ip::tcp;
using namespace nlohmann;
void CKodiClient::Start(CAmpSwitch* ampswitch)
{
m_ampswitch = ampswitch;
m_thread = std::thread(SProcess, this);
}
void CKodiClient::SProcess(CKodiClient* kodiclient)
{
kodiclient->Process();
}
void CKodiClient::Process()
{
printf("Kodi client started\n");
for(;;)
{
try
{
//TODO: make "localhost" work instead of "127.0.0.1"
boost::asio::io_service io_service;
tcp::socket socket(io_service);
boost::asio::ip::address address = boost::asio::ip::make_address("127.0.0.1");
//Connect to Kodi's JSONRPC, this will thrown an exception on failure.
socket.connect(tcp::endpoint(address, 9090));
printf("Connected to Kodi\n");
//Read data from the TCP socket, and split into separate JSON objects.
ResetSplit();
for(;;)
{
boost::asio::streambuf receive_buffer;
size_t bytesread = boost::asio::read(socket, receive_buffer,
boost::asio::transfer_at_least(1));
const char* data = boost::asio::buffer_cast<const char*>(receive_buffer.data());
Split(data, bytesread);
}
}
catch(boost::system::system_error& error)
{
m_ampswitch->SetPlayingState(false);
printf("ERROR: unable to connect to Kodi JSONRPC: %s\n", error.what());
printf("Retrying in 10 seconds\n");
sleep(10);
}
}
}
void CKodiClient::ResetSplit()
{
m_bracketlevel = 0;
m_instring = false;
m_escaped = false;
m_parsebuf.clear();
}
/*! Splits JSON objects from Kodi's JSON RPC and passes them to Parse().*/
void CKodiClient::Split(const char* data, uint32_t len)
{
//Parse the JSON data into separate JSON objects by finding the text from
//the starting { to ending }, while ignoring curly brackets in strings.
for (uint32_t i = 0; i < len; i++)
{
m_parsebuf.push_back(data[i]);
if (!m_instring)
{
if (data[i] == '"')
{
m_instring = true;
}
else if (data[i] == '{')
{
m_bracketlevel++;
}
else if (data[i] == '}')
{
if (m_bracketlevel > 0)
{
m_bracketlevel--;
if (m_bracketlevel == 0)
{ //Parse the full received JSON object.
Parse(m_parsebuf);
m_parsebuf.clear();
}
}
else
{
m_parsebuf.clear(); //Shouldn't happen.
}
}
}
else
{
if (!m_escaped)
{
if (data[i] == '\\')
m_escaped = true;
else if (data[i] == '"')
m_instring = false;
}
else
{
m_escaped = false;
}
}
}
}
void CKodiClient::Parse(const std::string& jsonstr)
{
json jsondata = json::parse(jsonstr);
if (jsondata.contains("method"))
{
std::string method = jsondata["method"];
if (method == "Player.OnPlay")
{
printf("Player started\n");
m_ampswitch->SetPlayingState(true);
}
else if (method == "Player.OnStop")
{
printf("Player stopped\n");
m_ampswitch->SetPlayingState(false);
}
}
}

View file

@ -1,48 +0,0 @@
/*
* ampswitch
* Copyright (C) Bob 2021
*
* ampswitch 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.
*
* ampswitch 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 this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef KODICLIENT_H
#define KODICLIENT_H
#include <thread>
#include <string>
class CAmpSwitch;
class CKodiClient
{
public:
void Start(CAmpSwitch* ampswitch);
private:
static void SProcess(CKodiClient* kodiclient);
void Process();
void ResetSplit();
void Split(const char* data, uint32_t len);
void Parse(const std::string& jsonstr);
std::thread m_thread;
CAmpSwitch* m_ampswitch;
uint32_t m_bracketlevel;
bool m_instring;
bool m_escaped;
std::string m_parsebuf;
};
#endif //KODICLIENT_H

View file

@ -1,33 +0,0 @@
/*
* ampswitch
* Copyright (C) Bob 2014
*
* ampswitch 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.
*
* ampswitch 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 this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "ampswitch.h"
int main (int argc, char *argv[])
{
CAmpSwitch ampswitch(argc, argv);
if (!ampswitch.Setup())
return 1;
ampswitch.Process();
ampswitch.Cleanup();
return 0;
}

177
waf vendored

File diff suppressed because one or more lines are too long

35
wscript
View file

@ -1,35 +0,0 @@
#! /usr/bin/env python
# encoding: utf-8
# the following two variables are used by the target "waf dist"
VERSION='0.0.1'
APPNAME='ampswitch'
# these variables are mandatory ('/' are converted automatically)
top = '.'
out = 'build'
def options(opt):
opt.load('compiler_cxx')
def configure(conf):
conf.load('compiler_cxx')
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)
conf.write_config_header('config.h')
def build(bld):
bld.program(source='src/main.cpp\
src/ampswitch.cpp\
src/kodiclient.cpp',
use=['jack', 'pthread'],
includes='./src',
cxxflags='-Wall -g',
target='ampswitch')