playing audio

main
_ 2021-11-12 14:33:38 -06:00
parent 15980d347c
commit b11c4ac0b8
4 changed files with 71 additions and 16 deletions

1
.gitignore vendored
View File

@ -1,2 +1,3 @@
/target
*.m4a
*.opus

7
Cargo.lock generated
View File

@ -88,6 +88,12 @@ version = "3.8.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8f1e260c3a9040a7c19a12468758f4c16f31a81a1fe087482be9570ec864bb6c"
[[package]]
name = "byteorder"
version = "1.4.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "14c189c53d098945499cdfa7ecc63567cf3886b3332b312a5b4585d8d3a6a610"
[[package]]
name = "bytes"
version = "1.1.0"
@ -421,6 +427,7 @@ name = "music_player"
version = "0.1.0"
dependencies = [
"anyhow",
"byteorder",
"cpal",
"ffmpeg-next",
]

View File

@ -7,5 +7,6 @@ edition = "2021"
[dependencies]
anyhow = "1.0.45"
byteorder = "1.4.3"
cpal = "0.13.4"
ffmpeg-next = "4.4.0"

View File

@ -1,4 +1,5 @@
use std::{
io::Cursor,
sync::{
Arc,
Condvar,
@ -13,6 +14,11 @@ use anyhow::{
Result,
};
use byteorder::{
LittleEndian,
ReadBytesExt,
};
use cpal::traits::{
DeviceTrait,
HostTrait,
@ -74,25 +80,35 @@ fn main () -> Result <()> {
let pair2 = Arc::clone (&pair);
let thread_decoder = thread::spawn (move|| {
/*
Pipeline:
- demuxer
- decoder
- resampler
- cpal
*/
let (lock, cvar) = &*pair2;
let freq = 75;
let period = SAMPLE_RATE / freq;
let mut input_ctx = ffmpeg_next::format::input (&"test.m4a")?;
let stream = input_ctx
.streams ()
.best (ffmpeg_next::media::Type::Audio)
.ok_or_else (|| anyhow! ("can't find good audio stream"))?;
let best_stream_idx = stream.index ();
let mut saw_counter = 0;
let mut decoder = stream.codec ().decoder ().audio ()?;
let mut resampler = decoder.resampler (
ffmpeg_next::util::format::sample::Sample::F32 (
ffmpeg_next::util::format::sample::Type::Packed,
),
ffmpeg_next::util::channel_layout::ChannelLayout::STEREO,
48000,
)?;
let mut frame = ffmpeg_next::util::frame::Audio::empty ();
let mut packets = input_ctx.packets ();
loop {
let mut buffer = vec! [0.0f32; 4000];
for x in &mut buffer {
*x = 0.25 * (saw_counter as f32 * 2.0 / period as f32 - 1.0);
saw_counter += 1;
if saw_counter >= period {
saw_counter = 0
}
}
// eprintln! ("decode thread parking");
let mut pcm_buffers = cvar.wait_while (lock.lock ().unwrap (), |pcm_buffers| {
@ -100,8 +116,38 @@ fn main () -> Result <()> {
pcm_buffers.samples_available () >= 48_000
}).unwrap ();
// dbg! (pcm_buffers.samples_available ());
pcm_buffers.produce (buffer);
let mut did_anything = false;
while decoder.receive_frame (&mut frame).is_ok () {
did_anything = true;
let mut buffer = vec! [0.0f32; frame.plane::<f32> (0).len () * 2];
let mut rdr_left = frame.plane::<f32> (0).iter ();
let mut rdr_right = frame.plane::<f32> (1).iter ();
for x in buffer.chunks_mut (2) {
x [0] = *rdr_left.next ().unwrap ();
x [1] = *rdr_right.next ().unwrap ();
}
pcm_buffers.produce (buffer);
}
match packets.next () {
None => {},
Some ((stream, packet)) => {
did_anything = true;
if stream.index () == best_stream_idx {
decoder.send_packet (&packet)?;
}
},
}
if ! did_anything {
break;
}
}
Ok::<_, anyhow::Error> (())