1/*** 2 This file is part of PulseAudio. 3 4 Copyright 2013 bct electronic GmbH 5 Contributor: Stefan Huber <s.huber@bct-electronic.com> 6 7 PulseAudio is free software; you can redistribute it and/or modify 8 it under the terms of the GNU Lesser General Public License as published 9 by the Free Software Foundation; either version 2.1 of the License, 10 or (at your option) any later version. 11 12 PulseAudio is distributed in the hope that it will be useful, but 13 WITHOUT ANY WARRANTY; without even the implied warranty of 14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 15 General Public License for more details. 16 17 You should have received a copy of the GNU Lesser General Public License 18 along with PulseAudio; if not, see <http://www.gnu.org/licenses/>. 19***/ 20 21#ifdef HAVE_CONFIG_H 22#include <config.h> 23#endif 24 25#include <stdio.h> 26 27#include <pulse/xmalloc.h> 28 29#include <pulsecore/i18n.h> 30#include <pulsecore/macro.h> 31#include <pulsecore/namereg.h> 32#include <pulsecore/module.h> 33#include <pulsecore/core-util.h> 34#include <pulsecore/modargs.h> 35#include <pulsecore/log.h> 36#include <pulsecore/rtpoll.h> 37#include <pulsecore/sample-util.h> 38#include <pulsecore/ltdl-helper.h> 39#include <pulsecore/mix.h> 40 41PA_MODULE_AUTHOR("Stefan Huber"); 42PA_MODULE_DESCRIPTION("Virtual channel remapping source"); 43PA_MODULE_VERSION(PACKAGE_VERSION); 44PA_MODULE_LOAD_ONCE(false); 45PA_MODULE_USAGE( 46 "source_name=<name for the source> " 47 "source_properties=<properties for the source> " 48 "master=<name of source to filter> " 49 "master_channel_map=<channel map> " 50 "format=<sample format> " 51 "rate=<sample rate> " 52 "channels=<number of channels> " 53 "channel_map=<channel map> " 54 "resample_method=<resampler> " 55 "remix=<remix channels?>"); 56 57struct userdata { 58 pa_module *module; 59 60 pa_source *source; 61 pa_source_output *source_output; 62 63 bool auto_desc; 64}; 65 66static const char* const valid_modargs[] = { 67 "source_name", 68 "source_properties", 69 "master", 70 "master_channel_map", 71 "format", 72 "rate", 73 "channels", 74 "channel_map", 75 "resample_method", 76 "remix", 77 NULL 78}; 79 80/* Called from I/O thread context */ 81static int source_process_msg_cb(pa_msgobject *o, int code, void *data, int64_t offset, pa_memchunk *chunk) { 82 struct userdata *u = PA_SOURCE(o)->userdata; 83 84 switch (code) { 85 86 case PA_SOURCE_MESSAGE_GET_LATENCY: 87 88 /* The source is _put() before the source output is, so let's 89 * make sure we don't access it in that time. Also, the 90 * source output is first shut down, the source second. */ 91 if (!PA_SOURCE_IS_LINKED(u->source->thread_info.state) || 92 !PA_SOURCE_OUTPUT_IS_LINKED(u->source_output->thread_info.state)) { 93 *((int64_t*) data) = 0; 94 return 0; 95 } 96 97 *((int64_t*) data) = 98 99 /* Get the latency of the master source */ 100 pa_source_get_latency_within_thread(u->source_output->source, true) + 101 /* Add the latency internal to our source output on top */ 102 pa_bytes_to_usec(pa_memblockq_get_length(u->source_output->thread_info.delay_memblockq), &u->source_output->source->sample_spec); 103 104 /* Add resampler delay */ 105 *((int64_t*) data) += pa_resampler_get_delay_usec(u->source_output->thread_info.resampler); 106 107 return 0; 108 } 109 110 return pa_source_process_msg(o, code, data, offset, chunk); 111} 112 113/* Called from main context */ 114static int source_set_state_in_main_thread_cb(pa_source *s, pa_source_state_t state, pa_suspend_cause_t suspend_cause) { 115 struct userdata *u; 116 117 pa_source_assert_ref(s); 118 pa_assert_se(u = s->userdata); 119 120 if (!PA_SOURCE_IS_LINKED(state) || 121 !PA_SOURCE_OUTPUT_IS_LINKED(u->source_output->state)) 122 return 0; 123 124 pa_source_output_cork(u->source_output, state == PA_SOURCE_SUSPENDED); 125 return 0; 126} 127 128/* Called from I/O thread context */ 129static void source_update_requested_latency_cb(pa_source *s) { 130 struct userdata *u; 131 132 pa_source_assert_ref(s); 133 pa_assert_se(u = s->userdata); 134 135 if (!PA_SOURCE_IS_LINKED(u->source->thread_info.state) || 136 !PA_SOURCE_OUTPUT_IS_LINKED(u->source_output->thread_info.state)) 137 return; 138 139 pa_log_debug("Source update requested latency."); 140 141 /* Just hand this one over to the master source */ 142 pa_source_output_set_requested_latency_within_thread( 143 u->source_output, 144 pa_source_get_requested_latency_within_thread(s)); 145} 146 147/* Called from output thread context */ 148static void source_output_push_cb(pa_source_output *o, const pa_memchunk *chunk) { 149 struct userdata *u; 150 151 pa_source_output_assert_ref(o); 152 pa_source_output_assert_io_context(o); 153 pa_assert_se(u = o->userdata); 154 155 if (!PA_SOURCE_IS_LINKED(u->source->thread_info.state)) 156 return; 157 158 if (!PA_SOURCE_OUTPUT_IS_LINKED(u->source_output->thread_info.state)) { 159 pa_log("push when no link?"); 160 return; 161 } 162 163 pa_source_post(u->source, chunk); 164} 165 166/* Called from output thread context */ 167static void source_output_process_rewind_cb(pa_source_output *o, size_t nbytes) { 168 struct userdata *u; 169 170 pa_source_output_assert_ref(o); 171 pa_source_output_assert_io_context(o); 172 pa_assert_se(u = o->userdata); 173 174 /* If the source is not yet linked, there is nothing to rewind */ 175 if (PA_SOURCE_IS_LINKED(u->source->thread_info.state)) 176 pa_source_process_rewind(u->source, nbytes); 177} 178 179/* Called from output thread context */ 180static void source_output_update_max_rewind_cb(pa_source_output *o, size_t nbytes) { 181 struct userdata *u; 182 183 pa_source_output_assert_ref(o); 184 pa_source_output_assert_io_context(o); 185 pa_assert_se(u = o->userdata); 186 187 pa_source_set_max_rewind_within_thread(u->source, nbytes); 188} 189 190/* Called from output thread context */ 191static void source_output_detach_cb(pa_source_output *o) { 192 struct userdata *u; 193 194 pa_source_output_assert_ref(o); 195 pa_source_output_assert_io_context(o); 196 pa_assert_se(u = o->userdata); 197 198 if (PA_SOURCE_IS_LINKED(u->source->thread_info.state)) 199 pa_source_detach_within_thread(u->source); 200 201 pa_source_set_rtpoll(u->source, NULL); 202} 203 204/* Called from output thread context */ 205static void source_output_attach_cb(pa_source_output *o) { 206 struct userdata *u; 207 208 pa_source_output_assert_ref(o); 209 pa_source_output_assert_io_context(o); 210 pa_assert_se(u = o->userdata); 211 212 pa_source_set_rtpoll(u->source, o->source->thread_info.rtpoll); 213 pa_source_set_latency_range_within_thread(u->source, o->source->thread_info.min_latency, o->source->thread_info.max_latency); 214 pa_source_set_fixed_latency_within_thread(u->source, o->source->thread_info.fixed_latency); 215 pa_source_set_max_rewind_within_thread(u->source, pa_source_output_get_max_rewind(o)); 216 217 if (PA_SOURCE_IS_LINKED(u->source->thread_info.state)) 218 pa_source_attach_within_thread(u->source); 219} 220 221/* Called from main thread */ 222static void source_output_kill_cb(pa_source_output *o) { 223 struct userdata *u; 224 225 pa_source_output_assert_ref(o); 226 pa_assert_ctl_context(); 227 pa_assert_se(u = o->userdata); 228 229 /* The order here matters! We first kill the source so that streams 230 * can properly be moved away while the source output is still connected 231 * to the master. */ 232 pa_source_output_cork(u->source_output, true); 233 pa_source_unlink(u->source); 234 pa_source_output_unlink(u->source_output); 235 236 pa_source_output_unref(u->source_output); 237 u->source_output = NULL; 238 239 pa_source_unref(u->source); 240 u->source = NULL; 241 242 pa_module_unload_request(u->module, true); 243} 244 245/* Called from output thread context except when cork() is called without valid source. */ 246static void source_output_state_change_cb(pa_source_output *o, pa_source_output_state_t state) { 247 struct userdata *u; 248 249 pa_source_output_assert_ref(o); 250 pa_assert_se(u = o->userdata); 251 252 pa_log_debug("Source output %d state %d.", o->index, state); 253} 254 255/* Called from main thread */ 256static void source_output_moving_cb(pa_source_output *o, pa_source *dest) { 257 struct userdata *u; 258 uint32_t idx; 259 pa_source_output *output; 260 261 pa_source_output_assert_ref(o); 262 pa_assert_ctl_context(); 263 pa_assert_se(u = o->userdata); 264 265 if (dest) { 266 pa_source_set_asyncmsgq(u->source, dest->asyncmsgq); 267 pa_source_update_flags(u->source, PA_SOURCE_LATENCY|PA_SOURCE_DYNAMIC_LATENCY, dest->flags); 268 } else 269 pa_source_set_asyncmsgq(u->source, NULL); 270 271 /* Propagate asyncmsq change to attached virtual sources */ 272 PA_IDXSET_FOREACH(output, u->source->outputs, idx) { 273 if (output->destination_source && output->moving) 274 output->moving(output, u->source); 275 } 276 277 if (u->auto_desc && dest) { 278 const char *k; 279 pa_proplist *pl; 280 281 pl = pa_proplist_new(); 282 k = pa_proplist_gets(dest->proplist, PA_PROP_DEVICE_DESCRIPTION); 283 pa_proplist_setf(pl, PA_PROP_DEVICE_DESCRIPTION, "Remapped %s", k ? k : dest->name); 284 285 pa_source_update_proplist(u->source, PA_UPDATE_REPLACE, pl); 286 pa_proplist_free(pl); 287 } 288} 289 290int pa__init(pa_module*m) { 291 struct userdata *u; 292 pa_sample_spec ss; 293 pa_resample_method_t resample_method = PA_RESAMPLER_INVALID; 294 pa_channel_map source_map, stream_map; 295 pa_modargs *ma; 296 pa_source *master; 297 pa_source_output_new_data source_output_data; 298 pa_source_new_data source_data; 299 bool remix = true; 300 301 pa_assert(m); 302 303 if (!(ma = pa_modargs_new(m->argument, valid_modargs))) { 304 pa_log("Failed to parse module arguments."); 305 goto fail; 306 } 307 308 if (!(master = pa_namereg_get(m->core, pa_modargs_get_value(ma, "master", NULL), PA_NAMEREG_SOURCE))) { 309 pa_log("Master source not found."); 310 goto fail; 311 } 312 313 ss = master->sample_spec; 314 source_map = master->channel_map; 315 if (pa_modargs_get_sample_spec_and_channel_map(ma, &ss, &source_map, PA_CHANNEL_MAP_DEFAULT) < 0) { 316 pa_log("Invalid sample format specification or channel map."); 317 goto fail; 318 } 319 320 stream_map = source_map; 321 if (pa_modargs_get_channel_map(ma, "master_channel_map", &stream_map) < 0) { 322 pa_log("Invalid master channel map."); 323 goto fail; 324 } 325 326 if (stream_map.channels != ss.channels) { 327 pa_log("Number of channels doesn't match."); 328 goto fail; 329 } 330 331 if (pa_channel_map_equal(&stream_map, &master->channel_map)) 332 pa_log_warn("No remapping configured, proceeding nonetheless!"); 333 334 if (pa_modargs_get_value_boolean(ma, "remix", &remix) < 0) { 335 pa_log("Invalid boolean remix parameter."); 336 goto fail; 337 } 338 339 if (pa_modargs_get_resample_method(ma, &resample_method) < 0) { 340 pa_log("Invalid resampling method"); 341 goto fail; 342 } 343 344 u = pa_xnew0(struct userdata, 1); 345 u->module = m; 346 m->userdata = u; 347 348 /* Create source */ 349 pa_source_new_data_init(&source_data); 350 source_data.driver = __FILE__; 351 source_data.module = m; 352 if (!(source_data.name = pa_xstrdup(pa_modargs_get_value(ma, "source_name", NULL)))) 353 source_data.name = pa_sprintf_malloc("%s.remapped", master->name); 354 pa_source_new_data_set_sample_spec(&source_data, &ss); 355 pa_source_new_data_set_channel_map(&source_data, &source_map); 356 pa_proplist_sets(source_data.proplist, PA_PROP_DEVICE_MASTER_DEVICE, master->name); 357 pa_proplist_sets(source_data.proplist, PA_PROP_DEVICE_CLASS, "filter"); 358 359 if (pa_modargs_get_proplist(ma, "source_properties", source_data.proplist, PA_UPDATE_REPLACE) < 0) { 360 pa_log("Invalid properties."); 361 pa_source_new_data_done(&source_data); 362 goto fail; 363 } 364 365 if ((u->auto_desc = !pa_proplist_contains(source_data.proplist, PA_PROP_DEVICE_DESCRIPTION))) { 366 const char *k; 367 368 k = pa_proplist_gets(master->proplist, PA_PROP_DEVICE_DESCRIPTION); 369 pa_proplist_setf(source_data.proplist, PA_PROP_DEVICE_DESCRIPTION, "Remapped %s", k ? k : master->name); 370 } 371 372 u->source = pa_source_new(m->core, &source_data, master->flags & (PA_SOURCE_LATENCY|PA_SOURCE_DYNAMIC_LATENCY)); 373 pa_source_new_data_done(&source_data); 374 375 if (!u->source) { 376 pa_log("Failed to create source."); 377 goto fail; 378 } 379 380 u->source->parent.process_msg = source_process_msg_cb; 381 u->source->set_state_in_main_thread = source_set_state_in_main_thread_cb; 382 u->source->update_requested_latency = source_update_requested_latency_cb; 383 384 u->source->userdata = u; 385 386 pa_source_set_asyncmsgq(u->source, master->asyncmsgq); 387 388 /* Create source output */ 389 pa_source_output_new_data_init(&source_output_data); 390 source_output_data.driver = __FILE__; 391 source_output_data.module = m; 392 pa_source_output_new_data_set_source(&source_output_data, master, false, true); 393 source_output_data.destination_source = u->source; 394 395 pa_proplist_sets(source_output_data.proplist, PA_PROP_MEDIA_NAME, "Remapped Stream"); 396 pa_proplist_sets(source_output_data.proplist, PA_PROP_MEDIA_ROLE, "filter"); 397 pa_source_output_new_data_set_sample_spec(&source_output_data, &ss); 398 pa_source_output_new_data_set_channel_map(&source_output_data, &stream_map); 399 source_output_data.flags = (remix ? 0 : PA_SOURCE_OUTPUT_NO_REMIX) | PA_SOURCE_OUTPUT_START_CORKED; 400 source_output_data.resample_method = resample_method; 401 402 pa_source_output_new(&u->source_output, m->core, &source_output_data); 403 pa_source_output_new_data_done(&source_output_data); 404 405 if (!u->source_output) 406 goto fail; 407 408 u->source_output->push = source_output_push_cb; 409 u->source_output->process_rewind = source_output_process_rewind_cb; 410 u->source_output->update_max_rewind = source_output_update_max_rewind_cb; 411 u->source_output->kill = source_output_kill_cb; 412 u->source_output->attach = source_output_attach_cb; 413 u->source_output->detach = source_output_detach_cb; 414 u->source_output->state_change = source_output_state_change_cb; 415 u->source_output->moving = source_output_moving_cb; 416 u->source_output->userdata = u; 417 418 u->source->output_from_master = u->source_output; 419 420 /* The order here is important. The output must be put first, 421 * otherwise streams might attach to the source before the 422 * source output is attached to the master. */ 423 pa_source_output_put(u->source_output); 424 pa_source_put(u->source); 425 pa_source_output_cork(u->source_output, false); 426 427 pa_modargs_free(ma); 428 429 return 0; 430 431fail: 432 if (ma) 433 pa_modargs_free(ma); 434 435 pa__done(m); 436 437 return -1; 438} 439 440int pa__get_n_used(pa_module *m) { 441 struct userdata *u; 442 443 pa_assert(m); 444 pa_assert_se(u = m->userdata); 445 446 return pa_source_linked_by(u->source); 447} 448 449void pa__done(pa_module*m) { 450 struct userdata *u; 451 452 pa_assert(m); 453 454 if (!(u = m->userdata)) 455 return; 456 457 /* See comments in source_output_kill_cb() above regarding 458 * destruction order! */ 459 460 if (u->source_output) 461 pa_source_output_cork(u->source_output, true); 462 463 if (u->source) 464 pa_source_unlink(u->source); 465 466 if (u->source_output) { 467 pa_source_output_unlink(u->source_output); 468 pa_source_output_unref(u->source_output); 469 } 470 471 if (u->source) 472 pa_source_unref(u->source); 473 474 pa_xfree(u); 475} 476