-
Notifications
You must be signed in to change notification settings - Fork 55
/
Copy pathaudio_decoder.rs
92 lines (88 loc) · 3.3 KB
/
audio_decoder.rs
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
extern crate servo_media;
extern crate servo_media_auto;
use servo_media::audio::buffer_source_node::{AudioBuffer, AudioBufferSourceNodeMessage};
use servo_media::audio::context::{AudioContextOptions, RealTimeAudioContextOptions};
use servo_media::audio::decoder::AudioDecoderCallbacks;
use servo_media::audio::node::{AudioNodeInit, AudioNodeMessage, AudioScheduledSourceNodeMessage};
use servo_media::{ClientContextId, ServoMedia};
use std::env;
use std::fs::File;
use std::io::Read;
use std::path::Path;
use std::sync::mpsc;
use std::sync::{Arc, Mutex};
use std::{thread, time};
fn run_example(servo_media: Arc<ServoMedia>) {
let options = <RealTimeAudioContextOptions>::default();
let sample_rate = options.sample_rate;
let context = servo_media
.create_audio_context(
&ClientContextId::build(1, 1),
AudioContextOptions::RealTimeAudioContext(options),
)
.unwrap();
let context = context.lock().unwrap();
let args: Vec<_> = env::args().collect();
let default = "./examples/resources/viper_cut.ogg";
let filename: &str = if args.len() == 2 {
args[1].as_ref()
} else if Path::new(default).exists() {
default
} else {
panic!("Usage: cargo run --bin audio_decoder <file_path>")
};
let mut file = File::open(filename).unwrap();
let mut bytes = vec![];
file.read_to_end(&mut bytes).unwrap();
let decoded_audio: Arc<Mutex<Vec<Vec<f32>>>> = Arc::new(Mutex::new(Vec::new()));
let decoded_audio_ = decoded_audio.clone();
let decoded_audio__ = decoded_audio.clone();
let (sender, receiver) = mpsc::channel();
let callbacks = AudioDecoderCallbacks::new()
.eos(move || {
sender.send(()).unwrap();
})
.error(|e| {
eprintln!("Error decoding audio {:?}", e);
})
.progress(move |buffer, channel| {
let mut decoded_audio = decoded_audio_.lock().unwrap();
decoded_audio[(channel - 1) as usize].extend_from_slice((*buffer).as_ref());
})
.ready(move |channels| {
println!("There are {:?} audio channels", channels);
decoded_audio__
.lock()
.unwrap()
.resize(channels as usize, Vec::new());
})
.build();
context.decode_audio_data(bytes.to_vec(), callbacks);
println!("Decoding audio");
receiver.recv().unwrap();
println!("Audio decoded");
let buffer_source = context.create_node(
AudioNodeInit::AudioBufferSourceNode(Default::default()),
Default::default(),
);
let dest = context.dest_node();
context.connect_ports(buffer_source.output(0), dest.input(0));
context.message_node(
buffer_source,
AudioNodeMessage::AudioScheduledSourceNode(AudioScheduledSourceNodeMessage::Start(0.)),
);
context.message_node(
buffer_source,
AudioNodeMessage::AudioBufferSourceNode(AudioBufferSourceNodeMessage::SetBuffer(Some(
AudioBuffer::from_buffers(decoded_audio.lock().unwrap().to_vec(), sample_rate),
))),
);
let _ = context.resume();
thread::sleep(time::Duration::from_millis(5000));
let _ = context.close();
}
fn main() {
ServoMedia::init::<servo_media_auto::Backend>();
let servo_media = ServoMedia::get();
run_example(servo_media);
}