Skip to content

Commit

Permalink
Add play() and pause() functions
Browse files Browse the repository at this point in the history
  • Loading branch information
tomaka committed Dec 23, 2014
1 parent 6e1d047 commit d947014
Show file tree
Hide file tree
Showing 5 changed files with 90 additions and 32 deletions.
12 changes: 8 additions & 4 deletions examples/beep.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,11 +18,15 @@ fn main() {
});

loop {
let mut buffer = channel.append_data(1, cpal::SamplesRate(44100), 32768);
{
let mut buffer = channel.append_data(1, cpal::SamplesRate(44100), 32768);

for sample in buffer.iter_mut() {
let value = data_source.next().unwrap();
*sample = value;
for sample in buffer.iter_mut() {
let value = data_source.next().unwrap();
*sample = value;
}
}

channel.play();
}
}
34 changes: 20 additions & 14 deletions examples/music.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ use std::io::BufReader;

fn main() {
let mut channel = cpal::Voice::new();
channel.play();

let mut decoder = vorbis::Decoder::new(BufReader::new(include_bin!("music.ogg")))
.unwrap();
Expand All @@ -20,22 +21,27 @@ fn main() {
continue 'main;
}

let mut buffer = channel.append_data(channels, cpal::SamplesRate(rate as u32), data.len());
let mut buffer = buffer.iter_mut();

loop {
let next_sample = match data.get(0) {
Some(s) => *s,
None => continue 'main
};

if let Some(output) = buffer.next() {
*output = next_sample as u16;
data = data.slice_from(1);
} else {
break;
{
let mut buffer = channel.append_data(channels, cpal::SamplesRate(rate as u32),
data.len());
let mut buffer = buffer.iter_mut();

loop {
let next_sample = match data.get(0) {
Some(s) => *s,
None => continue 'main
};

if let Some(output) = buffer.next() {
*output = next_sample as u16;
data = data.slice_from(1);
} else {
break;
}
}
}

channel.play();
}
}
}
9 changes: 9 additions & 0 deletions src/alsa/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,15 @@ impl Voice {
buffer: Vec::from_elem(elements, unsafe { mem::uninitialized() })
}
}

pub fn play(&mut self) {
// already playing
//unimplemented!()
}

pub fn pause(&mut self) {
unimplemented!()
}
}

impl Drop for Voice {
Expand Down
28 changes: 27 additions & 1 deletion src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,15 @@ for e in buffer.iter_mut() {
This is the case if the device doesn't have enough space available. **It happens very often**,
this is not some obscure situation that can be ignored.
After you have submitted data for the first time, call `play`:
```no_run
# let mut voice = cpal::Voice::new();
voice.play();
```
The audio device of the user will read the buffer that you sent, and play it. If the audio device
reaches the end of the data, it will stop playing. You **must** continuously fill the buffer by
reaches the end of the data, it will stop playing. You must continuously fill the buffer by
calling `append_data` repeatedly if you don't want the audio to stop playing.
# Native format
Expand Down Expand Up @@ -212,6 +219,25 @@ impl Voice {
}
}
}

/// Sends a command to the audio device that it should start playing.
///
/// Has no effect is the voice was already playing.
///
/// Only call this after you have submitted some data, otherwise you may hear
/// some glitches.
pub fn play(&mut self) {
self.0.play()
}

/// Sends a command to the audio device that it should stop playing.
///
/// Has no effect is the voice was already paused.
///
/// If you call `play` afterwards, the playback will resume exactly where it was.
pub fn pause(&mut self) {
self.0.pause()
}
}

impl<'a, T> Deref<[T]> for Buffer<'a, T> {
Expand Down
39 changes: 26 additions & 13 deletions src/wasapi/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,15 +13,13 @@ pub struct Voice {
bytes_per_frame: winapi::WORD,
samples_per_second: winapi::DWORD,
bits_per_sample: winapi::WORD,
started: bool,
playing: bool,
}

pub struct Buffer<'a, T> {
audio_client: *mut winapi::IAudioClient,
render_client: *mut winapi::IAudioRenderClient,
buffer: CVec<T>,
frames: winapi::UINT32,
start_on_drop: bool,
}

impl Voice {
Expand Down Expand Up @@ -83,18 +81,39 @@ impl Voice {
};

let buffer = Buffer {
audio_client: self.audio_client,
render_client: self.render_client,
buffer: buffer,
frames: frames_available,
start_on_drop: !self.started,
};

self.started = true;
return buffer;
}
}
}

pub fn play(&mut self) {
if !self.playing {
unsafe {
let f = self.audio_client.as_mut().unwrap().lpVtbl.as_ref().unwrap().Start;
let hresult = f(self.audio_client);
check_result(hresult).unwrap();
}
}

self.playing = true;
}

pub fn pause(&mut self) {
if self.playing {
unsafe {
let f = self.audio_client.as_mut().unwrap().lpVtbl.as_ref().unwrap().Stop;
let hresult = f(self.audio_client);
check_result(hresult).unwrap();
}
}

self.playing = false;
}
}

impl Drop for Voice {
Expand Down Expand Up @@ -124,12 +143,6 @@ impl<'a, T> Buffer<'a, T> {
let f = self.render_client.as_mut().unwrap().lpVtbl.as_ref().unwrap().ReleaseBuffer;
let hresult = f(self.render_client, self.frames as u32, 0);
check_result(hresult).unwrap();

if self.start_on_drop {
let f = self.audio_client.as_mut().unwrap().lpVtbl.as_ref().unwrap().Start;
let hresult = f(self.audio_client);
check_result(hresult).unwrap();
}
};
}
}
Expand Down Expand Up @@ -237,7 +250,7 @@ fn init() -> Result<Voice, String> {
bytes_per_frame: format.nBlockAlign,
samples_per_second: format.nSamplesPerSec,
bits_per_sample: format.wBitsPerSample,
started: false,
playing: false,
})
}
}
Expand Down

0 comments on commit d947014

Please sign in to comment.