1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
//! Bindings to the Linux Bluetooth low-complexity, subband codec (SBC) library.

extern crate failure;
extern crate libsbc_sys as ffi;
extern crate slice_deque;

pub use crate::error::{Error, ErrorKind, Result};

mod error;

use std::io::Read;
use std::mem;

use failure::ResultExt;
use slice_deque::SliceDeque;

// TODO: Tune these buffer sizes
/// Maximum number of samples present in an SBC frame
const MAX_SAMPLES_PER_FRAME: usize = 8196;

const BUFFER_SIZE: usize = MAX_SAMPLES_PER_FRAME * 15;
const REFILL_TRIGGER: usize = MAX_SAMPLES_PER_FRAME * 8;

/// SBC stream decoder that produces frames.
pub struct Decoder<R>
where
    R: Read,
{
    reader: R,
    buffer: SliceDeque<u8>,
    sbc: Box<ffi::sbc_struct>,
}

unsafe impl<R> Send for Decoder<R>
where
        R: Read + Send,
{
}

/// A SBC frame
pub struct Frame {
    /// Decoded audio
    pub data: Vec<i16>,
    /// Sample rate in hertz.
    pub sample_rate: i32,
    /// Number of channels in the frame.
    pub channels: usize,
}

impl<R> Decoder<R>
where
    R: Read,
{

    /// Create a new decoder from the reader.
    pub fn new(reader: R) -> Decoder<R> {
        let mut sbc = unsafe { Box::new(mem::zeroed()) };
        unsafe {
            // TODO: Magic number
            ffi::sbc_init(&mut *sbc, 0);
            // sbc.endian = ffi::SBC_BE as u8;
        };

        Decoder {
            reader,
            buffer: SliceDeque::with_capacity(BUFFER_SIZE),
            sbc,
        }
    }

    /// Decode the next frame from the stream.
    pub fn next_frame(&mut self) -> Result<Frame> {
        loop {
            if self.buffer.len() < REFILL_TRIGGER {
                if self.refill()? == 0 {
                    return Err(Error::eof());
                }
            }

            return self.decode_frame()
        }
    }

    fn decode_frame(&mut self) -> Result<Frame> {
        let mut pcm: Vec<i16> = Vec::with_capacity(MAX_SAMPLES_PER_FRAME);

        let mut num_written: usize = 0;
        let num_read: isize = unsafe {
            ffi::sbc_decode(
                &mut *self.sbc,
                self.buffer.as_ptr() as *const std::os::raw::c_void,
                self.buffer.len(),
                pcm.as_mut_ptr() as *mut std::os::raw::c_void,
                pcm.capacity(),
                &mut num_written,
            ) as _
        };

        let sample_rate = match self.sbc.frequency as u32 {
            ffi::SBC_FREQ_16000 => 16000,
            ffi::SBC_FREQ_32000 => 32000,
            ffi::SBC_FREQ_44100 => 44100,
            ffi::SBC_FREQ_48000 => 48000,
            _ => return Err(ErrorKind::BadDecode.into()),
        };

        let channels = match self.sbc.mode as u32 {
            ffi::SBC_MODE_MONO => 1,
            ffi::SBC_MODE_DUAL_CHANNEL => 2,
            ffi::SBC_MODE_STEREO => 2,
            ffi::SBC_MODE_JOINT_STEREO => 2,
            _ => return Err(ErrorKind::BadDecode.into()),
        };

        if num_written > 0 {
            // Divide by the size of i16
            unsafe { pcm.set_len(num_written / 2) }
        }

        let frame = Frame {
            data: pcm,
            sample_rate,
            channels,
        };

        let current_len = self.buffer.len();
        if num_read < 0 || num_read as usize > current_len {
            return Err(ErrorKind::BadDecode.into());
        }
        let num_read = num_read as usize;

        self.buffer.truncate_front(current_len - num_read);

        if num_written == 0 {
            Err(ErrorKind::NoData.into())
        } else {
            Ok(frame)
        }
    }

    fn refill(&mut self) -> Result<usize> {
        let mut data: [u8; MAX_SAMPLES_PER_FRAME * 5] = [0; MAX_SAMPLES_PER_FRAME * 5];
        let bytes_read = self.reader.read(&mut data).context(ErrorKind::Io)?;
        self.buffer.extend(data.iter());
        Ok(bytes_read)
    }
}