squeezers/src/output_alsa.rs

2391 lines
101 KiB
Rust
Raw Normal View History

use ::libc;
pub use crate::internal::__builtin_va_list;
pub use crate::internal::__va_list_tag;
pub use crate::stdarg_h::va_list;
pub use crate::stddef_h::size_t;
pub use crate::stdlib::_IO_codecvt;
pub use crate::stdlib::_IO_lock_t;
pub use crate::stdlib::_IO_marker;
pub use crate::stdlib::_IO_wide_data;
pub use crate::stdlib::__int32_t;
pub use crate::stdlib::__off64_t;
pub use crate::stdlib::__off_t;
pub use crate::stdlib::__uint32_t;
pub use crate::stdlib::__uint8_t;
pub use crate::stdlib::__useconds_t;
pub use crate::stdlib::int32_t;
pub use crate::stdlib::FILE;
pub use crate::stdlib::_IO_FILE;
pub use crate::stdlib::__pthread_internal_list;
pub use crate::stdlib::__pthread_list_t;
pub use crate::stdlib::__pthread_mutex_s;
pub use crate::stdlib::pthread_attr_t;
pub use crate::stdlib::pthread_mutex_t;
pub use crate::stdlib::pthread_t;
pub use crate::stdlib::sched_param;
pub use crate::stdlib::u_int32_t;
pub use crate::stdlib::u_int8_t;
pub use crate::squeezelite_h::_apply_cross;
pub use crate::squeezelite_h::_apply_gain;
pub use crate::squeezelite_h::buffer;
pub use crate::squeezelite_h::fade_dir;
pub use crate::squeezelite_h::fade_mode;
pub use crate::squeezelite_h::fade_state;
pub use crate::squeezelite_h::frames_t;
pub use crate::squeezelite_h::lDEBUG;
pub use crate::squeezelite_h::lERROR;
pub use crate::squeezelite_h::lINFO;
pub use crate::squeezelite_h::lSDEBUG;
pub use crate::squeezelite_h::lWARN;
pub use crate::squeezelite_h::log_level;
pub use crate::squeezelite_h::output_format;
pub use crate::squeezelite_h::output_state;
pub use crate::squeezelite_h::outputstate;
pub use crate::squeezelite_h::s32_t;
pub use crate::squeezelite_h::u32_t;
pub use crate::squeezelite_h::u8_t;
pub use crate::squeezelite_h::C2RustUnnamed_1;
pub use crate::squeezelite_h::FADE_ACTIVE;
pub use crate::squeezelite_h::FADE_CROSS;
pub use crate::squeezelite_h::FADE_CROSSFADE;
pub use crate::squeezelite_h::FADE_DOWN;
pub use crate::squeezelite_h::FADE_DUE;
pub use crate::squeezelite_h::FADE_IN;
pub use crate::squeezelite_h::FADE_INACTIVE;
pub use crate::squeezelite_h::FADE_INOUT;
pub use crate::squeezelite_h::FADE_NONE;
pub use crate::squeezelite_h::FADE_OUT;
pub use crate::squeezelite_h::FADE_UP;
pub use crate::squeezelite_h::OUTPUT_BUFFER;
pub use crate::squeezelite_h::OUTPUT_OFF;
pub use crate::squeezelite_h::OUTPUT_PAUSE_FRAMES;
pub use crate::squeezelite_h::OUTPUT_RUNNING;
pub use crate::squeezelite_h::OUTPUT_SKIP_FRAMES;
pub use crate::squeezelite_h::OUTPUT_START_AT;
pub use crate::squeezelite_h::OUTPUT_STOPPED;
pub use crate::squeezelite_h::S16_LE;
pub use crate::squeezelite_h::S24_3LE;
pub use crate::squeezelite_h::S24_LE;
pub use crate::squeezelite_h::S32_LE;
pub use crate::src::output::_output_frames;
pub use crate::src::output::output_close_common;
pub use crate::src::output::output_init_common;
pub use crate::src::output_pack::_scale_and_pack_frames;
pub use crate::src::utils::gettime_ms;
pub use crate::src::utils::logprint;
pub use crate::src::utils::logtime;
pub use crate::src::utils::next_param;
pub use crate::src::utils::touch_memory;
use crate::stdlib::__errno_location;
pub use crate::stdlib::_snd_mixer;
pub use crate::stdlib::_snd_mixer_class;
pub use crate::stdlib::_snd_mixer_elem;
pub use crate::stdlib::_snd_mixer_selem_channel_id;
pub use crate::stdlib::_snd_mixer_selem_id;
pub use crate::stdlib::_snd_output;
pub use crate::stdlib::_snd_pcm;
pub use crate::stdlib::_snd_pcm_access;
pub use crate::stdlib::_snd_pcm_channel_area;
pub use crate::stdlib::_snd_pcm_format;
pub use crate::stdlib::_snd_pcm_hw_params;
pub use crate::stdlib::_snd_pcm_state;
pub use crate::stdlib::_snd_pcm_stream;
use crate::stdlib::atoi;
use crate::stdlib::fflush;
use crate::stdlib::fprintf;
use crate::stdlib::free;
use crate::stdlib::malloc;
use crate::stdlib::memcpy;
use crate::stdlib::memset;
use crate::stdlib::printf;
pub use crate::stdlib::snd_lib_error_handler_t;
pub use crate::stdlib::snd_lib_error_set_handler;
pub use crate::stdlib::snd_mixer_attach;
pub use crate::stdlib::snd_mixer_class_t;
pub use crate::stdlib::snd_mixer_close;
pub use crate::stdlib::snd_mixer_elem_next;
pub use crate::stdlib::snd_mixer_elem_t;
pub use crate::stdlib::snd_mixer_find_selem;
pub use crate::stdlib::snd_mixer_first_elem;
pub use crate::stdlib::snd_mixer_load;
pub use crate::stdlib::snd_mixer_open;
pub use crate::stdlib::snd_mixer_selem_channel_id_t;
pub use crate::stdlib::snd_mixer_selem_get_id;
pub use crate::stdlib::snd_mixer_selem_get_playback_dB_range;
pub use crate::stdlib::snd_mixer_selem_get_playback_volume;
pub use crate::stdlib::snd_mixer_selem_get_playback_volume_range;
pub use crate::stdlib::snd_mixer_selem_has_playback_switch;
pub use crate::stdlib::snd_mixer_selem_has_playback_volume;
pub use crate::stdlib::snd_mixer_selem_id_get_index;
pub use crate::stdlib::snd_mixer_selem_id_get_name;
pub use crate::stdlib::snd_mixer_selem_id_set_index;
pub use crate::stdlib::snd_mixer_selem_id_set_name;
pub use crate::stdlib::snd_mixer_selem_id_sizeof;
pub use crate::stdlib::snd_mixer_selem_id_t;
pub use crate::stdlib::snd_mixer_selem_register;
pub use crate::stdlib::snd_mixer_selem_regopt;
pub use crate::stdlib::snd_mixer_selem_regopt_abstract;
pub use crate::stdlib::snd_mixer_selem_set_playback_dB;
pub use crate::stdlib::snd_mixer_selem_set_playback_switch_all;
pub use crate::stdlib::snd_mixer_selem_set_playback_volume;
pub use crate::stdlib::snd_mixer_t;
pub use crate::stdlib::snd_output_stdio_attach;
pub use crate::stdlib::snd_output_t;
pub use crate::stdlib::snd_pcm_access_t;
pub use crate::stdlib::snd_pcm_avail_update;
pub use crate::stdlib::snd_pcm_channel_area_t;
pub use crate::stdlib::snd_pcm_close;
pub use crate::stdlib::snd_pcm_delay;
pub use crate::stdlib::snd_pcm_dump;
pub use crate::stdlib::snd_pcm_format_name;
pub use crate::stdlib::snd_pcm_format_t;
pub use crate::stdlib::snd_pcm_hw_params;
pub use crate::stdlib::snd_pcm_hw_params_any;
pub use crate::stdlib::snd_pcm_hw_params_get_buffer_size;
pub use crate::stdlib::snd_pcm_hw_params_get_period_size;
pub use crate::stdlib::snd_pcm_hw_params_set_access;
pub use crate::stdlib::snd_pcm_hw_params_set_buffer_size_near;
pub use crate::stdlib::snd_pcm_hw_params_set_buffer_time_near;
pub use crate::stdlib::snd_pcm_hw_params_set_channels;
pub use crate::stdlib::snd_pcm_hw_params_set_format;
pub use crate::stdlib::snd_pcm_hw_params_set_period_size_near;
pub use crate::stdlib::snd_pcm_hw_params_set_periods_near;
pub use crate::stdlib::snd_pcm_hw_params_set_rate;
pub use crate::stdlib::snd_pcm_hw_params_set_rate_resample;
pub use crate::stdlib::snd_pcm_hw_params_sizeof;
pub use crate::stdlib::snd_pcm_hw_params_t;
pub use crate::stdlib::snd_pcm_hw_params_test_rate;
pub use crate::stdlib::snd_pcm_mmap_begin;
pub use crate::stdlib::snd_pcm_mmap_commit;
pub use crate::stdlib::snd_pcm_open;
pub use crate::stdlib::snd_pcm_recover;
pub use crate::stdlib::snd_pcm_sframes_t;
pub use crate::stdlib::snd_pcm_start;
pub use crate::stdlib::snd_pcm_state;
pub use crate::stdlib::snd_pcm_state_t;
pub use crate::stdlib::snd_pcm_stream_t;
pub use crate::stdlib::snd_pcm_t;
pub use crate::stdlib::snd_pcm_uframes_t;
pub use crate::stdlib::snd_pcm_wait;
pub use crate::stdlib::snd_pcm_writei;
pub use crate::stdlib::snd_strerror;
use crate::stdlib::stderr;
use crate::stdlib::strcmp;
use crate::stdlib::strcpy;
use crate::stdlib::strdup;
use crate::stdlib::strerror;
use crate::stdlib::strlen;
use crate::stdlib::strncmp;
use crate::stdlib::strrchr;
use crate::stdlib::strtok;
use crate::stdlib::vfprintf;
pub use crate::stdlib::SND_MIXER_SABSTRACT_BASIC;
pub use crate::stdlib::SND_MIXER_SABSTRACT_NONE;
pub use crate::stdlib::SND_MIXER_SCHN_FRONT_CENTER;
pub use crate::stdlib::SND_MIXER_SCHN_FRONT_LEFT;
pub use crate::stdlib::SND_MIXER_SCHN_FRONT_RIGHT;
pub use crate::stdlib::SND_MIXER_SCHN_LAST;
pub use crate::stdlib::SND_MIXER_SCHN_MONO;
pub use crate::stdlib::SND_MIXER_SCHN_REAR_CENTER;
pub use crate::stdlib::SND_MIXER_SCHN_REAR_LEFT;
pub use crate::stdlib::SND_MIXER_SCHN_REAR_RIGHT;
pub use crate::stdlib::SND_MIXER_SCHN_SIDE_LEFT;
pub use crate::stdlib::SND_MIXER_SCHN_SIDE_RIGHT;
pub use crate::stdlib::SND_MIXER_SCHN_UNKNOWN;
pub use crate::stdlib::SND_MIXER_SCHN_WOOFER;
pub use crate::stdlib::SND_PCM_ACCESS_LAST;
pub use crate::stdlib::SND_PCM_ACCESS_MMAP_COMPLEX;
pub use crate::stdlib::SND_PCM_ACCESS_MMAP_INTERLEAVED;
pub use crate::stdlib::SND_PCM_ACCESS_MMAP_NONINTERLEAVED;
pub use crate::stdlib::SND_PCM_ACCESS_RW_INTERLEAVED;
pub use crate::stdlib::SND_PCM_ACCESS_RW_NONINTERLEAVED;
pub use crate::stdlib::SND_PCM_FORMAT_A_LAW;
pub use crate::stdlib::SND_PCM_FORMAT_DSD_U16_BE;
pub use crate::stdlib::SND_PCM_FORMAT_DSD_U16_LE;
pub use crate::stdlib::SND_PCM_FORMAT_DSD_U32_BE;
pub use crate::stdlib::SND_PCM_FORMAT_DSD_U32_LE;
pub use crate::stdlib::SND_PCM_FORMAT_DSD_U8;
pub use crate::stdlib::SND_PCM_FORMAT_FLOAT;
pub use crate::stdlib::SND_PCM_FORMAT_FLOAT64;
pub use crate::stdlib::SND_PCM_FORMAT_FLOAT64_BE;
pub use crate::stdlib::SND_PCM_FORMAT_FLOAT64_LE;
pub use crate::stdlib::SND_PCM_FORMAT_FLOAT_BE;
pub use crate::stdlib::SND_PCM_FORMAT_FLOAT_LE;
pub use crate::stdlib::SND_PCM_FORMAT_G723_24;
pub use crate::stdlib::SND_PCM_FORMAT_G723_24_1B;
pub use crate::stdlib::SND_PCM_FORMAT_G723_40;
pub use crate::stdlib::SND_PCM_FORMAT_G723_40_1B;
pub use crate::stdlib::SND_PCM_FORMAT_GSM;
pub use crate::stdlib::SND_PCM_FORMAT_IEC958_SUBFRAME;
pub use crate::stdlib::SND_PCM_FORMAT_IEC958_SUBFRAME_BE;
pub use crate::stdlib::SND_PCM_FORMAT_IEC958_SUBFRAME_LE;
pub use crate::stdlib::SND_PCM_FORMAT_IMA_ADPCM;
pub use crate::stdlib::SND_PCM_FORMAT_LAST;
pub use crate::stdlib::SND_PCM_FORMAT_MPEG;
pub use crate::stdlib::SND_PCM_FORMAT_MU_LAW;
pub use crate::stdlib::SND_PCM_FORMAT_S16;
pub use crate::stdlib::SND_PCM_FORMAT_S16_BE;
pub use crate::stdlib::SND_PCM_FORMAT_S16_LE;
pub use crate::stdlib::SND_PCM_FORMAT_S18_3BE;
pub use crate::stdlib::SND_PCM_FORMAT_S18_3LE;
pub use crate::stdlib::SND_PCM_FORMAT_S20;
pub use crate::stdlib::SND_PCM_FORMAT_S20_3BE;
pub use crate::stdlib::SND_PCM_FORMAT_S20_3LE;
pub use crate::stdlib::SND_PCM_FORMAT_S20_BE;
pub use crate::stdlib::SND_PCM_FORMAT_S20_LE;
pub use crate::stdlib::SND_PCM_FORMAT_S24;
pub use crate::stdlib::SND_PCM_FORMAT_S24_3BE;
pub use crate::stdlib::SND_PCM_FORMAT_S24_3LE;
pub use crate::stdlib::SND_PCM_FORMAT_S24_BE;
pub use crate::stdlib::SND_PCM_FORMAT_S24_LE;
pub use crate::stdlib::SND_PCM_FORMAT_S32;
pub use crate::stdlib::SND_PCM_FORMAT_S32_BE;
pub use crate::stdlib::SND_PCM_FORMAT_S32_LE;
pub use crate::stdlib::SND_PCM_FORMAT_S8;
pub use crate::stdlib::SND_PCM_FORMAT_SPECIAL;
pub use crate::stdlib::SND_PCM_FORMAT_U16;
pub use crate::stdlib::SND_PCM_FORMAT_U16_BE;
pub use crate::stdlib::SND_PCM_FORMAT_U16_LE;
pub use crate::stdlib::SND_PCM_FORMAT_U18_3BE;
pub use crate::stdlib::SND_PCM_FORMAT_U18_3LE;
pub use crate::stdlib::SND_PCM_FORMAT_U20;
pub use crate::stdlib::SND_PCM_FORMAT_U20_3BE;
pub use crate::stdlib::SND_PCM_FORMAT_U20_3LE;
pub use crate::stdlib::SND_PCM_FORMAT_U20_BE;
pub use crate::stdlib::SND_PCM_FORMAT_U20_LE;
pub use crate::stdlib::SND_PCM_FORMAT_U24;
pub use crate::stdlib::SND_PCM_FORMAT_U24_3BE;
pub use crate::stdlib::SND_PCM_FORMAT_U24_3LE;
pub use crate::stdlib::SND_PCM_FORMAT_U24_BE;
pub use crate::stdlib::SND_PCM_FORMAT_U24_LE;
pub use crate::stdlib::SND_PCM_FORMAT_U32;
pub use crate::stdlib::SND_PCM_FORMAT_U32_BE;
pub use crate::stdlib::SND_PCM_FORMAT_U32_LE;
pub use crate::stdlib::SND_PCM_FORMAT_U8;
pub use crate::stdlib::SND_PCM_FORMAT_UNKNOWN;
pub use crate::stdlib::SND_PCM_STATE_DISCONNECTED;
pub use crate::stdlib::SND_PCM_STATE_DRAINING;
pub use crate::stdlib::SND_PCM_STATE_LAST;
pub use crate::stdlib::SND_PCM_STATE_OPEN;
pub use crate::stdlib::SND_PCM_STATE_PAUSED;
pub use crate::stdlib::SND_PCM_STATE_PREPARED;
pub use crate::stdlib::SND_PCM_STATE_PRIVATE1;
pub use crate::stdlib::SND_PCM_STATE_RUNNING;
pub use crate::stdlib::SND_PCM_STATE_SETUP;
pub use crate::stdlib::SND_PCM_STATE_SUSPENDED;
pub use crate::stdlib::SND_PCM_STATE_XRUN;
pub use crate::stdlib::SND_PCM_STREAM_CAPTURE;
pub use crate::stdlib::SND_PCM_STREAM_LAST;
pub use crate::stdlib::SND_PCM_STREAM_PLAYBACK;
use crate::stdlib::floor;
use crate::stdlib::log10;
use crate::stdlib::mallopt;
use crate::stdlib::mlockall;
use crate::stdlib::pthread_attr_destroy;
use crate::stdlib::pthread_attr_init;
use crate::stdlib::pthread_attr_setstacksize;
use crate::stdlib::pthread_create;
use crate::stdlib::pthread_join;
use crate::stdlib::pthread_mutex_lock;
use crate::stdlib::pthread_mutex_unlock;
use crate::stdlib::pthread_setschedparam;
use crate::stdlib::sleep;
use crate::stdlib::snd_device_name_free_hint;
use crate::stdlib::snd_device_name_get_hint;
use crate::stdlib::snd_device_name_hint;
use crate::stdlib::usleep;
extern "C" {
#[no_mangle]
pub static mut silencebuf: *mut crate::squeezelite_h::u8_t;
#[no_mangle]
pub static mut output: crate::squeezelite_h::outputstate;
#[no_mangle]
pub static mut outputbuf: *mut crate::squeezelite_h::buffer;
}
// ouput device
#[repr(C)]
#[derive(Copy, Clone)]
pub struct C2RustUnnamed_12 {
pub device: [libc::c_char; 129],
pub ctl: *mut libc::c_char,
pub mixer_ctl: *mut libc::c_char,
pub format: crate::stdlib::snd_pcm_format_t,
pub buffer_size: crate::stdlib::snd_pcm_uframes_t,
pub period_size: crate::stdlib::snd_pcm_uframes_t,
pub rate: libc::c_uint,
pub mmap: bool,
pub reopen: bool,
pub write_buf: *mut crate::squeezelite_h::u8_t,
pub volume_mixer_name: *const libc::c_char,
pub mixer_linear: bool,
pub mixer_elem: *mut crate::stdlib::snd_mixer_elem_t,
pub mixer_handle: *mut crate::stdlib::snd_mixer_t,
pub mixer_min: libc::c_long,
pub mixer_max: libc::c_long,
}
static mut fmts: [crate::stdlib::snd_pcm_format_t; 5] = [
crate::stdlib::SND_PCM_FORMAT_S32_LE,
crate::stdlib::SND_PCM_FORMAT_S24_LE,
crate::stdlib::SND_PCM_FORMAT_S24_3LE,
crate::stdlib::SND_PCM_FORMAT_S16_LE,
crate::stdlib::SND_PCM_FORMAT_UNKNOWN,
];
static mut alsa: C2RustUnnamed_12 = C2RustUnnamed_12 {
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: crate::stdlib::SND_PCM_FORMAT_S8,
buffer_size: 0,
period_size: 0,
rate: 0,
mmap: false,
reopen: false,
write_buf: 0 as *const crate::squeezelite_h::u8_t as *mut crate::squeezelite_h::u8_t,
volume_mixer_name: 0 as *const libc::c_char,
mixer_linear: false,
mixer_elem: 0 as *const crate::stdlib::snd_mixer_elem_t as *mut crate::stdlib::snd_mixer_elem_t,
mixer_handle: 0 as *const crate::stdlib::snd_mixer_t as *mut crate::stdlib::snd_mixer_t,
mixer_min: 0,
mixer_max: 0,
};
static mut pcmp: *mut crate::stdlib::snd_pcm_t =
0 as *const crate::stdlib::snd_pcm_t as *mut crate::stdlib::snd_pcm_t;
static mut loglevel: crate::squeezelite_h::log_level = crate::squeezelite_h::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 = 0 as *mut libc::c_char;
if crate::stdlib::strncmp(
device,
b"hw:\x00" as *const u8 as *const libc::c_char,
3 as libc::c_int as libc::c_ulong,
) == 0
{
ctl = crate::stdlib::strdup(device)
} else if crate::stdlib::strncmp(
device,
b"plughw:\x00" as *const u8 as *const libc::c_char,
7 as libc::c_int as libc::c_ulong,
) == 0
{
ctl = crate::stdlib::strdup(device.offset(4 as libc::c_int as isize))
}
if !ctl.is_null() {
let mut comma = 0 as *mut libc::c_char;
comma = crate::stdlib::strrchr(ctl, ',' as i32);
if !comma.is_null() {
*comma = '\u{0}' as i32 as libc::c_char
}
} else {
ctl = crate::stdlib::strdup(device)
}
return ctl;
}
#[no_mangle]
pub unsafe extern "C" fn list_devices() {
let mut hints = 0 as *mut *mut libc::c_void;
let mut n = 0 as *mut *mut libc::c_void;
if crate::stdlib::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;
crate::stdlib::printf(b"Output devices:\n\x00" as *const u8 as *const libc::c_char);
while !(*n).is_null() {
let mut name = crate::stdlib::snd_device_name_get_hint(
*n,
b"NAME\x00" as *const u8 as *const libc::c_char,
);
let mut desc = crate::stdlib::snd_device_name_get_hint(
*n,
b"DESC\x00" as *const u8 as *const libc::c_char,
);
if !name.is_null() {
crate::stdlib::printf(b" %-30s\x00" as *const u8 as *const libc::c_char, name);
}
if !desc.is_null() {
let mut s1 =
crate::stdlib::strtok(desc, b"\n\x00" as *const u8 as *const libc::c_char);
let mut s2 = crate::stdlib::strtok(
0 as *mut libc::c_char,
b"\n\x00" as *const u8 as *const libc::c_char,
);
if !s1.is_null() {
crate::stdlib::printf(b" - %s\x00" as *const u8 as *const libc::c_char, s1);
}
if !s2.is_null() {
crate::stdlib::printf(b" - %s\x00" as *const u8 as *const libc::c_char, s2);
}
}
crate::stdlib::printf(b"\n\x00" as *const u8 as *const libc::c_char);
if !name.is_null() {
crate::stdlib::free(name as *mut libc::c_void);
}
if !desc.is_null() {
crate::stdlib::free(desc as *mut libc::c_void);
}
n = n.offset(1)
}
crate::stdlib::snd_device_name_free_hint(hints);
}
crate::stdlib::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 = 0 as *mut crate::stdlib::snd_mixer_t;
let mut sid = 0 as *mut crate::stdlib::snd_mixer_selem_id_t;
let mut elem = 0 as *mut crate::stdlib::snd_mixer_elem_t;
let mut ctl = ctl4device(output_device);
let mut fresh0 = ::std::vec::from_elem(0, crate::stdlib::snd_mixer_selem_id_sizeof() as usize);
sid = fresh0.as_mut_ptr() as *mut crate::stdlib::snd_mixer_selem_id_t;
crate::stdlib::memset(
sid as *mut libc::c_void,
0 as libc::c_int,
crate::stdlib::snd_mixer_selem_id_sizeof(),
);
if loglevel as libc::c_uint >= crate::squeezelite_h::lINFO as libc::c_int as libc::c_uint {
crate::src::utils::logprint(
b"%s %s:%d listing mixers for: %s\n\x00" as *const u8 as *const libc::c_char,
crate::src::utils::logtime(),
(*::std::mem::transmute::<&[u8; 12], &[libc::c_char; 12]>(b"list_mixers\x00")).as_ptr(),
139 as libc::c_int,
output_device,
);
}
err = crate::stdlib::snd_mixer_open(&mut handle, 0 as libc::c_int);
if err < 0 as libc::c_int {
crate::src::utils::logprint(
b"%s %s:%d open error: %s\n\x00" as *const u8 as *const libc::c_char,
crate::src::utils::logtime(),
(*::std::mem::transmute::<&[u8; 12], &[libc::c_char; 12]>(b"list_mixers\x00")).as_ptr(),
142 as libc::c_int,
crate::stdlib::snd_strerror(err),
);
return;
}
err = crate::stdlib::snd_mixer_attach(handle, ctl);
if err < 0 as libc::c_int {
crate::src::utils::logprint(
b"%s %s:%d attach error: %s\n\x00" as *const u8 as *const libc::c_char,
crate::src::utils::logtime(),
(*::std::mem::transmute::<&[u8; 12], &[libc::c_char; 12]>(b"list_mixers\x00")).as_ptr(),
146 as libc::c_int,
crate::stdlib::snd_strerror(err),
);
crate::stdlib::snd_mixer_close(handle);
crate::stdlib::free(ctl as *mut libc::c_void);
return;
}
crate::stdlib::free(ctl as *mut libc::c_void);
err = crate::stdlib::snd_mixer_selem_register(
handle,
0 as *mut crate::stdlib::snd_mixer_selem_regopt,
0 as *mut *mut crate::stdlib::snd_mixer_class_t,
);
if err < 0 as libc::c_int {
crate::src::utils::logprint(
b"%s %s:%d register error: %s\n\x00" as *const u8 as *const libc::c_char,
crate::src::utils::logtime(),
(*::std::mem::transmute::<&[u8; 12], &[libc::c_char; 12]>(b"list_mixers\x00")).as_ptr(),
153 as libc::c_int,
crate::stdlib::snd_strerror(err),
);
crate::stdlib::snd_mixer_close(handle);
return;
}
err = crate::stdlib::snd_mixer_load(handle);
if err < 0 as libc::c_int {
crate::src::utils::logprint(
b"%s %s:%d load error: %s\n\x00" as *const u8 as *const libc::c_char,
crate::src::utils::logtime(),
(*::std::mem::transmute::<&[u8; 12], &[libc::c_char; 12]>(b"list_mixers\x00")).as_ptr(),
158 as libc::c_int,
crate::stdlib::snd_strerror(err),
);
crate::stdlib::snd_mixer_close(handle);
return;
}
crate::stdlib::printf(
b"Volume controls for %s\n\x00" as *const u8 as *const libc::c_char,
output_device,
);
elem = crate::stdlib::snd_mixer_first_elem(handle);
while !elem.is_null() {
if crate::stdlib::snd_mixer_selem_has_playback_volume(elem) != 0 {
crate::stdlib::snd_mixer_selem_get_id(elem, sid);
crate::stdlib::printf(
b" %s\x00" as *const u8 as *const libc::c_char,
crate::stdlib::snd_mixer_selem_id_get_name(sid),
);
if crate::stdlib::snd_mixer_selem_id_get_index(sid) != 0 {
crate::stdlib::printf(
b",%d\x00" as *const u8 as *const libc::c_char,
crate::stdlib::snd_mixer_selem_id_get_index(sid),
);
}
crate::stdlib::printf(b"\n\x00" as *const u8 as *const libc::c_char);
}
elem = crate::stdlib::snd_mixer_elem_next(elem)
}
crate::stdlib::printf(b"\n\x00" as *const u8 as *const libc::c_char);
crate::stdlib::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) + crate::stdlib::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) + crate::stdlib::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 >= crate::squeezelite_h::lDEBUG as libc::c_int as libc::c_uint {
crate::src::utils::logprint(
b"%s %s:%d setting vol raw [%ld..%ld]\n\x00" as *const u8 as *const libc::c_char,
crate::src::utils::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 = crate::stdlib::snd_mixer_selem_set_playback_volume(
alsa.mixer_elem,
crate::stdlib::SND_MIXER_SCHN_FRONT_LEFT,
lraw,
);
if err < 0 as libc::c_int {
crate::src::utils::logprint(
b"%s %s:%d error setting left volume: %s\n\x00" as *const u8 as *const libc::c_char,
crate::src::utils::logtime(),
(*::std::mem::transmute::<&[u8; 10], &[libc::c_char; 10]>(b"set_mixer\x00"))
.as_ptr(),
195 as libc::c_int,
crate::stdlib::snd_strerror(err),
);
}
err = crate::stdlib::snd_mixer_selem_set_playback_volume(
alsa.mixer_elem,
crate::stdlib::SND_MIXER_SCHN_FRONT_RIGHT,
rraw,
);
if err < 0 as libc::c_int {
crate::src::utils::logprint(
b"%s %s:%d error setting right volume: %s\n\x00" as *const u8
as *const libc::c_char,
crate::src::utils::logtime(),
(*::std::mem::transmute::<&[u8; 10], &[libc::c_char; 10]>(b"set_mixer\x00"))
.as_ptr(),
198 as libc::c_int,
crate::stdlib::snd_strerror(err),
);
}
} else {
// set db directly
if loglevel as libc::c_uint >= crate::squeezelite_h::lDEBUG as libc::c_int as libc::c_uint {
crate::src::utils::logprint(
b"%s %s:%d setting vol dB [%ld..%ld]\n\x00" as *const u8 as *const libc::c_char,
crate::src::utils::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 = crate::stdlib::snd_mixer_selem_set_playback_dB(
alsa.mixer_elem,
crate::stdlib::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 {
crate::src::utils::logprint(
b"%s %s:%d error setting left volume: %s\n\x00" as *const u8 as *const libc::c_char,
crate::src::utils::logtime(),
(*::std::mem::transmute::<&[u8; 10], &[libc::c_char; 10]>(b"set_mixer\x00"))
.as_ptr(),
212 as libc::c_int,
crate::stdlib::snd_strerror(err),
);
}
err = crate::stdlib::snd_mixer_selem_set_playback_dB(
alsa.mixer_elem,
crate::stdlib::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 {
crate::src::utils::logprint(
b"%s %s:%d error setting right volume: %s\n\x00" as *const u8
as *const libc::c_char,
crate::src::utils::logtime(),
(*::std::mem::transmute::<&[u8; 10], &[libc::c_char; 10]>(b"set_mixer\x00"))
.as_ptr(),
215 as libc::c_int,
crate::stdlib::snd_strerror(err),
);
}
}
err = crate::stdlib::snd_mixer_selem_get_playback_volume(
alsa.mixer_elem,
crate::stdlib::SND_MIXER_SCHN_FRONT_LEFT,
&mut nleft,
);
if err < 0 as libc::c_int {
crate::src::utils::logprint(
b"%s %s:%d error getting left vol: %s\n\x00" as *const u8 as *const libc::c_char,
crate::src::utils::logtime(),
(*::std::mem::transmute::<&[u8; 10], &[libc::c_char; 10]>(b"set_mixer\x00")).as_ptr(),
220 as libc::c_int,
crate::stdlib::snd_strerror(err),
);
}
err = crate::stdlib::snd_mixer_selem_get_playback_volume(
alsa.mixer_elem,
crate::stdlib::SND_MIXER_SCHN_FRONT_RIGHT,
&mut nright,
);
if err < 0 as libc::c_int {
crate::src::utils::logprint(
b"%s %s:%d error getting right vol: %s\n\x00" as *const u8 as *const libc::c_char,
crate::src::utils::logtime(),
(*::std::mem::transmute::<&[u8; 10], &[libc::c_char; 10]>(b"set_mixer\x00")).as_ptr(),
223 as libc::c_int,
crate::stdlib::snd_strerror(err),
);
}
if loglevel as libc::c_uint >= crate::squeezelite_h::lDEBUG as libc::c_int as libc::c_uint {
crate::src::utils::logprint(
b"%s %s:%d %s left: %3.1fdB -> %ld right: %3.1fdB -> %ld\n\x00" as *const u8
as *const libc::c_char,
crate::src::utils::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 >= crate::squeezelite_h::lDEBUG as libc::c_int as libc::c_uint {
crate::src::utils::logprint(
b"%s %s:%d setting internal gain left: %u right: %u\n\x00" as *const u8
as *const libc::c_char,
crate::src::utils::logtime(),
(*::std::mem::transmute::<&[u8; 11], &[libc::c_char; 11]>(b"set_volume\x00"))
.as_ptr(),
233 as libc::c_int,
left,
right,
);
}
crate::stdlib::pthread_mutex_lock(&mut (*outputbuf).mutex);
output.gainL = left;
output.gainR = right;
crate::stdlib::pthread_mutex_unlock(&mut (*outputbuf).mutex);
return;
} else {
crate::stdlib::pthread_mutex_lock(&mut (*outputbuf).mutex);
output.gainL = 0x10000 as libc::c_int as crate::squeezelite_h::u32_t;
output.gainR = 0x10000 as libc::c_int as crate::squeezelite_h::u32_t;
crate::stdlib::pthread_mutex_unlock(&mut (*outputbuf).mutex);
}
// convert 16.16 fixed point to dB
ldB = (20 as libc::c_int as libc::c_double
* crate::stdlib::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
* crate::stdlib::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 >= crate::squeezelite_h::lINFO as libc::c_int as libc::c_uint
&& err == 0 as libc::c_int
|| loglevel as libc::c_uint >= crate::squeezelite_h::lDEBUG as libc::c_int as libc::c_uint
{
crate::stdlib::fprintf(
crate::stdlib::stderr,
b"%s ALSA %s:%d \x00" as *const u8 as *const libc::c_char,
crate::src::utils::logtime(),
function,
line,
);
args_0 = args.clone();
crate::stdlib::vfprintf(crate::stdlib::stderr, fmt, args_0.as_va_list());
crate::stdlib::fprintf(
crate::stdlib::stderr,
b"\n\x00" as *const u8 as *const libc::c_char,
);
crate::stdlib::fflush(crate::stdlib::stderr);
}
return 0 as *mut libc::c_void;
}
unsafe extern "C" fn alsa_close() {
let mut err: libc::c_int = 0;
err = crate::stdlib::snd_pcm_close(pcmp);
if err < 0 as libc::c_int {
if loglevel as libc::c_uint >= crate::squeezelite_h::lINFO as libc::c_int as libc::c_uint {
crate::src::utils::logprint(
b"%s %s:%d snd_pcm_close error: %s\n\x00" as *const u8 as *const libc::c_char,
crate::src::utils::logtime(),
(*::std::mem::transmute::<&[u8; 11], &[libc::c_char; 11]>(b"alsa_close\x00"))
.as_ptr(),
268 as libc::c_int,
crate::stdlib::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 = 0 as *mut crate::stdlib::snd_pcm_t;
let mut hw_params = 0 as *mut crate::stdlib::snd_pcm_hw_params_t;
let mut fresh1 = ::std::vec::from_elem(0, crate::stdlib::snd_pcm_hw_params_sizeof() as usize);
hw_params = fresh1.as_mut_ptr() as *mut crate::stdlib::snd_pcm_hw_params_t;
crate::stdlib::memset(
hw_params as *mut libc::c_void,
0 as libc::c_int,
crate::stdlib::snd_pcm_hw_params_sizeof(),
);
// open device
err = crate::stdlib::snd_pcm_open(
&mut pcm,
device,
crate::stdlib::SND_PCM_STREAM_PLAYBACK,
0 as libc::c_int,
);
if err < 0 as libc::c_int {
crate::src::utils::logprint(
b"%s %s:%d playback open error: %s\n\x00" as *const u8 as *const libc::c_char,
crate::src::utils::logtime(),
(*::std::mem::transmute::<&[u8; 10], &[libc::c_char; 10]>(b"test_open\x00")).as_ptr(),
281 as libc::c_int,
crate::stdlib::snd_strerror(err),
);
return 0 as libc::c_int != 0;
}
// get max params
err = crate::stdlib::snd_pcm_hw_params_any(pcm, hw_params);
if err < 0 as libc::c_int {
crate::src::utils::logprint(
b"%s %s:%d hwparam init error: %s\n\x00" as *const u8 as *const libc::c_char,
crate::src::utils::logtime(),
(*::std::mem::transmute::<&[u8; 10], &[libc::c_char; 10]>(b"test_open\x00")).as_ptr(),
287 as libc::c_int,
crate::stdlib::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 crate::stdlib::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 = crate::stdlib::snd_pcm_close(pcm);
if err < 0 as libc::c_int {
crate::src::utils::logprint(
b"%s %s:%d snd_pcm_close error: %s\n\x00" as *const u8 as *const libc::c_char,
crate::src::utils::logtime(),
(*::std::mem::transmute::<&[u8; 10], &[libc::c_char; 10]>(b"test_open\x00")).as_ptr(),
304 as libc::c_int,
crate::stdlib::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 = 0 as *mut crate::stdlib::snd_pcm_t;
err = crate::stdlib::snd_pcm_open(
&mut pcm,
device,
crate::stdlib::SND_PCM_STREAM_PLAYBACK,
0 as libc::c_int,
);
if err < 0 as libc::c_int {
return 0 as libc::c_int != 0;
}
err = crate::stdlib::snd_pcm_close(pcm);
if err < 0 as libc::c_int {
crate::src::utils::logprint(
b"%s %s:%d snd_pcm_close error: %s\n\x00" as *const u8 as *const libc::c_char,
crate::src::utils::logtime(),
(*::std::mem::transmute::<&[u8; 10], &[libc::c_char; 10]>(b"pcm_probe\x00")).as_ptr(),
320 as libc::c_int,
crate::stdlib::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 = 0 as *mut crate::stdlib::snd_pcm_hw_params_t;
let mut fresh3 = ::std::vec::from_elem(0, crate::stdlib::snd_pcm_hw_params_sizeof() as usize);
hw_params = fresh3.as_mut_ptr() as *mut crate::stdlib::snd_pcm_hw_params_t;
crate::stdlib::memset(
hw_params as *mut libc::c_void,
0 as libc::c_int,
crate::stdlib::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 crate::stdlib::snd_pcm_uframes_t;
crate::stdlib::strcpy(alsa.device.as_mut_ptr(), device);
if crate::stdlib::strlen(device)
> (128 as libc::c_int - 4 as libc::c_int - 1 as libc::c_int) as libc::c_ulong
{
crate::src::utils::logprint(
b"%s %s:%d device name too long: %s\n\x00" as *const u8 as *const libc::c_char,
crate::src::utils::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 >= crate::squeezelite_h::lINFO as libc::c_int as libc::c_uint {
crate::src::utils::logprint(
b"%s %s:%d opening device at: %u\n\x00" as *const u8 as *const libc::c_char,
crate::src::utils::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 = crate::stdlib::snd_pcm_open(
&mut pcmp,
alsa.device.as_mut_ptr(),
crate::stdlib::SND_PCM_STREAM_PLAYBACK,
0 as libc::c_int,
);
if err < 0 as libc::c_int {
crate::src::utils::logprint(
b"%s %s:%d playback open error: %s\n\x00" as *const u8 as *const libc::c_char,
crate::src::utils::logtime(),
(*::std::mem::transmute::<&[u8; 10], &[libc::c_char; 10]>(b"alsa_open\x00"))
.as_ptr(),
357 as libc::c_int,
crate::stdlib::snd_strerror(err),
);
return err;
}
// init params
crate::stdlib::memset(
hw_params as *mut libc::c_void,
0 as libc::c_int,
crate::stdlib::snd_pcm_hw_params_sizeof(),
);
err = crate::stdlib::snd_pcm_hw_params_any(pcmp, hw_params);
if err < 0 as libc::c_int {
crate::src::utils::logprint(
b"%s %s:%d hwparam init error: %s\n\x00" as *const u8 as *const libc::c_char,
crate::src::utils::logtime(),
(*::std::mem::transmute::<&[u8; 10], &[libc::c_char; 10]>(b"alsa_open\x00"))
.as_ptr(),
364 as libc::c_int,
crate::stdlib::snd_strerror(err),
);
return err;
}
// open hw: devices without resampling, if sample rate fails try plughw: with resampling
let mut hw = crate::stdlib::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 = crate::stdlib::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 {
crate::src::utils::logprint(
b"%s %s:%d resampling setup failed: %s\n\x00" as *const u8 as *const libc::c_char,
crate::src::utils::logtime(),
(*::std::mem::transmute::<&[u8; 10], &[libc::c_char; 10]>(b"alsa_open\x00"))
.as_ptr(),
373 as libc::c_int,
crate::stdlib::snd_strerror(err),
);
return err;
}
err = crate::stdlib::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 {
crate::stdlib::strcpy(
alsa.device.as_mut_ptr().offset(4 as libc::c_int as isize),
device,
);
crate::stdlib::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
>= crate::squeezelite_h::lINFO as libc::c_int as libc::c_uint
{
crate::src::utils::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,
crate::src::utils::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(),
);
}
crate::stdlib::snd_pcm_close(pcmp);
retry = 1 as libc::c_int != 0
}
}
if !retry {
break;
}
}
// set access
if !alsa.mmap
|| crate::stdlib::snd_pcm_hw_params_set_access(
pcmp,
hw_params,
crate::stdlib::SND_PCM_ACCESS_MMAP_INTERLEAVED,
) < 0 as libc::c_int
{
err = crate::stdlib::snd_pcm_hw_params_set_access(
pcmp,
hw_params,
crate::stdlib::SND_PCM_ACCESS_RW_INTERLEAVED,
);
if err < 0 as libc::c_int {
crate::src::utils::logprint(
b"%s %s:%d access type not available: %s\n\x00" as *const u8 as *const libc::c_char,
crate::src::utils::logtime(),
(*::std::mem::transmute::<&[u8; 10], &[libc::c_char; 10]>(b"alsa_open\x00"))
.as_ptr(),
392 as libc::c_int,
crate::stdlib::snd_strerror(err),
);
return err;
}
alsa.mmap = 0 as libc::c_int != 0
}
// set the sample format
let mut fmt = if alsa.format as libc::c_int != 0 {
&mut alsa.format
} else {
fmts.as_mut_ptr()
};
loop {
if crate::stdlib::snd_pcm_hw_params_set_format(pcmp, hw_params, *fmt) >= 0 as libc::c_int {
if loglevel as libc::c_uint
>= crate::squeezelite_h::lINFO as libc::c_int as libc::c_uint
{
crate::src::utils::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,
crate::src::utils::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(),
crate::stdlib::snd_pcm_format_name(*fmt),
sample_rate,
alsa.mmap as libc::c_int,
);
}
alsa.format = *fmt;
break;
} else {
if alsa.format as u64 != 0 {
crate::src::utils::logprint(
b"%s %s:%d unable to open audio device requested format: %s\n\x00" as *const u8
as *const libc::c_char,
crate::src::utils::logtime(),
(*::std::mem::transmute::<&[u8; 10], &[libc::c_char; 10]>(b"alsa_open\x00"))
.as_ptr(),
427 as libc::c_int,
crate::stdlib::snd_pcm_format_name(alsa.format),
);
return -(1 as libc::c_int);
}
fmt = fmt.offset(1);
if *fmt as libc::c_int == crate::stdlib::SND_PCM_FORMAT_UNKNOWN as libc::c_int {
crate::src::utils::logprint(
b"%s %s:%d unable to open audio device with any supported format\n\x00"
as *const u8 as *const libc::c_char,
crate::src::utils::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 != crate::stdlib::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 = crate::squeezelite_h::S32_LE,
6 => output.format = crate::squeezelite_h::S24_LE,
32 => output.format = crate::squeezelite_h::S24_3LE,
2 => output.format = crate::squeezelite_h::S16_LE,
_ => {}
}
// set channels
err = crate::stdlib::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 {
crate::src::utils::logprint(
b"%s %s:%d channel count not available: %s\n\x00" as *const u8 as *const libc::c_char,
crate::src::utils::logtime(),
(*::std::mem::transmute::<&[u8; 10], &[libc::c_char; 10]>(b"alsa_open\x00")).as_ptr(),
465 as libc::c_int,
crate::stdlib::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 = alsa_period;
err = crate::stdlib::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 {
crate::src::utils::logprint(
b"%s %s:%d unable to set period count %s\n\x00" as *const u8 as *const libc::c_char,
crate::src::utils::logtime(),
(*::std::mem::transmute::<&[u8; 10], &[libc::c_char; 10]>(b"alsa_open\x00"))
.as_ptr(),
473 as libc::c_int,
crate::stdlib::snd_strerror(err),
);
return err;
}
} else {
let mut size = alsa_period as crate::stdlib::snd_pcm_uframes_t;
let mut dir = 0 as libc::c_int;
err = crate::stdlib::snd_pcm_hw_params_set_period_size_near(
pcmp, hw_params, &mut size, &mut dir,
);
if err < 0 as libc::c_int {
crate::src::utils::logprint(
b"%s %s:%d unable to set period size %s\n\x00" as *const u8 as *const libc::c_char,
crate::src::utils::logtime(),
(*::std::mem::transmute::<&[u8; 10], &[libc::c_char; 10]>(b"alsa_open\x00"))
.as_ptr(),
480 as libc::c_int,
crate::stdlib::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 = alsa_buffer.wrapping_mul(1000 as libc::c_int as libc::c_uint);
let mut dir_0 = 0 as libc::c_int;
err = crate::stdlib::snd_pcm_hw_params_set_buffer_time_near(
pcmp, hw_params, &mut time, &mut dir_0,
);
if err < 0 as libc::c_int {
crate::src::utils::logprint(
b"%s %s:%d unable to set buffer time %s\n\x00" as *const u8 as *const libc::c_char,
crate::src::utils::logtime(),
(*::std::mem::transmute::<&[u8; 10], &[libc::c_char; 10]>(b"alsa_open\x00"))
.as_ptr(),
490 as libc::c_int,
crate::stdlib::snd_strerror(err),
);
return err;
}
} else {
let mut size_0 = alsa_buffer as crate::stdlib::snd_pcm_uframes_t;
err = crate::stdlib::snd_pcm_hw_params_set_buffer_size_near(pcmp, hw_params, &mut size_0);
if err < 0 as libc::c_int {
crate::src::utils::logprint(
b"%s %s:%d unable to set buffer size %s\n\x00" as *const u8 as *const libc::c_char,
crate::src::utils::logtime(),
(*::std::mem::transmute::<&[u8; 10], &[libc::c_char; 10]>(b"alsa_open\x00"))
.as_ptr(),
496 as libc::c_int,
crate::stdlib::snd_strerror(err),
);
return err;
}
}
// get period_size
err = crate::stdlib::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 {
crate::src::utils::logprint(
b"%s %s:%d unable to get period size: %s\n\x00" as *const u8 as *const libc::c_char,
crate::src::utils::logtime(),
(*::std::mem::transmute::<&[u8; 10], &[libc::c_char; 10]>(b"alsa_open\x00")).as_ptr(),
503 as libc::c_int,
crate::stdlib::snd_strerror(err),
);
return err;
}
// get buffer_size
err = crate::stdlib::snd_pcm_hw_params_get_buffer_size(hw_params, &mut alsa.buffer_size);
if err < 0 as libc::c_int {
crate::src::utils::logprint(
b"%s %s:%d unable to get buffer size: %s\n\x00" as *const u8 as *const libc::c_char,
crate::src::utils::logtime(),
(*::std::mem::transmute::<&[u8; 10], &[libc::c_char; 10]>(b"alsa_open\x00")).as_ptr(),
509 as libc::c_int,
crate::stdlib::snd_strerror(err),
);
return err;
}
if loglevel as libc::c_uint >= crate::squeezelite_h::lINFO as libc::c_int as libc::c_uint {
crate::src::utils::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,
crate::src::utils::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 != crate::stdlib::SND_PCM_FORMAT_S32_LE as libc::c_int
{
alsa.write_buf = crate::stdlib::malloc(
alsa.buffer_size
.wrapping_mul(8 as libc::c_int as libc::c_ulong),
) as *mut crate::squeezelite_h::u8_t;
if alsa.write_buf.is_null() {
crate::src::utils::logprint(
b"%s %s:%d unable to malloc write_buf\n\x00" as *const u8 as *const libc::c_char,
crate::src::utils::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 = crate::stdlib::snd_pcm_hw_params(pcmp, hw_params);
if err < 0 as libc::c_int {
crate::src::utils::logprint(
b"%s %s:%d unable to set hw params: %s\n\x00" as *const u8 as *const libc::c_char,
crate::src::utils::logtime(),
(*::std::mem::transmute::<&[u8; 10], &[libc::c_char; 10]>(b"alsa_open\x00")).as_ptr(),
530 as libc::c_int,
crate::stdlib::snd_strerror(err),
);
return err;
}
// dump info
if loglevel as libc::c_uint == crate::squeezelite_h::lSDEBUG as libc::c_int as libc::c_uint {
static mut debug_output: *mut crate::stdlib::snd_output_t =
0 as *const crate::stdlib::snd_output_t as *mut crate::stdlib::snd_output_t;
crate::stdlib::snd_output_stdio_attach(
&mut debug_output,
crate::stdlib::stderr,
0 as libc::c_int,
);
crate::stdlib::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: crate::squeezelite_h::frames_t,
mut silence: bool,
mut gainL: crate::squeezelite_h::s32_t,
mut gainR: crate::squeezelite_h::s32_t,
mut cross_gain_in: crate::squeezelite_h::s32_t,
mut cross_gain_out: crate::squeezelite_h::s32_t,
mut cross_ptr: *mut *mut crate::squeezelite_h::s32_t,
) -> libc::c_int {
let mut areas = 0 as *const crate::stdlib::snd_pcm_channel_area_t;
let mut offset: crate::stdlib::snd_pcm_uframes_t = 0;
let mut outputptr = 0 as *mut libc::c_void;
let mut inputptr = 0 as *mut crate::squeezelite_h::s32_t;
let mut err: libc::c_int = 0;
if alsa.mmap {
let mut alsa_frames = out_frames as crate::stdlib::snd_pcm_uframes_t;
crate::stdlib::snd_pcm_avail_update(pcmp);
err = crate::stdlib::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
>= crate::squeezelite_h::lWARN as libc::c_int as libc::c_uint
{
crate::src::utils::logprint(
b"%s %s:%d error from mmap_begin: %s\n\x00" as *const u8 as *const libc::c_char,
crate::src::utils::logtime(),
(*::std::mem::transmute::<&[u8; 14], &[libc::c_char; 14]>(
b"_write_frames\x00",
))
.as_ptr(),
565 as libc::c_int,
crate::stdlib::snd_strerror(err),
);
}
return -(1 as libc::c_int);
}
out_frames = alsa_frames as crate::squeezelite_h::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
== crate::squeezelite_h::FADE_ACTIVE as libc::c_int as libc::c_uint
&& output.fade_dir as libc::c_uint
== crate::squeezelite_h::FADE_CROSS as libc::c_int as libc::c_uint
&& !(*cross_ptr).is_null()
{
crate::squeezelite_h::_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 crate::squeezelite_h::s32_t;
if alsa.mmap as libc::c_int != 0
|| alsa.format as libc::c_int != crate::stdlib::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
};
crate::src::output_pack::_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 {
crate::squeezelite_h::_apply_gain(outputbuf, out_frames, gainL, gainR);
}
}
}
if alsa.mmap {
let mut w = crate::stdlib::snd_pcm_mmap_commit(
pcmp,
offset,
out_frames as crate::stdlib::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
>= crate::squeezelite_h::lWARN as libc::c_int as libc::c_uint
{
crate::src::utils::logprint(
b"%s %s:%d mmap_commit error\n\x00" as *const u8 as *const libc::c_char,
crate::src::utils::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 = crate::stdlib::snd_pcm_writei(
pcmp,
outputptr,
out_frames as crate::stdlib::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 = crate::stdlib::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
>= crate::squeezelite_h::lWARN as libc::c_int as libc::c_uint
{
recover_count = recover_count.wrapping_add(1);
crate::src::utils::logprint(
b"%s %s:%d recover failed: %s [%u]\n\x00" as *const u8
as *const libc::c_char,
crate::src::utils::logtime(),
(*::std::mem::transmute::<&[u8; 14], &[libc::c_char; 14]>(
b"_write_frames\x00",
))
.as_ptr(),
626 as libc::c_int,
crate::stdlib::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 crate::stdlib::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
>= crate::squeezelite_h::lWARN as libc::c_int as libc::c_uint
{
crate::src::utils::logprint(
b"%s %s:%d writei only wrote %u of %u\n\x00" as *const u8
as *const libc::c_char,
crate::src::utils::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 crate::squeezelite_h::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 = 1 as libc::c_int != 0;
let mut output_off =
output.state as libc::c_int == crate::squeezelite_h::OUTPUT_OFF as libc::c_int;
let mut probe_device = !arg.is_null();
let mut err: libc::c_int = 0;
while running {
// disabled output - player is off
while output_off {
crate::stdlib::usleep(100000 as libc::c_int as crate::stdlib::__useconds_t);
crate::stdlib::pthread_mutex_lock(&mut (*outputbuf).mutex);
output_off =
output.state as libc::c_int == crate::squeezelite_h::OUTPUT_OFF as libc::c_int;
crate::stdlib::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
>= crate::squeezelite_h::lDEBUG as libc::c_int as libc::c_uint
{
crate::src::utils::logprint(
b"%s %s:%d waiting for device %s to return\n\x00" as *const u8
as *const libc::c_char,
crate::src::utils::logtime(),
(*::std::mem::transmute::<&[u8; 14], &[libc::c_char; 14]>(
b"output_thread\x00",
))
.as_ptr(),
665 as libc::c_int,
output.device,
);
}
crate::stdlib::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
>= crate::squeezelite_h::lINFO as libc::c_int as libc::c_uint
{
crate::src::utils::logprint(
b"%s %s:%d open output device: %s\n\x00" as *const u8 as *const libc::c_char,
crate::src::utils::logtime(),
(*::std::mem::transmute::<&[u8; 14], &[libc::c_char; 14]>(
b"output_thread\x00",
))
.as_ptr(),
687 as libc::c_int,
output.device,
);
}
crate::stdlib::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;
crate::stdlib::pthread_mutex_unlock(&mut (*outputbuf).mutex);
crate::stdlib::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;
crate::stdlib::pthread_mutex_unlock(&mut (*outputbuf).mutex);
}
}
let mut state = crate::stdlib::snd_pcm_state(pcmp);
if state as libc::c_uint == crate::stdlib::SND_PCM_STATE_XRUN as libc::c_int as libc::c_uint
{
if loglevel as libc::c_uint
>= crate::squeezelite_h::lINFO as libc::c_int as libc::c_uint
{
crate::src::utils::logprint(
b"%s %s:%d XRUN\n\x00" as *const u8 as *const libc::c_char,
crate::src::utils::logtime(),
(*::std::mem::transmute::<&[u8; 14], &[libc::c_char; 14]>(
b"output_thread\x00",
))
.as_ptr(),
717 as libc::c_int,
);
}
err = crate::stdlib::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
>= crate::squeezelite_h::lINFO as libc::c_int as libc::c_uint
{
crate::src::utils::logprint(
b"%s %s:%d XRUN recover failed: %s\n\x00" as *const u8
as *const libc::c_char,
crate::src::utils::logtime(),
(*::std::mem::transmute::<&[u8; 14], &[libc::c_char; 14]>(
b"output_thread\x00",
))
.as_ptr(),
719 as libc::c_int,
crate::stdlib::snd_strerror(err),
);
}
}
start = 1 as libc::c_int != 0
} else {
if state as libc::c_uint
== crate::stdlib::SND_PCM_STATE_SUSPENDED as libc::c_int as libc::c_uint
{
err = crate::stdlib::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
>= crate::squeezelite_h::lINFO as libc::c_int as libc::c_uint
{
crate::src::utils::logprint(
b"%s %s:%d SUSPEND recover failed: %s\n\x00" as *const u8
as *const libc::c_char,
crate::src::utils::logtime(),
(*::std::mem::transmute::<&[u8; 14], &[libc::c_char; 14]>(
b"output_thread\x00",
))
.as_ptr(),
725 as libc::c_int,
crate::stdlib::snd_strerror(err),
);
}
}
} else if state as libc::c_uint
== crate::stdlib::SND_PCM_STATE_DISCONNECTED as libc::c_int as libc::c_uint
{
if loglevel as libc::c_uint
>= crate::squeezelite_h::lINFO as libc::c_int as libc::c_uint
{
crate::src::utils::logprint(
b"%s %s:%d Device %s no longer available\n\x00" as *const u8
as *const libc::c_char,
crate::src::utils::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 crate::stdlib::snd_pcm_t;
probe_device = 1 as libc::c_int != 0;
continue;
}
let mut avail = crate::stdlib::snd_pcm_avail_update(pcmp);
if avail < 0 as libc::c_int as libc::c_long {
err = crate::stdlib::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
>= crate::squeezelite_h::lINFO as libc::c_int as libc::c_uint
{
crate::src::utils::logprint(
b"%s %s:%d Device %s no longer available\n\x00" as *const u8
as *const libc::c_char,
crate::src::utils::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 crate::stdlib::snd_pcm_t;
probe_device = 1 as libc::c_int != 0;
continue;
} else if loglevel as libc::c_uint
>= crate::squeezelite_h::lWARN as libc::c_int as libc::c_uint
{
crate::src::utils::logprint(
b"%s %s:%d recover failed: %s\n\x00" as *const u8
as *const libc::c_char,
crate::src::utils::logtime(),
(*::std::mem::transmute::<&[u8; 14], &[libc::c_char; 14]>(
b"output_thread\x00",
))
.as_ptr(),
746 as libc::c_int,
crate::stdlib::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 = crate::stdlib::snd_pcm_start(pcmp);
(err) < 0 as libc::c_int
} {
err = crate::stdlib::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
>= crate::squeezelite_h::lINFO as libc::c_int as libc::c_uint
{
crate::src::utils::logprint(
b"%s %s:%d Device %s no longer available\n\x00" as *const u8
as *const libc::c_char,
crate::src::utils::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 crate::stdlib::snd_pcm_t;
probe_device = 1 as libc::c_int != 0
} else {
if loglevel as libc::c_uint
>= crate::squeezelite_h::lINFO as libc::c_int as libc::c_uint
{
crate::src::utils::logprint(
b"%s %s:%d start error: %s\n\x00" as *const u8
as *const libc::c_char,
crate::src::utils::logtime(),
(*::std::mem::transmute::<&[u8; 14], &[libc::c_char; 14]>(
b"output_thread\x00",
))
.as_ptr(),
763 as libc::c_int,
crate::stdlib::snd_strerror(err),
);
}
crate::stdlib::usleep(
10000 as libc::c_int as crate::stdlib::__useconds_t,
);
}
} else {
start = 0 as libc::c_int != 0
}
} else {
crate::stdlib::usleep(10000 as libc::c_int as crate::stdlib::__useconds_t);
err = crate::stdlib::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
>= crate::squeezelite_h::lINFO as libc::c_int as libc::c_uint
{
crate::src::utils::logprint(
b"%s %s:%d pcm wait timeout\n\x00" as *const u8
as *const libc::c_char,
crate::src::utils::logtime(),
(*::std::mem::transmute::<&[u8; 14], &[libc::c_char; 14]>(
b"output_thread\x00",
))
.as_ptr(),
773 as libc::c_int,
);
}
}
err = crate::stdlib::snd_pcm_recover(pcmp, err, 1 as libc::c_int);
if err < 0 as libc::c_int {
if loglevel as libc::c_uint
>= crate::squeezelite_h::lINFO as libc::c_int as libc::c_uint
{
crate::src::utils::logprint(
b"%s %s:%d pcm wait error: %s\n\x00" as *const u8
as *const libc::c_char,
crate::src::utils::logtime(),
(*::std::mem::transmute::<&[u8; 14], &[libc::c_char; 14]>(
b"output_thread\x00",
))
.as_ptr(),
776 as libc::c_int,
crate::stdlib::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 crate::stdlib::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 crate::stdlib::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
>= crate::squeezelite_h::lSDEBUG as libc::c_int as libc::c_uint
{
crate::src::utils::logprint(
b"%s %s:%d avail 0 - sleeping\n\x00" as *const u8
as *const libc::c_char,
crate::src::utils::logtime(),
(*::std::mem::transmute::<&[u8; 14], &[libc::c_char; 14]>(
b"output_thread\x00",
))
.as_ptr(),
794 as libc::c_int,
);
}
crate::stdlib::usleep(10000 as libc::c_int as crate::stdlib::__useconds_t);
} else {
crate::stdlib::pthread_mutex_lock(&mut (*outputbuf).mutex);
// turn off if requested
if output.state as libc::c_int
== crate::squeezelite_h::OUTPUT_OFF as libc::c_int
{
crate::stdlib::pthread_mutex_unlock(&mut (*outputbuf).mutex);
if loglevel as libc::c_uint
>= crate::squeezelite_h::lINFO as libc::c_int as libc::c_uint
{
crate::src::utils::logprint(
b"%s %s:%d disabling output\n\x00" as *const u8
as *const libc::c_char,
crate::src::utils::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 crate::stdlib::snd_pcm_t;
output_off = 1 as libc::c_int != 0
} else {
// measure output delay
let mut delay: crate::stdlib::snd_pcm_sframes_t = 0;
err = crate::stdlib::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
crate::stdlib::pthread_mutex_unlock(&mut (*outputbuf).mutex);
continue;
} else if err == -(5 as libc::c_int) {
// EIO can occur with non existant pulse server
crate::stdlib::pthread_mutex_unlock(&mut (*outputbuf).mutex);
if loglevel as libc::c_uint
>= crate::squeezelite_h::lSDEBUG as libc::c_int as libc::c_uint
{
crate::src::utils::logprint(
b"%s %s:%d snd_pcm_delay returns: EIO - sleeping\n\x00"
as *const u8
as *const libc::c_char,
crate::src::utils::logtime(),
(*::std::mem::transmute::<&[u8; 14], &[libc::c_char; 14]>(
b"output_thread\x00",
))
.as_ptr(),
833 as libc::c_int,
);
}
crate::stdlib::usleep(
100000 as libc::c_int as crate::stdlib::__useconds_t,
);
continue;
} else if loglevel as libc::c_uint
>= crate::squeezelite_h::lDEBUG as libc::c_int as libc::c_uint
{
crate::src::utils::logprint(
b"%s %s:%d snd_pcm_delay returns: %d\n\x00" as *const u8
as *const libc::c_char,
crate::src::utils::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 = crate::src::utils::gettime_ms();
output.frames_played_dmp = output.frames_played
}
// process frames
let mut wrote = crate::src::output::_output_frames(
avail as crate::squeezelite_h::frames_t,
);
crate::stdlib::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
>= crate::squeezelite_h::lSDEBUG as libc::c_int as libc::c_uint
{
crate::src::utils::logprint(
b"%s %s:%d wrote 0 - sleeping\n\x00" as *const u8
as *const libc::c_char,
crate::src::utils::logtime(),
(*::std::mem::transmute::<&[u8; 14], &[libc::c_char; 14]>(
b"output_thread\x00",
))
.as_ptr(),
852 as libc::c_int,
);
}
crate::stdlib::usleep(
10000 as libc::c_int as crate::stdlib::__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 = 0 as *mut crate::stdlib::snd_mixer_selem_id_t;
err = crate::stdlib::snd_mixer_open(&mut alsa.mixer_handle, 0 as libc::c_int);
if err < 0 as libc::c_int {
crate::src::utils::logprint(
b"%s %s:%d open error: %s\n\x00" as *const u8 as *const libc::c_char,
crate::src::utils::logtime(),
(*::std::mem::transmute::<&[u8; 16], &[libc::c_char; 16]>(b"mixer_init_alsa\x00"))
.as_ptr(),
865 as libc::c_int,
crate::stdlib::snd_strerror(err),
);
return -(1 as libc::c_int);
}
err = crate::stdlib::snd_mixer_attach(alsa.mixer_handle, device);
if err < 0 as libc::c_int {
crate::src::utils::logprint(
b"%s %s:%d attach error: %s\n\x00" as *const u8 as *const libc::c_char,
crate::src::utils::logtime(),
(*::std::mem::transmute::<&[u8; 16], &[libc::c_char; 16]>(b"mixer_init_alsa\x00"))
.as_ptr(),
869 as libc::c_int,
crate::stdlib::snd_strerror(err),
);
crate::stdlib::snd_mixer_close(alsa.mixer_handle);
return -(1 as libc::c_int);
}
err = crate::stdlib::snd_mixer_selem_register(
alsa.mixer_handle,
0 as *mut crate::stdlib::snd_mixer_selem_regopt,
0 as *mut *mut crate::stdlib::snd_mixer_class_t,
);
if err < 0 as libc::c_int {
crate::src::utils::logprint(
b"%s %s:%d register error: %s\n\x00" as *const u8 as *const libc::c_char,
crate::src::utils::logtime(),
(*::std::mem::transmute::<&[u8; 16], &[libc::c_char; 16]>(b"mixer_init_alsa\x00"))
.as_ptr(),
874 as libc::c_int,
crate::stdlib::snd_strerror(err),
);
crate::stdlib::snd_mixer_close(alsa.mixer_handle);
return -(1 as libc::c_int);
}
err = crate::stdlib::snd_mixer_load(alsa.mixer_handle);
if err < 0 as libc::c_int {
crate::src::utils::logprint(
b"%s %s:%d load error: %s\n\x00" as *const u8 as *const libc::c_char,
crate::src::utils::logtime(),
(*::std::mem::transmute::<&[u8; 16], &[libc::c_char; 16]>(b"mixer_init_alsa\x00"))
.as_ptr(),
879 as libc::c_int,
crate::stdlib::snd_strerror(err),
);
crate::stdlib::snd_mixer_close(alsa.mixer_handle);
return -(1 as libc::c_int);
}
let mut fresh4 = ::std::vec::from_elem(0, crate::stdlib::snd_mixer_selem_id_sizeof() as usize);
sid = fresh4.as_mut_ptr() as *mut crate::stdlib::snd_mixer_selem_id_t;
crate::stdlib::memset(
sid as *mut libc::c_void,
0 as libc::c_int,
crate::stdlib::snd_mixer_selem_id_sizeof(),
);
crate::stdlib::snd_mixer_selem_id_set_index(sid, mixer_index as libc::c_uint);
crate::stdlib::snd_mixer_selem_id_set_name(sid, mixer);
alsa.mixer_elem = crate::stdlib::snd_mixer_find_selem(alsa.mixer_handle, sid);
if alsa.mixer_elem.is_null() {
crate::src::utils::logprint(
b"%s %s:%d error find selem %s\n\x00" as *const u8 as *const libc::c_char,
crate::src::utils::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,
);
crate::stdlib::snd_mixer_close(alsa.mixer_handle);
return -(1 as libc::c_int);
}
if crate::stdlib::snd_mixer_selem_has_playback_switch(alsa.mixer_elem) != 0 {
crate::stdlib::snd_mixer_selem_set_playback_switch_all(alsa.mixer_elem, 1 as libc::c_int);
// unmute
}
err = crate::stdlib::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 = crate::stdlib::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 {
crate::src::utils::logprint(
b"%s %s:%d Unable to get volume raw range\n\x00" as *const u8
as *const libc::c_char,
crate::src::utils::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: crate::stdlib::pthread_t = 0;
#[no_mangle]
pub unsafe extern "C" fn output_init_alsa(
mut level: crate::squeezelite_h::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 = 40 as libc::c_int as libc::c_uint;
let mut alsa_period = 4 as libc::c_int as libc::c_uint;
let mut alsa_sample_fmt = 0 as *mut libc::c_char;
let mut alsa_mmap = 1 as libc::c_int != 0;
let mut alsa_reopen = 0 as libc::c_int != 0;
let mut volume_mixer_name =
crate::src::utils::next_param(volume_mixer, ',' as i32 as libc::c_char);
let mut volume_mixer_index =
crate::src::utils::next_param(0 as *mut libc::c_char, ',' as i32 as libc::c_char);
let mut t = crate::src::utils::next_param(params, ':' as i32 as libc::c_char);
let mut c = crate::src::utils::next_param(0 as *mut libc::c_char, ':' as i32 as libc::c_char);
let mut s = crate::src::utils::next_param(0 as *mut libc::c_char, ':' as i32 as libc::c_char);
let mut m = crate::src::utils::next_param(0 as *mut libc::c_char, ':' as i32 as libc::c_char);
let mut r = crate::src::utils::next_param(0 as *mut libc::c_char, ':' as i32 as libc::c_char);
if !t.is_null() {
alsa_buffer = crate::stdlib::atoi(t) as libc::c_uint
}
if !c.is_null() {
alsa_period = crate::stdlib::atoi(c) as libc::c_uint
}
if !s.is_null() {
alsa_sample_fmt = s
}
if !m.is_null() {
alsa_mmap = crate::stdlib::atoi(m) != 0
}
if !r.is_null() {
alsa_reopen = crate::stdlib::atoi(r) != 0
}
loglevel = level;
if loglevel as libc::c_uint >= crate::squeezelite_h::lINFO as libc::c_int as libc::c_uint {
crate::src::utils::logprint(
b"%s %s:%d init output\n\x00" as *const u8 as *const libc::c_char,
crate::src::utils::logtime(),
(*::std::mem::transmute::<&[u8; 17], &[libc::c_char; 17]>(b"output_init_alsa\x00"))
.as_ptr(),
939 as libc::c_int,
);
}
crate::stdlib::memset(
&mut output as *mut crate::squeezelite_h::outputstate as *mut libc::c_void,
0 as libc::c_int,
::std::mem::size_of::<crate::squeezelite_h::outputstate>() as libc::c_ulong,
);
alsa.mmap = alsa_mmap;
alsa.write_buf = 0 as *mut crate::squeezelite_h::u8_t;
alsa.format = crate::stdlib::SND_PCM_FORMAT_S8;
alsa.reopen = alsa_reopen;
alsa.mixer_handle = 0 as *mut crate::stdlib::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 = crate::squeezelite_h::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(
_: crate::squeezelite_h::frames_t,
_: bool,
_: crate::squeezelite_h::s32_t,
_: crate::squeezelite_h::s32_t,
_: crate::squeezelite_h::s32_t,
_: crate::squeezelite_h::s32_t,
_: *mut *mut crate::squeezelite_h::s32_t,
) -> libc::c_int,
);
output.rate_delay = rate_delay;
if !alsa_sample_fmt.is_null() {
if crate::stdlib::strcmp(
alsa_sample_fmt,
b"32\x00" as *const u8 as *const libc::c_char,
) == 0
{
alsa.format = crate::stdlib::SND_PCM_FORMAT_S32_LE
}
if crate::stdlib::strcmp(
alsa_sample_fmt,
b"24\x00" as *const u8 as *const libc::c_char,
) == 0
{
alsa.format = crate::stdlib::SND_PCM_FORMAT_S24_LE
}
if crate::stdlib::strcmp(
alsa_sample_fmt,
b"24_3\x00" as *const u8 as *const libc::c_char,
) == 0
{
alsa.format = crate::stdlib::SND_PCM_FORMAT_S24_3LE
}
if crate::stdlib::strcmp(
alsa_sample_fmt,
b"16\x00" as *const u8 as *const libc::c_char,
) == 0
{
alsa.format = crate::stdlib::SND_PCM_FORMAT_S16_LE
}
}
if loglevel as libc::c_uint >= crate::squeezelite_h::lINFO as libc::c_int as libc::c_uint {
crate::src::utils::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,
crate::src::utils::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,
);
}
crate::stdlib::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,
>,
crate::stdlib::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,
)));
crate::src::output::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() {
crate::stdlib::atoi(volume_mixer_index)
} else {
0 as libc::c_int
}),
) < 0 as libc::c_int
{
crate::src::utils::logprint(
b"%s %s:%d Initialization of mixer failed, reverting to software volume\n\x00"
as *const u8 as *const libc::c_char,
crate::src::utils::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 crate::stdlib::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 crate::stdlib::mlockall(1 as libc::c_int | 2 as libc::c_int) == -(1 as libc::c_int) {
if loglevel as libc::c_uint >= crate::squeezelite_h::lINFO as libc::c_int as libc::c_uint {
crate::src::utils::logprint(
b"%s %s:%d unable to lock memory: %s\n\x00" as *const u8 as *const libc::c_char,
crate::src::utils::logtime(),
(*::std::mem::transmute::<&[u8; 17], &[libc::c_char; 17]>(b"output_init_alsa\x00"))
.as_ptr(),
1003 as libc::c_int,
crate::stdlib::strerror(*crate::stdlib::__errno_location()),
);
}
} else if loglevel as libc::c_uint >= crate::squeezelite_h::lINFO as libc::c_int as libc::c_uint
{
crate::src::utils::logprint(
b"%s %s:%d memory locked\n\x00" as *const u8 as *const libc::c_char,
crate::src::utils::logtime(),
(*::std::mem::transmute::<&[u8; 17], &[libc::c_char; 17]>(b"output_init_alsa\x00"))
.as_ptr(),
1005 as libc::c_int,
);
}
crate::stdlib::mallopt(-(1 as libc::c_int), -(1 as libc::c_int));
crate::stdlib::mallopt(-(4 as libc::c_int), 0 as libc::c_int);
if loglevel as libc::c_uint >= crate::squeezelite_h::lINFO as libc::c_int as libc::c_uint {
crate::src::utils::logprint(
b"%s %s:%d glibc detected using mallopt\n\x00" as *const u8 as *const libc::c_char,
crate::src::utils::logtime(),
(*::std::mem::transmute::<&[u8; 17], &[libc::c_char; 17]>(b"output_init_alsa\x00"))
.as_ptr(),
1011 as libc::c_int,
);
}
crate::src::utils::touch_memory(
silencebuf,
(2048 as libc::c_int * 8 as libc::c_int) as crate::stddef_h::size_t,
);
crate::src::utils::touch_memory((*outputbuf).buf, (*outputbuf).size);
// start output thread
let mut attr = crate::stdlib::pthread_attr_t { __size: [0; 56] };
crate::stdlib::pthread_attr_init(&mut attr);
crate::stdlib::pthread_attr_setstacksize(
&mut attr,
(16384 as libc::c_int + 64 as libc::c_int * 1024 as libc::c_int) as crate::stddef_h::size_t,
);
crate::stdlib::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,
);
crate::stdlib::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 = crate::stdlib::sched_param { sched_priority: 0 };
param.sched_priority = rt_priority as libc::c_int;
if crate::stdlib::pthread_setschedparam(thread, 1 as libc::c_int, &mut param)
!= 0 as libc::c_int
{
if loglevel as libc::c_uint >= crate::squeezelite_h::lDEBUG as libc::c_int as libc::c_uint {
crate::src::utils::logprint(
b"%s %s:%d unable to set output sched fifo: %s\n\x00" as *const u8
as *const libc::c_char,
crate::src::utils::logtime(),
(*::std::mem::transmute::<&[u8; 17], &[libc::c_char; 17]>(b"output_init_alsa\x00"))
.as_ptr(),
1029 as libc::c_int,
crate::stdlib::strerror(*crate::stdlib::__errno_location()),
);
}
} else if loglevel as libc::c_uint
>= crate::squeezelite_h::lDEBUG as libc::c_int as libc::c_uint
{
crate::src::utils::logprint(
b"%s %s:%d set output sched fifo rt: %u\n\x00" as *const u8 as *const libc::c_char,
crate::src::utils::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 >= crate::squeezelite_h::lINFO as libc::c_int as libc::c_uint {
crate::src::utils::logprint(
b"%s %s:%d close output\n\x00" as *const u8 as *const libc::c_char,
crate::src::utils::logtime(),
(*::std::mem::transmute::<&[u8; 18], &[libc::c_char; 18]>(b"output_close_alsa\x00"))
.as_ptr(),
1036 as libc::c_int,
);
}
crate::stdlib::pthread_mutex_lock(&mut (*outputbuf).mutex);
running = 0 as libc::c_int != 0;
crate::stdlib::pthread_mutex_unlock(&mut (*outputbuf).mutex);
crate::stdlib::pthread_join(thread, 0 as *mut *mut libc::c_void);
if !alsa.write_buf.is_null() {
crate::stdlib::free(alsa.write_buf as *mut libc::c_void);
}
if !alsa.ctl.is_null() {
crate::stdlib::free(alsa.ctl as *mut libc::c_void);
}
if !alsa.mixer_ctl.is_null() {
crate::stdlib::free(alsa.mixer_ctl as *mut libc::c_void);
}
if !alsa.mixer_handle.is_null() {
crate::stdlib::snd_mixer_close(alsa.mixer_handle);
}
crate::src::output::output_close_common();
}
// ALSA