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
use std;
use failure::Error;
use sdl2::audio::AudioQueue;
use sdl2::{self, AudioSubsystem};
use euphrates::host_multimedia::SimpleAudio;
pub const DEFAULT_BUFFER_SIZE: u16 = 0x800;
pub const DEFAULT_FREQUENCY: u32 = 1000000;
pub struct Audio {
buffer: Box<[i16]>,
queue: AudioQueue<i16>,
audio_subsystem: AudioSubsystem,
}
impl Audio {
pub fn new(sdl: &sdl2::Sdl) -> std::result::Result<Audio, Error> {
let audio_subsystem = sdl
.audio()
.map_err(|s| format_err!("Unable to create SDL audio subsystem: {}", s))?;
let queue = audio_subsystem
.open_queue(
None,
&sdl2::audio::AudioSpecDesired {
freq: Some(DEFAULT_FREQUENCY as i32),
channels: Some(1),
samples: Some(DEFAULT_BUFFER_SIZE as u16),
},
)
.map_err(|s| format_err!("Unable to create SDL audio subsystem: {}", s))?;
Ok(Audio {
buffer: vec![0i16; DEFAULT_BUFFER_SIZE as usize].into_boxed_slice(),
queue,
audio_subsystem,
})
}
}
impl SimpleAudio for Audio {
fn configure(&mut self, frequency: u32, buffer_size: u16) -> std::result::Result<(), Error> {
self.queue = self
.audio_subsystem
.open_queue(
None,
&sdl2::audio::AudioSpecDesired {
freq: Some(frequency as i32),
channels: Some(1),
samples: Some(buffer_size as u16),
},
)
.map_err(|s| format_err!("SDL audio error {}", s))?;
self.buffer = vec![0i16; buffer_size as usize].into_boxed_slice();
Ok(())
}
fn play(&mut self) -> std::result::Result<(), Error> {
self.queue.resume();
Ok(())
}
fn pause(&mut self) -> std::result::Result<(), Error> {
self.queue.pause();
Ok(())
}
#[inline]
fn buffer_set(&mut self, i: usize, value: i16) {
self.buffer[i] = value
}
#[inline]
fn buffer_len(&self) -> usize {
self.buffer.len()
}
fn queue_buffer(&mut self) -> std::result::Result<(), Error> {
if self.queue.queue(&self.buffer) {
Ok(())
} else {
Err(format_err!("SDL Audio error {}", sdl2::get_error()))
}
}
fn clear(&mut self) -> std::result::Result<(), Error> {
self.queue.clear();
Ok(())
}
}