use std;
use libc;
use capi;
use std::os::raw::c_char;
use std::ffi::CStr;
use std::ptr::null;
pub use capi::pa_volume_t as Volume;
pub use capi::PA_VOLUME_NORM as VOLUME_NORM;
pub use capi::PA_VOLUME_MUTED as VOLUME_MUTED;
pub use capi::PA_VOLUME_MAX as VOLUME_MAX;
pub use capi::PA_VOLUME_INVALID as VOLUME_INVALID;
pub type VolumeDB = f64;
#[inline(always)]
pub fn volume_ui_max() -> Volume {
capi::pa_volume_ui_max()
}
pub const DECIBEL_MININFTY: VolumeDB = capi::PA_DECIBEL_MININFTY;
#[repr(C)]
#[derive(Debug, Copy, Clone, Default)]
pub struct CVolume {
pub channels: u8,
pub values: [Volume; ::sample::CHANNELS_MAX],
}
pub const CVOLUME_PRINT_MAX: usize = capi::PA_CVOLUME_SNPRINT_MAX;
pub const CVOLUME_PRINT_DB_MAX: usize = capi::PA_SW_CVOLUME_SNPRINT_DB_MAX;
pub const CVOLUME_PRINT_VERBOSE_MAX: usize = capi::PA_CVOLUME_SNPRINT_VERBOSE_MAX;
pub const VOLUME_PRINT_MAX: usize = capi::PA_VOLUME_SNPRINT_MAX;
pub const VOLUME_PRINT_DB_MAX: usize = capi::PA_SW_VOLUME_SNPRINT_DB_MAX;
pub const VOLUME_PRINT_VERBOSE_MAX: usize = capi::PA_VOLUME_SNPRINT_VERBOSE_MAX;
#[inline(always)]
pub fn volume_is_valid(v: Volume) -> bool {
capi::pa_volume_is_valid(v)
}
#[inline(always)]
pub fn volume_clamp(v: Volume) -> Volume {
capi::pa_clamp_volume(v)
}
pub fn sw_volume_from_db(f: VolumeDB) -> Volume {
unsafe { capi::pa_sw_volume_from_dB(f) }
}
pub fn sw_volume_to_db(v: Volume) -> VolumeDB {
unsafe { capi::pa_sw_volume_to_dB(v) }
}
pub fn sw_volume_from_linear(v: VolumeDB) -> Volume {
unsafe { capi::pa_sw_volume_from_linear(v) }
}
pub fn sw_volume_to_linear(v: Volume) -> VolumeDB {
unsafe { capi::pa_sw_volume_to_linear(v) }
}
pub fn sw_volume_multiply(a: Volume, b: Volume) -> Volume {
unsafe { capi::pa_sw_volume_multiply(a, b) }
}
pub fn sw_volume_divide(a: Volume, b: Volume) -> Volume {
unsafe { capi::pa_sw_volume_divide(a, b) }
}
pub fn print(v: Volume) -> Option<String> {
let tmp = unsafe { libc::malloc(VOLUME_PRINT_MAX) as *mut c_char };
if tmp.is_null() {
return None;
}
unsafe {
capi::pa_volume_snprint(tmp, VOLUME_PRINT_MAX, v);
let ret = Some(CStr::from_ptr(tmp).to_string_lossy().into_owned());
libc::free(tmp as *mut libc::c_void);
ret
}
}
pub fn print_db(v: Volume) -> Option<String> {
let tmp = unsafe { libc::malloc(VOLUME_PRINT_DB_MAX) as *mut c_char };
if tmp.is_null() {
return None;
}
unsafe {
capi::pa_sw_volume_snprint_dB(tmp, VOLUME_PRINT_DB_MAX, v);
let ret = Some(CStr::from_ptr(tmp).to_string_lossy().into_owned());
libc::free(tmp as *mut libc::c_void);
ret
}
}
pub fn print_verbose(v: Volume, print_db: bool) -> Option<String> {
let tmp = unsafe { libc::malloc(VOLUME_PRINT_VERBOSE_MAX) as *mut c_char };
if tmp.is_null() {
return None;
}
unsafe {
capi::pa_volume_snprint_verbose(tmp, VOLUME_PRINT_VERBOSE_MAX, v, print_db as i32);
let ret = Some(CStr::from_ptr(tmp).to_string_lossy().into_owned());
libc::free(tmp as *mut libc::c_void);
ret
}
}
impl CVolume {
pub fn init(&mut self) -> &Self {
unsafe { capi::pa_cvolume_init(std::mem::transmute(&self)) };
self
}
pub fn set(&mut self, channels: u32, v: Volume) -> &Self {
unsafe { capi::pa_cvolume_set(std::mem::transmute(&self), channels, v) };
self
}
pub fn reset(&mut self, channels: u32) -> &Self {
self.set(channels, VOLUME_NORM)
}
pub fn mute(&mut self, channels: u32) -> &Self {
self.set(channels, VOLUME_MUTED)
}
pub fn equal_to(&self, to: &Self) -> bool {
unsafe { capi::pa_cvolume_equal(std::mem::transmute(self), std::mem::transmute(to)) != 0 }
}
pub fn is_muted(&mut self) -> bool {
self.channels_equal_to(VOLUME_MUTED)
}
pub fn is_norm(&mut self) -> bool {
self.channels_equal_to(VOLUME_NORM)
}
pub fn avg(&self) -> Volume {
unsafe { capi::pa_cvolume_avg(std::mem::transmute(self)) }
}
pub fn avg_mask(&self, cm: &::channelmap::Map, mask: Option<::channelmap::PositionMask>
) -> Volume
{
let mask_actual = mask.unwrap_or(::channelmap::POSITION_MASK_ALL);
unsafe { capi::pa_cvolume_avg_mask(std::mem::transmute(self), std::mem::transmute(cm),
mask_actual) }
}
pub fn max(&self) -> Volume {
unsafe { capi::pa_cvolume_max(std::mem::transmute(self)) }
}
pub fn max_mask(&self, cm: &::channelmap::Map, mask: Option<::channelmap::PositionMask>
) -> Volume
{
let mask_actual = mask.unwrap_or(::channelmap::POSITION_MASK_ALL);
unsafe { capi::pa_cvolume_max_mask(std::mem::transmute(self), std::mem::transmute(cm),
mask_actual) }
}
pub fn min(&self) -> Volume {
unsafe { capi::pa_cvolume_min(std::mem::transmute(self)) }
}
pub fn min_mask(&self, cm: &::channelmap::Map, mask: Option<::channelmap::PositionMask>
) -> Volume
{
let mask_actual = mask.unwrap_or(::channelmap::POSITION_MASK_ALL);
unsafe { capi::pa_cvolume_min_mask(std::mem::transmute(self), std::mem::transmute(cm),
mask_actual) }
}
pub fn is_valid(&self) -> bool {
unsafe { capi::pa_cvolume_valid(std::mem::transmute(self)) != 0 }
}
pub fn channels_equal_to(&self, v: Volume) -> bool {
unsafe { capi::pa_cvolume_channels_equal_to(std::mem::transmute(self), v) != 0 }
}
pub fn sw_multiply(&mut self, with: Option<&Self>) -> &mut Self {
match with {
Some(with) => unsafe { capi::pa_sw_cvolume_multiply(
std::mem::transmute(&self), std::mem::transmute(&self),
std::mem::transmute(with)) },
None => unsafe { capi::pa_sw_cvolume_multiply(
std::mem::transmute(&self), std::mem::transmute(&self),
std::mem::transmute(&self)) },
};
self
}
pub fn sw_multiply_scalar(&mut self, with: Volume) -> &mut Self {
unsafe { capi::pa_sw_cvolume_multiply_scalar(std::mem::transmute(&self),
std::mem::transmute(&self), with) };
self
}
pub fn sw_divide(&mut self, with: Option<&Self>) -> &mut Self {
match with {
Some(with) => unsafe { capi::pa_sw_cvolume_divide(
std::mem::transmute(&self), std::mem::transmute(&self),
std::mem::transmute(with)) },
None => unsafe { capi::pa_sw_cvolume_divide(
std::mem::transmute(&self), std::mem::transmute(&self),
std::mem::transmute(&self)) },
};
self
}
pub fn sw_divide_scalar(&mut self, with: Volume) -> &mut Self {
unsafe { capi::pa_sw_cvolume_divide_scalar(std::mem::transmute(&self),
std::mem::transmute(&self), with) };
self
}
pub fn remap(&mut self, from: &::channelmap::Map, to: &::channelmap::Map) -> &mut Self {
unsafe { capi::pa_cvolume_remap(std::mem::transmute(&self),
std::mem::transmute(from), std::mem::transmute(to)) };
self
}
pub fn is_compatible_with_ss(&self, ss: &::sample::Spec) -> bool {
unsafe { capi::pa_cvolume_compatible(std::mem::transmute(self),
std::mem::transmute(ss)) != 0 }
}
pub fn is_compatible_with_cm(&self, cm: &::channelmap::Map) -> bool {
unsafe { capi::pa_cvolume_compatible_with_channel_map(std::mem::transmute(self),
std::mem::transmute(cm)) != 0 }
}
pub fn get_balance(&self, map: &::channelmap::Map) -> f32 {
unsafe { capi::pa_cvolume_get_balance(std::mem::transmute(self), std::mem::transmute(map)) }
}
pub fn set_balance(&mut self, map: &::channelmap::Map, new_balance: f32) -> Option<&mut Self> {
let ptr = unsafe { capi::pa_cvolume_set_balance(std::mem::transmute(&self),
std::mem::transmute(map), new_balance) };
if ptr.is_null() {
return None;
}
Some(self)
}
pub fn get_fade(&self, map: &::channelmap::Map) -> f32 {
unsafe { capi::pa_cvolume_get_fade(std::mem::transmute(self), std::mem::transmute(map)) }
}
pub fn set_fade(&mut self, map: &::channelmap::Map, new_fade: f32) -> Option<&mut Self>{
let ptr = unsafe { capi::pa_cvolume_set_fade(std::mem::transmute(&self),
std::mem::transmute(map), new_fade) };
if ptr.is_null() {
return None;
}
Some(self)
}
pub fn get_lfe_balance(&self, map: &::channelmap::Map) -> f32 {
unsafe { capi::pa_cvolume_get_lfe_balance(std::mem::transmute(self),
std::mem::transmute(map)) }
}
pub fn set_lfe_balance(&mut self, map: &::channelmap::Map, new_balance: f32
) -> Option<&mut Self>
{
let ptr = unsafe { capi::pa_cvolume_set_lfe_balance(std::mem::transmute(&self),
std::mem::transmute(map), new_balance) };
if ptr.is_null() {
return None;
}
Some(self)
}
pub fn scale(&mut self, max: Volume) -> Option<&mut Self> {
let ptr = unsafe { capi::pa_cvolume_scale(std::mem::transmute(&self), max) };
if ptr.is_null() {
return None;
}
Some(self)
}
pub fn scale_mask(&mut self, max: Volume, cm: &mut ::channelmap::Map,
mask: Option<::channelmap::PositionMask>) -> Option<&mut Self>
{
let mask_actual = mask.unwrap_or(::channelmap::POSITION_MASK_ALL);
let ptr = unsafe { capi::pa_cvolume_scale_mask(std::mem::transmute(&self), max,
std::mem::transmute(cm), mask_actual) };
if ptr.is_null() {
return None;
}
Some(self)
}
pub fn set_position(&mut self, map: &::channelmap::Map, t: ::channelmap::Position, v: Volume
) -> Option<&mut Self>
{
let ptr = unsafe { capi::pa_cvolume_set_position(std::mem::transmute(&self),
std::mem::transmute(map), t.into(), v) };
if ptr.is_null() {
return None;
}
Some(self)
}
pub fn get_position(&mut self, map: &::channelmap::Map, t: ::channelmap::Position) -> Volume {
unsafe { capi::pa_cvolume_get_position(std::mem::transmute(self), std::mem::transmute(map),
t.into()) }
}
pub fn merge(&mut self, with: &Self) -> Option<&mut Self> {
let ptr = unsafe { capi::pa_cvolume_merge(std::mem::transmute(&self),
std::mem::transmute(&self), std::mem::transmute(with)) };
if ptr.is_null() {
return None;
}
Some(self)
}
pub fn inc_clamp(&mut self, inc: Volume, limit: Volume) -> Option<&mut Self> {
let ptr = unsafe { capi::pa_cvolume_inc_clamp(std::mem::transmute(&self), inc, limit) };
if ptr.is_null() {
return None;
}
Some(self)
}
pub fn inc(&mut self, inc: Volume) -> Option<&mut Self> {
let ptr = unsafe { capi::pa_cvolume_inc(std::mem::transmute(&self), inc) };
if ptr.is_null() {
return None;
}
Some(self)
}
pub fn dec(&mut self, dec: Volume) -> Option<&mut Self> {
let ptr = unsafe { capi::pa_cvolume_dec(std::mem::transmute(&self), dec) };
if ptr.is_null() {
return None;
}
Some(self)
}
pub fn print(&self) -> Option<String> {
let tmp = unsafe { libc::malloc(CVOLUME_PRINT_MAX) as *mut c_char };
if tmp.is_null() {
return None;
}
unsafe {
capi::pa_cvolume_snprint(tmp, CVOLUME_PRINT_MAX, std::mem::transmute(self));
let ret = Some(CStr::from_ptr(tmp).to_string_lossy().into_owned());
libc::free(tmp as *mut libc::c_void);
ret
}
}
pub fn print_db(&self) -> Option<String> {
let tmp = unsafe { libc::malloc(CVOLUME_PRINT_DB_MAX) as *mut c_char };
if tmp.is_null() {
return None;
}
unsafe {
capi::pa_sw_cvolume_snprint_dB(tmp, CVOLUME_PRINT_DB_MAX, std::mem::transmute(self));
let ret = Some(CStr::from_ptr(tmp).to_string_lossy().into_owned());
libc::free(tmp as *mut libc::c_void);
ret
}
}
pub fn print_verbose(&self, map: Option<&::channelmap::Map>, print_db: bool) -> Option<String> {
let p_map: *const capi::pa_channel_map = match map {
Some(map) => unsafe { std::mem::transmute(map) },
None => null::<capi::pa_channel_map>(),
};
let tmp = unsafe { libc::malloc(CVOLUME_PRINT_VERBOSE_MAX) as *mut c_char };
if tmp.is_null() {
return None;
}
unsafe {
capi::pa_cvolume_snprint_verbose(tmp, CVOLUME_PRINT_VERBOSE_MAX,
std::mem::transmute(self), p_map, print_db as i32);
let ret = Some(CStr::from_ptr(tmp).to_string_lossy().into_owned());
libc::free(tmp as *mut libc::c_void);
ret
}
}
}