-
Notifications
You must be signed in to change notification settings - Fork 463
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge branch 'master' into unsafe-textures-feature
- Loading branch information
Showing
7 changed files
with
254 additions
and
15 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,136 @@ | ||
extern crate sdl2; | ||
|
||
use sdl2::audio::{AudioCallback, AudioSpecDesired}; | ||
use sdl2::AudioSubsystem; | ||
use std::time::Duration; | ||
use std::sync::mpsc; | ||
use std::i16; | ||
|
||
const RECORDING_LENGTH_SECONDS: usize = 3; | ||
|
||
|
||
struct Recording { | ||
record_buffer: Vec<i16>, | ||
pos: usize, | ||
done_sender: mpsc::Sender<Vec<i16>>, | ||
done: bool, | ||
} | ||
|
||
// Append the input of the callback to the record_buffer. | ||
// When the record_buffer is full, send it to the main thread via done_sender. | ||
impl AudioCallback for Recording { | ||
type Channel = i16; | ||
|
||
fn callback(&mut self, input: &mut [i16]) { | ||
if self.done { | ||
return; | ||
} | ||
|
||
for x in input { | ||
self.record_buffer[self.pos] = *x; | ||
self.pos += 1; | ||
if self.pos >= self.record_buffer.len() { | ||
self.done = true; | ||
self.done_sender.send(self.record_buffer.clone()).unwrap(); | ||
break; | ||
} | ||
} | ||
} | ||
} | ||
|
||
fn record(audio_subsystem: &AudioSubsystem, desired_spec: &AudioSpecDesired) -> Vec<i16> { | ||
println!("Capturing {:} seconds... Please rock!", RECORDING_LENGTH_SECONDS); | ||
|
||
let (done_sender, done_receiver) = mpsc::channel(); | ||
|
||
let capture_device = audio_subsystem.open_capture(None, desired_spec, |spec| { | ||
println!("Capture Spec = {:?}", spec); | ||
Recording { | ||
record_buffer: vec![0; spec.freq as usize * RECORDING_LENGTH_SECONDS * spec.channels as usize], | ||
pos: 0, | ||
done_sender, | ||
done: false | ||
} | ||
}).unwrap(); | ||
|
||
println!("AudioDriver: {:?}", capture_device.subsystem().current_audio_driver()); | ||
capture_device.resume(); | ||
|
||
// Wait until the recording is done. | ||
let recorded_vec = done_receiver.recv().unwrap(); | ||
|
||
capture_device.pause(); | ||
|
||
// Device is automatically closed when dropped. | ||
// Depending on your system it might be even important that the capture_device is dropped | ||
// before the playback starts. | ||
|
||
recorded_vec | ||
} | ||
|
||
|
||
/// Returns a percent value | ||
fn calculate_average_volume(recorded_vec: &[i16]) -> f32 { | ||
let sum: i64 = recorded_vec.iter().map(|&x| (x as i64).abs()).sum(); | ||
(sum as f32) / (recorded_vec.len() as f32) / (i16::MAX as f32) * 100.0 | ||
} | ||
|
||
/// Returns a percent value | ||
fn calculate_max_volume(recorded_vec: &[i16]) -> f32 { | ||
let max: i64 = recorded_vec.iter().map(|&x| (x as i64).abs()).max().unwrap(); | ||
(max as f32) / (i16::MAX as f32) * 100.0 | ||
} | ||
|
||
|
||
struct SoundPlayback { | ||
data: Vec<i16>, | ||
pos: usize, | ||
} | ||
|
||
impl AudioCallback for SoundPlayback { | ||
type Channel = i16; | ||
|
||
fn callback(&mut self, out: &mut [i16]) { | ||
for dst in out.iter_mut() { | ||
*dst = *self.data.get(self.pos).unwrap_or(&0); | ||
self.pos += 1; | ||
} | ||
} | ||
} | ||
|
||
fn replay_recorded_vec(audio_subsystem: &AudioSubsystem, desired_spec: &AudioSpecDesired, recorded_vec: Vec<i16>) { | ||
println!("Playing..."); | ||
|
||
let playback_device = audio_subsystem.open_playback(None, desired_spec, |spec| { | ||
println!("Playback Spec = {:?}", spec); | ||
SoundPlayback { | ||
data: recorded_vec, | ||
pos: 0, | ||
} | ||
}).unwrap(); | ||
|
||
// Start playback | ||
playback_device.resume(); | ||
|
||
std::thread::sleep(Duration::from_secs(RECORDING_LENGTH_SECONDS as u64)); | ||
// Device is automatically closed when dropped | ||
} | ||
|
||
|
||
fn main() { | ||
let sdl_context = sdl2::init().unwrap(); | ||
let audio_subsystem = sdl_context.audio().unwrap(); | ||
|
||
let desired_spec = AudioSpecDesired { | ||
freq: None, | ||
channels: None, | ||
samples: None | ||
}; | ||
|
||
let recorded_vec = record(&audio_subsystem, &desired_spec); | ||
|
||
println!("Average Volume of your Recording = {:?}%", calculate_average_volume(&recorded_vec)); | ||
println!("Max Volume of your Recording = {:?}%", calculate_max_volume(&recorded_vec)); | ||
|
||
replay_recorded_vec(&audio_subsystem, &desired_spec, recorded_vec); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters