-#include "convolver.h"
+#include <pthread.h>
#include <sndfile.h>
+#include "convolver.h"
#include "FFTConvolver.h"
#include "Utilities.h"
-extern "C" void _die(const char *filename, const int linenumber, const char *format, ...);
+extern "C" void _warn(const char *filename, const int linenumber, const char *format, ...);
extern "C" void _debug(const char *filename, const int linenumber, int level, const char *format, ...);
-#define die(...) _die(__FILE__, __LINE__, __VA_ARGS__)
+#define warn(...) _warn(__FILE__, __LINE__, __VA_ARGS__)
#define debug(...) _debug(__FILE__, __LINE__, __VA_ARGS__)
-static fftconvolver::FFTConvolver convolver_l;
-static fftconvolver::FFTConvolver convolver_r;
+fftconvolver::FFTConvolver convolver_l;
+fftconvolver::FFTConvolver convolver_r;
+
+// always lock use this when accessing the playing conn value
+pthread_mutex_t convolver_lock = PTHREAD_MUTEX_INITIALIZER;
-void convolver_init(const char* filename, int max_length)
-{
+int convolver_init(const char* filename, int max_length) {
+ int success = 0;
SF_INFO info;
- assert(filename);
- SNDFILE* file = sf_open(filename, SFM_READ, &info);
- assert(file);
-
- if (info.samplerate != 44100)
- die("Impulse file \"%s\" sample rate is %d Hz. Only 44100 Hz is supported", filename, info.samplerate);
-
- if (info.channels != 1 && info.channels != 2)
- die("Impulse file \"%s\" contains %d channels. Only 1 or 2 is supported.", filename, info.channels);
+ if (filename) {
+ SNDFILE* file = sf_open(filename, SFM_READ, &info);
+ if (file) {
- const size_t size = info.frames > max_length ? max_length : info.frames;
- float buffer[size*info.channels];
+ if (info.samplerate == 44100) {
+ if ((info.channels == 1) || (info.channels == 2)) {
+ const size_t size = info.frames > max_length ? max_length : info.frames;
+ float buffer[size*info.channels];
- size_t l = sf_readf_float(file, buffer, size);
- assert(l == size);
-
- convolver_l.reset(); // it is possible that init could be called more than once
- convolver_r.reset(); // so it could be necessary to remove all previous settings
+ size_t l = sf_readf_float(file, buffer, size);
+ if (l != 0) {
+ pthread_mutex_lock(&convolver_lock);
+ convolver_l.reset(); // it is possible that init could be called more than once
+ convolver_r.reset(); // so it could be necessary to remove all previous settings
- if (info.channels == 1) {
- convolver_l.init(352, buffer, size);
- convolver_r.init(352, buffer, size);
- } else {
- // deinterleave
- float buffer_l[size];
- float buffer_r[size];
+ if (info.channels == 1) {
+ convolver_l.init(352, buffer, size);
+ convolver_r.init(352, buffer, size);
+ } else {
+ // deinterleave
+ float buffer_l[size];
+ float buffer_r[size];
- unsigned int i;
- for (i=0; i<size; ++i)
- {
- buffer_l[i] = buffer[2*i+0];
- buffer_r[i] = buffer[2*i+1];
- }
+ unsigned int i;
+ for (i=0; i<size; ++i)
+ {
+ buffer_l[i] = buffer[2*i+0];
+ buffer_r[i] = buffer[2*i+1];
+ }
- convolver_l.init(352, buffer_l, size);
- convolver_r.init(352, buffer_r, size);
+ convolver_l.init(352, buffer_l, size);
+ convolver_r.init(352, buffer_r, size);
+
+ }
+ pthread_mutex_unlock(&convolver_lock);
+ success = 1;
+ }
+ debug(1, "IR initialized from \"%s\" with %d channels and %d samples", filename, info.channels, size);
+ } else {
+ warn("Impulse file \"%s\" contains %d channels. Only 1 or 2 is supported.", filename, info.channels);
+ }
+ } else {
+ warn("Impulse file \"%s\" sample rate is %d Hz. Only 44100 Hz is supported", filename, info.samplerate);
+ }
+ sf_close(file);
+ }
}
-
- debug(1, "IR initialized from \"%s\" with %d channels and %d samples", filename, info.channels, size);
-
- sf_close(file);
+ return success;
}
-void convolver_process_l(float* data, int length)
-{
+void convolver_process_l(float* data, int length) {
+ pthread_mutex_lock(&convolver_lock);
convolver_l.process(data, data, length);
+ pthread_mutex_unlock(&convolver_lock);
}
-void convolver_process_r(float* data, int length)
-{
+void convolver_process_r(float* data, int length) {
+ pthread_mutex_lock(&convolver_lock);
convolver_r.process(data, data, length);
+ pthread_mutex_unlock(&convolver_lock);
}
if (shairport_sync_get_convolution(skeleton)) {
debug(1, ">> activating convolution");
config.convolution = 1;
+ config.convolver_valid = convolver_init(config.convolution_ir_file, config.convolution_max_length);
} else {
debug(1, ">> deactivating convolution");
config.convolution = 0;
free(config.convolution_ir_file);
config.convolution_ir_file = strdup(th);
debug(1, ">> setting configuration impulse response filter file to \"%s\".", config.convolution_ir_file);
- convolver_init(config.convolution_ir_file, config.convolution_max_length);
+ config.convolver_valid = convolver_init(config.convolution_ir_file, config.convolution_max_length);
return TRUE;
}
#else
}
if (config.convolution_ir_file)
shairport_sync_set_convolution_impulse_response_file(SHAIRPORT_SYNC(shairportSyncSkeleton), config.convolution_ir_file);
- else
- shairport_sync_set_convolution_impulse_response_file(SHAIRPORT_SYNC(shairportSyncSkeleton), NULL);
+// else
+// shairport_sync_set_convolution_impulse_response_file(SHAIRPORT_SYNC(shairportSyncSkeleton), NULL);
#endif
shairport_sync_set_version(SHAIRPORT_SYNC(shairportSyncSkeleton), PACKAGE_VERSION);
# Set Drift Tolerance to 1 millisecond
dbus-send --print-reply --system --dest=org.gnome.ShairportSync /org/gnome/ShairportSync org.freedesktop.DBus.Properties.Set string:org.gnome.ShairportSync string:DriftTolerance variant:double:0.001
+# Is Loudness Enabled:
+dbus-send --print-reply --system --dest=org.gnome.ShairportSync /org/gnome/ShairportSync org.freedesktop.DBus.Properties.Get string:org.gnome.ShairportSync string:LoudnessThreshold
# Enable Loudness Filter
+dbus-send --print-reply --system --dest=org.gnome.ShairportSync /org/gnome/ShairportSync org.freedesktop.DBus.Properties.Set string:org.gnome.ShairportSync string:Loudness variant:boolean:true
+# Get Loudness Threshold
+dbus-send --print-reply --system --dest=org.gnome.ShairportSync /org/gnome/ShairportSync org.freedesktop.DBus.Properties.Get string:org.gnome.ShairportSync string:LoudnessThreshold
+
+# Set Loudness Threshold
+dbus-send --print-reply --system --dest=org.gnome.ShairportSync /org/gnome/ShairportSync org.freedesktop.DBus.Properties.Set string:org.gnome.ShairportSync string:LoudnessThreshold variant:double:-15.0
# Is Convolution enabled:
dbus-send --print-reply --system --dest=org.gnome.ShairportSync /org/gnome/ShairportSync org.freedesktop.DBus.Properties.Get string:org.gnome.ShairportSync string:Convolution
# Get Convolution Impulse Response File:
dbus-send --print-reply --system --dest=org.gnome.ShairportSync /org/gnome/ShairportSync org.freedesktop.DBus.Properties.Get string:org.gnome.ShairportSync string:ConvolutionImpulseResponseFile
+
+# Set Convolution Impulse Response File:
+dbus-send --print-reply --system --dest=org.gnome.ShairportSync /org/gnome/ShairportSync org.freedesktop.DBus.Properties.Set string:org.gnome.ShairportSync string:ConvolutionImpulseResponseFile variant:string:"/etc/shairport-sync/boom.wav"
\ No newline at end of file
amount_to_stuff = 0; // no stuffing if it's been disabled
// Apply DSP here
- if (config.loudness
+
+ // check the state of loudness and convolution flags here and don't change them for the frame
+
+ int do_loudness = config.loudness;
+
+ int do_convolution = 0;
+ if ((config.convolution) && (config.convolver_valid))
+ do_convolution = 1;
+
+ // we will apply the convolution gain if convolution is enabled, even if there is no valid convolution happening
+
+ int convolution_is_enabled = 0;
+ if (config.convolution)
+ convolution_is_enabled = 1;
+
+ if (do_loudness
#ifdef CONFIG_CONVOLUTION
- || config.convolution
+ || convolution_is_enabled
#endif
) {
int32_t *tbuf32 = (int32_t *)conn->tbuf;
#ifdef CONFIG_CONVOLUTION
// Apply convolution
- if (config.convolution) {
+ if (do_convolution) {
convolver_process_l(fbuf_l, inbuflength);
convolver_process_r(fbuf_r, inbuflength);
-
+ }
+ if (convolution_is_enabled) {
float gain = pow(10.0, config.convolution_gain / 20.0);
for (i = 0; i < inbuflength; ++i) {
fbuf_l[i] *= gain;
}
#endif
- if (config.loudness) {
+ if (do_loudness) {
// Apply volume and loudness
// Volume must be applied here because the loudness filter will increase the
// signal level and it would saturate the int32_t otherwise