summaryrefslogtreecommitdiff
path: root/src/audio.rs
diff options
context:
space:
mode:
authorJustin Worthe <justin.worthe@gmail.com>2016-10-13 18:07:21 +0200
committerJustin Worthe <justin.worthe@gmail.com>2016-10-13 18:07:21 +0200
commite6cbba66fed669c9c6808584a4f1551cfdb5de30 (patch)
tree4b218ac7ed0c6c24f249df357b924b198827dfb3 /src/audio.rs
parentb37f7697c100d7f89054c57d8108ee64902865eb (diff)
Function to start listening on microphone
Messy. To clean up once I've seen if it works.
Diffstat (limited to 'src/audio.rs')
-rw-r--r--src/audio.rs90
1 files changed, 57 insertions, 33 deletions
diff --git a/src/audio.rs b/src/audio.rs
index 526a227..cdeb88a 100644
--- a/src/audio.rs
+++ b/src/audio.rs
@@ -1,58 +1,86 @@
extern crate portaudio;
use portaudio as pa;
+use std::sync::mpsc::*;
+
const SAMPLE_RATE: f64 = 44100.0;
const FRAMES: usize = 512;
-pub fn get_device_list() -> Result<Vec<(u32, String)>, pa::Error> {
- let pa = try!(pa::PortAudio::new());
- let default_host = try!(pa.default_host_api());
- println!("Using default host: {:#?}", default_host);
+pub fn init() -> Result<pa::PortAudio, pa::Error> {
+ pa::PortAudio::new()
+}
- let mut list = Vec::new();
- let devices = try!(pa.devices());
- for device in devices {
- let (pa::DeviceIndex(idx), info) = try!(device);
- if info.max_input_channels == 0 {
- continue;
- }
- list.push((idx, info.name.to_string()));
- }
+pub fn get_device_list(pa: &pa::PortAudio) -> Result<Vec<(u32, String)>, pa::Error> {
+ // This pa.devices gives a Result of devices, each of which is
+ // also a Result. So a Result<Collection<Result<Device>>>. We
+ // mould it into devices: a Vec<(index, DeviceInfo)>.
+ let devices = try!(try!(pa.devices()).map(|device| {
+ device.map(|(pa::DeviceIndex(idx), info)| (idx, info))
+ }).collect::<Result<Vec<_>, _>>());
+
+ let list = devices.iter().filter(|&&(_, ref info)| info.max_input_channels > 0)
+ .map(|&(idx, ref info)| (idx, info.name.to_string()))
+ .collect();
Ok(list)
}
-pub fn run(device_index: u32) -> Result<(), pa::Error> {
- let pa = try!(pa::PortAudio::new());
+#[test]
+fn get_device_list_returns_devices() {
+ let pa = init().expect("Could not init portaudio");
+ let devices = get_device_list(&pa).expect("Getting devices had an error");
+
+ // all machines should have at least one input stream, even if
+ // that's just a virtual stream with a name like "default".
+ assert!(devices.len() > 0);
+}
+
+
+pub struct OpenRecordingChannel<'a> {
+ receiver: Receiver<Vec<f64>>,
+ //pa: &'a portaudio::PortAudio,
+ stream: pa::Stream<'a, pa::NonBlocking, pa::Input<f32>>
+}
- let input_info = try!(pa.device_info(pa::DeviceIndex(device_index)));
- println!("Using {} for input", input_info.name);
+pub fn start_listening<'a>(pa: &'a pa::PortAudio, device_index: u32) -> Result<OpenRecordingChannel<'a>, pa::Error> {
+ //let pa = try!(pa::PortAudio::new());
+ let device_info = try!(pa.device_info(pa::DeviceIndex(device_index)));
+ let latency = device_info.default_low_input_latency;
// Construct the input stream parameters.
- let latency = input_info.default_low_input_latency;
+
let input_params = pa::StreamParameters::<f32>::new(pa::DeviceIndex(device_index), 1, true, latency);
// Check that the stream format is supported.
try!(pa.is_input_format_supported(input_params, SAMPLE_RATE));
- // Construct the settings with which we'll open our duplex stream.
- let settings = pa::InputStreamSettings::new(input_params, SAMPLE_RATE, FRAMES as u32);
+ // Construct the settings with which we'll open our stream.
+ let stream_settings = pa::InputStreamSettings::new(input_params, SAMPLE_RATE, FRAMES as u32);
- // We'll use this channel to send the count_down to the main thread for fun.
- let (sender, receiver) = ::std::sync::mpsc::channel();
+ // This channel will let us read from and control the audio stream
+ let (sender, receiver) = channel();
- // A callback to pass to the non-blocking stream.
+ // This callback A callback to pass to the non-blocking stream.
let callback = move |pa::InputStreamCallbackArgs { buffer, .. }| {
sender.send(buffer.iter().map(|x| *x as f64).collect()).ok();
pa::Continue
};
- // Construct a stream with input and output sample types of f32.
- let mut stream = try!(pa.open_non_blocking_stream(settings, callback));
-
+ let mut stream = try!(pa.open_non_blocking_stream(stream_settings, callback));
try!(stream.start());
+
+
+ //How do I call this? try!(stream.stop());
+
+ Ok(OpenRecordingChannel {
+ receiver: receiver,
+// pa: &pa,
+ stream: stream
+ })
+}
- let mut samples_index = 0;
- // Do some stuff!
+
+/*
+ let mut samples_index = 0;
while let Ok(samples) = receiver.recv() {
samples_index += 1;
if samples_index % 100 != 0 {
@@ -67,8 +95,4 @@ pub fn run(device_index: u32) -> Result<(), pa::Error> {
).unwrap().max_freq;
println!("{}Hz", max_frequency.floor());
}
-
- try!(stream.stop());
-
- Ok(())
-}
+*/