feat: 完成立体声 demo 的 client / server 构建

This commit is contained in:
Del Wang
2025-12-29 11:23:58 +08:00
parent e3c8bbb347
commit d7eeba90fd
7 changed files with 171 additions and 136 deletions
+3 -1
View File
@@ -12,7 +12,6 @@ strip = true
debug = false debug = false
[dependencies] [dependencies]
alsa = "0.11"
opus = "0.3" opus = "0.3"
anyhow = "1.0" anyhow = "1.0"
tokio = { version = "1.47", features = ["full"] } tokio = { version = "1.47", features = ["full"] }
@@ -22,3 +21,6 @@ postcard = { version = "1.0", features = ["alloc", "use-std"] }
log = "0.4" log = "0.4"
env_logger = "0.11" env_logger = "0.11"
byteorder = "1.5" byteorder = "1.5"
[target.'cfg(target_os = "linux")'.dependencies]
alsa = "0.11"
+2 -2
View File
@@ -7,7 +7,7 @@ set -e
# # 1. 编译 demo # # 1. 编译 demo
# echo "Compiling hello demo..." # echo "Compiling hello demo..."
# docker run --rm -v $(pwd):/app/hello open-xiaoai-runtime \ # docker run --rm -v $(pwd):/app/hello open-xiaoai-runtime \
# cargo build --manifest-path hello/Cargo.toml --target armv7-unknown-linux-gnueabihf --release # cargo build --manifest-path hello/Cargo.toml --target armv7-unknown-linux-gnueabihf --bin client --release
# # 2. 上传二进制文件到小爱音箱 # # 2. 上传二进制文件到小爱音箱
# function upload_to_xiaoai() { # function upload_to_xiaoai() {
@@ -21,5 +21,5 @@ set -e
# upload_to_xiaoai client 192.168.31.153 # left # upload_to_xiaoai client 192.168.31.153 # left
# upload_to_xiaoai client 192.168.31.235 # right # upload_to_xiaoai client 192.168.31.235 # right
cargo build --release cargo build --bin server --release
./target/release/server ./target/release/server
+4
View File
@@ -1,8 +1,12 @@
#[cfg(target_os = "linux")]
pub mod recorder; pub mod recorder;
#[cfg(target_os = "linux")]
pub mod player; pub mod player;
pub mod codec; pub mod codec;
#[cfg(target_os = "linux")]
pub use recorder::AudioRecorder; pub use recorder::AudioRecorder;
#[cfg(target_os = "linux")]
pub use player::AudioPlayer; pub use player::AudioPlayer;
pub use codec::OpusCodec; pub use codec::OpusCodec;
+1
View File
@@ -1,3 +1,4 @@
#![cfg(target_os = "linux")]
use crate::config::AudioConfig; use crate::config::AudioConfig;
use alsa::pcm::{Access, Format, HwParams, PCM}; use alsa::pcm::{Access, Format, HwParams, PCM};
use alsa::Direction; use alsa::Direction;
+1
View File
@@ -1,3 +1,4 @@
#![cfg(target_os = "linux")]
use alsa::pcm::{PCM, HwParams, Format, Access}; use alsa::pcm::{PCM, HwParams, Format, Access};
use alsa::Direction; use alsa::Direction;
use anyhow::{Result, Context}; use anyhow::{Result, Context};
+14
View File
@@ -1,5 +1,9 @@
use anyhow::Result; use anyhow::Result;
#[cfg(not(target_os = "linux"))]
use hello::audio::OpusCodec;
#[cfg(target_os = "linux")]
use hello::audio::{AudioPlayer, OpusCodec}; use hello::audio::{AudioPlayer, OpusCodec};
use hello::config::AudioConfig; use hello::config::AudioConfig;
use hello::net::{AudioPacket, ChannelRole, ControlPacket, Discovery}; use hello::net::{AudioPacket, ChannelRole, ControlPacket, Discovery};
use hello::sync::{ClockSync, now_us}; use hello::sync::{ClockSync, now_us};
@@ -11,6 +15,14 @@ use tokio::net::TcpStream;
#[tokio::main] #[tokio::main]
async fn main() -> Result<()> { async fn main() -> Result<()> {
#[cfg(not(target_os = "linux"))]
{
println!("Client is only supported on Linux (ALSA required)");
return Ok(());
}
#[cfg(target_os = "linux")]
{
env_logger::init(); env_logger::init();
let args: Vec<String> = env::args().collect(); let args: Vec<String> = env::args().collect();
if args.len() < 2 { if args.len() < 2 {
@@ -54,6 +66,7 @@ async fn main() -> Result<()> {
if let Ok(ControlPacket::Pong { if let Ok(ControlPacket::Pong {
client_ts, client_ts,
server_ts, server_ts,
..
}) = postcard::from_bytes::<ControlPacket>(&buf[..n]) }) = postcard::from_bytes::<ControlPacket>(&buf[..n])
{ {
let t4 = now_us(); let t4 = now_us();
@@ -117,4 +130,5 @@ async fn main() -> Result<()> {
tokio::time::sleep(Duration::from_millis(5)).await; tokio::time::sleep(Duration::from_millis(5)).await;
} }
} }
}
} }
+14 -1
View File
@@ -1,10 +1,22 @@
#[cfg(not(target_os = "linux"))]
use hello::audio::OpusCodec;
#[cfg(target_os = "linux")]
use hello::audio::{AudioPlayer, AudioRecorder, OpusCodec}; use hello::audio::{AudioPlayer, AudioRecorder, OpusCodec};
use hello::config::AudioConfig;
use anyhow::Result; use anyhow::Result;
use hello::config::AudioConfig;
use std::collections::VecDeque; use std::collections::VecDeque;
use std::time::{Duration, Instant}; use std::time::{Duration, Instant};
fn main() -> Result<()> { fn main() -> Result<()> {
#[cfg(not(target_os = "linux"))]
{
println!("Test utility is only supported on Linux (ALSA required)");
return Ok(());
}
#[cfg(target_os = "linux")]
{
let config = AudioConfig::default(); let config = AudioConfig::default();
println!("Starting Audio Modular Demo with 1s delay"); println!("Starting Audio Modular Demo with 1s delay");
println!( println!(
@@ -57,4 +69,5 @@ fn main() -> Result<()> {
} }
} }
} }
}
} }