diff --git a/Bin/x86_64-linux/bs2bconvert b/Bin/x86_64-linux/bs2bconvert new file mode 100755 index 0000000..dc74978 Binary files /dev/null and b/Bin/x86_64-linux/bs2bconvert differ diff --git a/HTML/EN/plugins/BS2B/settings/player.html b/HTML/EN/plugins/BS2B/settings/player.html new file mode 100644 index 0000000..655afd7 --- /dev/null +++ b/HTML/EN/plugins/BS2B/settings/player.html @@ -0,0 +1,12 @@ +[% PROCESS settings/header.html %] + +[% WRAPPER settingSection %] + + [% WRAPPER setting title="Enable BS2B" desc="" %] + + + [% END %] + +[% END %] + +[% PROCESS settings/footer.html %] diff --git a/PlayerSettings.pm b/PlayerSettings.pm new file mode 100644 index 0000000..446e1e1 --- /dev/null +++ b/PlayerSettings.pm @@ -0,0 +1,47 @@ +package Plugins::BS2B::PlayerSettings; + +use strict; + +use base qw(Slim::Web::Settings); + +use Slim::Utils::Prefs; +use Slim::Utils::Log; +use Slim::Player::CapabilitiesHelper; + +use Plugins::BS2B::Plugin; + +my $prefs = preferences('plugin.bs2b'); +my $log = logger('plugin.bs2b'); + +sub getDisplayName { + return 'PLUGIN_BS2B'; +} + +sub needsClient { + return 1; +} + +sub name { + return Slim::Web::HTTP::CSRF->protectName('PLUGIN_BS2B'); +} + +sub page { + return Slim::Web::HTTP::CSRF->protectURI('plugins/BS2B/settings/player.html'); +} + +sub handler { + my ($class, $client, $params, $callback, @args) = @_; + + if ($params->{'saveSettings'}) { + + $prefs->client($client)->set('bs2b', $params->{'pref_bs2b'} || 0); + + Plugins::BS2B::Plugin::setupTranscoder($client); + } + + $params->{'prefs'}->{'pref_bs2b'}= $prefs->client($client)->get('bs2b') || 0; + + return $class->SUPER::handler($client, $params); +} + +1; diff --git a/Plugin.pm b/Plugin.pm new file mode 100644 index 0000000..e8fe5aa --- /dev/null +++ b/Plugin.pm @@ -0,0 +1,59 @@ +package Plugins::BS2B::Plugin; + +use strict; + +use base qw(Slim::Plugin::OPMLBased); + +use Slim::Utils::Log; +use Slim::Utils::Prefs; +use Slim::Player::TranscodingHelper; + +use Plugins::BS2B::PlayerSettings; + +my $prefs = preferences('plugin.bs2b'); + +my $log = Slim::Utils::Log->addLogCategory({ + 'category' => 'plugin.bs2b', + 'defaultLevel' => 'WARN', + 'description' => 'PLUGIN_BS2B', +}); + +sub initPlugin { + my $class = shift; + + Plugins::BS2B::PlayerSettings->new; + + Slim::Control::Request::subscribe(\&initClient, [['client'],['new','reconnect']]); +} + +sub setupTranscoder { + my $client = $_[0] || return; + + my $usebs2b = $prefs->client($client)->get('bs2b'); + + my $flc = 'flc-flc-*-' . lc($client->macaddress); + + if ($usebs2b) { + + # AU is specifically designed to be written to a pipe (http://www.mega-nerd.com/libsndfile/FAQ.html#Q017) + my $cmdTable = '[sox] -q -t flac $FILE$ -t au - $START$ | [bs2bconvert] /dev/stdin /dev/stdout | [sox] -q -t au - -t flac -C 0 -'; + my $capabilities = { F => 'noArgs', T => 'START=trim %s' }; + + $Slim::Player::TranscodingHelper::commandTable{ $flc } = $cmdTable; + $Slim::Player::TranscodingHelper::capabilities{ $flc } = $capabilities; + + } else { + + $Slim::Player::TranscodingHelper::commandTable{ $flc } = "-"; + $Slim::Player::TranscodingHelper::capabilities{ $flc } = {}; + + } +} + +sub initClient { + my $request = shift; + + setupTranscoder($request->client()); +} + +1; diff --git a/install.xml b/install.xml new file mode 100644 index 0000000..aa7bdb5 --- /dev/null +++ b/install.xml @@ -0,0 +1,17 @@ + + + PLUGIN_BS2B + Plugins::BS2B::Plugin + 0.01 + PLUGIN_BS2B_DESC + Terual + https://github.com/terual/BS2B + enabled + 2 + + + SlimServer + 7.9 + 8.* + + diff --git a/src/Dockerfile b/src/Dockerfile new file mode 100644 index 0000000..a4d9d85 --- /dev/null +++ b/src/Dockerfile @@ -0,0 +1,6 @@ +FROM ubuntu:14.04 +ENV DEBIAN_FRONTEND noninteractive + +RUN apt-get -y update && apt-get -y upgrade && \ + apt-get install -y gcc g++ make libsndfile-dev build-essential + diff --git a/src/build.sh b/src/build.sh new file mode 100755 index 0000000..2fff56c --- /dev/null +++ b/src/build.sh @@ -0,0 +1,14 @@ +#!/bin/bash + +docker build . -t bs2b + +rm -rf "libbs2b-3.1.0" +tar -xvf "libbs2b-3.1.0.tar.bz2" +patch -p0 < fix-stderr.patch + +cd "libbs2b-3.1.0" +docker run -t --rm -u "${UID}" -v "${PWD}:${PWD}" -w "${PWD}" \ + bs2b \ + sh -c "./configure --help && LIBS=-lm ./configure --enable-static --disable-shared && make" + + diff --git a/src/fix-stderr.patch b/src/fix-stderr.patch new file mode 100644 index 0000000..aab3639 --- /dev/null +++ b/src/fix-stderr.patch @@ -0,0 +1,76 @@ +--- libbs2b-3.1.0/src/bs2bconvert.c.orig 2009-06-04 20:01:15.000000000 +0200 ++++ libbs2b-3.1.0/src/bs2bconvert.c 2020-10-05 15:00:34.332595456 +0200 +@@ -146,20 +146,20 @@ + + if( strcmp( infilename, outfilename ) == 0 ) + { +- printf( "Error : Input and output filenames are the same.\n\n" ); ++ fprintf( stderr, "Error : Input and output filenames are the same.\n\n" ); + return 1; + } + + if( ( infile = sf_open( infilename, SFM_READ, &sfinfo ) ) == NULL ) + { +- printf( "Not able to open input file %s.\n", infilename ); +- printf( sf_strerror( NULL ) ); ++ fprintf( stderr, "Not able to open input file %s.\n", infilename ); ++ fprintf( stderr, sf_strerror( NULL ) ); + return 1; + } + + if( sfinfo.channels != 2 ) + { +- printf( "Input file is not a stereo.\n" ); ++ fprintf( stderr, "Input file is not a stereo.\n" ); + sf_close( infile ); + return 1; + } +@@ -168,7 +168,7 @@ + + if( srate < BS2B_MINSRATE || srate > BS2B_MAXSRATE ) + { +- printf( "Not supported sample rate '%d'.\n", srate ); ++ fprintf( stderr, "Not supported sample rate '%d'.\n", srate ); + sf_close( infile ); + return 1; + } +@@ -176,7 +176,7 @@ + /* Open the output file. */ + if( ( outfile = sf_open( outfilename, SFM_WRITE, &sfinfo ) ) == NULL ) + { +- printf( "Not able to open output file %s : %s\n", ++ fprintf( stderr, "Not able to open output file %s : %s\n", + outfilename, sf_strerror( NULL ) ); + sf_close( infile ); + return 1; +@@ -184,7 +184,7 @@ + + if( NULL == ( bs2bdp = bs2b_open() ) ) + { +- printf( "Not able to allocate data\n" ); ++ fprintf( stderr, "Not able to allocate data\n" ); + sf_close( infile ); + sf_close( outfile ); + return 1; +@@ -193,10 +193,10 @@ + bs2b_set_srate( bs2bdp, srate ); + bs2b_set_level( bs2bdp, level ); + +- printf( "Crossfeed level: %.1f dB, %d Hz, %d us.\n", ++ fprintf( stderr, "Crossfeed level: %.1f dB, %d Hz, %d us.\n", + ( double )bs2b_get_level_feed( bs2bdp ) / 10.0, + bs2b_get_level_fcut( bs2bdp ), bs2b_get_level_delay( bs2bdp ) ); +- printf( "Converting file '%s' to file '%s'\nsample rate = %u...", ++ fprintf( stderr, "Converting file '%s' to file '%s'\nsample rate = %u...", + infilename, outfilename, bs2b_get_srate( bs2bdp ) ); + + copy_metadata( outfile, infile ); +@@ -209,7 +209,7 @@ + sf_close( infile ); + sf_close( outfile ); + +- printf( " Done.\n" ); ++ fprintf( stderr, " Done.\n" ); + + return 0; + } /* main() */ diff --git a/src/libbs2b-3.1.0.tar.bz2 b/src/libbs2b-3.1.0.tar.bz2 new file mode 100644 index 0000000..6e0e5bb Binary files /dev/null and b/src/libbs2b-3.1.0.tar.bz2 differ diff --git a/strings.txt b/strings.txt new file mode 100644 index 0000000..f856232 --- /dev/null +++ b/strings.txt @@ -0,0 +1,10 @@ +# String file for BS2B plugin + +PLUGIN_BS2B + EN Bauer stereophonic-to-binaural DSP + +PLUGIN_BS2B_DESC + EN Bauer stereophonic-to-binaural DSP: headphone filter + +PLUGIN_BS2B_ENABLE + EN Enable Bauer stereophonic-to-binaural DSP for this player