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 <stdio.h> 2653a5a1b3Sopenharmony_ci 2753a5a1b3Sopenharmony_ci#include <alsa/asoundlib.h> 2853a5a1b3Sopenharmony_ci 2953a5a1b3Sopenharmony_ci#ifdef HAVE_VALGRIND_MEMCHECK_H 3053a5a1b3Sopenharmony_ci#include <valgrind/memcheck.h> 3153a5a1b3Sopenharmony_ci#endif 3253a5a1b3Sopenharmony_ci 3353a5a1b3Sopenharmony_ci#include <pulsecore/module.h> 3453a5a1b3Sopenharmony_ci#include <pulsecore/modargs.h> 3553a5a1b3Sopenharmony_ci#include <pulsecore/log.h> 3653a5a1b3Sopenharmony_ci#include <pulsecore/macro.h> 3753a5a1b3Sopenharmony_ci 3853a5a1b3Sopenharmony_ci#include "alsa-util.h" 3953a5a1b3Sopenharmony_ci#include "alsa-source.h" 4053a5a1b3Sopenharmony_ci 4153a5a1b3Sopenharmony_ciPA_MODULE_AUTHOR("Lennart Poettering"); 4253a5a1b3Sopenharmony_ciPA_MODULE_DESCRIPTION("ALSA Source"); 4353a5a1b3Sopenharmony_ciPA_MODULE_VERSION(PACKAGE_VERSION); 4453a5a1b3Sopenharmony_ciPA_MODULE_LOAD_ONCE(false); 4553a5a1b3Sopenharmony_ciPA_MODULE_USAGE( 4653a5a1b3Sopenharmony_ci "name=<name for the source, to be prefixed> " 4753a5a1b3Sopenharmony_ci "source_name=<name for the source> " 4853a5a1b3Sopenharmony_ci "source_properties=<properties for the source> " 4953a5a1b3Sopenharmony_ci "namereg_fail=<when false attempt to synthesise new source_name if it is already taken> " 5053a5a1b3Sopenharmony_ci "device=<ALSA device> " 5153a5a1b3Sopenharmony_ci "device_id=<ALSA card index> " 5253a5a1b3Sopenharmony_ci "format=<sample format> " 5353a5a1b3Sopenharmony_ci "rate=<sample rate> " 5453a5a1b3Sopenharmony_ci "alternate_rate=<alternate sample rate> " 5553a5a1b3Sopenharmony_ci "channels=<number of channels> " 5653a5a1b3Sopenharmony_ci "channel_map=<channel map> " 5753a5a1b3Sopenharmony_ci "fragments=<number of fragments> " 5853a5a1b3Sopenharmony_ci "fragment_size=<fragment size> " 5953a5a1b3Sopenharmony_ci "mmap=<enable memory mapping?> " 6053a5a1b3Sopenharmony_ci "tsched=<enable system timer based scheduling mode?> " 6153a5a1b3Sopenharmony_ci "tsched_buffer_size=<buffer size when using timer based scheduling> " 6253a5a1b3Sopenharmony_ci "tsched_buffer_watermark=<upper fill watermark> " 6353a5a1b3Sopenharmony_ci "ignore_dB=<ignore dB information from the device?> " 6453a5a1b3Sopenharmony_ci "control=<name of mixer control, or name and index separated by a comma>" 6553a5a1b3Sopenharmony_ci "deferred_volume=<Synchronize software and hardware volume changes to avoid momentary jumps?> " 6653a5a1b3Sopenharmony_ci "deferred_volume_safety_margin=<usec adjustment depending on volume direction> " 6753a5a1b3Sopenharmony_ci "deferred_volume_extra_delay=<usec adjustment to HW volume changes> " 6853a5a1b3Sopenharmony_ci "fixed_latency_range=<disable latency range changes on overrun?>"); 6953a5a1b3Sopenharmony_ci 7053a5a1b3Sopenharmony_cistatic const char* const valid_modargs[] = { 7153a5a1b3Sopenharmony_ci "name", 7253a5a1b3Sopenharmony_ci "source_name", 7353a5a1b3Sopenharmony_ci "source_properties", 7453a5a1b3Sopenharmony_ci "namereg_fail", 7553a5a1b3Sopenharmony_ci "device", 7653a5a1b3Sopenharmony_ci "device_id", 7753a5a1b3Sopenharmony_ci "format", 7853a5a1b3Sopenharmony_ci "rate", 7953a5a1b3Sopenharmony_ci "alternate_rate", 8053a5a1b3Sopenharmony_ci "channels", 8153a5a1b3Sopenharmony_ci "channel_map", 8253a5a1b3Sopenharmony_ci "fragments", 8353a5a1b3Sopenharmony_ci "fragment_size", 8453a5a1b3Sopenharmony_ci "mmap", 8553a5a1b3Sopenharmony_ci "tsched", 8653a5a1b3Sopenharmony_ci "tsched_buffer_size", 8753a5a1b3Sopenharmony_ci "tsched_buffer_watermark", 8853a5a1b3Sopenharmony_ci "ignore_dB", 8953a5a1b3Sopenharmony_ci "control", 9053a5a1b3Sopenharmony_ci "deferred_volume", 9153a5a1b3Sopenharmony_ci "deferred_volume_safety_margin", 9253a5a1b3Sopenharmony_ci "deferred_volume_extra_delay", 9353a5a1b3Sopenharmony_ci "fixed_latency_range", 9453a5a1b3Sopenharmony_ci NULL 9553a5a1b3Sopenharmony_ci}; 9653a5a1b3Sopenharmony_ci 9753a5a1b3Sopenharmony_ciint pa__init(pa_module*m) { 9853a5a1b3Sopenharmony_ci pa_modargs *ma = NULL; 9953a5a1b3Sopenharmony_ci 10053a5a1b3Sopenharmony_ci pa_assert(m); 10153a5a1b3Sopenharmony_ci 10253a5a1b3Sopenharmony_ci pa_alsa_refcnt_inc(); 10353a5a1b3Sopenharmony_ci 10453a5a1b3Sopenharmony_ci if (!(ma = pa_modargs_new(m->argument, valid_modargs))) { 10553a5a1b3Sopenharmony_ci pa_log("Failed to parse module arguments"); 10653a5a1b3Sopenharmony_ci goto fail; 10753a5a1b3Sopenharmony_ci } 10853a5a1b3Sopenharmony_ci 10953a5a1b3Sopenharmony_ci if (!(m->userdata = pa_alsa_source_new(m, ma, __FILE__, NULL, NULL))) 11053a5a1b3Sopenharmony_ci goto fail; 11153a5a1b3Sopenharmony_ci 11253a5a1b3Sopenharmony_ci pa_modargs_free(ma); 11353a5a1b3Sopenharmony_ci 11453a5a1b3Sopenharmony_ci return 0; 11553a5a1b3Sopenharmony_ci 11653a5a1b3Sopenharmony_cifail: 11753a5a1b3Sopenharmony_ci 11853a5a1b3Sopenharmony_ci if (ma) 11953a5a1b3Sopenharmony_ci pa_modargs_free(ma); 12053a5a1b3Sopenharmony_ci 12153a5a1b3Sopenharmony_ci pa__done(m); 12253a5a1b3Sopenharmony_ci 12353a5a1b3Sopenharmony_ci return -1; 12453a5a1b3Sopenharmony_ci} 12553a5a1b3Sopenharmony_ci 12653a5a1b3Sopenharmony_ciint pa__get_n_used(pa_module *m) { 12753a5a1b3Sopenharmony_ci pa_source *source; 12853a5a1b3Sopenharmony_ci 12953a5a1b3Sopenharmony_ci pa_assert(m); 13053a5a1b3Sopenharmony_ci pa_assert_se(source = m->userdata); 13153a5a1b3Sopenharmony_ci 13253a5a1b3Sopenharmony_ci return pa_source_linked_by(source); 13353a5a1b3Sopenharmony_ci} 13453a5a1b3Sopenharmony_ci 13553a5a1b3Sopenharmony_civoid pa__done(pa_module*m) { 13653a5a1b3Sopenharmony_ci pa_source *source; 13753a5a1b3Sopenharmony_ci 13853a5a1b3Sopenharmony_ci pa_assert(m); 13953a5a1b3Sopenharmony_ci 14053a5a1b3Sopenharmony_ci if ((source = m->userdata)) 14153a5a1b3Sopenharmony_ci pa_alsa_source_free(source); 14253a5a1b3Sopenharmony_ci 14353a5a1b3Sopenharmony_ci pa_alsa_refcnt_dec(); 14453a5a1b3Sopenharmony_ci} 145