2391 lines
101 KiB
Rust
2391 lines
101 KiB
Rust
|
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
|