1mod error;
2
3pub use error::Error;
4use libc::{c_int, c_long};
5use mpg123_sys as mpg123;
6use std::error::Error as StdError;
7use std::ffi;
8use std::ops::Drop;
9use std::ptr;
10use std::sync::Once;
11
12static INIT: Once = Once::new();
13
14#[derive(Debug)]
15pub struct Format {
16 pub rate: i64,
17 pub channels: i32,
18 pub encoding: i32,
19}
20
21impl Default for Format {
22 fn default() -> Format {
23 Format {
24 rate: 0,
25 channels: 0,
26 encoding: 0,
27 }
28 }
29}
30
31pub struct Decoder {
32 mh: *mut mpg123::mpg123_handle,
33 format: Format,
34}
35
36impl Decoder {
37 pub fn new(filename: &str, params: Option<c_long>) -> Result<Decoder, Box<StdError>> {
38 unsafe {
39 init()?;
40
41 let mut res = 0;
42 let mh = mpg123::mpg123_new(ptr::null(), &mut res);
43 if res != mpg123::MPG123_OK as c_int || mh.is_null() {
44 return Err(Box::from("failed to instantiate mpg123"));
45 }
46
47 if let Some(flags) = params {
48 if mpg123::mpg123_param(mh, mpg123::MPG123_FLAGS, flags, 0.)
49 != mpg123::MPG123_OK as c_int
50 {
51 return Err(Box::from("failed to set parameters"));
52 }
53 }
54
55 let mut decoder = Decoder {
56 mh,
57 format: Format::default(),
58 };
59
60 decoder.open(filename)?;
61 decoder.get_format()?;
62
63 Ok(decoder)
64 }
65 }
66
67 fn open(&self, filename: &str) -> Result<(), Box<StdError>> {
68 let fname = ffi::CString::new(filename)?;
69
70 unsafe {
71 if mpg123::mpg123_open(self.mh, fname.as_ptr()) != mpg123::MPG123_OK as c_int {
72 return Err(Box::from(format!("failed to open `{}`", filename)));
73 }
74 }
75
76 Ok(())
77 }
78
79 fn get_format(&mut self) -> Result<(), Box<StdError>> {
80 unsafe {
81 if mpg123::mpg123_getformat(
82 self.mh,
83 &mut self.format.rate,
84 &mut self.format.channels,
85 &mut self.format.encoding,
86 ) != mpg123::MPG123_OK as c_int
87 {
88 return Err(Box::from("failed to get format"));
89 }
90 }
91
92 Ok(())
93 }
94
95 pub fn format(&self) -> &Format {
96 &self.format
97 }
98
99 pub fn read(&self, buf: &mut [u8]) -> Result<(), Error> {
100 unsafe {
101 let mut done = 0;
102 let res = mpg123::mpg123_read(self.mh, buf.as_mut_ptr(), buf.len(), &mut done);
103 if res != mpg123::MPG123_OK as c_int && res != mpg123::MPG123_DONE as c_int {
104 return Err(Error::BadInput);
105 }
106 if res == mpg123::MPG123_DONE as c_int {
107 return Err(Error::EOF);
108 }
109 }
110
111 Ok(())
112 }
113
114 fn close(&self) -> Result<(), Box<StdError>> {
115 unsafe {
116 if mpg123::mpg123_close(self.mh) != mpg123::MPG123_OK as c_int {
117 return Err(Box::from("failed to close"));
118 }
119 }
120
121 Ok(())
122 }
123
124 fn delete(&self) {
125 unsafe {
126 mpg123::mpg123_delete(self.mh);
127 }
128 }
129}
130
131impl Drop for Decoder {
132 fn drop(&mut self) {
133 if !self.mh.is_null() {
134 self.close().unwrap_or_else(|e| println!("{}", e));
135 self.delete();
136 }
137 }
138}
139
140fn init() -> Result<(), Box<StdError>> {
141 let mut result = Ok(());
142
143 INIT.call_once(|| unsafe {
144 if mpg123::mpg123_init() != mpg123::MPG123_OK as c_int {
145 result = Err(Box::from("Failed to initialize mpg123"));
146 }
147 });
148
149 result
150}