shine-rs 0.1.3

A pure Rust MP3 encoder based on the shine library, providing complete MPEG Layer III encoding functionality
Documentation

shine-rs 库

这是 shine-rs MP3 编码器的核心库实现。该库提供了完整的 MP3 Layer III 编码功能,严格遵循 Shine C 语言参考实现。

库架构

核心模块

  • encoder - 主编码器模块,提供底层 Shine 兼容接口
  • mp3_encoder - 高级编码器接口,提供更友好的 Rust API
  • config - 编码配置管理
  • error - 错误类型定义

算法模块

  • subband - 32频带子带分析滤波器
  • mdct - 修正离散余弦变换 (Modified Discrete Cosine Transform)
  • quantization - 量化循环和比特率控制
  • huffman - Huffman 编码器
  • bitstream - MP3 比特流写入器
  • reservoir - 比特池管理

数据和查找表

  • tables - 所有 MP3 编码所需的查找表
  • psychoacoustic - 心理声学模型(简化版)

API 使用

高级接口 (推荐)

use shine_rs::{Mp3Encoder, Mp3EncoderConfig, StereoMode};

// 创建配置
let config = Mp3EncoderConfig::new()
    .sample_rate(44100)
    .bitrate(128)
    .channels(2)
    .stereo_mode(StereoMode::Stereo);

// 创建编码器
let mut encoder = Mp3Encoder::new(config)?;

// 编码音频数据 (交错格式)
let pcm_samples = vec![0i16; encoder.samples_per_frame()];
let mp3_data = encoder.encode_interleaved(&pcm_samples)?;

// 完成编码
let final_data = encoder.finish()?;

底层接口 (Shine 兼容)

use shine_rs::{
    ShineConfig, ShineWave, ShineMpeg,
    shine_initialise, shine_encode_buffer_interleaved, 
    shine_flush, shine_close
};

// 初始化配置
let mut config = ShineConfig::default();
config.wave.samplerate = 44100;
config.wave.channels = 2;
config.mpeg.bitr = 128;

// 初始化编码器
shine_initialise(&mut config);

// 编码数据
let pcm_data = vec![0i16; config.samples_per_pass()];
let mp3_data = shine_encode_buffer_interleaved(&mut config, &pcm_data);

// 完成编码
let final_data = shine_flush(&mut config);
shine_close(&mut config);

配置选项

Mp3EncoderConfig

pub struct Mp3EncoderConfig {
    sample_rate: u32,      // 采样率 (8000-48000 Hz)
    bitrate: u32,          // 比特率 (8-320 kbps)
    channels: u16,         // 声道数 (1-2)
    stereo_mode: StereoMode, // 立体声模式
    copyright: bool,       // 版权标志
    original: bool,        // 原创标志
    emphasis: Emphasis,    // 预加重
}

立体声模式

pub enum StereoMode {
    Stereo,      // 立体声
    JointStereo, // 联合立体声
    DualChannel, // 双声道
    Mono,        // 单声道
}

支持的采样率和比特率组合

MPEG版本 采样率 (Hz) 比特率范围 (kbps)
MPEG-1 32000, 44100, 48000 32-320
MPEG-2 16000, 22050, 24000 8-160
MPEG-2.5 8000, 11025, 12000 8-64

错误处理

use shine_rs::EncodingError;

match encoder.encode_interleaved(&pcm_data) {
    Ok(mp3_data) => {
        // 处理编码数据
    }
    Err(EncodingError::InvalidSampleRate(rate)) => {
        eprintln!("不支持的采样率: {}", rate);
    }
    Err(EncodingError::InvalidBitrate(bitrate)) => {
        eprintln!("不支持的比特率: {}", bitrate);
    }
    Err(EncodingError::InvalidChannelCount(channels)) => {
        eprintln!("不支持的声道数: {}", channels);
    }
    Err(e) => {
        eprintln!("编码错误: {}", e);
    }
}

内存管理

缓冲区大小

// 获取每帧所需的 PCM 样本数
let samples_per_frame = encoder.samples_per_frame(); // 通常是 1152

// 获取最大 MP3 帧大小
let max_mp3_frame_size = encoder.max_mp3_frame_size(); // 取决于比特率

// 预分配缓冲区
let mut pcm_buffer = vec![0i16; samples_per_frame];
let mut mp3_buffer = Vec::with_capacity(max_mp3_frame_size);

批量处理

// 处理大量音频数据
let chunk_size = encoder.samples_per_frame();
for chunk in pcm_data.chunks(chunk_size) {
    if chunk.len() == chunk_size {
        let mp3_frame = encoder.encode_interleaved(chunk)?;
        output.extend_from_slice(&mp3_frame);
    } else {
        // 处理最后一个不完整的块
        let mut padded_chunk = vec![0i16; chunk_size];
        padded_chunk[..chunk.len()].copy_from_slice(chunk);
        let mp3_frame = encoder.encode_interleaved(&padded_chunk)?;
        output.extend_from_slice(&mp3_frame);
    }
}

调试功能

启用诊断特性

[dependencies]

shine-rs = { version = "0.1", features = ["diagnostics"] }

#[cfg(feature = "diagnostics")]
{
    // 访问内部诊断数据
    let diagnostics = encoder.get_diagnostics();
    println!("MDCT 系数: {:?}", diagnostics.mdct_coefficients);
    println!("量化参数: {:?}", diagnostics.quantization_params);
}

日志输出

use log::{info, debug};

// 启用日志
env_logger::init();

// 编码时会输出详细日志
debug!("开始编码帧 {}", frame_number);
info!("编码完成,输出 {} 字节", mp3_data.len());

性能优化

预分配缓冲区

// 避免重复分配
let mut encoder = Mp3Encoder::new(config)?;
let mut pcm_buffer = vec![0i16; encoder.samples_per_frame()];
let mut mp3_output = Vec::new();

loop {
    // 重用缓冲区
    if let Some(samples) = read_audio_samples(&mut pcm_buffer) {
        let mp3_frame = encoder.encode_interleaved(&pcm_buffer[..samples])?;
        mp3_output.extend_from_slice(&mp3_frame);
    } else {
        break;
    }
}

批量处理

// 处理多个帧以减少函数调用开销
const BATCH_SIZE: usize = 10;
let frame_size = encoder.samples_per_frame();
let batch_size = frame_size * BATCH_SIZE;

for batch in pcm_data.chunks(batch_size) {
    for frame in batch.chunks(frame_size) {
        let mp3_frame = encoder.encode_interleaved(frame)?;
        output.extend_from_slice(&mp3_frame);
    }
}

线程安全

该库不是线程安全的。如需在多线程环境中使用,请为每个线程创建独立的编码器实例:

use std::thread;
use std::sync::mpsc;

// 为每个线程创建独立的编码器
let handles: Vec<_> = (0..num_threads).map(|_| {
    let config = config.clone();
    thread::spawn(move || {
        let mut encoder = Mp3Encoder::new(config).unwrap();
        // 处理音频数据...
    })
}).collect();

与 Shine C 实现的对应关系

Rust 函数 Shine C 函数 说明
Mp3Encoder::new() shine_initialise() 初始化编码器
encode_interleaved() shine_encode_buffer_interleaved() 编码交错音频数据
finish() shine_flush() + shine_close() 完成编码并清理
samples_per_frame() shine_samples_per_pass() 每帧样本数

测试和验证

# 运行单元测试

cargo test


# 运行集成测试

cargo test --test integration_*


# 启用诊断特性测试

cargo test --features diagnostics


# 性能基准测试

cargo bench

构建特性

  • default - 标准功能
  • diagnostics - 启用内部诊断数据访问
  • logging - 启用详细日志输出
[dependencies]

shine-rs = { version = "0.1", features = ["diagnostics", "logging"] }