This module is based off Lennart Poettering's LADSPA sink and swaps out
LADSPA functionality for a dbus-aware STFT OLA based digital equalizer.
This module is based off Lennart Poettering's LADSPA sink and swaps out
LADSPA functionality for a dbus-aware STFT OLA based digital equalizer.
PA_MODULE_AUTHOR("Jason Newton");
PA_MODULE_DESCRIPTION(_("General Purpose Equalizer"));
PA_MODULE_VERSION(PACKAGE_VERSION);
PA_MODULE_AUTHOR("Jason Newton");
PA_MODULE_DESCRIPTION(_("General Purpose Equalizer"));
PA_MODULE_VERSION(PACKAGE_VERSION);
/* h=.5*(1-cos(2*pi*j/(window_size+1)), COLA for R=(M+1)/2 */
for (size_t i = 0; i < window_size; ++i)
W[i] = (float).5 * (1 - cos(2*M_PI*i / (window_size+1)));
}
/* h=.5*(1-cos(2*pi*j/(window_size+1)), COLA for R=(M+1)/2 */
for (size_t i = 0; i < window_size; ++i)
W[i] = (float).5 * (1 - cos(2*M_PI*i / (window_size+1)));
}
-static void interpolate(float *signal, size_t length, uint32_t *xs, float *ys, size_t n_points){
+static void interpolate(float *samples, size_t length, uint32_t *xs, float *ys, size_t n_points) {
/* Note that xs must be monotonically increasing! */
float x_range_lower, x_range_upper, c0;
/* Note that xs must be monotonically increasing! */
float x_range_lower, x_range_upper, c0;
return pa_sink_process_msg(o, code, data, offset, chunk);
}
return pa_sink_process_msg(o, code, data, offset, chunk);
}
/* Called from main context */
static int sink_set_state_cb(pa_sink *s, pa_sink_state_t state) {
struct userdata *u;
/* Called from main context */
static int sink_set_state_cb(pa_sink *s, pa_sink_state_t state) {
struct userdata *u;
- pa_sink_input_request_rewind(u->sink_input, s->thread_info.rewind_nbytes+pa_memblockq_get_length(u->input_q), TRUE, FALSE, FALSE);
+ pa_sink_input_request_rewind(u->sink_input, s->thread_info.rewind_nbytes+pa_memblockq_get_length(u->input_q), true, false, false);
- pa_sink_input_set_volume(u->sink_input, &s->real_volume, s->save_volume, TRUE);
+ pa_sink_input_set_volume(u->sink_input, &s->real_volume, s->save_volume, true);
const float * restrict H,//The freq. magnitude scalers filter
const float * restrict W,//The windowing function
fftwf_complex * restrict output_window,//The transformed windowed src
const float * restrict H,//The freq. magnitude scalers filter
const float * restrict W,//The windowing function
fftwf_complex * restrict output_window,//The transformed windowed src
memset(dst + u->window_size, 0, (u->fft_size - u->window_size) * sizeof(float));
//Processing is done here!
//do fft
fftwf_execute_dft_r2c(u->forward_plan, dst, output_window);
//perform filtering
memset(dst + u->window_size, 0, (u->fft_size - u->window_size) * sizeof(float));
//Processing is done here!
//do fft
fftwf_execute_dft_r2c(u->forward_plan, dst, output_window);
//perform filtering
////debug: tests overlapping add
////and negates ALL PREVIOUS processing
////yields a perfect reconstruction if COLA is held
////debug: tests overlapping add
////and negates ALL PREVIOUS processing
////yields a perfect reconstruction if COLA is held
// u->work_buffer[j] = u->W[j] * u->input[c][j];
//}
//overlap add and preserve overlap component from this window (linear phase)
// u->work_buffer[j] = u->W[j] * u->input[c][j];
//}
//overlap add and preserve overlap component from this window (linear phase)
u->work_buffer[j] += overlap[j];
overlap[j] = dst[u->R + j];
}
////debug: tests if basic buffering works
////shouldn't modify the signal AT ALL (beyond roundoff)
u->work_buffer[j] += overlap[j];
overlap[j] = dst[u->R + j];
}
////debug: tests if basic buffering works
////shouldn't modify the signal AT ALL (beyond roundoff)
const float * restrict H,//The freq. magnitude scalers filter
const float * restrict W,//The windowing function
fftwf_complex * restrict output_window,//The transformed windowed src
const float * restrict H,//The freq. magnitude scalers filter
const float * restrict W,//The windowing function
fftwf_complex * restrict output_window,//The transformed windowed src
const size_t overlap_size = PA_ROUND_UP(u->overlap_size, v_size);
float_vector_t x;
x.f[0] = x.f[1] = x.f[2] = x.f[3] = X;
//assert(u->samples_gathered >= u->R);
//use a linear-phase sliding STFT and overlap-add method
const size_t overlap_size = PA_ROUND_UP(u->overlap_size, v_size);
float_vector_t x;
x.f[0] = x.f[1] = x.f[2] = x.f[3] = X;
//assert(u->samples_gathered >= u->R);
//use a linear-phase sliding STFT and overlap-add method
//dst[j] = W[j] * src[j];
float_vector_t *d = (float_vector_t*) (dst + j);
float_vector_t *w = (float_vector_t*) (W + j);
//dst[j] = W[j] * src[j];
float_vector_t *d = (float_vector_t*) (dst + j);
float_vector_t *w = (float_vector_t*) (W + j);
memset(dst + u->window_size, 0, (u->fft_size - u->window_size) * sizeof(float));
//Processing is done here!
//do fft
fftwf_execute_dft_r2c(u->forward_plan, dst, output_window);
//perform filtering - purely magnitude based
memset(dst + u->window_size, 0, (u->fft_size - u->window_size) * sizeof(float));
//Processing is done here!
//do fft
fftwf_execute_dft_r2c(u->forward_plan, dst, output_window);
//perform filtering - purely magnitude based
//output_window[j][0]*=H[j];
//output_window[j][1]*=H[j];
float_vector_t *d = (float_vector_t*)( ((float *) output_window) + 2 * j);
//output_window[j][0]*=H[j];
//output_window[j][1]*=H[j];
float_vector_t *d = (float_vector_t*)( ((float *) output_window) + 2 * j);
////debug: tests overlapping add
////and negates ALL PREVIOUS processing
////yields a perfect reconstruction if COLA is held
////debug: tests overlapping add
////and negates ALL PREVIOUS processing
////yields a perfect reconstruction if COLA is held
// dst[j] = W[j] * src[j];
//}
//overlap add and preserve overlap component from this window (linear phase)
// dst[j] = W[j] * src[j];
//}
//overlap add and preserve overlap component from this window (linear phase)
tchunk.index = 0;
tchunk.length = PA_MIN((u->output_buffer_length - i), mbs);
tchunk.memblock = pa_memblock_new(u->sink->core->mempool, tchunk.length);
tchunk.index = 0;
tchunk.length = PA_MIN((u->output_buffer_length - i), mbs);
tchunk.memblock = pa_memblock_new(u->sink->core->mempool, tchunk.length);
pa_assert(u->samples_gathered >= u->window_size);
iterations = (u->samples_gathered - u->overlap_size) / u->R;
//make sure there is enough buffer memory allocated
pa_assert(u->samples_gathered >= u->window_size);
iterations = (u->samples_gathered - u->overlap_size) / u->R;
//make sure there is enough buffer memory allocated
u->output_buffer_max_length = iterations * u->R * fs;
pa_xfree(u->output_buffer);
u->output_buffer = pa_xmalloc(u->output_buffer_max_length);
}
u->output_buffer_length = iterations * u->R * fs;
u->output_buffer_max_length = iterations * u->R * fs;
pa_xfree(u->output_buffer);
u->output_buffer = pa_xmalloc(u->output_buffer_max_length);
}
u->output_buffer_length = iterations * u->R * fs;
offset = iter * u->R * fs;
for(size_t c = 0;c < u->channels; c++) {
a_i = pa_aupdate_read_begin(u->a_H[c]);
offset = iter * u->R * fs;
for(size_t c = 0;c < u->channels; c++) {
a_i = pa_aupdate_read_begin(u->a_H[c]);
/* The windowing function will make the audio ramped in, as a cheap fix we can
* undo the windowing (for non-zero window values)
*/
/* The windowing function will make the audio ramped in, as a cheap fix we can
* undo the windowing (for non-zero window values)
*/
u->work_buffer[i] = u->W[i] <= FLT_EPSILON ? u->work_buffer[i] : u->work_buffer[i] / u->W[i];
}
}
pa_sample_clamp(PA_SAMPLE_FLOAT32NE, (uint8_t *) (((float *)u->output_buffer) + c) + offset, fs, u->work_buffer, sizeof(float), u->R);
}
u->work_buffer[i] = u->W[i] <= FLT_EPSILON ? u->work_buffer[i] : u->work_buffer[i] / u->W[i];
}
}
pa_sample_clamp(PA_SAMPLE_FLOAT32NE, (uint8_t *) (((float *)u->output_buffer) + c) + offset, fs, u->work_buffer, sizeof(float), u->R);
}
pa_assert(u->samples_gathered + samples <= u->input_buffer_max);
for(size_t c = 0; c < u->channels; c++) {
//buffer with an offset after the overlap from previous
pa_assert(u->samples_gathered + samples <= u->input_buffer_max);
for(size_t c = 0; c < u->channels; c++) {
//buffer with an offset after the overlap from previous
fs = pa_frame_size(&(u->sink->sample_spec));
mbs = pa_mempool_block_size_max(u->sink->core->mempool);
fs = pa_frame_size(&(u->sink->sample_spec));
mbs = pa_mempool_block_size_max(u->sink->core->mempool);
//mbs = PA_MAX(mbs, u->R);
//target_samples = PA_MAX(target_samples, mbs);
//pa_log_debug("target samples: %ld", target_samples);
//mbs = PA_MAX(mbs, u->R);
//target_samples = PA_MAX(target_samples, mbs);
//pa_log_debug("target samples: %ld", target_samples);
for(size_t i = 0; i < u->channels; ++i)
pa_memzero(u->overlap_accum[i], u->overlap_size * sizeof(float));
for(size_t i = 0; i < u->channels; ++i)
pa_memzero(u->overlap_accum[i], u->overlap_size * sizeof(float));
//set buffer size to max request, no overlap copy
max_request = PA_ROUND_UP(pa_sink_input_get_max_request(u->sink_input) / fs , u->R);
max_request = PA_MAX(max_request, u->window_size);
//set buffer size to max request, no overlap copy
max_request = PA_ROUND_UP(pa_sink_input_get_max_request(u->sink_input) / fs , u->R);
max_request = PA_MAX(max_request, u->window_size);
- pa_memblockq_seek(u->input_q, - (int64_t) amount, PA_SEEK_RELATIVE, TRUE);
+ pa_memblockq_seek(u->input_q, - (int64_t) amount, PA_SEEK_RELATIVE, true);
pa_memblockq_set_maxrewind(u->input_q, nbytes);
pa_sink_set_max_rewind_within_thread(u->sink, nbytes);
}
pa_memblockq_set_maxrewind(u->input_q, nbytes);
pa_sink_set_max_rewind_within_thread(u->sink, nbytes);
}
max_request = PA_MAX(max_request, u->window_size);
pa_sink_set_max_request_within_thread(u->sink, max_request * fs);
max_request = PA_MAX(max_request, u->window_size);
pa_sink_set_max_request_within_thread(u->sink, max_request * fs);
pa_sink_set_max_rewind_within_thread(u->sink, pa_sink_input_get_max_rewind(i));
pa_sink_attach_within_thread(u->sink);
pa_sink_set_max_rewind_within_thread(u->sink, pa_sink_input_get_max_rewind(i));
pa_sink_attach_within_thread(u->sink);
if (PA_SINK_INPUT_IS_LINKED(state) &&
i->thread_info.state == PA_SINK_INPUT_INIT) {
pa_log_debug("Requesting rewind due to state change.");
if (PA_SINK_INPUT_IS_LINKED(state) &&
i->thread_info.state == PA_SINK_INPUT_INIT) {
pa_log_debug("Requesting rewind due to state change.");
- pa_sink_input_request_rewind(i, 0, FALSE, TRUE, TRUE);
+ pa_sink_input_request_rewind(i, 0, false, true, true);
-static void pack(char **strs, size_t len, char **packed, size_t *length){
+static void pack(char **strs, size_t len, char **packed, size_t *length) {
t_len += strlen(strs[i]);
}
*length = headers + t_len;
p = *packed = pa_xmalloc0(*length);
*((uint16_t *) p) = (uint16_t) len;
p += sizeof(uint16_t);
t_len += strlen(strs[i]);
}
*length = headers + t_len;
p = *packed = pa_xmalloc0(*length);
*((uint16_t *) p) = (uint16_t) len;
p += sizeof(uint16_t);
-static void unpack(char *str, size_t length, char ***strs, size_t *len){
+static void unpack(char *str, size_t length, char ***strs, size_t *len) {
char *p = str;
*len = *((uint16_t *) p);
p += sizeof(uint16_t);
*strs = pa_xnew(char *, *len);
char *p = str;
*len = *((uint16_t *) p);
p += sizeof(uint16_t);
*strs = pa_xnew(char *, *len);
size_t l = *((uint16_t *) p);
p += sizeof(uint16_t);
(*strs)[i] = pa_xnew(char, l + 1);
size_t l = *((uint16_t *) p);
p += sizeof(uint16_t);
(*strs)[i] = pa_xnew(char, l + 1);
- pa_database_set(u->database, &key, &data, TRUE);
+ pa_database_set(u->database, &key, &data, true);
- pa_assert_se(dbname = pa_state_path(EQ_STATE_DB, FALSE));
- pa_assert_se(database = pa_database_open(dbname, TRUE));
+ pa_assert_se(dbname = pa_state_path(EQ_STATE_DB, false));
+ pa_assert_se(database = pa_database_open(dbname, true));
- pa_database_set(database, &key, &data, TRUE);
+ pa_database_set(database, &key, &data, true);
- if(pa_database_get(u->database, &key, &value) != NULL){
- if(value.size == profile_size){
+ if (pa_database_get(u->database, &key, &value) != NULL) {
+ if (value.size == profile_size) {
float *profile = (float *) value.data;
a_i = pa_aupdate_write_begin(u->a_H[channel]);
u->Xs[channel][a_i] = profile[0];
float *profile = (float *) value.data;
a_i = pa_aupdate_write_begin(u->a_H[channel]);
u->Xs[channel][a_i] = profile[0];
- pa_assert_se(dbname = pa_state_path(EQ_STATE_DB, FALSE));
- database = pa_database_open(dbname, FALSE);
+ pa_assert_se(dbname = pa_state_path(EQ_STATE_DB, false));
+ database = pa_database_open(dbname, false);
- if(pa_database_get(database, &key, &value) != NULL){
- if(value.size > FILTER_STATE_SIZE(u) * sizeof(float) + sizeof(uint16_t)){
+ if (pa_database_get(database, &key, &value) != NULL) {
+ if (value.size > FILTER_STATE_SIZE(u) * sizeof(float) + sizeof(uint16_t)) {
a_i = pa_aupdate_write_begin(u->a_H[c]);
H = state + c * CHANNEL_PROFILE_SIZE(u) + 1;
u->Xs[c][a_i] = state[c * CHANNEL_PROFILE_SIZE(u)];
a_i = pa_aupdate_write_begin(u->a_H[c]);
H = state + c * CHANNEL_PROFILE_SIZE(u) + 1;
u->Xs[c][a_i] = state[c * CHANNEL_PROFILE_SIZE(u)];
}
unpack(((char *)value.data) + FILTER_STATE_SIZE(u) * sizeof(float), value.size - FILTER_STATE_SIZE(u) * sizeof(float), &names, &n_profs);
n_profs = PA_MIN(n_profs, u->channels);
}
unpack(((char *)value.data) + FILTER_STATE_SIZE(u) * sizeof(float), value.size - FILTER_STATE_SIZE(u) * sizeof(float), &names, &n_profs);
n_profs = PA_MIN(n_profs, u->channels);
u->inverse_plan = fftwf_plan_dft_c2r_1d(u->fft_size, u->output_window, u->work_buffer, FFTW_ESTIMATE);
hanning_window(u->W, u->window_size);
u->inverse_plan = fftwf_plan_dft_c2r_1d(u->fft_size, u->output_window, u->work_buffer, FFTW_ESTIMATE);
hanning_window(u->W, u->window_size);
u->base_profiles = pa_xnew0(char *, u->channels);
for (c = 0; c < u->channels; ++c)
u->base_profiles = pa_xnew0(char *, u->channels);
for (c = 0; c < u->channels; ++c)
pa_sink_set_set_mute_callback(u->sink, sink_set_mute_cb);
if (!use_volume_sharing) {
pa_sink_set_set_volume_callback(u->sink, sink_set_volume_cb);
pa_sink_set_set_mute_callback(u->sink, sink_set_mute_cb);
if (!use_volume_sharing) {
pa_sink_set_set_volume_callback(u->sink, sink_set_volume_cb);
pa_sink_input_new_data_init(&sink_input_data);
sink_input_data.driver = __FILE__;
sink_input_data.module = m;
pa_sink_input_new_data_init(&sink_input_data);
sink_input_data.driver = __FILE__;
sink_input_data.module = m;
sink_input_data.origin_sink = u->sink;
pa_proplist_sets(sink_input_data.proplist, PA_PROP_MEDIA_NAME, "Equalized Stream");
pa_proplist_sets(sink_input_data.proplist, PA_PROP_MEDIA_ROLE, "filter");
sink_input_data.origin_sink = u->sink;
pa_proplist_sets(sink_input_data.proplist, PA_PROP_MEDIA_NAME, "Equalized Stream");
pa_proplist_sets(sink_input_data.proplist, PA_PROP_MEDIA_ROLE, "filter");
pa_idxset *sink_list = NULL;
u->dbus_protocol=pa_dbus_protocol_get(u->sink->core);
u->dbus_path=pa_sprintf_malloc("/org/pulseaudio/core1/sink%d", u->sink->index);
pa_idxset *sink_list = NULL;
u->dbus_protocol=pa_dbus_protocol_get(u->sink->core);
u->dbus_path=pa_sprintf_malloc("/org/pulseaudio/core1/sink%d", u->sink->index);
pa_dbus_protocol_add_interface(u->dbus_protocol, u->dbus_path, &equalizer_info, u);
sink_list = pa_shared_get(u->sink->core, SINKLIST);
u->database = pa_shared_get(u->sink->core, EQDB);
pa_dbus_protocol_add_interface(u->dbus_protocol, u->dbus_path, &equalizer_info, u);
sink_list = pa_shared_get(u->sink->core, SINKLIST);
u->database = pa_shared_get(u->sink->core, EQDB);
char *dbname;
sink_list=pa_idxset_new(&pa_idxset_trivial_hash_func, &pa_idxset_trivial_compare_func);
pa_shared_set(u->sink->core, SINKLIST, sink_list);
char *dbname;
sink_list=pa_idxset_new(&pa_idxset_trivial_hash_func, &pa_idxset_trivial_compare_func);
pa_shared_set(u->sink->core, SINKLIST, sink_list);
- pa_assert_se(dbname = pa_state_path("equalizer-presets", FALSE));
- pa_assert_se(u->database = pa_database_open(dbname, TRUE));
+ pa_assert_se(dbname = pa_state_path("equalizer-presets", false));
+ pa_assert_se(u->database = pa_database_open(dbname, true));
pa_xfree(dbname);
pa_shared_set(u->sink->core, EQDB, u->database);
pa_dbus_protocol_add_interface(u->dbus_protocol, MANAGER_PATH, &manager_info, u->sink->core);
pa_xfree(dbname);
pa_shared_set(u->sink->core, EQDB, u->database);
pa_dbus_protocol_add_interface(u->dbus_protocol, MANAGER_PATH, &manager_info, u->sink->core);
- pa_assert_se((signal = dbus_message_new_signal(MANAGER_PATH, MANAGER_IFACE, manager_signals[MANAGER_SIGNAL_SINK_ADDED].name)));
- dbus_message_append_args(signal, DBUS_TYPE_OBJECT_PATH, &u->dbus_path, DBUS_TYPE_INVALID);
- pa_dbus_protocol_send_signal(u->dbus_protocol, signal);
- dbus_message_unref(signal);
+ pa_assert_se((message = dbus_message_new_signal(MANAGER_PATH, MANAGER_IFACE, manager_signals[MANAGER_SIGNAL_SINK_ADDED].name)));
+ dbus_message_append_args(message, DBUS_TYPE_OBJECT_PATH, &u->dbus_path, DBUS_TYPE_INVALID);
+ pa_dbus_protocol_send_signal(u->dbus_protocol, message);
+ dbus_message_unref(message);
- DBusMessage *signal = NULL;
- pa_assert_se((signal = dbus_message_new_signal(MANAGER_PATH, MANAGER_IFACE, manager_signals[MANAGER_SIGNAL_SINK_REMOVED].name)));
- dbus_message_append_args(signal, DBUS_TYPE_OBJECT_PATH, &u->dbus_path, DBUS_TYPE_INVALID);
- pa_dbus_protocol_send_signal(u->dbus_protocol, signal);
- dbus_message_unref(signal);
+ DBusMessage *message = NULL;
+ pa_assert_se((message = dbus_message_new_signal(MANAGER_PATH, MANAGER_IFACE, manager_signals[MANAGER_SIGNAL_SINK_REMOVED].name)));
+ dbus_message_append_args(message, DBUS_TYPE_OBJECT_PATH, &u->dbus_path, DBUS_TYPE_INVALID);
+ pa_dbus_protocol_send_signal(u->dbus_protocol, message);
+ dbus_message_unref(message);
pa_assert_se(sink_list=pa_shared_get(u->sink->core,SINKLIST));
pa_idxset_remove_by_data(sink_list,u,&dummy);
pa_assert_se(sink_list=pa_shared_get(u->sink->core,SINKLIST));
pa_idxset_remove_by_data(sink_list,u,&dummy);
pa_dbus_protocol_unregister_extension(u->dbus_protocol, EXTNAME);
pa_dbus_protocol_remove_interface(u->dbus_protocol, MANAGER_PATH, manager_info.name);
pa_shared_remove(u->sink->core, EQDB);
pa_dbus_protocol_unregister_extension(u->dbus_protocol, EXTNAME);
pa_dbus_protocol_remove_interface(u->dbus_protocol, MANAGER_PATH, manager_info.name);
pa_shared_remove(u->sink->core, EQDB);
void manager_handle_remove_profile(DBusConnection *conn, DBusMessage *msg, void *_u) {
DBusError error;
pa_core *c = (pa_core *)_u;
void manager_handle_remove_profile(DBusConnection *conn, DBusMessage *msg, void *_u) {
DBusError error;
pa_core *c = (pa_core *)_u;
pa_dbus_send_error(conn, msg, DBUS_ERROR_INVALID_ARGS, "%s", error.message);
dbus_error_free(&error);
return;
pa_dbus_send_error(conn, msg, DBUS_ERROR_INVALID_ARGS, "%s", error.message);
dbus_error_free(&error);
return;
- pa_assert_se((signal = dbus_message_new_signal(MANAGER_PATH, MANAGER_IFACE, manager_signals[MANAGER_SIGNAL_PROFILES_CHANGED].name)));
+ pa_assert_se((message = dbus_message_new_signal(MANAGER_PATH, MANAGER_IFACE, manager_signals[MANAGER_SIGNAL_PROFILES_CHANGED].name)));
uint32_t rev=1;
pa_dbus_send_basic_value_reply(conn, msg, DBUS_TYPE_UINT32, &rev);
}
uint32_t rev=1;
pa_dbus_send_basic_value_reply(conn, msg, DBUS_TYPE_UINT32, &rev);
}
pa_assert_se(sink_list = pa_shared_get(u, SINKLIST));
*n_sinks = (unsigned) pa_idxset_size(sink_list);
*names = *n_sinks > 0 ? pa_xnew0(char *,*n_sinks) : NULL;
pa_assert_se(sink_list = pa_shared_get(u, SINKLIST));
*n_sinks = (unsigned) pa_idxset_size(sink_list);
*names = *n_sinks > 0 ? pa_xnew0(char *,*n_sinks) : NULL;
sink_u = (struct userdata *) pa_idxset_iterate(sink_list, &iter, &dummy);
(*names)[i] = pa_xstrdup(sink_u->dbus_path);
}
}
sink_u = (struct userdata *) pa_idxset_iterate(sink_list, &iter, &dummy);
(*names)[i] = pa_xstrdup(sink_u->dbus_path);
}
}
get_sinks((pa_core *) _u, &names, &n);
pa_dbus_send_basic_array_variant_reply(conn, msg, DBUS_TYPE_OBJECT_PATH, names, n);
get_sinks((pa_core *) _u, &names, &n);
pa_dbus_send_basic_array_variant_reply(conn, msg, DBUS_TYPE_OBJECT_PATH, names, n);
done = !pa_database_next(database, &key, &next_key, NULL);
name=pa_xmalloc(key.size + 1);
memcpy(name, key.data, key.size);
done = !pa_database_next(database, &key, &next_key, NULL);
name=pa_xmalloc(key.size + 1);
memcpy(name, key.data, key.size);
get_profiles((pa_core *)_u, &names, &n);
pa_dbus_send_basic_array_variant_reply(conn, msg, DBUS_TYPE_STRING, names, n);
get_profiles((pa_core *)_u, &names, &n);
pa_dbus_send_basic_array_variant_reply(conn, msg, DBUS_TYPE_STRING, names, n);
get_sinks(c, &names, &n);
pa_dbus_append_basic_array_variant_dict_entry(&dict_iter,manager_handlers[MANAGER_HANDLER_EQUALIZED_SINKS].property_name, DBUS_TYPE_OBJECT_PATH, names, n);
get_sinks(c, &names, &n);
pa_dbus_append_basic_array_variant_dict_entry(&dict_iter,manager_handlers[MANAGER_HANDLER_EQUALIZED_SINKS].property_name, DBUS_TYPE_OBJECT_PATH, names, n);
pa_xfree(names[i]);
}
pa_xfree(names);
get_profiles(c, &names, &n);
pa_dbus_append_basic_array_variant_dict_entry(&dict_iter, manager_handlers[MANAGER_HANDLER_PROFILES].property_name, DBUS_TYPE_STRING, names, n);
pa_xfree(names[i]);
}
pa_xfree(names);
get_profiles(c, &names, &n);
pa_dbus_append_basic_array_variant_dict_entry(&dict_iter, manager_handlers[MANAGER_HANDLER_PROFILES].property_name, DBUS_TYPE_STRING, names, n);
float *ys;
uint32_t *xs, channel, r_channel;
double *_ys, preamp;
unsigned x_npoints, y_npoints, a_i;
float *H;
float *ys;
uint32_t *xs, channel, r_channel;
double *_ys, preamp;
unsigned x_npoints, y_npoints, a_i;
float *H;
DBUS_TYPE_UINT32, &channel,
DBUS_TYPE_ARRAY, DBUS_TYPE_UINT32, &xs, &x_npoints,
DBUS_TYPE_ARRAY, DBUS_TYPE_DOUBLE, &_ys, &y_npoints,
DBUS_TYPE_DOUBLE, &preamp,
DBUS_TYPE_UINT32, &channel,
DBUS_TYPE_ARRAY, DBUS_TYPE_UINT32, &xs, &x_npoints,
DBUS_TYPE_ARRAY, DBUS_TYPE_DOUBLE, &_ys, &y_npoints,
DBUS_TYPE_DOUBLE, &preamp,
pa_dbus_send_error(conn, msg, DBUS_ERROR_INVALID_ARGS, "%s", error.message);
dbus_error_free(&error);
return;
}
pa_dbus_send_error(conn, msg, DBUS_ERROR_INVALID_ARGS, "%s", error.message);
dbus_error_free(&error);
return;
}
pa_dbus_send_error(conn, msg, DBUS_ERROR_INVALID_ARGS, "invalid channel: %d", channel);
dbus_error_free(&error);
return;
}
pa_dbus_send_error(conn, msg, DBUS_ERROR_INVALID_ARGS, "invalid channel: %d", channel);
dbus_error_free(&error);
return;
}
pa_dbus_send_error(conn, msg, DBUS_ERROR_INVALID_ARGS, "xs must be monotonic and 0<=x<=%zd", u->fft_size / 2);
dbus_error_free(&error);
return;
pa_dbus_send_error(conn, msg, DBUS_ERROR_INVALID_ARGS, "xs must be monotonic and 0<=x<=%zd", u->fft_size / 2);
dbus_error_free(&error);
return;
pa_dbus_send_error(conn, msg, DBUS_ERROR_INVALID_ARGS, "xs and ys must be the same length and 2<=l<=%zd!", FILTER_SIZE(u));
dbus_error_free(&error);
return;
pa_dbus_send_error(conn, msg, DBUS_ERROR_INVALID_ARGS, "xs and ys must be the same length and 2<=l<=%zd!", FILTER_SIZE(u));
dbus_error_free(&error);
return;
pa_dbus_send_error(conn, msg, DBUS_ERROR_INVALID_ARGS, "xs[0] must be 0 and xs[-1]=fft_size/2");
dbus_error_free(&error);
return;
}
ys = pa_xmalloc(x_npoints * sizeof(float));
pa_dbus_send_error(conn, msg, DBUS_ERROR_INVALID_ARGS, "xs[0] must be 0 and xs[-1]=fft_size/2");
dbus_error_free(&error);
return;
}
ys = pa_xmalloc(x_npoints * sizeof(float));
u->Xs[r_channel][a_i] = preamp;
interpolate(H, FILTER_SIZE(u), xs, ys, x_npoints);
fix_filter(H, u->fft_size);
u->Xs[r_channel][a_i] = preamp;
interpolate(H, FILTER_SIZE(u), xs, ys, x_npoints);
fix_filter(H, u->fft_size);
- pa_assert_se((signal = dbus_message_new_signal(u->dbus_path, EQUALIZER_IFACE, equalizer_signals[EQUALIZER_SIGNAL_FILTER_CHANGED].name)));
- pa_dbus_protocol_send_signal(u->dbus_protocol, signal);
- dbus_message_unref(signal);
+ pa_assert_se((message = dbus_message_new_signal(u->dbus_path, EQUALIZER_IFACE, equalizer_signals[EQUALIZER_SIGNAL_FILTER_CHANGED].name)));
+ pa_dbus_protocol_send_signal(u->dbus_protocol, message);
+ dbus_message_unref(message);
DBUS_TYPE_UINT32, &channel,
DBUS_TYPE_ARRAY, DBUS_TYPE_UINT32, &xs, &x_npoints,
DBUS_TYPE_UINT32, &channel,
DBUS_TYPE_ARRAY, DBUS_TYPE_UINT32, &xs, &x_npoints,
pa_dbus_send_error(conn, msg, DBUS_ERROR_INVALID_ARGS, "%s", error.message);
dbus_error_free(&error);
return;
}
pa_dbus_send_error(conn, msg, DBUS_ERROR_INVALID_ARGS, "%s", error.message);
dbus_error_free(&error);
return;
}
pa_dbus_send_error(conn, msg, DBUS_ERROR_INVALID_ARGS, "invalid channel: %d", channel);
dbus_error_free(&error);
return;
}
pa_dbus_send_error(conn, msg, DBUS_ERROR_INVALID_ARGS, "invalid channel: %d", channel);
dbus_error_free(&error);
return;
}
pa_dbus_send_error(conn, msg, DBUS_ERROR_INVALID_ARGS, "xs indices/length must be <= %zd!", FILTER_SIZE(u));
dbus_error_free(&error);
return;
pa_dbus_send_error(conn, msg, DBUS_ERROR_INVALID_ARGS, "xs indices/length must be <= %zd!", FILTER_SIZE(u));
dbus_error_free(&error);
return;
a_i = pa_aupdate_read_begin(u->a_H[r_channel]);
H = u->Hs[r_channel][a_i];
preamp = u->Xs[r_channel][a_i];
a_i = pa_aupdate_read_begin(u->a_H[r_channel]);
H = u->Hs[r_channel][a_i];
preamp = u->Xs[r_channel][a_i];
-static void get_filter(struct userdata *u, size_t channel, double **H_, double *preamp){
+static void get_filter(struct userdata *u, size_t channel, double **H_, double *preamp) {
float *H;
unsigned a_i;
size_t r_channel = channel == u->channels ? 0 : channel;
*H_ = pa_xnew0(double, FILTER_SIZE(u));
a_i = pa_aupdate_read_begin(u->a_H[r_channel]);
H = u->Hs[r_channel][a_i];
float *H;
unsigned a_i;
size_t r_channel = channel == u->channels ? 0 : channel;
*H_ = pa_xnew0(double, FILTER_SIZE(u));
a_i = pa_aupdate_read_begin(u->a_H[r_channel]);
H = u->Hs[r_channel][a_i];
pa_dbus_send_error(conn, msg, DBUS_ERROR_INVALID_ARGS, "%s", error.message);
dbus_error_free(&error);
return;
}
pa_dbus_send_error(conn, msg, DBUS_ERROR_INVALID_ARGS, "%s", error.message);
dbus_error_free(&error);
return;
}
pa_dbus_send_error(conn, msg, DBUS_ERROR_INVALID_ARGS, "invalid channel: %d", channel);
dbus_error_free(&error);
return;
pa_dbus_send_error(conn, msg, DBUS_ERROR_INVALID_ARGS, "invalid channel: %d", channel);
dbus_error_free(&error);
return;
-static void set_filter(struct userdata *u, size_t channel, double *H_, double preamp){
+static void set_filter(struct userdata *u, size_t channel, double *H_, double preamp) {
a_i = pa_aupdate_write_begin(u->a_H[r_channel]);
u->Xs[r_channel][a_i] = (float) preamp;
H = u->Hs[r_channel][a_i];
a_i = pa_aupdate_write_begin(u->a_H[r_channel]);
u->Xs[r_channel][a_i] = (float) preamp;
H = u->Hs[r_channel][a_i];
unsigned b_i = pa_aupdate_write_begin(u->a_H[c]);
u->Xs[c][b_i] = u->Xs[r_channel][a_i];
memcpy(u->Hs[c][b_i], u->Hs[r_channel][a_i], FILTER_SIZE(u) * sizeof(float));
unsigned b_i = pa_aupdate_write_begin(u->a_H[c]);
u->Xs[c][b_i] = u->Xs[r_channel][a_i];
memcpy(u->Hs[c][b_i], u->Hs[r_channel][a_i], FILTER_SIZE(u) * sizeof(float));
DBUS_TYPE_UINT32, &channel,
DBUS_TYPE_ARRAY, DBUS_TYPE_DOUBLE, &H, &_n_coefs,
DBUS_TYPE_DOUBLE, &preamp,
DBUS_TYPE_UINT32, &channel,
DBUS_TYPE_ARRAY, DBUS_TYPE_DOUBLE, &H, &_n_coefs,
DBUS_TYPE_DOUBLE, &preamp,
pa_dbus_send_error(conn, msg, DBUS_ERROR_INVALID_ARGS, "%s", error.message);
dbus_error_free(&error);
return;
}
pa_dbus_send_error(conn, msg, DBUS_ERROR_INVALID_ARGS, "%s", error.message);
dbus_error_free(&error);
return;
}
pa_dbus_send_error(conn, msg, DBUS_ERROR_INVALID_ARGS, "invalid channel: %d", channel);
dbus_error_free(&error);
return;
}
pa_dbus_send_error(conn, msg, DBUS_ERROR_INVALID_ARGS, "invalid channel: %d", channel);
dbus_error_free(&error);
return;
}
pa_dbus_send_error(conn, msg, DBUS_ERROR_INVALID_ARGS, "This filter takes exactly %zd coefficients, you gave %d", FILTER_SIZE(u), _n_coefs);
return;
}
pa_dbus_send_error(conn, msg, DBUS_ERROR_INVALID_ARGS, "This filter takes exactly %zd coefficients, you gave %d", FILTER_SIZE(u), _n_coefs);
return;
}
- pa_assert_se((signal = dbus_message_new_signal(u->dbus_path, EQUALIZER_IFACE, equalizer_signals[EQUALIZER_SIGNAL_FILTER_CHANGED].name)));
- pa_dbus_protocol_send_signal(u->dbus_protocol, signal);
- dbus_message_unref(signal);
+ pa_assert_se((message = dbus_message_new_signal(u->dbus_path, EQUALIZER_IFACE, equalizer_signals[EQUALIZER_SIGNAL_FILTER_CHANGED].name)));
+ pa_dbus_protocol_send_signal(u->dbus_protocol, message);
+ dbus_message_unref(message);
}
void equalizer_handle_save_profile(DBusConnection *conn, DBusMessage *msg, void *_u) {
struct userdata *u = (struct userdata *) _u;
char *name;
uint32_t channel, r_channel;
}
void equalizer_handle_save_profile(DBusConnection *conn, DBusMessage *msg, void *_u) {
struct userdata *u = (struct userdata *) _u;
char *name;
uint32_t channel, r_channel;
pa_dbus_send_error(conn, msg, DBUS_ERROR_INVALID_ARGS, "%s", error.message);
dbus_error_free(&error);
return;
}
pa_dbus_send_error(conn, msg, DBUS_ERROR_INVALID_ARGS, "%s", error.message);
dbus_error_free(&error);
return;
}
pa_dbus_send_error(conn, msg, DBUS_ERROR_INVALID_ARGS, "invalid channel: %d", channel);
dbus_error_free(&error);
return;
pa_dbus_send_error(conn, msg, DBUS_ERROR_INVALID_ARGS, "invalid channel: %d", channel);
dbus_error_free(&error);
return;
save_profile(u, r_channel, name);
pa_dbus_send_empty_reply(conn, msg);
save_profile(u, r_channel, name);
pa_dbus_send_empty_reply(conn, msg);
- pa_assert_se((signal = dbus_message_new_signal(MANAGER_PATH, MANAGER_IFACE, manager_signals[MANAGER_SIGNAL_PROFILES_CHANGED].name)));
- pa_dbus_protocol_send_signal(u->dbus_protocol, signal);
- dbus_message_unref(signal);
+ pa_assert_se((message = dbus_message_new_signal(MANAGER_PATH, MANAGER_IFACE, manager_signals[MANAGER_SIGNAL_PROFILES_CHANGED].name)));
+ pa_dbus_protocol_send_signal(u->dbus_protocol, message);
+ dbus_message_unref(message);
DBusError error;
uint32_t channel, r_channel;
const char *err_msg = NULL;
DBusError error;
uint32_t channel, r_channel;
const char *err_msg = NULL;
pa_dbus_send_error(conn, msg, DBUS_ERROR_INVALID_ARGS, "%s", error.message);
dbus_error_free(&error);
return;
}
pa_dbus_send_error(conn, msg, DBUS_ERROR_INVALID_ARGS, "%s", error.message);
dbus_error_free(&error);
return;
}
pa_dbus_send_error(conn, msg, DBUS_ERROR_INVALID_ARGS, "invalid channel: %d", channel);
dbus_error_free(&error);
return;
pa_dbus_send_error(conn, msg, DBUS_ERROR_INVALID_ARGS, "invalid channel: %d", channel);
dbus_error_free(&error);
return;
r_channel = channel == u->channels ? 0 : channel;
err_msg = load_profile(u, r_channel, name);
r_channel = channel == u->channels ? 0 : channel;
err_msg = load_profile(u, r_channel, name);
pa_dbus_send_error(conn, msg, DBUS_ERROR_FAILED, "error loading profile %s: %s", name, err_msg);
dbus_error_free(&error);
return;
}
pa_dbus_send_error(conn, msg, DBUS_ERROR_FAILED, "error loading profile %s: %s", name, err_msg);
dbus_error_free(&error);
return;
}
load_profile(u, c, name);
}
}
pa_dbus_send_empty_reply(conn, msg);
load_profile(u, c, name);
}
}
pa_dbus_send_empty_reply(conn, msg);
- pa_assert_se((signal = dbus_message_new_signal(u->dbus_path, EQUALIZER_IFACE, equalizer_signals[EQUALIZER_SIGNAL_FILTER_CHANGED].name)));
- pa_dbus_protocol_send_signal(u->dbus_protocol, signal);
- dbus_message_unref(signal);
+ pa_assert_se((message = dbus_message_new_signal(u->dbus_path, EQUALIZER_IFACE, equalizer_signals[EQUALIZER_SIGNAL_FILTER_CHANGED].name)));
+ pa_dbus_protocol_send_signal(u->dbus_protocol, message);
+ dbus_message_unref(message);
struct userdata *u = (struct userdata *) _u;
DBusError error;
uint32_t channel, r_channel;
struct userdata *u = (struct userdata *) _u;
DBusError error;
uint32_t channel, r_channel;
pa_dbus_send_error(conn, msg, DBUS_ERROR_INVALID_ARGS, "%s", error.message);
dbus_error_free(&error);
return;
}
pa_dbus_send_error(conn, msg, DBUS_ERROR_INVALID_ARGS, "%s", error.message);
dbus_error_free(&error);
return;
}
pa_dbus_send_error(conn, msg, DBUS_ERROR_INVALID_ARGS, "invalid channel: %d", channel);
dbus_error_free(&error);
return;
pa_dbus_send_error(conn, msg, DBUS_ERROR_INVALID_ARGS, "invalid channel: %d", channel);
dbus_error_free(&error);
return;
pa_dbus_send_basic_value_reply(conn,msg, DBUS_TYPE_STRING, &u->base_profiles[r_channel]);
}
pa_dbus_send_basic_value_reply(conn,msg, DBUS_TYPE_STRING, &u->base_profiles[r_channel]);
}
uint32_t rev=1;
pa_dbus_send_basic_value_reply(conn, msg, DBUS_TYPE_UINT32, &rev);
}
uint32_t rev=1;
pa_dbus_send_basic_value_reply(conn, msg, DBUS_TYPE_UINT32, &rev);
}
pa_dbus_send_basic_variant_reply(conn, msg, DBUS_TYPE_UINT32, &channels);
}
pa_dbus_send_basic_variant_reply(conn, msg, DBUS_TYPE_UINT32, &channels);
}
pa_dbus_send_basic_variant_reply(conn, msg, DBUS_TYPE_UINT32, &n_coefs);
}
pa_dbus_send_basic_variant_reply(conn, msg, DBUS_TYPE_UINT32, &n_coefs);
}
pa_dbus_send_basic_variant_reply(conn, msg, DBUS_TYPE_UINT32, &rate);
}
pa_dbus_send_basic_variant_reply(conn, msg, DBUS_TYPE_UINT32, &rate);
}
pa_dbus_send_basic_variant_reply(conn, msg, DBUS_TYPE_UINT32, &fft_size);
}
pa_dbus_send_basic_variant_reply(conn, msg, DBUS_TYPE_UINT32, &fft_size);
}
struct userdata *u;
DBusMessage *reply = NULL;
DBusMessageIter msg_iter, dict_iter;
struct userdata *u;
DBusMessage *reply = NULL;
DBusMessageIter msg_iter, dict_iter;