153a5a1b3Sopenharmony_ci/*** 253a5a1b3Sopenharmony_ci This file is part of PulseAudio. 353a5a1b3Sopenharmony_ci 453a5a1b3Sopenharmony_ci Copyright 2004-2008 Lennart Poettering 553a5a1b3Sopenharmony_ci Copyright 2006 Pierre Ossman <ossman@cendio.se> for Cendio AB 653a5a1b3Sopenharmony_ci 753a5a1b3Sopenharmony_ci PulseAudio is free software; you can redistribute it and/or modify 853a5a1b3Sopenharmony_ci it under the terms of the GNU Lesser General Public License as published 953a5a1b3Sopenharmony_ci by the Free Software Foundation; either version 2.1 of the License, 1053a5a1b3Sopenharmony_ci or (at your option) any later version. 1153a5a1b3Sopenharmony_ci 1253a5a1b3Sopenharmony_ci PulseAudio is distributed in the hope that it will be useful, but 1353a5a1b3Sopenharmony_ci WITHOUT ANY WARRANTY; without even the implied warranty of 1453a5a1b3Sopenharmony_ci MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 1553a5a1b3Sopenharmony_ci General Public License for more details. 1653a5a1b3Sopenharmony_ci 1753a5a1b3Sopenharmony_ci You should have received a copy of the GNU Lesser General Public License 1853a5a1b3Sopenharmony_ci along with PulseAudio; if not, see <http://www.gnu.org/licenses/>. 1953a5a1b3Sopenharmony_ci***/ 2053a5a1b3Sopenharmony_ci 2153a5a1b3Sopenharmony_ci#ifdef HAVE_CONFIG_H 2253a5a1b3Sopenharmony_ci#include <config.h> 2353a5a1b3Sopenharmony_ci#endif 2453a5a1b3Sopenharmony_ci 2553a5a1b3Sopenharmony_ci#include <pulsecore/module.h> 2653a5a1b3Sopenharmony_ci#include <pulsecore/sink.h> 2753a5a1b3Sopenharmony_ci#include <pulsecore/modargs.h> 2853a5a1b3Sopenharmony_ci 2953a5a1b3Sopenharmony_ci#include "alsa-util.h" 3053a5a1b3Sopenharmony_ci#include "alsa-sink.h" 3153a5a1b3Sopenharmony_ci 3253a5a1b3Sopenharmony_ciPA_MODULE_AUTHOR("Lennart Poettering"); 3353a5a1b3Sopenharmony_ciPA_MODULE_DESCRIPTION("ALSA Sink"); 3453a5a1b3Sopenharmony_ciPA_MODULE_VERSION(PACKAGE_VERSION); 3553a5a1b3Sopenharmony_ciPA_MODULE_LOAD_ONCE(false); 3653a5a1b3Sopenharmony_ciPA_MODULE_USAGE( 3753a5a1b3Sopenharmony_ci "name=<name of the sink, to be prefixed> " 3853a5a1b3Sopenharmony_ci "sink_name=<name for the sink> " 3953a5a1b3Sopenharmony_ci "sink_properties=<properties for the sink> " 4053a5a1b3Sopenharmony_ci "namereg_fail=<when false attempt to synthesise new sink_name if it is already taken> " 4153a5a1b3Sopenharmony_ci "device=<ALSA device> " 4253a5a1b3Sopenharmony_ci "device_id=<ALSA card index> " 4353a5a1b3Sopenharmony_ci "format=<sample format> " 4453a5a1b3Sopenharmony_ci "rate=<sample rate> " 4553a5a1b3Sopenharmony_ci "alternate_rate=<alternate sample rate> " 4653a5a1b3Sopenharmony_ci "channels=<number of channels> " 4753a5a1b3Sopenharmony_ci "channel_map=<channel map> " 4853a5a1b3Sopenharmony_ci "fragments=<number of fragments> " 4953a5a1b3Sopenharmony_ci "fragment_size=<fragment size> " 5053a5a1b3Sopenharmony_ci "mmap=<enable memory mapping?> " 5153a5a1b3Sopenharmony_ci "tsched=<enable system timer based scheduling mode?> " 5253a5a1b3Sopenharmony_ci "tsched_buffer_size=<buffer size when using timer based scheduling> " 5353a5a1b3Sopenharmony_ci "tsched_buffer_watermark=<lower fill watermark> " 5453a5a1b3Sopenharmony_ci "ignore_dB=<ignore dB information from the device?> " 5553a5a1b3Sopenharmony_ci "control=<name of mixer control, or name and index separated by a comma> " 5653a5a1b3Sopenharmony_ci "rewind_safeguard=<number of bytes that cannot be rewound> " 5753a5a1b3Sopenharmony_ci "deferred_volume=<Synchronize software and hardware volume changes to avoid momentary jumps?> " 5853a5a1b3Sopenharmony_ci "deferred_volume_safety_margin=<usec adjustment depending on volume direction> " 5953a5a1b3Sopenharmony_ci "deferred_volume_extra_delay=<usec adjustment to HW volume changes> " 6053a5a1b3Sopenharmony_ci "fixed_latency_range=<disable latency range changes on underrun?>"); 6153a5a1b3Sopenharmony_ci 6253a5a1b3Sopenharmony_cistatic const char* const valid_modargs[] = { 6353a5a1b3Sopenharmony_ci "name", 6453a5a1b3Sopenharmony_ci "sink_name", 6553a5a1b3Sopenharmony_ci "sink_properties", 6653a5a1b3Sopenharmony_ci "namereg_fail", 6753a5a1b3Sopenharmony_ci "device", 6853a5a1b3Sopenharmony_ci "device_id", 6953a5a1b3Sopenharmony_ci "format", 7053a5a1b3Sopenharmony_ci "rate", 7153a5a1b3Sopenharmony_ci "alternate_rate", 7253a5a1b3Sopenharmony_ci "channels", 7353a5a1b3Sopenharmony_ci "channel_map", 7453a5a1b3Sopenharmony_ci "fragments", 7553a5a1b3Sopenharmony_ci "fragment_size", 7653a5a1b3Sopenharmony_ci "mmap", 7753a5a1b3Sopenharmony_ci "tsched", 7853a5a1b3Sopenharmony_ci "tsched_buffer_size", 7953a5a1b3Sopenharmony_ci "tsched_buffer_watermark", 8053a5a1b3Sopenharmony_ci "ignore_dB", 8153a5a1b3Sopenharmony_ci "control", 8253a5a1b3Sopenharmony_ci "rewind_safeguard", 8353a5a1b3Sopenharmony_ci "deferred_volume", 8453a5a1b3Sopenharmony_ci "deferred_volume_safety_margin", 8553a5a1b3Sopenharmony_ci "deferred_volume_extra_delay", 8653a5a1b3Sopenharmony_ci "fixed_latency_range", 8753a5a1b3Sopenharmony_ci NULL 8853a5a1b3Sopenharmony_ci}; 8953a5a1b3Sopenharmony_ci 9053a5a1b3Sopenharmony_ciint pa__init(pa_module*m) { 9153a5a1b3Sopenharmony_ci pa_modargs *ma = NULL; 9253a5a1b3Sopenharmony_ci 9353a5a1b3Sopenharmony_ci pa_assert(m); 9453a5a1b3Sopenharmony_ci 9553a5a1b3Sopenharmony_ci pa_alsa_refcnt_inc(); 9653a5a1b3Sopenharmony_ci 9753a5a1b3Sopenharmony_ci if (!(ma = pa_modargs_new(m->argument, valid_modargs))) { 9853a5a1b3Sopenharmony_ci pa_log("Failed to parse module arguments"); 9953a5a1b3Sopenharmony_ci goto fail; 10053a5a1b3Sopenharmony_ci } 10153a5a1b3Sopenharmony_ci 10253a5a1b3Sopenharmony_ci if (!(m->userdata = pa_alsa_sink_new(m, ma, __FILE__, NULL, NULL))) 10353a5a1b3Sopenharmony_ci goto fail; 10453a5a1b3Sopenharmony_ci 10553a5a1b3Sopenharmony_ci pa_modargs_free(ma); 10653a5a1b3Sopenharmony_ci 10753a5a1b3Sopenharmony_ci return 0; 10853a5a1b3Sopenharmony_ci 10953a5a1b3Sopenharmony_cifail: 11053a5a1b3Sopenharmony_ci 11153a5a1b3Sopenharmony_ci if (ma) 11253a5a1b3Sopenharmony_ci pa_modargs_free(ma); 11353a5a1b3Sopenharmony_ci 11453a5a1b3Sopenharmony_ci pa__done(m); 11553a5a1b3Sopenharmony_ci 11653a5a1b3Sopenharmony_ci return -1; 11753a5a1b3Sopenharmony_ci} 11853a5a1b3Sopenharmony_ci 11953a5a1b3Sopenharmony_ciint pa__get_n_used(pa_module *m) { 12053a5a1b3Sopenharmony_ci pa_sink *sink; 12153a5a1b3Sopenharmony_ci 12253a5a1b3Sopenharmony_ci pa_assert(m); 12353a5a1b3Sopenharmony_ci pa_assert_se(sink = m->userdata); 12453a5a1b3Sopenharmony_ci 12553a5a1b3Sopenharmony_ci return pa_sink_linked_by(sink); 12653a5a1b3Sopenharmony_ci} 12753a5a1b3Sopenharmony_ci 12853a5a1b3Sopenharmony_civoid pa__done(pa_module*m) { 12953a5a1b3Sopenharmony_ci pa_sink *sink; 13053a5a1b3Sopenharmony_ci 13153a5a1b3Sopenharmony_ci pa_assert(m); 13253a5a1b3Sopenharmony_ci 13353a5a1b3Sopenharmony_ci if ((sink = m->userdata)) 13453a5a1b3Sopenharmony_ci pa_alsa_sink_free(sink); 13553a5a1b3Sopenharmony_ci 13653a5a1b3Sopenharmony_ci pa_alsa_refcnt_dec(); 13753a5a1b3Sopenharmony_ci} 138