Skip to content

Commit

Permalink
feat: mp3 decoder wip
Browse files Browse the repository at this point in the history
  • Loading branch information
twlite committed Sep 27, 2023
1 parent 7356d09 commit 4117ccc
Show file tree
Hide file tree
Showing 7 changed files with 88 additions and 4 deletions.
1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ version = "0.0.0"
crate-type = ["cdylib"]

[dependencies]
minimp3-sys = "0.3.2"
napi = { git = "https://github.com/napi-rs/napi-rs", default-features = false, features = [
"napi4",
] }
Expand Down
3 changes: 2 additions & 1 deletion index.js
Original file line number Diff line number Diff line change
Expand Up @@ -136,7 +136,7 @@ function readMetadata(result) {
return res;
}

const { CodecType, probe, probeSync, OpusEncoder, getOpusVersion } = binding;
const { CodecType, probe, probeSync, OpusEncoder, getOpusVersion, Mp3Decoder } = binding;
const { version } = require('./package.json');

module.exports = {
Expand All @@ -147,5 +147,6 @@ module.exports = {
readMetadata,
OpusEncoder,
getOpusVersion,
Mp3Decoder,
version
};
13 changes: 13 additions & 0 deletions js-binding.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,15 @@ export interface MetadataField {
}
export function probe(data: Buffer): Promise<ProbeResult>
export function probeSync(data: Buffer): ProbeResult
export interface Mp3DecodedFrame {
frameBytes: number
frameOffset: number
channels: number
hz: number
layer: number
bitrateKbps: number
data: Buffer
}
export type JsOpusEncoder = OpusEncoder
export class OpusEncoder {
constructor(sampleRate: number, channels: number)
Expand All @@ -105,3 +114,7 @@ export class OpusEncoder {
applyDecoderCtl(request: number, value: number): void
get version(): string
}
export class Mp3Decoder {
constructor()
decode(data: Buffer): Mp3DecodedFrame
}
3 changes: 2 additions & 1 deletion js-binding.js
Original file line number Diff line number Diff line change
Expand Up @@ -252,10 +252,11 @@ if (!nativeBinding) {
throw new Error(`Failed to load native binding`)
}

const { getOpusVersion, OpusEncoder, CodecType, probe, probeSync } = nativeBinding
const { getOpusVersion, OpusEncoder, CodecType, probe, probeSync, Mp3Decoder } = nativeBinding

module.exports.getOpusVersion = getOpusVersion
module.exports.OpusEncoder = OpusEncoder
module.exports.CodecType = CodecType
module.exports.probe = probe
module.exports.probeSync = probeSync
module.exports.Mp3Decoder = Mp3Decoder
1 change: 1 addition & 0 deletions src/decoder/mod.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
mod mp3;
68 changes: 68 additions & 0 deletions src/decoder/mp3/mod.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
use minimp3_sys::{mp3d_sample_t, mp3dec_frame_info_t};
use minimp3_sys::{mp3dec_decode_frame, mp3dec_init, mp3dec_t, MINIMP3_MAX_SAMPLES_PER_FRAME};
use napi::bindgen_prelude::*;
use napi::Error;
use napi::Result;
use std::mem;

#[napi(object)]
pub struct Mp3DecodedFrame {
pub frame_bytes: i32,
pub frame_offset: i32,
pub channels: i32,
pub hz: i32,
pub layer: i32,
pub bitrate_kbps: i32,
pub data: Buffer,
}

#[napi]
pub struct Mp3Decoder {
decoder: mp3dec_t,
}

#[napi]
impl Mp3Decoder {
#[napi(constructor)]
pub fn new() -> Self {
let mut context = unsafe { mem::zeroed() };
unsafe { mp3dec_init(&mut context) };

Self { decoder: context }
}

#[napi]
pub fn decode(&mut self, data: Buffer) -> Result<Mp3DecodedFrame> {
let mut frame_info: mp3dec_frame_info_t = unsafe { mem::zeroed() };
let buffer = data.as_ref();
let input_len = buffer.len();
let mut pcm = Vec::with_capacity(MINIMP3_MAX_SAMPLES_PER_FRAME as usize);
let samples: usize = unsafe {
mp3dec_decode_frame(
&mut self.decoder,
buffer.as_ptr(),
input_len as _,
pcm.as_mut_ptr(),
&mut frame_info,
) as _
};

if samples > 0 {
unsafe {
pcm.set_len(samples * frame_info.channels as usize);
}
}

let out_vec = unsafe { std::mem::transmute::<&mut [i16], &mut [u8]>(&mut pcm.as_mut()) };

Ok(Mp3DecodedFrame {
frame_bytes: frame_info.frame_bytes,
frame_offset: frame_info.frame_offset,
channels: frame_info.channels,
hz: frame_info.hz,
layer: frame_info.layer,
bitrate_kbps: frame_info.bitrate_kbps,
data: out_vec.to_vec().into(),
})
}
}
3 changes: 1 addition & 2 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@
#[macro_use]
extern crate napi_derive;

// mod dasp;
// mod decoder;
mod opus;
mod probe;
mod decoder;

0 comments on commit 4117ccc

Please sign in to comment.