use jack_sys;
use std::ffi::CStr;
use std::marker::PhantomData;
use std::slice;
use std::str::FromStr;
use num;
use midi::*;
use types::*;
use callbackhandler::*;
type Jackptr = *mut jack_sys::jack_port_t;
pub trait Port {
#[doc(hidden)]
fn new(c_port: Jackptr) -> Self;
#[doc(hidden)]
unsafe fn get_raw(&self) -> Jackptr;
fn get_name(&self) -> String {
unsafe {
let raw = self.get_raw();
let cstr = jack_sys::jack_port_name(raw);
String::from_str(CStr::from_ptr(cstr).to_str().unwrap()).unwrap()
}
}
fn get_port_flags(&self) -> port_flags::PortFlags {
let rawbits = unsafe { jack_sys::jack_port_flags(self.get_raw()) };
port_flags::PortFlags::from_bits(rawbits as u32).unwrap()
}
}
#[derive(Debug, Clone, Copy)]
pub struct UnknownPortHandle {
c_port: Jackptr
}
impl UnknownPortHandle {
pub fn as_input<SampleType>(self) -> Option<InputPortHandle<SampleType>> {
let flags = self.get_port_flags();
if flags.contains(port_flags::PORT_IS_INPUT) {
Some(InputPortHandle::<SampleType>::new(self.c_port))
} else {
None
}
}
pub fn as_output<SampleType>(self) -> Option<OutputPortHandle<SampleType>> {
let flags = self.get_port_flags();
if flags.contains(port_flags::PORT_IS_OUTPUT) {
Some(OutputPortHandle::<SampleType>::new(self.c_port))
} else {
None
}
}
pub unsafe fn force_as_input<SampleType>(self) -> InputPortHandle<SampleType> {
InputPortHandle::<SampleType>::new(self.c_port)
}
pub unsafe fn force_as_output<SampleType>(self) -> OutputPortHandle<SampleType> {
OutputPortHandle::<SampleType>::new(self.c_port)
}
}
impl Port for UnknownPortHandle {
#[doc(hidden)]
fn new(c_port: Jackptr) -> Self {
UnknownPortHandle { c_port: c_port }
}
#[doc(hidden)]
unsafe fn get_raw(&self) -> Jackptr { self.c_port }
}
#[derive(Debug, Clone, Copy)]
pub struct InputPortHandle<SampleType> {
c_port: Jackptr,
phantom: PhantomData<SampleType>,
}
impl<SampleType> Port for InputPortHandle<SampleType> {
#[doc(hidden)]
fn new(c_port: Jackptr) -> Self {
InputPortHandle {
c_port: c_port,
phantom: PhantomData,
}
}
#[doc(hidden)]
unsafe fn get_raw(&self) -> Jackptr { self.c_port }
}
impl<SampleType: num::Num> InputPortHandle<SampleType> {
pub fn get_read_buffer<'a>(&self, nframes: NumFrames, _ctx: &'a CallbackContext)
-> &'a [SampleType]
{
unsafe {
let ptr = jack_sys::jack_port_get_buffer(self.c_port, nframes);
let ptr = ptr as *mut SampleType;
slice::from_raw_parts_mut(ptr, nframes as usize)
}
}
}
impl InputPortHandle<MidiEvent> {
pub fn get_read_buffer<'a>(&self, nframes:NumFrames, _ctx: &'a CallbackContext)
-> MidiEventBuf<'a>
{
unsafe {
let ptr = jack_sys::jack_port_get_buffer(self.c_port, nframes);
MidiEventBuf::new(ptr)
}
}
}
#[derive(Debug, Clone, Copy)]
pub struct OutputPortHandle<SampleType> {
c_port: Jackptr,
phantom: PhantomData<SampleType>
}
impl<SampleType> Port for OutputPortHandle<SampleType> {
#[doc(hidden)]
fn new(c_port: Jackptr) -> Self {
OutputPortHandle {
c_port: c_port,
phantom: PhantomData,
}
}
#[doc(hidden)]
unsafe fn get_raw(&self) -> Jackptr { self.c_port }
}
impl<SampleType> OutputPortHandle<SampleType> {
pub fn get_write_buffer<'a>(&self, nframes: NumFrames, _ctx: &'a CallbackContext)
-> &'a mut [SampleType]
{
unsafe {
let ptr = jack_sys::jack_port_get_buffer(self.c_port, nframes);
let ptr = ptr as *mut SampleType;
slice::from_raw_parts_mut(ptr, nframes as usize)
}
}
}