Update player component with current playback position
This commit is contained in:
parent
ba54ab3890
commit
2d458651e6
|
@ -14,7 +14,7 @@ yewtil = "0.3.1"
|
||||||
wasm-bindgen = "0.2"
|
wasm-bindgen = "0.2"
|
||||||
js-sys = "0.3.44"
|
js-sys = "0.3.44"
|
||||||
futures = "0.3.5"
|
futures = "0.3.5"
|
||||||
cpal = { version = "0.12.1", features = ["wasm-bindgen"] }
|
cpal = { path = "/home/rob/dev/cpal", version = "0.12.1", features = ["wasm-bindgen"] }
|
||||||
wasm-bindgen-futures = "0.4"
|
wasm-bindgen-futures = "0.4"
|
||||||
console_error_panic_hook = "0.1.6"
|
console_error_panic_hook = "0.1.6"
|
||||||
|
|
||||||
|
|
|
@ -15,7 +15,8 @@ mod utils;
|
||||||
|
|
||||||
#[wasm_bindgen(start)]
|
#[wasm_bindgen(start)]
|
||||||
pub fn run_app() {
|
pub fn run_app() {
|
||||||
#[cfg(debug_assertions)]
|
// TODO: fix debug/release setup
|
||||||
|
// #[cfg(debug_assertions)]
|
||||||
panic::set_hook(Box::new(console_error_panic_hook::hook));
|
panic::set_hook(Box::new(console_error_panic_hook::hook));
|
||||||
|
|
||||||
App::<app::App>::new().mount_to_body();
|
App::<app::App>::new().mount_to_body();
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
use crate::agents::audio_agent::{self, AudioAgent, AudioData};
|
use crate::agents::audio_agent::{AudioAgent, AudioData};
|
||||||
use cpal::traits::{DeviceTrait, HostTrait, StreamTrait};
|
use cpal::traits::{DeviceTrait, HostTrait, StreamTrait};
|
||||||
use cpal::{Device, Sample, SampleFormat, SampleRate, Stream, StreamConfig};
|
use cpal::{Device, Sample, SampleFormat, Stream, StreamConfig};
|
||||||
|
use std::sync::atomic::{AtomicUsize, Ordering};
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
use yew::agent::Dispatcher;
|
|
||||||
use yew::prelude::*;
|
use yew::prelude::*;
|
||||||
use yew::services::ConsoleService;
|
use yew::services::ConsoleService;
|
||||||
|
|
||||||
|
@ -15,7 +15,7 @@ pub struct Player {
|
||||||
link: ComponentLink<Self>,
|
link: ComponentLink<Self>,
|
||||||
status: Status,
|
status: Status,
|
||||||
stream: Option<Stream>,
|
stream: Option<Stream>,
|
||||||
audio_agent: Box<dyn Bridge<AudioAgent>>,
|
_audio_agent: Box<dyn Bridge<AudioAgent>>,
|
||||||
audio_data: Option<Arc<AudioData>>,
|
audio_data: Option<Arc<AudioData>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -35,12 +35,12 @@ impl Component for Player {
|
||||||
link,
|
link,
|
||||||
status: Status::Stopped,
|
status: Status::Stopped,
|
||||||
stream: None,
|
stream: None,
|
||||||
audio_agent: AudioAgent::bridge(cb),
|
_audio_agent: AudioAgent::bridge(cb),
|
||||||
audio_data: None,
|
audio_data: None,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn rendered(&mut self, first_render: bool) {}
|
fn rendered(&mut self, _first_render: bool) {}
|
||||||
|
|
||||||
fn update(&mut self, msg: Self::Message) -> ShouldRender {
|
fn update(&mut self, msg: Self::Message) -> ShouldRender {
|
||||||
match msg {
|
match msg {
|
||||||
|
@ -81,14 +81,7 @@ impl Player {
|
||||||
let host = cpal::default_host();
|
let host = cpal::default_host();
|
||||||
let device = host.default_output_device().unwrap();
|
let device = host.default_output_device().unwrap();
|
||||||
|
|
||||||
// TODO: improve
|
let config = device.default_output_config().unwrap();
|
||||||
let config = device
|
|
||||||
.supported_output_configs()
|
|
||||||
.unwrap()
|
|
||||||
.nth(0)
|
|
||||||
.unwrap()
|
|
||||||
.with_sample_rate(SampleRate(44100));
|
|
||||||
|
|
||||||
ConsoleService::log(&format!("Using output config: {:?}", config));
|
ConsoleService::log(&format!("Using output config: {:?}", config));
|
||||||
|
|
||||||
let stream = match config.sample_format() {
|
let stream = match config.sample_format() {
|
||||||
|
@ -114,18 +107,21 @@ impl Player {
|
||||||
let err_fn = |err| ConsoleService::warn(&format!("an error occurred on stream: {}", err));
|
let err_fn = |err| ConsoleService::warn(&format!("an error occurred on stream: {}", err));
|
||||||
let num_channels = audio_data.num_channels as usize;
|
let num_channels = audio_data.num_channels as usize;
|
||||||
|
|
||||||
let mut idx: usize = 0; // current playback frame
|
// TODO: consider passing the link into the audio callback? Need to double check
|
||||||
|
// performance implications.
|
||||||
|
// https://discord.com/channels/701068342760570933/703449306497024049/753646647938121738
|
||||||
|
let idx = Arc::new(AtomicUsize::new(0));
|
||||||
let stream = device
|
let stream = device
|
||||||
.build_output_stream(
|
.build_output_stream(
|
||||||
config,
|
config,
|
||||||
move |output: &mut [T], _| {
|
move |output: &mut [T], _| {
|
||||||
for (i, frame) in output.chunks_mut(num_channels).enumerate() {
|
for frame in output.chunks_mut(num_channels) {
|
||||||
|
let i = idx.fetch_add(1, Ordering::Relaxed);
|
||||||
for (j, sample) in frame.iter_mut().enumerate() {
|
for (j, sample) in frame.iter_mut().enumerate() {
|
||||||
let buffer = &audio_data.buffers[j];
|
let buffer = &audio_data.buffers[j];
|
||||||
let value: T = Sample::from::<f32>(&buffer[idx]);
|
let value: T = Sample::from::<f32>(&buffer[i]);
|
||||||
*sample = value;
|
*sample = value;
|
||||||
}
|
}
|
||||||
idx += 1;
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
err_fn,
|
err_fn,
|
||||||
|
|
Loading…
Reference in New Issue