maudio 0.1.5

Rust bindings to the miniaudio library
Documentation
use maudio_sys::ffi as sys;

use crate::{
    device::device_builder::{
        CaptureDeviceState, DuplexDeviceState, LoopbackDeviceState, PlaybackDeviceState,
    },
    pcm_frames::PcmFormat,
    util::device_notif::DeviceNotificationType,
};

pub(crate) unsafe extern "C" fn device_notification_playback_callback<F: PcmFormat, C>(
    notification: *const sys::ma_device_notification,
) {
    if notification.is_null() {
        return;
    }

    let device = (&*notification).pDevice;
    if device.is_null() {
        return;
    }

    let user_data = (*device).pUserData;
    if user_data.is_null() {
        return;
    }

    let state = user_data.cast::<PlaybackDeviceState<F, C>>();

    let mask = match (&*notification).type_ {
        sys::ma_device_notification_type_ma_device_notification_type_started => {
            DeviceNotificationType::Started.bit()
        }
        sys::ma_device_notification_type_ma_device_notification_type_stopped => {
            DeviceNotificationType::Stopped.bit()
        }
        sys::ma_device_notification_type_ma_device_notification_type_rerouted => {
            DeviceNotificationType::Rerouted.bit()
        }
        sys::ma_device_notification_type_ma_device_notification_type_interruption_began => {
            DeviceNotificationType::InterruptionBegan.bit()
        }
        sys::ma_device_notification_type_ma_device_notification_type_interruption_ended => {
            DeviceNotificationType::InterruptionEnded.bit()
        }
        sys::ma_device_notification_type_ma_device_notification_type_unlocked => {
            DeviceNotificationType::Unlocked.bit()
        }
        _ => 0,
    };

    (*state).state_notif.store_notifications(mask);
}

pub(crate) unsafe extern "C" fn device_notification_capture_callback<F: PcmFormat, C>(
    notification: *const sys::ma_device_notification,
) {
    if notification.is_null() {
        return;
    }

    let device = (&*notification).pDevice;
    if device.is_null() {
        return;
    }

    let user_data = (*device).pUserData;
    if user_data.is_null() {
        return;
    }

    let state = user_data.cast::<CaptureDeviceState<F, C>>();

    let mask = match (&*notification).type_ {
        sys::ma_device_notification_type_ma_device_notification_type_started => {
            DeviceNotificationType::Started.bit()
        }
        sys::ma_device_notification_type_ma_device_notification_type_stopped => {
            DeviceNotificationType::Stopped.bit()
        }
        sys::ma_device_notification_type_ma_device_notification_type_rerouted => {
            DeviceNotificationType::Rerouted.bit()
        }
        sys::ma_device_notification_type_ma_device_notification_type_interruption_began => {
            DeviceNotificationType::InterruptionBegan.bit()
        }
        sys::ma_device_notification_type_ma_device_notification_type_interruption_ended => {
            DeviceNotificationType::InterruptionEnded.bit()
        }
        sys::ma_device_notification_type_ma_device_notification_type_unlocked => {
            DeviceNotificationType::Unlocked.bit()
        }
        _ => 0,
    };

    (*state).state_notif.store_notifications(mask);
}

pub(crate) unsafe extern "C" fn device_notification_duplex_callback<F: PcmFormat, C>(
    notification: *const sys::ma_device_notification,
) {
    if notification.is_null() {
        return;
    }

    let device = (&*notification).pDevice;
    if device.is_null() {
        return;
    }

    let user_data = (*device).pUserData;
    if user_data.is_null() {
        return;
    }

    let state = user_data.cast::<DuplexDeviceState<F, C>>();

    let mask = match (&*notification).type_ {
        sys::ma_device_notification_type_ma_device_notification_type_started => {
            DeviceNotificationType::Started.bit()
        }
        sys::ma_device_notification_type_ma_device_notification_type_stopped => {
            DeviceNotificationType::Stopped.bit()
        }
        sys::ma_device_notification_type_ma_device_notification_type_rerouted => {
            DeviceNotificationType::Rerouted.bit()
        }
        sys::ma_device_notification_type_ma_device_notification_type_interruption_began => {
            DeviceNotificationType::InterruptionBegan.bit()
        }
        sys::ma_device_notification_type_ma_device_notification_type_interruption_ended => {
            DeviceNotificationType::InterruptionEnded.bit()
        }
        sys::ma_device_notification_type_ma_device_notification_type_unlocked => {
            DeviceNotificationType::Unlocked.bit()
        }
        _ => 0,
    };

    (*state).state_notif.store_notifications(mask);
}

pub(crate) unsafe extern "C" fn device_notification_loopback_callback<F: PcmFormat, C>(
    notification: *const sys::ma_device_notification,
) {
    if notification.is_null() {
        return;
    }

    let device = (&*notification).pDevice;
    if device.is_null() {
        return;
    }

    let user_data = (*device).pUserData;
    if user_data.is_null() {
        return;
    }

    let state = user_data.cast::<LoopbackDeviceState<F, C>>();

    let mask = match (&*notification).type_ {
        sys::ma_device_notification_type_ma_device_notification_type_started => {
            DeviceNotificationType::Started.bit()
        }
        sys::ma_device_notification_type_ma_device_notification_type_stopped => {
            DeviceNotificationType::Stopped.bit()
        }
        sys::ma_device_notification_type_ma_device_notification_type_rerouted => {
            DeviceNotificationType::Rerouted.bit()
        }
        sys::ma_device_notification_type_ma_device_notification_type_interruption_began => {
            DeviceNotificationType::InterruptionBegan.bit()
        }
        sys::ma_device_notification_type_ma_device_notification_type_interruption_ended => {
            DeviceNotificationType::InterruptionEnded.bit()
        }
        sys::ma_device_notification_type_ma_device_notification_type_unlocked => {
            DeviceNotificationType::Unlocked.bit()
        }
        _ => 0,
    };

    (*state).state_notif.store_notifications(mask);
}