sdl.rs 1.4 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556
  1. use super::{Open, Sink};
  2. use sdl2::audio::{AudioQueue, AudioSpecDesired};
  3. use std::{io, thread, time};
  4. type Channel = i16;
  5. pub struct SdlSink {
  6. queue: AudioQueue<Channel>,
  7. }
  8. impl Open for SdlSink {
  9. fn open(device: Option<String>) -> SdlSink {
  10. debug!("Using SDL sink");
  11. if device.is_some() {
  12. panic!("SDL sink does not support specifying a device name");
  13. }
  14. let ctx = sdl2::init().expect("Could not init SDL");
  15. let audio = ctx.audio().expect("Could not init SDL audio subsystem");
  16. let desired_spec = AudioSpecDesired {
  17. freq: Some(44_100),
  18. channels: Some(2),
  19. samples: None,
  20. };
  21. let queue = audio
  22. .open_queue(None, &desired_spec)
  23. .expect("Could not open SDL audio device");
  24. SdlSink { queue: queue }
  25. }
  26. }
  27. impl Sink for SdlSink {
  28. fn start(&mut self) -> io::Result<()> {
  29. self.queue.clear();
  30. self.queue.resume();
  31. Ok(())
  32. }
  33. fn stop(&mut self) -> io::Result<()> {
  34. self.queue.pause();
  35. self.queue.clear();
  36. Ok(())
  37. }
  38. fn write(&mut self, data: &[i16]) -> io::Result<()> {
  39. while self.queue.size() > (2 * 2 * 44_100) {
  40. // sleep and wait for sdl thread to drain the queue a bit
  41. thread::sleep(time::Duration::from_millis(10));
  42. }
  43. self.queue.queue(data);
  44. Ok(())
  45. }
  46. }