squeezers/src/output_alsa.rs
2020-04-17 13:12:00 +02:00

2280 lines
110 KiB
Rust

use ::libc;
extern "C" {
pub type _IO_wide_data;
pub type _IO_codecvt;
pub type _IO_marker;
pub type _snd_mixer;
pub type _snd_mixer_selem_id;
pub type _snd_mixer_elem;
pub type _snd_mixer_class;
pub type _snd_pcm;
pub type _snd_pcm_hw_params;
pub type _snd_output;
#[no_mangle]
static mut stderr: *mut FILE;
#[no_mangle]
fn fflush(__stream: *mut FILE) -> libc::c_int;
#[no_mangle]
fn fprintf(_: *mut FILE, _: *const libc::c_char, _: ...) -> libc::c_int;
#[no_mangle]
fn printf(_: *const libc::c_char, _: ...) -> libc::c_int;
#[no_mangle]
fn vfprintf(_: *mut FILE, _: *const libc::c_char, _: ::std::ffi::VaList)
-> libc::c_int;
#[no_mangle]
fn atoi(__nptr: *const libc::c_char) -> libc::c_int;
#[no_mangle]
fn malloc(_: libc::c_ulong) -> *mut libc::c_void;
#[no_mangle]
fn free(__ptr: *mut libc::c_void);
#[no_mangle]
fn memcpy(_: *mut libc::c_void, _: *const libc::c_void, _: libc::c_ulong)
-> *mut libc::c_void;
#[no_mangle]
fn memset(_: *mut libc::c_void, _: libc::c_int, _: libc::c_ulong)
-> *mut libc::c_void;
#[no_mangle]
fn strcpy(_: *mut libc::c_char, _: *const libc::c_char)
-> *mut libc::c_char;
#[no_mangle]
fn strcmp(_: *const libc::c_char, _: *const libc::c_char) -> libc::c_int;
#[no_mangle]
fn strncmp(_: *const libc::c_char, _: *const libc::c_char,
_: libc::c_ulong) -> libc::c_int;
#[no_mangle]
fn strdup(_: *const libc::c_char) -> *mut libc::c_char;
#[no_mangle]
fn strrchr(_: *const libc::c_char, _: libc::c_int) -> *mut libc::c_char;
#[no_mangle]
fn strtok(_: *mut libc::c_char, _: *const libc::c_char)
-> *mut libc::c_char;
#[no_mangle]
fn strlen(_: *const libc::c_char) -> libc::c_ulong;
#[no_mangle]
fn strerror(_: libc::c_int) -> *mut libc::c_char;
#[no_mangle]
fn __errno_location() -> *mut libc::c_int;
#[no_mangle]
fn sleep(__seconds: libc::c_uint) -> libc::c_uint;
#[no_mangle]
fn usleep(__useconds: __useconds_t) -> libc::c_int;
#[no_mangle]
fn pthread_create(__newthread: *mut pthread_t,
__attr: *const pthread_attr_t,
__start_routine:
Option<unsafe extern "C" fn(_: *mut libc::c_void)
-> *mut libc::c_void>,
__arg: *mut libc::c_void) -> libc::c_int;
#[no_mangle]
fn pthread_join(__th: pthread_t, __thread_return: *mut *mut libc::c_void)
-> libc::c_int;
#[no_mangle]
fn pthread_attr_init(__attr: *mut pthread_attr_t) -> libc::c_int;
#[no_mangle]
fn pthread_attr_destroy(__attr: *mut pthread_attr_t) -> libc::c_int;
#[no_mangle]
fn pthread_attr_setstacksize(__attr: *mut pthread_attr_t,
__stacksize: size_t) -> libc::c_int;
#[no_mangle]
fn pthread_setschedparam(__target_thread: pthread_t,
__policy: libc::c_int,
__param: *const sched_param) -> libc::c_int;
#[no_mangle]
fn pthread_mutex_lock(__mutex: *mut pthread_mutex_t) -> libc::c_int;
#[no_mangle]
fn pthread_mutex_unlock(__mutex: *mut pthread_mutex_t) -> libc::c_int;
#[no_mangle]
fn logtime() -> *const libc::c_char;
#[no_mangle]
fn logprint(fmt: *const libc::c_char, _: ...);
#[no_mangle]
fn next_param(src: *mut libc::c_char, c: libc::c_char)
-> *mut libc::c_char;
#[no_mangle]
fn gettime_ms() -> u32_t;
#[no_mangle]
fn touch_memory(buf: *mut u8_t, size: size_t);
#[no_mangle]
fn output_init_common(level: log_level, device: *const libc::c_char,
output_buf_size: libc::c_uint,
rates: *mut libc::c_uint, idle: libc::c_uint);
#[no_mangle]
fn output_close_common();
#[no_mangle]
fn _output_frames(avail: frames_t) -> frames_t;
#[no_mangle]
fn _apply_cross(outputbuf_0: *mut buffer, out_frames: frames_t,
cross_gain_in: s32_t, cross_gain_out: s32_t,
cross_ptr: *mut *mut s32_t);
#[no_mangle]
fn _scale_and_pack_frames(outputptr: *mut libc::c_void,
inputptr: *mut s32_t, cnt: frames_t,
gainL: s32_t, gainR: s32_t,
format: output_format);
#[no_mangle]
fn _apply_gain(outputbuf_0: *mut buffer, count: frames_t, gainL: s32_t,
gainR: s32_t);
#[no_mangle]
fn snd_pcm_open(pcm: *mut *mut snd_pcm_t, name: *const libc::c_char,
stream: snd_pcm_stream_t, mode: libc::c_int)
-> libc::c_int;
#[no_mangle]
fn snd_pcm_close(pcm: *mut snd_pcm_t) -> libc::c_int;
#[no_mangle]
fn snd_pcm_hw_params(pcm: *mut snd_pcm_t,
params: *mut snd_pcm_hw_params_t) -> libc::c_int;
#[no_mangle]
fn snd_pcm_start(pcm: *mut snd_pcm_t) -> libc::c_int;
#[no_mangle]
fn snd_pcm_state(pcm: *mut snd_pcm_t) -> snd_pcm_state_t;
#[no_mangle]
fn snd_pcm_delay(pcm: *mut snd_pcm_t, delayp: *mut snd_pcm_sframes_t)
-> libc::c_int;
#[no_mangle]
fn snd_pcm_avail_update(pcm: *mut snd_pcm_t) -> snd_pcm_sframes_t;
#[no_mangle]
fn snd_pcm_writei(pcm: *mut snd_pcm_t, buffer: *const libc::c_void,
size: snd_pcm_uframes_t) -> snd_pcm_sframes_t;
#[no_mangle]
fn snd_pcm_wait(pcm: *mut snd_pcm_t, timeout: libc::c_int) -> libc::c_int;
#[no_mangle]
fn snd_pcm_recover(pcm: *mut snd_pcm_t, err: libc::c_int,
silent: libc::c_int) -> libc::c_int;
#[no_mangle]
fn snd_pcm_hw_params_any(pcm: *mut snd_pcm_t,
params: *mut snd_pcm_hw_params_t) -> libc::c_int;
#[no_mangle]
fn snd_pcm_hw_params_sizeof() -> size_t;
#[no_mangle]
fn snd_pcm_hw_params_set_access(pcm: *mut snd_pcm_t,
params: *mut snd_pcm_hw_params_t,
_access: snd_pcm_access_t) -> libc::c_int;
#[no_mangle]
fn snd_pcm_hw_params_set_format(pcm: *mut snd_pcm_t,
params: *mut snd_pcm_hw_params_t,
val: snd_pcm_format_t) -> libc::c_int;
#[no_mangle]
fn snd_pcm_hw_params_set_channels(pcm: *mut snd_pcm_t,
params: *mut snd_pcm_hw_params_t,
val: libc::c_uint) -> libc::c_int;
#[no_mangle]
fn snd_pcm_hw_params_test_rate(pcm: *mut snd_pcm_t,
params: *mut snd_pcm_hw_params_t,
val: libc::c_uint, dir: libc::c_int)
-> libc::c_int;
#[no_mangle]
fn snd_pcm_hw_params_set_rate(pcm: *mut snd_pcm_t,
params: *mut snd_pcm_hw_params_t,
val: libc::c_uint, dir: libc::c_int)
-> libc::c_int;
#[no_mangle]
fn snd_pcm_hw_params_set_rate_resample(pcm: *mut snd_pcm_t,
params: *mut snd_pcm_hw_params_t,
val: libc::c_uint) -> libc::c_int;
#[no_mangle]
fn snd_pcm_hw_params_get_period_size(params: *const snd_pcm_hw_params_t,
frames: *mut snd_pcm_uframes_t,
dir: *mut libc::c_int)
-> libc::c_int;
#[no_mangle]
fn snd_pcm_hw_params_set_period_size_near(pcm: *mut snd_pcm_t,
params:
*mut snd_pcm_hw_params_t,
val: *mut snd_pcm_uframes_t,
dir: *mut libc::c_int)
-> libc::c_int;
#[no_mangle]
fn snd_pcm_hw_params_set_periods_near(pcm: *mut snd_pcm_t,
params: *mut snd_pcm_hw_params_t,
val: *mut libc::c_uint,
dir: *mut libc::c_int)
-> libc::c_int;
#[no_mangle]
fn snd_pcm_hw_params_set_buffer_time_near(pcm: *mut snd_pcm_t,
params:
*mut snd_pcm_hw_params_t,
val: *mut libc::c_uint,
dir: *mut libc::c_int)
-> libc::c_int;
#[no_mangle]
fn snd_pcm_hw_params_get_buffer_size(params: *const snd_pcm_hw_params_t,
val: *mut snd_pcm_uframes_t)
-> libc::c_int;
#[no_mangle]
fn snd_pcm_hw_params_set_buffer_size_near(pcm: *mut snd_pcm_t,
params:
*mut snd_pcm_hw_params_t,
val: *mut snd_pcm_uframes_t)
-> libc::c_int;
#[no_mangle]
fn snd_pcm_format_name(format: snd_pcm_format_t) -> *const libc::c_char;
#[no_mangle]
fn snd_mixer_find_selem(mixer: *mut snd_mixer_t,
id: *const snd_mixer_selem_id_t)
-> *mut snd_mixer_elem_t;
#[no_mangle]
fn snd_device_name_free_hint(hints: *mut *mut libc::c_void)
-> libc::c_int;
#[no_mangle]
fn snd_pcm_mmap_begin(pcm: *mut snd_pcm_t,
areas: *mut *const snd_pcm_channel_area_t,
offset: *mut snd_pcm_uframes_t,
frames: *mut snd_pcm_uframes_t) -> libc::c_int;
#[no_mangle]
fn snd_pcm_mmap_commit(pcm: *mut snd_pcm_t, offset: snd_pcm_uframes_t,
frames: snd_pcm_uframes_t) -> snd_pcm_sframes_t;
#[no_mangle]
fn snd_device_name_get_hint(hint: *const libc::c_void,
id: *const libc::c_char) -> *mut libc::c_char;
#[no_mangle]
fn snd_lib_error_set_handler(handler: snd_lib_error_handler_t)
-> libc::c_int;
#[no_mangle]
fn snd_device_name_hint(card: libc::c_int, iface: *const libc::c_char,
hints: *mut *mut *mut libc::c_void)
-> libc::c_int;
#[no_mangle]
fn snd_mixer_selem_id_set_index(obj: *mut snd_mixer_selem_id_t,
val: libc::c_uint);
#[no_mangle]
fn snd_mixer_selem_id_set_name(obj: *mut snd_mixer_selem_id_t,
val: *const libc::c_char);
#[no_mangle]
fn snd_mixer_close(mixer: *mut snd_mixer_t) -> libc::c_int;
#[no_mangle]
fn snd_mixer_selem_has_playback_switch(elem: *mut snd_mixer_elem_t)
-> libc::c_int;
#[no_mangle]
fn snd_mixer_selem_set_playback_switch_all(elem: *mut snd_mixer_elem_t,
value: libc::c_int)
-> libc::c_int;
#[no_mangle]
fn snd_mixer_selem_get_playback_dB_range(elem: *mut snd_mixer_elem_t,
min: *mut libc::c_long,
max: *mut libc::c_long)
-> libc::c_int;
#[no_mangle]
fn snd_mixer_selem_get_playback_volume_range(elem: *mut snd_mixer_elem_t,
min: *mut libc::c_long,
max: *mut libc::c_long)
-> libc::c_int;
#[no_mangle]
fn snd_output_stdio_attach(outputp: *mut *mut snd_output_t, fp: *mut FILE,
_close: libc::c_int) -> libc::c_int;
#[no_mangle]
fn snd_pcm_dump(pcm: *mut snd_pcm_t, out: *mut snd_output_t)
-> libc::c_int;
#[no_mangle]
fn snd_mixer_selem_set_playback_volume(elem: *mut snd_mixer_elem_t,
channel:
snd_mixer_selem_channel_id_t,
value: libc::c_long)
-> libc::c_int;
#[no_mangle]
fn snd_mixer_selem_set_playback_dB(elem: *mut snd_mixer_elem_t,
channel: snd_mixer_selem_channel_id_t,
value: libc::c_long, dir: libc::c_int)
-> libc::c_int;
#[no_mangle]
fn snd_mixer_selem_get_playback_volume(elem: *mut snd_mixer_elem_t,
channel:
snd_mixer_selem_channel_id_t,
value: *mut libc::c_long)
-> libc::c_int;
#[no_mangle]
fn snd_mixer_selem_id_sizeof() -> size_t;
#[no_mangle]
fn snd_mixer_open(mixer: *mut *mut snd_mixer_t, mode: libc::c_int)
-> libc::c_int;
#[no_mangle]
fn snd_mixer_attach(mixer: *mut snd_mixer_t, name: *const libc::c_char)
-> libc::c_int;
#[no_mangle]
fn snd_mixer_selem_register(mixer: *mut snd_mixer_t,
options: *mut snd_mixer_selem_regopt,
classp: *mut *mut snd_mixer_class_t)
-> libc::c_int;
#[no_mangle]
fn snd_mixer_load(mixer: *mut snd_mixer_t) -> libc::c_int;
#[no_mangle]
fn snd_strerror(errnum: libc::c_int) -> *const libc::c_char;
#[no_mangle]
fn snd_mixer_first_elem(mixer: *mut snd_mixer_t) -> *mut snd_mixer_elem_t;
#[no_mangle]
fn snd_mixer_elem_next(elem: *mut snd_mixer_elem_t)
-> *mut snd_mixer_elem_t;
#[no_mangle]
fn snd_mixer_selem_has_playback_volume(elem: *mut snd_mixer_elem_t)
-> libc::c_int;
#[no_mangle]
fn snd_mixer_selem_get_id(element: *mut snd_mixer_elem_t,
id: *mut snd_mixer_selem_id_t);
#[no_mangle]
fn snd_mixer_selem_id_get_name(obj: *const snd_mixer_selem_id_t)
-> *const libc::c_char;
#[no_mangle]
fn snd_mixer_selem_id_get_index(obj: *const snd_mixer_selem_id_t)
-> libc::c_uint;
#[no_mangle]
fn mlockall(__flags: libc::c_int) -> libc::c_int;
#[no_mangle]
fn mallopt(__param: libc::c_int, __val: libc::c_int) -> libc::c_int;
#[no_mangle]
fn log10(_: libc::c_double) -> libc::c_double;
#[no_mangle]
fn floor(_: libc::c_double) -> libc::c_double;
#[no_mangle]
static mut silencebuf: *mut u8_t;
#[no_mangle]
static mut output: outputstate;
#[no_mangle]
static mut outputbuf: *mut buffer;
}
pub type __builtin_va_list = [__va_list_tag; 1];
#[derive(Copy, Clone)]
#[repr(C)]
pub struct __va_list_tag {
pub gp_offset: libc::c_uint,
pub fp_offset: libc::c_uint,
pub overflow_arg_area: *mut libc::c_void,
pub reg_save_area: *mut libc::c_void,
}
pub type size_t = libc::c_ulong;
pub type va_list = __builtin_va_list;
pub type __uint8_t = libc::c_uchar;
pub type __int32_t = libc::c_int;
pub type __uint32_t = libc::c_uint;
pub type __off_t = libc::c_long;
pub type __off64_t = libc::c_long;
pub type __useconds_t = libc::c_uint;
#[derive(Copy, Clone)]
#[repr(C)]
pub struct _IO_FILE {
pub _flags: libc::c_int,
pub _IO_read_ptr: *mut libc::c_char,
pub _IO_read_end: *mut libc::c_char,
pub _IO_read_base: *mut libc::c_char,
pub _IO_write_base: *mut libc::c_char,
pub _IO_write_ptr: *mut libc::c_char,
pub _IO_write_end: *mut libc::c_char,
pub _IO_buf_base: *mut libc::c_char,
pub _IO_buf_end: *mut libc::c_char,
pub _IO_save_base: *mut libc::c_char,
pub _IO_backup_base: *mut libc::c_char,
pub _IO_save_end: *mut libc::c_char,
pub _markers: *mut _IO_marker,
pub _chain: *mut _IO_FILE,
pub _fileno: libc::c_int,
pub _flags2: libc::c_int,
pub _old_offset: __off_t,
pub _cur_column: libc::c_ushort,
pub _vtable_offset: libc::c_schar,
pub _shortbuf: [libc::c_char; 1],
pub _lock: *mut libc::c_void,
pub _offset: __off64_t,
pub _codecvt: *mut _IO_codecvt,
pub _wide_data: *mut _IO_wide_data,
pub _freeres_list: *mut _IO_FILE,
pub _freeres_buf: *mut libc::c_void,
pub __pad5: size_t,
pub _mode: libc::c_int,
pub _unused2: [libc::c_char; 20],
}
pub type _IO_lock_t = ();
pub type FILE = _IO_FILE;
pub type int32_t = __int32_t;
pub type u_int8_t = __uint8_t;
pub type u_int32_t = __uint32_t;
#[derive(Copy, Clone)]
#[repr(C)]
pub struct __pthread_internal_list {
pub __prev: *mut __pthread_internal_list,
pub __next: *mut __pthread_internal_list,
}
pub type __pthread_list_t = __pthread_internal_list;
#[derive(Copy, Clone)]
#[repr(C)]
pub struct __pthread_mutex_s {
pub __lock: libc::c_int,
pub __count: libc::c_uint,
pub __owner: libc::c_int,
pub __nusers: libc::c_uint,
pub __kind: libc::c_int,
pub __spins: libc::c_short,
pub __elision: libc::c_short,
pub __list: __pthread_list_t,
}
pub type pthread_t = libc::c_ulong;
#[derive(Copy, Clone)]
#[repr(C)]
pub union pthread_attr_t {
pub __size: [libc::c_char; 56],
pub __align: libc::c_long,
}
#[derive(Copy, Clone)]
#[repr(C)]
pub union pthread_mutex_t {
pub __data: __pthread_mutex_s,
pub __size: [libc::c_char; 40],
pub __align: libc::c_long,
}
#[derive(Copy, Clone)]
#[repr(C)]
pub struct sched_param {
pub sched_priority: libc::c_int,
}
pub type u8_t = u_int8_t;
pub type u32_t = u_int32_t;
pub type s32_t = int32_t;
pub type frames_t = u32_t;
pub type log_level = libc::c_uint;
pub const lSDEBUG: log_level = 4;
pub const lDEBUG: log_level = 3;
pub const lINFO: log_level = 2;
pub const lWARN: log_level = 1;
pub const lERROR: log_level = 0;
#[derive(Copy, Clone)]
#[repr(C)]
pub struct buffer {
pub buf: *mut u8_t,
pub readp: *mut u8_t,
pub writep: *mut u8_t,
pub wrap: *mut u8_t,
pub size: size_t,
pub base_size: size_t,
pub mutex: pthread_mutex_t,
}
pub type output_state = libc::c_int;
pub const OUTPUT_START_AT: output_state = 5;
pub const OUTPUT_SKIP_FRAMES: output_state = 4;
pub const OUTPUT_PAUSE_FRAMES: output_state = 3;
pub const OUTPUT_RUNNING: output_state = 2;
pub const OUTPUT_BUFFER: output_state = 1;
pub const OUTPUT_STOPPED: output_state = 0;
pub const OUTPUT_OFF: output_state = -1;
pub type output_format = libc::c_uint;
pub const S16_LE: output_format = 3;
pub const S24_3LE: output_format = 2;
pub const S24_LE: output_format = 1;
pub const S32_LE: output_format = 0;
pub type fade_state = libc::c_uint;
pub const FADE_ACTIVE: fade_state = 2;
pub const FADE_DUE: fade_state = 1;
pub const FADE_INACTIVE: fade_state = 0;
pub type fade_dir = libc::c_uint;
pub const FADE_CROSS: fade_dir = 3;
pub const FADE_DOWN: fade_dir = 2;
pub const FADE_UP: fade_dir = 1;
pub type fade_mode = libc::c_uint;
pub const FADE_INOUT: fade_mode = 4;
pub const FADE_OUT: fade_mode = 3;
pub const FADE_IN: fade_mode = 2;
pub const FADE_CROSSFADE: fade_mode = 1;
pub const FADE_NONE: fade_mode = 0;
#[derive(Copy, Clone)]
#[repr(C)]
pub struct outputstate {
pub state: output_state,
pub format: output_format,
pub device: *const libc::c_char,
pub buffer: libc::c_uint,
pub period: libc::c_uint,
pub track_started: bool,
pub write_cb: Option<unsafe extern "C" fn(_: frames_t, _: bool, _: s32_t,
_: s32_t, _: s32_t, _: s32_t,
_: *mut *mut s32_t)
-> libc::c_int>,
pub start_frames: libc::c_uint,
pub frames_played: libc::c_uint,
pub frames_played_dmp: libc::c_uint,
pub current_sample_rate: libc::c_uint,
pub supported_rates: [libc::c_uint; 18],
pub default_sample_rate: libc::c_uint,
pub error_opening: bool,
pub device_frames: libc::c_uint,
pub updated: u32_t,
pub track_start_time: u32_t,
pub current_replay_gain: u32_t,
pub c2rust_unnamed: C2RustUnnamed,
pub next_sample_rate: libc::c_uint,
pub track_start: *mut u8_t,
pub gainL: u32_t,
pub gainR: u32_t,
pub invert: bool,
pub next_replay_gain: u32_t,
pub threshold: libc::c_uint,
pub fade: fade_state,
pub fade_start: *mut u8_t,
pub fade_end: *mut u8_t,
pub fade_dir: fade_dir,
pub fade_mode: fade_mode,
pub fade_secs: libc::c_uint,
pub rate_delay: libc::c_uint,
pub delay_active: bool,
pub stop_time: u32_t,
pub idle_to: u32_t,
}
#[derive(Copy, Clone)]
#[repr(C)]
pub union C2RustUnnamed {
pub pause_frames: u32_t,
pub skip_frames: u32_t,
pub start_at: u32_t,
}
pub type snd_mixer_t = _snd_mixer;
pub type snd_mixer_selem_id_t = _snd_mixer_selem_id;
pub type snd_mixer_elem_t = _snd_mixer_elem;
pub type snd_mixer_class_t = _snd_mixer_class;
#[derive(Copy, Clone)]
#[repr(C)]
pub struct snd_mixer_selem_regopt {
pub ver: libc::c_int,
pub abstract_0: snd_mixer_selem_regopt_abstract,
pub device: *const libc::c_char,
pub playback_pcm: *mut snd_pcm_t,
pub capture_pcm: *mut snd_pcm_t,
}
pub type snd_pcm_t = _snd_pcm;
pub type snd_mixer_selem_regopt_abstract = libc::c_uint;
pub const SND_MIXER_SABSTRACT_BASIC: snd_mixer_selem_regopt_abstract = 1;
pub const SND_MIXER_SABSTRACT_NONE: snd_mixer_selem_regopt_abstract = 0;
// ouput device
#[derive(Copy, Clone)]
#[repr(C)]
pub struct C2RustUnnamed_0 {
pub device: [libc::c_char; 129],
pub ctl: *mut libc::c_char,
pub mixer_ctl: *mut libc::c_char,
pub format: snd_pcm_format_t,
pub buffer_size: snd_pcm_uframes_t,
pub period_size: snd_pcm_uframes_t,
pub rate: libc::c_uint,
pub mmap: bool,
pub reopen: bool,
pub write_buf: *mut u8_t,
pub volume_mixer_name: *const libc::c_char,
pub mixer_linear: bool,
pub mixer_elem: *mut snd_mixer_elem_t,
pub mixer_handle: *mut snd_mixer_t,
pub mixer_min: libc::c_long,
pub mixer_max: libc::c_long,
}
pub type snd_pcm_uframes_t = libc::c_ulong;
pub type snd_pcm_format_t = _snd_pcm_format;
pub type _snd_pcm_format = libc::c_int;
pub const SND_PCM_FORMAT_U20: _snd_pcm_format = 27;
pub const SND_PCM_FORMAT_S20: _snd_pcm_format = 25;
pub const SND_PCM_FORMAT_IEC958_SUBFRAME: _snd_pcm_format = 18;
pub const SND_PCM_FORMAT_FLOAT64: _snd_pcm_format = 16;
pub const SND_PCM_FORMAT_FLOAT: _snd_pcm_format = 14;
pub const SND_PCM_FORMAT_U32: _snd_pcm_format = 12;
pub const SND_PCM_FORMAT_S32: _snd_pcm_format = 10;
pub const SND_PCM_FORMAT_U24: _snd_pcm_format = 8;
pub const SND_PCM_FORMAT_S24: _snd_pcm_format = 6;
pub const SND_PCM_FORMAT_U16: _snd_pcm_format = 4;
pub const SND_PCM_FORMAT_S16: _snd_pcm_format = 2;
pub const SND_PCM_FORMAT_LAST: _snd_pcm_format = 52;
pub const SND_PCM_FORMAT_DSD_U32_BE: _snd_pcm_format = 52;
pub const SND_PCM_FORMAT_DSD_U16_BE: _snd_pcm_format = 51;
pub const SND_PCM_FORMAT_DSD_U32_LE: _snd_pcm_format = 50;
pub const SND_PCM_FORMAT_DSD_U16_LE: _snd_pcm_format = 49;
pub const SND_PCM_FORMAT_DSD_U8: _snd_pcm_format = 48;
pub const SND_PCM_FORMAT_G723_40_1B: _snd_pcm_format = 47;
pub const SND_PCM_FORMAT_G723_40: _snd_pcm_format = 46;
pub const SND_PCM_FORMAT_G723_24_1B: _snd_pcm_format = 45;
pub const SND_PCM_FORMAT_G723_24: _snd_pcm_format = 44;
pub const SND_PCM_FORMAT_U18_3BE: _snd_pcm_format = 43;
pub const SND_PCM_FORMAT_U18_3LE: _snd_pcm_format = 42;
pub const SND_PCM_FORMAT_S18_3BE: _snd_pcm_format = 41;
pub const SND_PCM_FORMAT_S18_3LE: _snd_pcm_format = 40;
pub const SND_PCM_FORMAT_U20_3BE: _snd_pcm_format = 39;
pub const SND_PCM_FORMAT_U20_3LE: _snd_pcm_format = 38;
pub const SND_PCM_FORMAT_S20_3BE: _snd_pcm_format = 37;
pub const SND_PCM_FORMAT_S20_3LE: _snd_pcm_format = 36;
pub const SND_PCM_FORMAT_U24_3BE: _snd_pcm_format = 35;
pub const SND_PCM_FORMAT_U24_3LE: _snd_pcm_format = 34;
pub const SND_PCM_FORMAT_S24_3BE: _snd_pcm_format = 33;
pub const SND_PCM_FORMAT_S24_3LE: _snd_pcm_format = 32;
pub const SND_PCM_FORMAT_SPECIAL: _snd_pcm_format = 31;
pub const SND_PCM_FORMAT_U20_BE: _snd_pcm_format = 28;
pub const SND_PCM_FORMAT_U20_LE: _snd_pcm_format = 27;
pub const SND_PCM_FORMAT_S20_BE: _snd_pcm_format = 26;
pub const SND_PCM_FORMAT_S20_LE: _snd_pcm_format = 25;
pub const SND_PCM_FORMAT_GSM: _snd_pcm_format = 24;
pub const SND_PCM_FORMAT_MPEG: _snd_pcm_format = 23;
pub const SND_PCM_FORMAT_IMA_ADPCM: _snd_pcm_format = 22;
pub const SND_PCM_FORMAT_A_LAW: _snd_pcm_format = 21;
pub const SND_PCM_FORMAT_MU_LAW: _snd_pcm_format = 20;
pub const SND_PCM_FORMAT_IEC958_SUBFRAME_BE: _snd_pcm_format = 19;
pub const SND_PCM_FORMAT_IEC958_SUBFRAME_LE: _snd_pcm_format = 18;
pub const SND_PCM_FORMAT_FLOAT64_BE: _snd_pcm_format = 17;
pub const SND_PCM_FORMAT_FLOAT64_LE: _snd_pcm_format = 16;
pub const SND_PCM_FORMAT_FLOAT_BE: _snd_pcm_format = 15;
pub const SND_PCM_FORMAT_FLOAT_LE: _snd_pcm_format = 14;
pub const SND_PCM_FORMAT_U32_BE: _snd_pcm_format = 13;
pub const SND_PCM_FORMAT_U32_LE: _snd_pcm_format = 12;
pub const SND_PCM_FORMAT_S32_BE: _snd_pcm_format = 11;
pub const SND_PCM_FORMAT_S32_LE: _snd_pcm_format = 10;
pub const SND_PCM_FORMAT_U24_BE: _snd_pcm_format = 9;
pub const SND_PCM_FORMAT_U24_LE: _snd_pcm_format = 8;
pub const SND_PCM_FORMAT_S24_BE: _snd_pcm_format = 7;
pub const SND_PCM_FORMAT_S24_LE: _snd_pcm_format = 6;
pub const SND_PCM_FORMAT_U16_BE: _snd_pcm_format = 5;
pub const SND_PCM_FORMAT_U16_LE: _snd_pcm_format = 4;
pub const SND_PCM_FORMAT_S16_BE: _snd_pcm_format = 3;
pub const SND_PCM_FORMAT_S16_LE: _snd_pcm_format = 2;
pub const SND_PCM_FORMAT_U8: _snd_pcm_format = 1;
pub const SND_PCM_FORMAT_S8: _snd_pcm_format = 0;
pub const SND_PCM_FORMAT_UNKNOWN: _snd_pcm_format = -1;
pub type snd_mixer_selem_channel_id_t = _snd_mixer_selem_channel_id;
pub type _snd_mixer_selem_channel_id = libc::c_int;
pub const SND_MIXER_SCHN_MONO: _snd_mixer_selem_channel_id = 0;
pub const SND_MIXER_SCHN_LAST: _snd_mixer_selem_channel_id = 31;
pub const SND_MIXER_SCHN_REAR_CENTER: _snd_mixer_selem_channel_id = 8;
pub const SND_MIXER_SCHN_SIDE_RIGHT: _snd_mixer_selem_channel_id = 7;
pub const SND_MIXER_SCHN_SIDE_LEFT: _snd_mixer_selem_channel_id = 6;
pub const SND_MIXER_SCHN_WOOFER: _snd_mixer_selem_channel_id = 5;
pub const SND_MIXER_SCHN_FRONT_CENTER: _snd_mixer_selem_channel_id = 4;
pub const SND_MIXER_SCHN_REAR_RIGHT: _snd_mixer_selem_channel_id = 3;
pub const SND_MIXER_SCHN_REAR_LEFT: _snd_mixer_selem_channel_id = 2;
pub const SND_MIXER_SCHN_FRONT_RIGHT: _snd_mixer_selem_channel_id = 1;
pub const SND_MIXER_SCHN_FRONT_LEFT: _snd_mixer_selem_channel_id = 0;
pub const SND_MIXER_SCHN_UNKNOWN: _snd_mixer_selem_channel_id = -1;
pub type snd_pcm_hw_params_t = _snd_pcm_hw_params;
pub type snd_pcm_stream_t = _snd_pcm_stream;
pub type _snd_pcm_stream = libc::c_uint;
pub const SND_PCM_STREAM_LAST: _snd_pcm_stream = 1;
pub const SND_PCM_STREAM_CAPTURE: _snd_pcm_stream = 1;
pub const SND_PCM_STREAM_PLAYBACK: _snd_pcm_stream = 0;
pub type snd_pcm_sframes_t = libc::c_long;
pub const SND_PCM_STATE_DISCONNECTED: _snd_pcm_state = 8;
pub type snd_pcm_state_t = _snd_pcm_state;
pub type _snd_pcm_state = libc::c_uint;
pub const SND_PCM_STATE_PRIVATE1: _snd_pcm_state = 1024;
pub const SND_PCM_STATE_LAST: _snd_pcm_state = 8;
pub const SND_PCM_STATE_SUSPENDED: _snd_pcm_state = 7;
pub const SND_PCM_STATE_PAUSED: _snd_pcm_state = 6;
pub const SND_PCM_STATE_DRAINING: _snd_pcm_state = 5;
pub const SND_PCM_STATE_XRUN: _snd_pcm_state = 4;
pub const SND_PCM_STATE_RUNNING: _snd_pcm_state = 3;
pub const SND_PCM_STATE_PREPARED: _snd_pcm_state = 2;
pub const SND_PCM_STATE_SETUP: _snd_pcm_state = 1;
pub const SND_PCM_STATE_OPEN: _snd_pcm_state = 0;
pub type snd_output_t = _snd_output;
pub type snd_pcm_access_t = _snd_pcm_access;
pub type _snd_pcm_access = libc::c_uint;
pub const SND_PCM_ACCESS_LAST: _snd_pcm_access = 4;
pub const SND_PCM_ACCESS_RW_NONINTERLEAVED: _snd_pcm_access = 4;
pub const SND_PCM_ACCESS_RW_INTERLEAVED: _snd_pcm_access = 3;
pub const SND_PCM_ACCESS_MMAP_COMPLEX: _snd_pcm_access = 2;
pub const SND_PCM_ACCESS_MMAP_NONINTERLEAVED: _snd_pcm_access = 1;
pub const SND_PCM_ACCESS_MMAP_INTERLEAVED: _snd_pcm_access = 0;
pub type snd_lib_error_handler_t
=
Option<unsafe extern "C" fn(_: *const libc::c_char, _: libc::c_int,
_: *const libc::c_char, _: libc::c_int,
_: *const libc::c_char, _: ...) -> ()>;
pub type snd_pcm_channel_area_t = _snd_pcm_channel_area;
#[derive(Copy, Clone)]
#[repr(C)]
pub struct _snd_pcm_channel_area {
pub addr: *mut libc::c_void,
pub first: libc::c_uint,
pub step: libc::c_uint,
}
static mut fmts: [snd_pcm_format_t; 5] =
[SND_PCM_FORMAT_S32_LE, SND_PCM_FORMAT_S24_LE, SND_PCM_FORMAT_S24_3LE,
SND_PCM_FORMAT_S16_LE, SND_PCM_FORMAT_UNKNOWN];
static mut alsa: C2RustUnnamed_0 =
C2RustUnnamed_0{device: [0; 129],
ctl: 0 as *const libc::c_char as *mut libc::c_char,
mixer_ctl: 0 as *const libc::c_char as *mut libc::c_char,
format: SND_PCM_FORMAT_S8,
buffer_size: 0,
period_size: 0,
rate: 0,
mmap: false,
reopen: false,
write_buf: 0 as *const u8_t as *mut u8_t,
volume_mixer_name: 0 as *const libc::c_char,
mixer_linear: false,
mixer_elem:
0 as *const snd_mixer_elem_t as *mut snd_mixer_elem_t,
mixer_handle: 0 as *const snd_mixer_t as *mut snd_mixer_t,
mixer_min: 0,
mixer_max: 0,};
static mut pcmp: *mut snd_pcm_t = 0 as *const snd_pcm_t as *mut snd_pcm_t;
static mut loglevel: log_level = lERROR;
static mut running: bool = 1 as libc::c_int != 0;
unsafe extern "C" fn ctl4device(mut device: *const libc::c_char)
-> *mut libc::c_char {
let mut ctl: *mut libc::c_char = 0 as *mut libc::c_char;
if strncmp(device, b"hw:\x00" as *const u8 as *const libc::c_char,
3 as libc::c_int as libc::c_ulong) == 0 {
ctl = strdup(device)
} else if strncmp(device,
b"plughw:\x00" as *const u8 as *const libc::c_char,
7 as libc::c_int as libc::c_ulong) == 0 {
ctl = strdup(device.offset(4 as libc::c_int as isize))
}
if !ctl.is_null() {
let mut comma: *mut libc::c_char = 0 as *mut libc::c_char;
comma = strrchr(ctl, ',' as i32);
if !comma.is_null() { *comma = '\u{0}' as i32 as libc::c_char }
} else { ctl = strdup(device) }
return ctl;
}
#[no_mangle]
pub unsafe extern "C" fn list_devices() {
let mut hints: *mut *mut libc::c_void = 0 as *mut *mut libc::c_void;
let mut n: *mut *mut libc::c_void = 0 as *mut *mut libc::c_void;
if snd_device_name_hint(-(1 as libc::c_int),
b"pcm\x00" as *const u8 as *const libc::c_char,
&mut hints) >= 0 as libc::c_int {
n = hints;
printf(b"Output devices:\n\x00" as *const u8 as *const libc::c_char);
while !(*n).is_null() {
let mut name: *mut libc::c_char =
snd_device_name_get_hint(*n,
b"NAME\x00" as *const u8 as
*const libc::c_char);
let mut desc: *mut libc::c_char =
snd_device_name_get_hint(*n,
b"DESC\x00" as *const u8 as
*const libc::c_char);
if !name.is_null() {
printf(b" %-30s\x00" as *const u8 as *const libc::c_char,
name);
}
if !desc.is_null() {
let mut s1: *mut libc::c_char =
strtok(desc,
b"\n\x00" as *const u8 as *const libc::c_char);
let mut s2: *mut libc::c_char =
strtok(0 as *mut libc::c_char,
b"\n\x00" as *const u8 as *const libc::c_char);
if !s1.is_null() {
printf(b" - %s\x00" as *const u8 as *const libc::c_char,
s1);
}
if !s2.is_null() {
printf(b" - %s\x00" as *const u8 as *const libc::c_char,
s2);
}
}
printf(b"\n\x00" as *const u8 as *const libc::c_char);
if !name.is_null() { free(name as *mut libc::c_void); }
if !desc.is_null() { free(desc as *mut libc::c_void); }
n = n.offset(1)
}
snd_device_name_free_hint(hints);
}
printf(b"\n\x00" as *const u8 as *const libc::c_char);
}
#[no_mangle]
pub unsafe extern "C" fn list_mixers(mut output_device: *const libc::c_char) {
let mut err: libc::c_int = 0;
let mut handle: *mut snd_mixer_t = 0 as *mut snd_mixer_t;
let mut sid: *mut snd_mixer_selem_id_t = 0 as *mut snd_mixer_selem_id_t;
let mut elem: *mut snd_mixer_elem_t = 0 as *mut snd_mixer_elem_t;
let mut ctl: *mut libc::c_char = ctl4device(output_device);
let mut fresh0 =
::std::vec::from_elem(0, snd_mixer_selem_id_sizeof() as usize);
sid = fresh0.as_mut_ptr() as *mut snd_mixer_selem_id_t;
memset(sid as *mut libc::c_void, 0 as libc::c_int,
snd_mixer_selem_id_sizeof());
if loglevel as libc::c_uint >= lINFO as libc::c_int as libc::c_uint {
logprint(b"%s %s:%d listing mixers for: %s\n\x00" as *const u8 as
*const libc::c_char, logtime(),
(*::std::mem::transmute::<&[u8; 12],
&[libc::c_char; 12]>(b"list_mixers\x00")).as_ptr(),
139 as libc::c_int, output_device);
}
err = snd_mixer_open(&mut handle, 0 as libc::c_int);
if err < 0 as libc::c_int {
logprint(b"%s %s:%d open error: %s\n\x00" as *const u8 as
*const libc::c_char, logtime(),
(*::std::mem::transmute::<&[u8; 12],
&[libc::c_char; 12]>(b"list_mixers\x00")).as_ptr(),
142 as libc::c_int, snd_strerror(err));
return
}
err = snd_mixer_attach(handle, ctl);
if err < 0 as libc::c_int {
logprint(b"%s %s:%d attach error: %s\n\x00" as *const u8 as
*const libc::c_char, logtime(),
(*::std::mem::transmute::<&[u8; 12],
&[libc::c_char; 12]>(b"list_mixers\x00")).as_ptr(),
146 as libc::c_int, snd_strerror(err));
snd_mixer_close(handle);
free(ctl as *mut libc::c_void);
return
}
free(ctl as *mut libc::c_void);
err =
snd_mixer_selem_register(handle, 0 as *mut snd_mixer_selem_regopt,
0 as *mut *mut snd_mixer_class_t);
if err < 0 as libc::c_int {
logprint(b"%s %s:%d register error: %s\n\x00" as *const u8 as
*const libc::c_char, logtime(),
(*::std::mem::transmute::<&[u8; 12],
&[libc::c_char; 12]>(b"list_mixers\x00")).as_ptr(),
153 as libc::c_int, snd_strerror(err));
snd_mixer_close(handle);
return
}
err = snd_mixer_load(handle);
if err < 0 as libc::c_int {
logprint(b"%s %s:%d load error: %s\n\x00" as *const u8 as
*const libc::c_char, logtime(),
(*::std::mem::transmute::<&[u8; 12],
&[libc::c_char; 12]>(b"list_mixers\x00")).as_ptr(),
158 as libc::c_int, snd_strerror(err));
snd_mixer_close(handle);
return
}
printf(b"Volume controls for %s\n\x00" as *const u8 as
*const libc::c_char, output_device);
elem = snd_mixer_first_elem(handle);
while !elem.is_null() {
if snd_mixer_selem_has_playback_volume(elem) != 0 {
snd_mixer_selem_get_id(elem, sid);
printf(b" %s\x00" as *const u8 as *const libc::c_char,
snd_mixer_selem_id_get_name(sid));
if snd_mixer_selem_id_get_index(sid) != 0 {
printf(b",%d\x00" as *const u8 as *const libc::c_char,
snd_mixer_selem_id_get_index(sid));
}
printf(b"\n\x00" as *const u8 as *const libc::c_char);
}
elem = snd_mixer_elem_next(elem)
}
printf(b"\n\x00" as *const u8 as *const libc::c_char);
snd_mixer_close(handle);
}
// LMS volume map for SqueezePlay sends values in range ~ -72..0 dB
unsafe extern "C" fn set_mixer(mut setmax: bool, mut ldB: libc::c_float,
mut rdB: libc::c_float) {
let mut err: libc::c_int = 0;
let mut nleft: libc::c_long = 0;
let mut nright: libc::c_long = 0;
if alsa.mixer_linear {
let mut lraw: libc::c_long = 0;
let mut rraw: libc::c_long = 0;
if setmax {
rraw = alsa.mixer_max;
lraw = rraw
} else {
lraw =
((if ldB > -(72 as libc::c_int) as libc::c_float {
(72 as libc::c_int as libc::c_double) +
floor(ldB as libc::c_double)
} else { 0 as libc::c_int as libc::c_double }) /
72 as libc::c_int as libc::c_double *
(alsa.mixer_max - alsa.mixer_min) as libc::c_double +
alsa.mixer_min as libc::c_double) as libc::c_long;
rraw =
((if rdB > -(72 as libc::c_int) as libc::c_float {
(72 as libc::c_int as libc::c_double) +
floor(rdB as libc::c_double)
} else { 0 as libc::c_int as libc::c_double }) /
72 as libc::c_int as libc::c_double *
(alsa.mixer_max - alsa.mixer_min) as libc::c_double +
alsa.mixer_min as libc::c_double) as libc::c_long
}
if loglevel as libc::c_uint >= lDEBUG as libc::c_int as libc::c_uint {
logprint(b"%s %s:%d setting vol raw [%ld..%ld]\n\x00" as *const u8
as *const libc::c_char, logtime(),
(*::std::mem::transmute::<&[u8; 10],
&[libc::c_char; 10]>(b"set_mixer\x00")).as_ptr(),
193 as libc::c_int, alsa.mixer_min, alsa.mixer_max);
}
err =
snd_mixer_selem_set_playback_volume(alsa.mixer_elem,
SND_MIXER_SCHN_FRONT_LEFT,
lraw);
if err < 0 as libc::c_int {
logprint(b"%s %s:%d error setting left volume: %s\n\x00" as
*const u8 as *const libc::c_char, logtime(),
(*::std::mem::transmute::<&[u8; 10],
&[libc::c_char; 10]>(b"set_mixer\x00")).as_ptr(),
195 as libc::c_int, snd_strerror(err));
}
err =
snd_mixer_selem_set_playback_volume(alsa.mixer_elem,
SND_MIXER_SCHN_FRONT_RIGHT,
rraw);
if err < 0 as libc::c_int {
logprint(b"%s %s:%d error setting right volume: %s\n\x00" as
*const u8 as *const libc::c_char, logtime(),
(*::std::mem::transmute::<&[u8; 10],
&[libc::c_char; 10]>(b"set_mixer\x00")).as_ptr(),
198 as libc::c_int, snd_strerror(err));
}
} else {
// set db directly
if loglevel as libc::c_uint >= lDEBUG as libc::c_int as libc::c_uint {
logprint(b"%s %s:%d setting vol dB [%ld..%ld]\n\x00" as *const u8
as *const libc::c_char, logtime(),
(*::std::mem::transmute::<&[u8; 10],
&[libc::c_char; 10]>(b"set_mixer\x00")).as_ptr(),
202 as libc::c_int, alsa.mixer_min, alsa.mixer_max);
}
if setmax {
// set to 0dB if available as this should be max volume for music recored at max pcm values
if alsa.mixer_max >= 0 as libc::c_int as libc::c_long &&
alsa.mixer_min <= 0 as libc::c_int as libc::c_long {
rdB = 0 as libc::c_int as libc::c_float;
ldB = rdB
} else { rdB = alsa.mixer_max as libc::c_float; ldB = rdB }
}
err =
snd_mixer_selem_set_playback_dB(alsa.mixer_elem,
SND_MIXER_SCHN_FRONT_LEFT,
(100 as libc::c_int as
libc::c_float * ldB) as
libc::c_long,
1 as libc::c_int);
if err < 0 as libc::c_int {
logprint(b"%s %s:%d error setting left volume: %s\n\x00" as
*const u8 as *const libc::c_char, logtime(),
(*::std::mem::transmute::<&[u8; 10],
&[libc::c_char; 10]>(b"set_mixer\x00")).as_ptr(),
212 as libc::c_int, snd_strerror(err));
}
err =
snd_mixer_selem_set_playback_dB(alsa.mixer_elem,
SND_MIXER_SCHN_FRONT_RIGHT,
(100 as libc::c_int as
libc::c_float * rdB) as
libc::c_long,
1 as libc::c_int);
if err < 0 as libc::c_int {
logprint(b"%s %s:%d error setting right volume: %s\n\x00" as
*const u8 as *const libc::c_char, logtime(),
(*::std::mem::transmute::<&[u8; 10],
&[libc::c_char; 10]>(b"set_mixer\x00")).as_ptr(),
215 as libc::c_int, snd_strerror(err));
}
}
err =
snd_mixer_selem_get_playback_volume(alsa.mixer_elem,
SND_MIXER_SCHN_FRONT_LEFT,
&mut nleft);
if err < 0 as libc::c_int {
logprint(b"%s %s:%d error getting left vol: %s\n\x00" as *const u8 as
*const libc::c_char, logtime(),
(*::std::mem::transmute::<&[u8; 10],
&[libc::c_char; 10]>(b"set_mixer\x00")).as_ptr(),
220 as libc::c_int, snd_strerror(err));
}
err =
snd_mixer_selem_get_playback_volume(alsa.mixer_elem,
SND_MIXER_SCHN_FRONT_RIGHT,
&mut nright);
if err < 0 as libc::c_int {
logprint(b"%s %s:%d error getting right vol: %s\n\x00" as *const u8 as
*const libc::c_char, logtime(),
(*::std::mem::transmute::<&[u8; 10],
&[libc::c_char; 10]>(b"set_mixer\x00")).as_ptr(),
223 as libc::c_int, snd_strerror(err));
}
if loglevel as libc::c_uint >= lDEBUG as libc::c_int as libc::c_uint {
logprint(b"%s %s:%d %s left: %3.1fdB -> %ld right: %3.1fdB -> %ld\n\x00"
as *const u8 as *const libc::c_char, logtime(),
(*::std::mem::transmute::<&[u8; 10],
&[libc::c_char; 10]>(b"set_mixer\x00")).as_ptr(),
226 as libc::c_int, alsa.volume_mixer_name,
ldB as libc::c_double, nleft, rdB as libc::c_double, nright);
};
}
#[no_mangle]
pub unsafe extern "C" fn set_volume(mut left: libc::c_uint,
mut right: libc::c_uint) {
let mut ldB: libc::c_float = 0.;
let mut rdB: libc::c_float = 0.;
if alsa.volume_mixer_name.is_null() {
if loglevel as libc::c_uint >= lDEBUG as libc::c_int as libc::c_uint {
logprint(b"%s %s:%d setting internal gain left: %u right: %u\n\x00"
as *const u8 as *const libc::c_char, logtime(),
(*::std::mem::transmute::<&[u8; 11],
&[libc::c_char; 11]>(b"set_volume\x00")).as_ptr(),
233 as libc::c_int, left, right);
}
pthread_mutex_lock(&mut (*outputbuf).mutex);
output.gainL = left;
output.gainR = right;
pthread_mutex_unlock(&mut (*outputbuf).mutex);
return
} else {
pthread_mutex_lock(&mut (*outputbuf).mutex);
output.gainL = 0x10000 as libc::c_int as u32_t;
output.gainR = 0x10000 as libc::c_int as u32_t;
pthread_mutex_unlock(&mut (*outputbuf).mutex);
}
// convert 16.16 fixed point to dB
ldB =
(20 as libc::c_int as libc::c_double *
log10((left as libc::c_float / 65536.0f32) as libc::c_double)) as
libc::c_float;
rdB =
(20 as libc::c_int as libc::c_double *
log10((right as libc::c_float / 65536.0f32) as libc::c_double))
as libc::c_float;
set_mixer(0 as libc::c_int != 0, ldB, rdB);
}
unsafe extern "C" fn alsa_error_handler(mut file: *const libc::c_char,
mut line: libc::c_int,
mut function: *const libc::c_char,
mut err: libc::c_int,
mut fmt: *const libc::c_char,
mut args: ...) -> *mut libc::c_void {
let mut args_0: ::std::ffi::VaListImpl;
if loglevel as libc::c_uint >= lINFO as libc::c_int as libc::c_uint &&
err == 0 as libc::c_int ||
loglevel as libc::c_uint >= lDEBUG as libc::c_int as libc::c_uint {
fprintf(stderr,
b"%s ALSA %s:%d \x00" as *const u8 as *const libc::c_char,
logtime(), function, line);
args_0 = args.clone();
vfprintf(stderr, fmt, args_0.as_va_list());
fprintf(stderr, b"\n\x00" as *const u8 as *const libc::c_char);
fflush(stderr);
}
return 0 as *mut libc::c_void;
}
unsafe extern "C" fn alsa_close() {
let mut err: libc::c_int = 0;
err = snd_pcm_close(pcmp);
if err < 0 as libc::c_int {
if loglevel as libc::c_uint >= lINFO as libc::c_int as libc::c_uint {
logprint(b"%s %s:%d snd_pcm_close error: %s\n\x00" as *const u8 as
*const libc::c_char, logtime(),
(*::std::mem::transmute::<&[u8; 11],
&[libc::c_char; 11]>(b"alsa_close\x00")).as_ptr(),
268 as libc::c_int, snd_strerror(err));
}
};
}
#[no_mangle]
pub unsafe extern "C" fn test_open(mut device: *const libc::c_char,
mut rates: *mut libc::c_uint,
mut userdef_rates: bool) -> bool {
let mut err: libc::c_int = 0;
let mut pcm: *mut snd_pcm_t = 0 as *mut snd_pcm_t;
let mut hw_params: *mut snd_pcm_hw_params_t =
0 as *mut snd_pcm_hw_params_t;
let mut fresh1 =
::std::vec::from_elem(0, snd_pcm_hw_params_sizeof() as usize);
hw_params = fresh1.as_mut_ptr() as *mut snd_pcm_hw_params_t;
memset(hw_params as *mut libc::c_void, 0 as libc::c_int,
snd_pcm_hw_params_sizeof());
// open device
err =
snd_pcm_open(&mut pcm, device, SND_PCM_STREAM_PLAYBACK,
0 as libc::c_int);
if err < 0 as libc::c_int {
logprint(b"%s %s:%d playback open error: %s\n\x00" as *const u8 as
*const libc::c_char, logtime(),
(*::std::mem::transmute::<&[u8; 10],
&[libc::c_char; 10]>(b"test_open\x00")).as_ptr(),
281 as libc::c_int, snd_strerror(err));
return 0 as libc::c_int != 0
}
// get max params
err = snd_pcm_hw_params_any(pcm, hw_params);
if err < 0 as libc::c_int {
logprint(b"%s %s:%d hwparam init error: %s\n\x00" as *const u8 as
*const libc::c_char, logtime(),
(*::std::mem::transmute::<&[u8; 10],
&[libc::c_char; 10]>(b"test_open\x00")).as_ptr(),
287 as libc::c_int, snd_strerror(err));
return 0 as libc::c_int != 0
}
// find supported sample rates to enable client side resampling of non supported rates
if !userdef_rates {
let mut i: libc::c_uint = 0;
let mut ind: libc::c_uint = 0;
let mut ref_0: [libc::c_uint; 18] =
[768000 as libc::c_int as libc::c_uint,
705600 as libc::c_int as libc::c_uint,
384000 as libc::c_int as libc::c_uint,
352800 as libc::c_int as libc::c_uint,
192000 as libc::c_int as libc::c_uint,
176400 as libc::c_int as libc::c_uint,
96000 as libc::c_int as libc::c_uint,
88200 as libc::c_int as libc::c_uint,
48000 as libc::c_int as libc::c_uint,
44100 as libc::c_int as libc::c_uint,
32000 as libc::c_int as libc::c_uint,
24000 as libc::c_int as libc::c_uint,
22500 as libc::c_int as libc::c_uint,
16000 as libc::c_int as libc::c_uint,
12000 as libc::c_int as libc::c_uint,
11025 as libc::c_int as libc::c_uint,
8000 as libc::c_int as libc::c_uint,
0 as libc::c_int as libc::c_uint];
i = 0 as libc::c_int as libc::c_uint;
ind = 0 as libc::c_int as libc::c_uint;
while ref_0[i as usize] != 0 {
if snd_pcm_hw_params_test_rate(pcm, hw_params, ref_0[i as usize],
0 as libc::c_int) ==
0 as libc::c_int {
let fresh2 = ind;
ind = ind.wrapping_add(1);
*rates.offset(fresh2 as isize) = ref_0[i as usize]
}
i = i.wrapping_add(1)
}
}
err = snd_pcm_close(pcm);
if err < 0 as libc::c_int {
logprint(b"%s %s:%d snd_pcm_close error: %s\n\x00" as *const u8 as
*const libc::c_char, logtime(),
(*::std::mem::transmute::<&[u8; 10],
&[libc::c_char; 10]>(b"test_open\x00")).as_ptr(),
304 as libc::c_int, snd_strerror(err));
return 0 as libc::c_int != 0
}
return 1 as libc::c_int != 0;
}
unsafe extern "C" fn pcm_probe(mut device: *const libc::c_char) -> bool {
let mut err: libc::c_int = 0;
let mut pcm: *mut snd_pcm_t = 0 as *mut snd_pcm_t;
err =
snd_pcm_open(&mut pcm, device, SND_PCM_STREAM_PLAYBACK,
0 as libc::c_int);
if err < 0 as libc::c_int { return 0 as libc::c_int != 0 }
err = snd_pcm_close(pcm);
if err < 0 as libc::c_int {
logprint(b"%s %s:%d snd_pcm_close error: %s\n\x00" as *const u8 as
*const libc::c_char, logtime(),
(*::std::mem::transmute::<&[u8; 10],
&[libc::c_char; 10]>(b"pcm_probe\x00")).as_ptr(),
320 as libc::c_int, snd_strerror(err));
}
return 1 as libc::c_int != 0;
}
unsafe extern "C" fn alsa_open(mut device: *const libc::c_char,
mut sample_rate: libc::c_uint,
mut alsa_buffer: libc::c_uint,
mut alsa_period: libc::c_uint) -> libc::c_int {
let mut err: libc::c_int = 0;
let mut hw_params: *mut snd_pcm_hw_params_t =
0 as *mut snd_pcm_hw_params_t;
let mut fresh3 =
::std::vec::from_elem(0, snd_pcm_hw_params_sizeof() as usize);
hw_params = fresh3.as_mut_ptr() as *mut snd_pcm_hw_params_t;
memset(hw_params as *mut libc::c_void, 0 as libc::c_int,
snd_pcm_hw_params_sizeof());
// close if already open
if !pcmp.is_null() { alsa_close(); }
// reset params
alsa.rate = 0 as libc::c_int as libc::c_uint;
alsa.period_size = 0 as libc::c_int as snd_pcm_uframes_t;
strcpy(alsa.device.as_mut_ptr(), device);
if strlen(device) >
(128 as libc::c_int - 4 as libc::c_int - 1 as libc::c_int) as
libc::c_ulong {
logprint(b"%s %s:%d device name too long: %s\n\x00" as *const u8 as
*const libc::c_char, logtime(),
(*::std::mem::transmute::<&[u8; 10],
&[libc::c_char; 10]>(b"alsa_open\x00")).as_ptr(),
347 as libc::c_int, device);
return -(1 as libc::c_int)
}
if loglevel as libc::c_uint >= lINFO as libc::c_int as libc::c_uint {
logprint(b"%s %s:%d opening device at: %u\n\x00" as *const u8 as
*const libc::c_char, logtime(),
(*::std::mem::transmute::<&[u8; 10],
&[libc::c_char; 10]>(b"alsa_open\x00")).as_ptr(),
351 as libc::c_int, sample_rate);
}
let mut retry: bool = false;
loop {
// open device
err =
snd_pcm_open(&mut pcmp, alsa.device.as_mut_ptr(),
SND_PCM_STREAM_PLAYBACK, 0 as libc::c_int);
if err < 0 as libc::c_int {
logprint(b"%s %s:%d playback open error: %s\n\x00" as *const u8 as
*const libc::c_char, logtime(),
(*::std::mem::transmute::<&[u8; 10],
&[libc::c_char; 10]>(b"alsa_open\x00")).as_ptr(),
357 as libc::c_int, snd_strerror(err));
return err
}
// init params
memset(hw_params as *mut libc::c_void, 0 as libc::c_int,
snd_pcm_hw_params_sizeof());
err = snd_pcm_hw_params_any(pcmp, hw_params);
if err < 0 as libc::c_int {
logprint(b"%s %s:%d hwparam init error: %s\n\x00" as *const u8 as
*const libc::c_char, logtime(),
(*::std::mem::transmute::<&[u8; 10],
&[libc::c_char; 10]>(b"alsa_open\x00")).as_ptr(),
364 as libc::c_int, snd_strerror(err));
return err
}
// open hw: devices without resampling, if sample rate fails try plughw: with resampling
let mut hw: bool =
strncmp(alsa.device.as_mut_ptr(),
b"hw:\x00" as *const u8 as *const libc::c_char,
3 as libc::c_int as libc::c_ulong) == 0;
retry = 0 as libc::c_int != 0;
err =
snd_pcm_hw_params_set_rate_resample(pcmp, hw_params,
!hw as libc::c_int as
libc::c_uint);
if err < 0 as libc::c_int {
logprint(b"%s %s:%d resampling setup failed: %s\n\x00" as
*const u8 as *const libc::c_char, logtime(),
(*::std::mem::transmute::<&[u8; 10],
&[libc::c_char; 10]>(b"alsa_open\x00")).as_ptr(),
373 as libc::c_int, snd_strerror(err));
return err
}
err =
snd_pcm_hw_params_set_rate(pcmp, hw_params, sample_rate,
0 as libc::c_int);
if err < 0 as libc::c_int {
if hw {
strcpy(alsa.device.as_mut_ptr().offset(4 as libc::c_int as
isize), device);
memcpy(alsa.device.as_mut_ptr() as *mut libc::c_void,
b"plug\x00" as *const u8 as *const libc::c_char as
*const libc::c_void,
4 as libc::c_int as libc::c_ulong);
if loglevel as libc::c_uint >=
lINFO as libc::c_int as libc::c_uint {
logprint(b"%s %s:%d reopening device %s in plug mode as %s for resampling\n\x00"
as *const u8 as *const libc::c_char,
logtime(),
(*::std::mem::transmute::<&[u8; 10],
&[libc::c_char; 10]>(b"alsa_open\x00")).as_ptr(),
381 as libc::c_int, device,
alsa.device.as_mut_ptr());
}
snd_pcm_close(pcmp);
retry = 1 as libc::c_int != 0
}
}
if !retry { break ; }
}
// set access
if !alsa.mmap ||
snd_pcm_hw_params_set_access(pcmp, hw_params,
SND_PCM_ACCESS_MMAP_INTERLEAVED) <
0 as libc::c_int {
err =
snd_pcm_hw_params_set_access(pcmp, hw_params,
SND_PCM_ACCESS_RW_INTERLEAVED);
if err < 0 as libc::c_int {
logprint(b"%s %s:%d access type not available: %s\n\x00" as
*const u8 as *const libc::c_char, logtime(),
(*::std::mem::transmute::<&[u8; 10],
&[libc::c_char; 10]>(b"alsa_open\x00")).as_ptr(),
392 as libc::c_int, snd_strerror(err));
return err
}
alsa.mmap = 0 as libc::c_int != 0
}
// set the sample format
let mut fmt: *mut snd_pcm_format_t =
if alsa.format as libc::c_int != 0 {
&mut alsa.format
} else { fmts.as_mut_ptr() };
loop {
if snd_pcm_hw_params_set_format(pcmp, hw_params, *fmt) >=
0 as libc::c_int {
if loglevel as libc::c_uint >=
lINFO as libc::c_int as libc::c_uint {
logprint(b"%s %s:%d opened device %s using format: %s sample rate: %u mmap: %u\n\x00"
as *const u8 as *const libc::c_char, logtime(),
(*::std::mem::transmute::<&[u8; 10],
&[libc::c_char; 10]>(b"alsa_open\x00")).as_ptr(),
422 as libc::c_int, alsa.device.as_mut_ptr(),
snd_pcm_format_name(*fmt), sample_rate,
alsa.mmap as libc::c_int);
}
alsa.format = *fmt;
break ;
} else {
if alsa.format as u64 != 0 {
logprint(b"%s %s:%d unable to open audio device requested format: %s\n\x00"
as *const u8 as *const libc::c_char, logtime(),
(*::std::mem::transmute::<&[u8; 10],
&[libc::c_char; 10]>(b"alsa_open\x00")).as_ptr(),
427 as libc::c_int,
snd_pcm_format_name(alsa.format));
return -(1 as libc::c_int)
}
fmt = fmt.offset(1);
if *fmt as libc::c_int == SND_PCM_FORMAT_UNKNOWN as libc::c_int {
logprint(b"%s %s:%d unable to open audio device with any supported format\n\x00"
as *const u8 as *const libc::c_char, logtime(),
(*::std::mem::transmute::<&[u8; 10],
&[libc::c_char; 10]>(b"alsa_open\x00")).as_ptr(),
432 as libc::c_int);
return -(1 as libc::c_int)
}
if !(*fmt as libc::c_int != SND_PCM_FORMAT_UNKNOWN as libc::c_int)
{
break ;
}
}
}
// set the output format to be used by _scale_and_pack
match alsa.format as libc::c_int {
10 => { output.format = S32_LE }
6 => { output.format = S24_LE }
32 => { output.format = S24_3LE }
2 => { output.format = S16_LE }
_ => { }
}
// set channels
err =
snd_pcm_hw_params_set_channels(pcmp, hw_params,
2 as libc::c_int as libc::c_uint);
if err < 0 as libc::c_int {
logprint(b"%s %s:%d channel count not available: %s\n\x00" as
*const u8 as *const libc::c_char, logtime(),
(*::std::mem::transmute::<&[u8; 10],
&[libc::c_char; 10]>(b"alsa_open\x00")).as_ptr(),
465 as libc::c_int, snd_strerror(err));
return err
}
// set period size - value of < 50 treated as period count, otherwise size in bytes
if alsa_period < 50 as libc::c_int as libc::c_uint {
let mut count: libc::c_uint = alsa_period;
err =
snd_pcm_hw_params_set_periods_near(pcmp, hw_params, &mut count,
0 as *mut libc::c_int);
if err < 0 as libc::c_int {
logprint(b"%s %s:%d unable to set period count %s\n\x00" as
*const u8 as *const libc::c_char, logtime(),
(*::std::mem::transmute::<&[u8; 10],
&[libc::c_char; 10]>(b"alsa_open\x00")).as_ptr(),
473 as libc::c_int, snd_strerror(err));
return err
}
} else {
let mut size: snd_pcm_uframes_t = alsa_period as snd_pcm_uframes_t;
let mut dir: libc::c_int = 0 as libc::c_int;
err =
snd_pcm_hw_params_set_period_size_near(pcmp, hw_params, &mut size,
&mut dir);
if err < 0 as libc::c_int {
logprint(b"%s %s:%d unable to set period size %s\n\x00" as
*const u8 as *const libc::c_char, logtime(),
(*::std::mem::transmute::<&[u8; 10],
&[libc::c_char; 10]>(b"alsa_open\x00")).as_ptr(),
480 as libc::c_int, snd_strerror(err));
return err
}
}
// set buffer size - value of < 500 treated as buffer time in ms, otherwise size in bytes
if alsa_buffer < 500 as libc::c_int as libc::c_uint {
let mut time: libc::c_uint =
alsa_buffer.wrapping_mul(1000 as libc::c_int as libc::c_uint);
let mut dir_0: libc::c_int = 0 as libc::c_int;
err =
snd_pcm_hw_params_set_buffer_time_near(pcmp, hw_params, &mut time,
&mut dir_0);
if err < 0 as libc::c_int {
logprint(b"%s %s:%d unable to set buffer time %s\n\x00" as
*const u8 as *const libc::c_char, logtime(),
(*::std::mem::transmute::<&[u8; 10],
&[libc::c_char; 10]>(b"alsa_open\x00")).as_ptr(),
490 as libc::c_int, snd_strerror(err));
return err
}
} else {
let mut size_0: snd_pcm_uframes_t = alsa_buffer as snd_pcm_uframes_t;
err =
snd_pcm_hw_params_set_buffer_size_near(pcmp, hw_params,
&mut size_0);
if err < 0 as libc::c_int {
logprint(b"%s %s:%d unable to set buffer size %s\n\x00" as
*const u8 as *const libc::c_char, logtime(),
(*::std::mem::transmute::<&[u8; 10],
&[libc::c_char; 10]>(b"alsa_open\x00")).as_ptr(),
496 as libc::c_int, snd_strerror(err));
return err
}
}
// get period_size
err =
snd_pcm_hw_params_get_period_size(hw_params, &mut alsa.period_size,
0 as *mut libc::c_int);
if err < 0 as libc::c_int {
logprint(b"%s %s:%d unable to get period size: %s\n\x00" as *const u8
as *const libc::c_char, logtime(),
(*::std::mem::transmute::<&[u8; 10],
&[libc::c_char; 10]>(b"alsa_open\x00")).as_ptr(),
503 as libc::c_int, snd_strerror(err));
return err
}
// get buffer_size
err = snd_pcm_hw_params_get_buffer_size(hw_params, &mut alsa.buffer_size);
if err < 0 as libc::c_int {
logprint(b"%s %s:%d unable to get buffer size: %s\n\x00" as *const u8
as *const libc::c_char, logtime(),
(*::std::mem::transmute::<&[u8; 10],
&[libc::c_char; 10]>(b"alsa_open\x00")).as_ptr(),
509 as libc::c_int, snd_strerror(err));
return err
}
if loglevel as libc::c_uint >= lINFO as libc::c_int as libc::c_uint {
logprint(b"%s %s:%d buffer: %u period: %u -> buffer size: %u period size: %u\n\x00"
as *const u8 as *const libc::c_char, logtime(),
(*::std::mem::transmute::<&[u8; 10],
&[libc::c_char; 10]>(b"alsa_open\x00")).as_ptr(),
513 as libc::c_int, alsa_buffer, alsa_period,
alsa.buffer_size, alsa.period_size);
}
// ensure we have two buffer sizes of samples before starting output
output.start_frames =
alsa.buffer_size.wrapping_mul(2 as libc::c_int as libc::c_ulong) as
libc::c_uint;
// create an intermediate buffer for non mmap case for all but NATIVE_FORMAT
// this is used to pack samples into the output format before calling writei
if !alsa.mmap && alsa.write_buf.is_null() &&
alsa.format as libc::c_int != SND_PCM_FORMAT_S32_LE as libc::c_int
{
alsa.write_buf =
malloc(alsa.buffer_size.wrapping_mul(8 as libc::c_int as
libc::c_ulong)) as
*mut u8_t;
if alsa.write_buf.is_null() {
logprint(b"%s %s:%d unable to malloc write_buf\n\x00" as *const u8
as *const libc::c_char, logtime(),
(*::std::mem::transmute::<&[u8; 10],
&[libc::c_char; 10]>(b"alsa_open\x00")).as_ptr(),
523 as libc::c_int);
return -(1 as libc::c_int)
}
}
// set params
err = snd_pcm_hw_params(pcmp, hw_params);
if err < 0 as libc::c_int {
logprint(b"%s %s:%d unable to set hw params: %s\n\x00" as *const u8 as
*const libc::c_char, logtime(),
(*::std::mem::transmute::<&[u8; 10],
&[libc::c_char; 10]>(b"alsa_open\x00")).as_ptr(),
530 as libc::c_int, snd_strerror(err));
return err
}
// dump info
if loglevel as libc::c_uint == lSDEBUG as libc::c_int as libc::c_uint {
static mut debug_output: *mut snd_output_t =
0 as *const snd_output_t as *mut snd_output_t;
snd_output_stdio_attach(&mut debug_output, stderr, 0 as libc::c_int);
snd_pcm_dump(pcmp, debug_output);
}
// this indicates we have opened the device ok
alsa.rate = sample_rate;
return 0 as libc::c_int;
}
unsafe extern "C" fn _write_frames(mut out_frames: frames_t,
mut silence: bool, mut gainL: s32_t,
mut gainR: s32_t, mut cross_gain_in: s32_t,
mut cross_gain_out: s32_t,
mut cross_ptr: *mut *mut s32_t)
-> libc::c_int {
let mut areas: *const snd_pcm_channel_area_t =
0 as *const snd_pcm_channel_area_t;
let mut offset: snd_pcm_uframes_t = 0;
let mut outputptr: *mut libc::c_void = 0 as *mut libc::c_void;
let mut inputptr: *mut s32_t = 0 as *mut s32_t;
let mut err: libc::c_int = 0;
if alsa.mmap {
let mut alsa_frames: snd_pcm_uframes_t =
out_frames as snd_pcm_uframes_t;
snd_pcm_avail_update(pcmp);
err =
snd_pcm_mmap_begin(pcmp, &mut areas, &mut offset,
&mut alsa_frames);
if err < 0 as libc::c_int {
if loglevel as libc::c_uint >=
lWARN as libc::c_int as libc::c_uint {
logprint(b"%s %s:%d error from mmap_begin: %s\n\x00" as
*const u8 as *const libc::c_char, logtime(),
(*::std::mem::transmute::<&[u8; 14],
&[libc::c_char; 14]>(b"_write_frames\x00")).as_ptr(),
565 as libc::c_int, snd_strerror(err));
}
return -(1 as libc::c_int)
}
out_frames = alsa_frames as frames_t
}
if !silence {
// applying cross fade is delayed until this point as mmap_begin can change out_frames
if output.fade as libc::c_uint ==
FADE_ACTIVE as libc::c_int as libc::c_uint &&
output.fade_dir as libc::c_uint ==
FADE_CROSS as libc::c_int as libc::c_uint &&
!(*cross_ptr).is_null() {
_apply_cross(outputbuf, out_frames, cross_gain_in, cross_gain_out,
cross_ptr);
}
}
inputptr =
if silence as libc::c_int != 0 {
silencebuf
} else { (*outputbuf).readp } as *mut s32_t;
if alsa.mmap as libc::c_int != 0 ||
alsa.format as libc::c_int != SND_PCM_FORMAT_S32_LE as libc::c_int
{
outputptr =
if alsa.mmap as libc::c_int != 0 {
(*areas.offset(0 as libc::c_int as
isize)).addr.offset(((*areas.offset(0 as
libc::c_int
as
isize)).first
as
libc::c_ulong).wrapping_add(offset.wrapping_mul((*areas.offset(0
as
libc::c_int
as
isize)).step
as
libc::c_ulong)).wrapping_div(8
as
libc::c_int
as
libc::c_ulong)
as isize)
} else { alsa.write_buf as *mut libc::c_void };
_scale_and_pack_frames(outputptr, inputptr, out_frames, gainL, gainR,
output.format);
} else {
outputptr = inputptr as *mut libc::c_void;
if !silence {
if gainL != 0x10000 as libc::c_int ||
gainR != 0x10000 as libc::c_int {
_apply_gain(outputbuf, out_frames, gainL, gainR);
}
}
}
if alsa.mmap {
let mut w: snd_pcm_sframes_t =
snd_pcm_mmap_commit(pcmp, offset,
out_frames as snd_pcm_uframes_t);
if w < 0 as libc::c_int as libc::c_long ||
w != out_frames as libc::c_long {
if loglevel as libc::c_uint >=
lWARN as libc::c_int as libc::c_uint {
logprint(b"%s %s:%d mmap_commit error\n\x00" as *const u8 as
*const libc::c_char, logtime(),
(*::std::mem::transmute::<&[u8; 14],
&[libc::c_char; 14]>(b"_write_frames\x00")).as_ptr(),
615 as libc::c_int);
}
return -(1 as libc::c_int)
}
} else {
let mut w_0: snd_pcm_sframes_t =
snd_pcm_writei(pcmp, outputptr, out_frames as snd_pcm_uframes_t);
if w_0 < 0 as libc::c_int as libc::c_long {
//if (w != -EAGAIN && ((err = snd_pcm_recover(pcmp, w, 1)) < 0)) {
err = snd_pcm_recover(pcmp, w_0 as libc::c_int, 1 as libc::c_int);
if err < 0 as libc::c_int {
static mut recover_count: libc::c_uint =
0 as libc::c_int as libc::c_uint;
if loglevel as libc::c_uint >=
lWARN as libc::c_int as libc::c_uint {
recover_count = recover_count.wrapping_add(1);
logprint(b"%s %s:%d recover failed: %s [%u]\n\x00" as
*const u8 as *const libc::c_char, logtime(),
(*::std::mem::transmute::<&[u8; 14],
&[libc::c_char; 14]>(b"_write_frames\x00")).as_ptr(),
626 as libc::c_int, snd_strerror(err),
recover_count);
}
if recover_count >= 10 as libc::c_int as libc::c_uint {
recover_count = 0 as libc::c_int as libc::c_uint;
alsa_close();
pcmp = 0 as *mut snd_pcm_t
}
}
return -(1 as libc::c_int)
} else {
if w_0 != out_frames as libc::c_long {
if loglevel as libc::c_uint >=
lWARN as libc::c_int as libc::c_uint {
logprint(b"%s %s:%d writei only wrote %u of %u\n\x00" as
*const u8 as *const libc::c_char, logtime(),
(*::std::mem::transmute::<&[u8; 14],
&[libc::c_char; 14]>(b"_write_frames\x00")).as_ptr(),
636 as libc::c_int, w_0, out_frames);
}
}
out_frames = w_0 as frames_t
}
}
return out_frames as libc::c_int;
}
unsafe extern "C" fn output_thread(mut arg: *mut libc::c_void)
-> *mut libc::c_void {
let mut start: bool = 1 as libc::c_int != 0;
let mut output_off: bool =
output.state as libc::c_int == OUTPUT_OFF as libc::c_int;
let mut probe_device: bool = !arg.is_null();
let mut err: libc::c_int = 0;
while running {
// disabled output - player is off
while output_off {
usleep(100000 as libc::c_int as __useconds_t);
pthread_mutex_lock(&mut (*outputbuf).mutex);
output_off =
output.state as libc::c_int == OUTPUT_OFF as libc::c_int;
pthread_mutex_unlock(&mut (*outputbuf).mutex);
if !running { return 0 as *mut libc::c_void }
}
// wait until device returns - to allow usb audio devices to be turned off
if probe_device {
while !pcm_probe(output.device) {
if loglevel as libc::c_uint >=
lDEBUG as libc::c_int as libc::c_uint {
logprint(b"%s %s:%d waiting for device %s to return\n\x00"
as *const u8 as *const libc::c_char,
logtime(),
(*::std::mem::transmute::<&[u8; 14],
&[libc::c_char; 14]>(b"output_thread\x00")).as_ptr(),
665 as libc::c_int, output.device);
}
sleep(5 as libc::c_int as libc::c_uint);
}
probe_device = 0 as libc::c_int != 0
}
if pcmp.is_null() || alsa.rate != output.current_sample_rate {
if loglevel as libc::c_uint >=
lINFO as libc::c_int as libc::c_uint {
logprint(b"%s %s:%d open output device: %s\n\x00" as *const u8
as *const libc::c_char, logtime(),
(*::std::mem::transmute::<&[u8; 14],
&[libc::c_char; 14]>(b"output_thread\x00")).as_ptr(),
687 as libc::c_int, output.device);
}
pthread_mutex_lock(&mut (*outputbuf).mutex);
// FIXME - some alsa hardware requires opening twice for a new sample rate to work
// this is a workaround which should be removed
if alsa.reopen {
alsa_open(output.device, output.current_sample_rate,
output.buffer, output.period);
}
if alsa_open(output.device, output.current_sample_rate,
output.buffer, output.period) != 0 {
output.error_opening = 1 as libc::c_int != 0;
pthread_mutex_unlock(&mut (*outputbuf).mutex);
sleep(5 as libc::c_int as libc::c_uint);
continue ;
} else {
output.error_opening = 0 as libc::c_int != 0;
start = 1 as libc::c_int != 0;
pthread_mutex_unlock(&mut (*outputbuf).mutex);
}
}
let mut state: snd_pcm_state_t = snd_pcm_state(pcmp);
if state as libc::c_uint ==
SND_PCM_STATE_XRUN as libc::c_int as libc::c_uint {
if loglevel as libc::c_uint >=
lINFO as libc::c_int as libc::c_uint {
logprint(b"%s %s:%d XRUN\n\x00" as *const u8 as
*const libc::c_char, logtime(),
(*::std::mem::transmute::<&[u8; 14],
&[libc::c_char; 14]>(b"output_thread\x00")).as_ptr(),
717 as libc::c_int);
}
err =
snd_pcm_recover(pcmp, -(32 as libc::c_int), 1 as libc::c_int);
if err < 0 as libc::c_int {
if loglevel as libc::c_uint >=
lINFO as libc::c_int as libc::c_uint {
logprint(b"%s %s:%d XRUN recover failed: %s\n\x00" as
*const u8 as *const libc::c_char, logtime(),
(*::std::mem::transmute::<&[u8; 14],
&[libc::c_char; 14]>(b"output_thread\x00")).as_ptr(),
719 as libc::c_int, snd_strerror(err));
}
}
start = 1 as libc::c_int != 0
} else {
if state as libc::c_uint ==
SND_PCM_STATE_SUSPENDED as libc::c_int as libc::c_uint {
err =
snd_pcm_recover(pcmp, -(86 as libc::c_int),
1 as libc::c_int);
if err < 0 as libc::c_int {
if loglevel as libc::c_uint >=
lINFO as libc::c_int as libc::c_uint {
logprint(b"%s %s:%d SUSPEND recover failed: %s\n\x00"
as *const u8 as *const libc::c_char,
logtime(),
(*::std::mem::transmute::<&[u8; 14],
&[libc::c_char; 14]>(b"output_thread\x00")).as_ptr(),
725 as libc::c_int, snd_strerror(err));
}
}
} else if state as libc::c_uint ==
SND_PCM_STATE_DISCONNECTED as libc::c_int as
libc::c_uint {
if loglevel as libc::c_uint >=
lINFO as libc::c_int as libc::c_uint {
logprint(b"%s %s:%d Device %s no longer available\n\x00"
as *const u8 as *const libc::c_char,
logtime(),
(*::std::mem::transmute::<&[u8; 14],
&[libc::c_char; 14]>(b"output_thread\x00")).as_ptr(),
728 as libc::c_int, output.device);
}
alsa_close();
pcmp = 0 as *mut snd_pcm_t;
probe_device = 1 as libc::c_int != 0;
continue ;
}
let mut avail: snd_pcm_sframes_t = snd_pcm_avail_update(pcmp);
if avail < 0 as libc::c_int as libc::c_long {
err =
snd_pcm_recover(pcmp, avail as libc::c_int,
1 as libc::c_int);
if err < 0 as libc::c_int {
if err == -(19 as libc::c_int) {
if loglevel as libc::c_uint >=
lINFO as libc::c_int as libc::c_uint {
logprint(b"%s %s:%d Device %s no longer available\n\x00"
as *const u8 as *const libc::c_char,
logtime(),
(*::std::mem::transmute::<&[u8; 14],
&[libc::c_char; 14]>(b"output_thread\x00")).as_ptr(),
740 as libc::c_int, output.device);
}
alsa_close();
pcmp = 0 as *mut snd_pcm_t;
probe_device = 1 as libc::c_int != 0;
continue ;
} else if loglevel as libc::c_uint >=
lWARN as libc::c_int as libc::c_uint {
logprint(b"%s %s:%d recover failed: %s\n\x00" as
*const u8 as *const libc::c_char,
logtime(),
(*::std::mem::transmute::<&[u8; 14],
&[libc::c_char; 14]>(b"output_thread\x00")).as_ptr(),
746 as libc::c_int, snd_strerror(err));
}
}
start = 1 as libc::c_int != 0
} else if (avail as libc::c_ulong) < alsa.period_size {
if start {
if alsa.mmap as libc::c_int != 0 &&
{
err = snd_pcm_start(pcmp);
(err) < 0 as libc::c_int
} {
err = snd_pcm_recover(pcmp, err, 1 as libc::c_int);
if !(err < 0 as libc::c_int) { continue ; }
if err == -(19 as libc::c_int) {
if loglevel as libc::c_uint >=
lINFO as libc::c_int as libc::c_uint {
logprint(b"%s %s:%d Device %s no longer available\n\x00"
as *const u8 as
*const libc::c_char, logtime(),
(*::std::mem::transmute::<&[u8; 14],
&[libc::c_char; 14]>(b"output_thread\x00")).as_ptr(),
757 as libc::c_int, output.device);
}
alsa_close();
pcmp = 0 as *mut snd_pcm_t;
probe_device = 1 as libc::c_int != 0
} else {
if loglevel as libc::c_uint >=
lINFO as libc::c_int as libc::c_uint {
logprint(b"%s %s:%d start error: %s\n\x00" as
*const u8 as *const libc::c_char,
logtime(),
(*::std::mem::transmute::<&[u8; 14],
&[libc::c_char; 14]>(b"output_thread\x00")).as_ptr(),
763 as libc::c_int,
snd_strerror(err));
}
usleep(10000 as libc::c_int as __useconds_t);
}
} else { start = 0 as libc::c_int != 0 }
} else {
usleep(10000 as libc::c_int as __useconds_t);
err = snd_pcm_wait(pcmp, 1000 as libc::c_int);
if err <= 0 as libc::c_int {
if err == 0 as libc::c_int {
if loglevel as libc::c_uint >=
lINFO as libc::c_int as libc::c_uint {
logprint(b"%s %s:%d pcm wait timeout\n\x00" as
*const u8 as *const libc::c_char,
logtime(),
(*::std::mem::transmute::<&[u8; 14],
&[libc::c_char; 14]>(b"output_thread\x00")).as_ptr(),
773 as libc::c_int);
}
}
err = snd_pcm_recover(pcmp, err, 1 as libc::c_int);
if err < 0 as libc::c_int {
if loglevel as libc::c_uint >=
lINFO as libc::c_int as libc::c_uint {
logprint(b"%s %s:%d pcm wait error: %s\n\x00"
as *const u8 as
*const libc::c_char, logtime(),
(*::std::mem::transmute::<&[u8; 14],
&[libc::c_char; 14]>(b"output_thread\x00")).as_ptr(),
776 as libc::c_int,
snd_strerror(err));
}
}
start = 1 as libc::c_int != 0
}
}
} else {
// restrict avail to within sensible limits as alsa drivers can return erroneous large values
// in writei mode restrict to period_size due to size of write_buf
if alsa.mmap {
avail =
if (avail as libc::c_ulong) < alsa.buffer_size {
avail as libc::c_ulong
} else { alsa.buffer_size } as snd_pcm_sframes_t
} else {
avail =
if (avail as libc::c_ulong) < alsa.period_size {
avail as libc::c_ulong
} else { alsa.period_size } as snd_pcm_sframes_t
}
// avoid spinning in cases where wait returns but no bytes available (seen with pulse audio)
if avail == 0 as libc::c_int as libc::c_long {
if loglevel as libc::c_uint >=
lSDEBUG as libc::c_int as libc::c_uint {
logprint(b"%s %s:%d avail 0 - sleeping\n\x00" as
*const u8 as *const libc::c_char,
logtime(),
(*::std::mem::transmute::<&[u8; 14],
&[libc::c_char; 14]>(b"output_thread\x00")).as_ptr(),
794 as libc::c_int);
}
usleep(10000 as libc::c_int as __useconds_t);
} else {
pthread_mutex_lock(&mut (*outputbuf).mutex);
// turn off if requested
if output.state as libc::c_int ==
OUTPUT_OFF as libc::c_int {
pthread_mutex_unlock(&mut (*outputbuf).mutex);
if loglevel as libc::c_uint >=
lINFO as libc::c_int as libc::c_uint {
logprint(b"%s %s:%d disabling output\n\x00" as
*const u8 as *const libc::c_char,
logtime(),
(*::std::mem::transmute::<&[u8; 14],
&[libc::c_char; 14]>(b"output_thread\x00")).as_ptr(),
804 as libc::c_int);
}
alsa_close();
pcmp = 0 as *mut snd_pcm_t;
output_off = 1 as libc::c_int != 0
} else {
// measure output delay
let mut delay: snd_pcm_sframes_t = 0;
err = snd_pcm_delay(pcmp, &mut delay);
if err < 0 as libc::c_int {
if err == -(32 as libc::c_int) {
// EPIPE indicates underrun - attempt to recover
pthread_mutex_unlock(&mut (*outputbuf).mutex);
continue ;
} else if err == -(5 as libc::c_int) {
// EIO can occur with non existant pulse server
pthread_mutex_unlock(&mut (*outputbuf).mutex);
if loglevel as libc::c_uint >=
lSDEBUG as libc::c_int as libc::c_uint
{
logprint(b"%s %s:%d snd_pcm_delay returns: EIO - sleeping\n\x00"
as *const u8 as
*const libc::c_char,
logtime(),
(*::std::mem::transmute::<&[u8; 14],
&[libc::c_char; 14]>(b"output_thread\x00")).as_ptr(),
833 as libc::c_int);
}
usleep(100000 as libc::c_int as __useconds_t);
continue ;
} else if loglevel as libc::c_uint >=
lDEBUG as libc::c_int as
libc::c_uint {
logprint(b"%s %s:%d snd_pcm_delay returns: %d\n\x00"
as *const u8 as
*const libc::c_char, logtime(),
(*::std::mem::transmute::<&[u8; 14],
&[libc::c_char; 14]>(b"output_thread\x00")).as_ptr(),
837 as libc::c_int, err);
}
} else {
output.device_frames = delay as libc::c_uint;
output.updated = gettime_ms();
output.frames_played_dmp = output.frames_played
}
// process frames
let mut wrote: frames_t =
_output_frames(avail as frames_t);
pthread_mutex_unlock(&mut (*outputbuf).mutex);
// some output devices such as alsa null refuse any data, avoid spinning
if wrote == 0 {
if loglevel as libc::c_uint >=
lSDEBUG as libc::c_int as libc::c_uint {
logprint(b"%s %s:%d wrote 0 - sleeping\n\x00"
as *const u8 as
*const libc::c_char, logtime(),
(*::std::mem::transmute::<&[u8; 14],
&[libc::c_char; 14]>(b"output_thread\x00")).as_ptr(),
852 as libc::c_int);
}
usleep(10000 as libc::c_int as __useconds_t);
}
}
}
}
}
}
return 0 as *mut libc::c_void;
}
#[no_mangle]
pub unsafe extern "C" fn mixer_init_alsa(mut device: *const libc::c_char,
mut mixer: *const libc::c_char,
mut mixer_index: libc::c_int)
-> libc::c_int {
let mut err: libc::c_int = 0;
let mut sid: *mut snd_mixer_selem_id_t = 0 as *mut snd_mixer_selem_id_t;
err = snd_mixer_open(&mut alsa.mixer_handle, 0 as libc::c_int);
if err < 0 as libc::c_int {
logprint(b"%s %s:%d open error: %s\n\x00" as *const u8 as
*const libc::c_char, logtime(),
(*::std::mem::transmute::<&[u8; 16],
&[libc::c_char; 16]>(b"mixer_init_alsa\x00")).as_ptr(),
865 as libc::c_int, snd_strerror(err));
return -(1 as libc::c_int)
}
err = snd_mixer_attach(alsa.mixer_handle, device);
if err < 0 as libc::c_int {
logprint(b"%s %s:%d attach error: %s\n\x00" as *const u8 as
*const libc::c_char, logtime(),
(*::std::mem::transmute::<&[u8; 16],
&[libc::c_char; 16]>(b"mixer_init_alsa\x00")).as_ptr(),
869 as libc::c_int, snd_strerror(err));
snd_mixer_close(alsa.mixer_handle);
return -(1 as libc::c_int)
}
err =
snd_mixer_selem_register(alsa.mixer_handle,
0 as *mut snd_mixer_selem_regopt,
0 as *mut *mut snd_mixer_class_t);
if err < 0 as libc::c_int {
logprint(b"%s %s:%d register error: %s\n\x00" as *const u8 as
*const libc::c_char, logtime(),
(*::std::mem::transmute::<&[u8; 16],
&[libc::c_char; 16]>(b"mixer_init_alsa\x00")).as_ptr(),
874 as libc::c_int, snd_strerror(err));
snd_mixer_close(alsa.mixer_handle);
return -(1 as libc::c_int)
}
err = snd_mixer_load(alsa.mixer_handle);
if err < 0 as libc::c_int {
logprint(b"%s %s:%d load error: %s\n\x00" as *const u8 as
*const libc::c_char, logtime(),
(*::std::mem::transmute::<&[u8; 16],
&[libc::c_char; 16]>(b"mixer_init_alsa\x00")).as_ptr(),
879 as libc::c_int, snd_strerror(err));
snd_mixer_close(alsa.mixer_handle);
return -(1 as libc::c_int)
}
let mut fresh4 =
::std::vec::from_elem(0, snd_mixer_selem_id_sizeof() as usize);
sid = fresh4.as_mut_ptr() as *mut snd_mixer_selem_id_t;
memset(sid as *mut libc::c_void, 0 as libc::c_int,
snd_mixer_selem_id_sizeof());
snd_mixer_selem_id_set_index(sid, mixer_index as libc::c_uint);
snd_mixer_selem_id_set_name(sid, mixer);
alsa.mixer_elem = snd_mixer_find_selem(alsa.mixer_handle, sid);
if alsa.mixer_elem.is_null() {
logprint(b"%s %s:%d error find selem %s\n\x00" as *const u8 as
*const libc::c_char, logtime(),
(*::std::mem::transmute::<&[u8; 16],
&[libc::c_char; 16]>(b"mixer_init_alsa\x00")).as_ptr(),
889 as libc::c_int, alsa.mixer_handle);
snd_mixer_close(alsa.mixer_handle);
return -(1 as libc::c_int)
}
if snd_mixer_selem_has_playback_switch(alsa.mixer_elem) != 0 {
snd_mixer_selem_set_playback_switch_all(alsa.mixer_elem,
1 as libc::c_int);
// unmute
}
err =
snd_mixer_selem_get_playback_dB_range(alsa.mixer_elem,
&mut alsa.mixer_min,
&mut alsa.mixer_max);
if err < 0 as libc::c_int ||
alsa.mixer_max - alsa.mixer_min <
1000 as libc::c_int as libc::c_long ||
alsa.mixer_linear as libc::c_int != 0 {
alsa.mixer_linear = 1 as libc::c_int != 0;
// unable to get db range or range is less than 10dB - ignore and set using raw values
err =
snd_mixer_selem_get_playback_volume_range(alsa.mixer_elem,
&mut alsa.mixer_min,
&mut alsa.mixer_max);
if err < 0 as libc::c_int {
logprint(b"%s %s:%d Unable to get volume raw range\n\x00" as
*const u8 as *const libc::c_char, logtime(),
(*::std::mem::transmute::<&[u8; 16],
&[libc::c_char; 16]>(b"mixer_init_alsa\x00")).as_ptr(),
905 as libc::c_int);
return -(1 as libc::c_int)
}
}
return 0 as libc::c_int;
}
static mut thread: pthread_t = 0;
#[no_mangle]
pub unsafe extern "C" fn output_init_alsa(mut level: log_level,
mut device: *const libc::c_char,
mut output_buf_size: libc::c_uint,
mut params: *mut libc::c_char,
mut rates: *mut libc::c_uint,
mut rate_delay: libc::c_uint,
mut rt_priority: libc::c_uint,
mut idle: libc::c_uint,
mut mixer_device: *mut libc::c_char,
mut volume_mixer: *mut libc::c_char,
mut mixer_unmute: bool,
mut mixer_linear: bool) {
let mut alsa_buffer: libc::c_uint = 40 as libc::c_int as libc::c_uint;
let mut alsa_period: libc::c_uint = 4 as libc::c_int as libc::c_uint;
let mut alsa_sample_fmt: *mut libc::c_char = 0 as *mut libc::c_char;
let mut alsa_mmap: bool = 1 as libc::c_int != 0;
let mut alsa_reopen: bool = 0 as libc::c_int != 0;
let mut volume_mixer_name: *mut libc::c_char =
next_param(volume_mixer, ',' as i32 as libc::c_char);
let mut volume_mixer_index: *mut libc::c_char =
next_param(0 as *mut libc::c_char, ',' as i32 as libc::c_char);
let mut t: *mut libc::c_char =
next_param(params, ':' as i32 as libc::c_char);
let mut c: *mut libc::c_char =
next_param(0 as *mut libc::c_char, ':' as i32 as libc::c_char);
let mut s: *mut libc::c_char =
next_param(0 as *mut libc::c_char, ':' as i32 as libc::c_char);
let mut m: *mut libc::c_char =
next_param(0 as *mut libc::c_char, ':' as i32 as libc::c_char);
let mut r: *mut libc::c_char =
next_param(0 as *mut libc::c_char, ':' as i32 as libc::c_char);
if !t.is_null() { alsa_buffer = atoi(t) as libc::c_uint }
if !c.is_null() { alsa_period = atoi(c) as libc::c_uint }
if !s.is_null() { alsa_sample_fmt = s }
if !m.is_null() { alsa_mmap = atoi(m) != 0 }
if !r.is_null() { alsa_reopen = atoi(r) != 0 }
loglevel = level;
if loglevel as libc::c_uint >= lINFO as libc::c_int as libc::c_uint {
logprint(b"%s %s:%d init output\n\x00" as *const u8 as
*const libc::c_char, logtime(),
(*::std::mem::transmute::<&[u8; 17],
&[libc::c_char; 17]>(b"output_init_alsa\x00")).as_ptr(),
939 as libc::c_int);
}
memset(&mut output as *mut outputstate as *mut libc::c_void,
0 as libc::c_int,
::std::mem::size_of::<outputstate>() as libc::c_ulong);
alsa.mmap = alsa_mmap;
alsa.write_buf = 0 as *mut u8_t;
alsa.format = SND_PCM_FORMAT_S8;
alsa.reopen = alsa_reopen;
alsa.mixer_handle = 0 as *mut snd_mixer_t;
alsa.ctl = ctl4device(device);
alsa.mixer_ctl =
if !mixer_device.is_null() {
ctl4device(mixer_device)
} else { alsa.ctl };
alsa.volume_mixer_name = volume_mixer_name;
alsa.mixer_linear = mixer_linear;
output.format = S32_LE;
output.buffer = alsa_buffer;
output.period = alsa_period;
output.start_frames = 0 as libc::c_int as libc::c_uint;
output.write_cb =
Some(_write_frames as
unsafe extern "C" fn(_: frames_t, _: bool, _: s32_t,
_: s32_t, _: s32_t, _: s32_t,
_: *mut *mut s32_t) -> libc::c_int);
output.rate_delay = rate_delay;
if !alsa_sample_fmt.is_null() {
if strcmp(alsa_sample_fmt,
b"32\x00" as *const u8 as *const libc::c_char) == 0 {
alsa.format = SND_PCM_FORMAT_S32_LE
}
if strcmp(alsa_sample_fmt,
b"24\x00" as *const u8 as *const libc::c_char) == 0 {
alsa.format = SND_PCM_FORMAT_S24_LE
}
if strcmp(alsa_sample_fmt,
b"24_3\x00" as *const u8 as *const libc::c_char) == 0 {
alsa.format = SND_PCM_FORMAT_S24_3LE
}
if strcmp(alsa_sample_fmt,
b"16\x00" as *const u8 as *const libc::c_char) == 0 {
alsa.format = SND_PCM_FORMAT_S16_LE
}
}
if loglevel as libc::c_uint >= lINFO as libc::c_int as libc::c_uint {
logprint(b"%s %s:%d requested alsa_buffer: %u alsa_period: %u format: %s mmap: %u\n\x00"
as *const u8 as *const libc::c_char, logtime(),
(*::std::mem::transmute::<&[u8; 17],
&[libc::c_char; 17]>(b"output_init_alsa\x00")).as_ptr(),
979 as libc::c_int, output.buffer, output.period,
if !alsa_sample_fmt.is_null() {
alsa_sample_fmt as *const libc::c_char
} else { b"any\x00" as *const u8 as *const libc::c_char },
alsa.mmap as libc::c_int);
}
snd_lib_error_set_handler(::std::mem::transmute::<Option<unsafe extern "C" fn(_:
*const libc::c_char,
_:
libc::c_int,
_:
*const libc::c_char,
_:
libc::c_int,
_:
*const libc::c_char,
_:
...)
->
*mut libc::c_void>,
snd_lib_error_handler_t>(Some(alsa_error_handler
as
unsafe extern "C" fn(_:
*const libc::c_char,
_:
libc::c_int,
_:
*const libc::c_char,
_:
libc::c_int,
_:
*const libc::c_char,
_:
...)
->
*mut libc::c_void)));
output_init_common(level, device, output_buf_size, rates, idle);
if !volume_mixer_name.is_null() {
if mixer_init_alsa(alsa.mixer_ctl, alsa.volume_mixer_name,
(if !volume_mixer_index.is_null() {
atoi(volume_mixer_index)
} else { 0 as libc::c_int })) < 0 as libc::c_int {
logprint(b"%s %s:%d Initialization of mixer failed, reverting to software volume\n\x00"
as *const u8 as *const libc::c_char, logtime(),
(*::std::mem::transmute::<&[u8; 17],
&[libc::c_char; 17]>(b"output_init_alsa\x00")).as_ptr(),
989 as libc::c_int);
alsa.mixer_handle = 0 as *mut snd_mixer_t;
alsa.volume_mixer_name = 0 as *const libc::c_char
}
}
if mixer_unmute as libc::c_int != 0 && !alsa.volume_mixer_name.is_null() {
set_mixer(1 as libc::c_int != 0, 0 as libc::c_int as libc::c_float,
0 as libc::c_int as libc::c_float);
alsa.volume_mixer_name = 0 as *const libc::c_char
}
// RT linux - aim to avoid pagefaults by locking memory:
// https://rt.wiki.kernel.org/index.php/Threaded_RT-application_with_memory_locking_and_stack_handling_example
if mlockall(1 as libc::c_int | 2 as libc::c_int) == -(1 as libc::c_int) {
if loglevel as libc::c_uint >= lINFO as libc::c_int as libc::c_uint {
logprint(b"%s %s:%d unable to lock memory: %s\n\x00" as *const u8
as *const libc::c_char, logtime(),
(*::std::mem::transmute::<&[u8; 17],
&[libc::c_char; 17]>(b"output_init_alsa\x00")).as_ptr(),
1003 as libc::c_int, strerror(*__errno_location()));
}
} else if loglevel as libc::c_uint >= lINFO as libc::c_int as libc::c_uint
{
logprint(b"%s %s:%d memory locked\n\x00" as *const u8 as
*const libc::c_char, logtime(),
(*::std::mem::transmute::<&[u8; 17],
&[libc::c_char; 17]>(b"output_init_alsa\x00")).as_ptr(),
1005 as libc::c_int);
}
mallopt(-(1 as libc::c_int), -(1 as libc::c_int));
mallopt(-(4 as libc::c_int), 0 as libc::c_int);
if loglevel as libc::c_uint >= lINFO as libc::c_int as libc::c_uint {
logprint(b"%s %s:%d glibc detected using mallopt\n\x00" as *const u8
as *const libc::c_char, logtime(),
(*::std::mem::transmute::<&[u8; 17],
&[libc::c_char; 17]>(b"output_init_alsa\x00")).as_ptr(),
1011 as libc::c_int);
}
touch_memory(silencebuf,
(2048 as libc::c_int * 8 as libc::c_int) as size_t);
touch_memory((*outputbuf).buf, (*outputbuf).size);
// start output thread
let mut attr: pthread_attr_t = pthread_attr_t{__size: [0; 56],};
pthread_attr_init(&mut attr);
pthread_attr_setstacksize(&mut attr,
(16384 as libc::c_int +
64 as libc::c_int * 1024 as libc::c_int) as
size_t);
pthread_create(&mut thread, &mut attr,
Some(output_thread as
unsafe extern "C" fn(_: *mut libc::c_void)
-> *mut libc::c_void),
if *rates.offset(0 as libc::c_int as isize) != 0 {
b"probe\x00" as *const u8 as *const libc::c_char
} else { 0 as *const libc::c_char } as *mut libc::c_void);
pthread_attr_destroy(&mut attr);
// try to set this thread to real-time scheduler class, only works as root or if user has permission
let mut param: sched_param = sched_param{sched_priority: 0,};
param.sched_priority = rt_priority as libc::c_int;
if pthread_setschedparam(thread, 1 as libc::c_int, &mut param) !=
0 as libc::c_int {
if loglevel as libc::c_uint >= lDEBUG as libc::c_int as libc::c_uint {
logprint(b"%s %s:%d unable to set output sched fifo: %s\n\x00" as
*const u8 as *const libc::c_char, logtime(),
(*::std::mem::transmute::<&[u8; 17],
&[libc::c_char; 17]>(b"output_init_alsa\x00")).as_ptr(),
1029 as libc::c_int, strerror(*__errno_location()));
}
} else if loglevel as libc::c_uint >=
lDEBUG as libc::c_int as libc::c_uint {
logprint(b"%s %s:%d set output sched fifo rt: %u\n\x00" as *const u8
as *const libc::c_char, logtime(),
(*::std::mem::transmute::<&[u8; 17],
&[libc::c_char; 17]>(b"output_init_alsa\x00")).as_ptr(),
1031 as libc::c_int, param.sched_priority);
};
}
#[no_mangle]
pub unsafe extern "C" fn output_close_alsa() {
if loglevel as libc::c_uint >= lINFO as libc::c_int as libc::c_uint {
logprint(b"%s %s:%d close output\n\x00" as *const u8 as
*const libc::c_char, logtime(),
(*::std::mem::transmute::<&[u8; 18],
&[libc::c_char; 18]>(b"output_close_alsa\x00")).as_ptr(),
1036 as libc::c_int);
}
pthread_mutex_lock(&mut (*outputbuf).mutex);
running = 0 as libc::c_int != 0;
pthread_mutex_unlock(&mut (*outputbuf).mutex);
pthread_join(thread, 0 as *mut *mut libc::c_void);
if !alsa.write_buf.is_null() {
free(alsa.write_buf as *mut libc::c_void);
}
if !alsa.ctl.is_null() { free(alsa.ctl as *mut libc::c_void); }
if !alsa.mixer_ctl.is_null() {
free(alsa.mixer_ctl as *mut libc::c_void);
}
if !alsa.mixer_handle.is_null() { snd_mixer_close(alsa.mixer_handle); }
output_close_common();
}
// ALSA