Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implement AnalyserNode #127

Merged
merged 7 commits into from Sep 14, 2018
Merged
Changes from 1 commit
Commits
File filter...
Filter file types
Jump to…
Jump to file
Failed to load files.

Always

Just for now

Add serde impls for Block

  • Loading branch information
Manishearth committed Sep 14, 2018
commit 7f4761df3cbf54a34fa7bc991f5c886ca096b11c

Some generated files are not rendered by default. Learn more.

@@ -10,6 +10,8 @@ name = "servo_media_audio"
[dependencies]
boxfnonce = "0.1"
euclid = "0.19.0"
serde_derive = "1.0.66"
serde = "1.0.66"
servo_media_derive = { path = "../servo-media-derive" }
smallvec = "0.6.1"

@@ -3,7 +3,7 @@ use node::AudioNodeEngine;
use node::BlockInfo;
use node::{AudioNodeType, ChannelInfo, ChannelInterpretation};
use std::f32::consts::PI;
use std::{cmp, mem};
use std::cmp;

#[derive(AudioNodeCommon)]
pub(crate) struct AnalyserNode {
@@ -153,10 +153,24 @@ impl AnalysisEngine {
&mut self.data[index..(index + FRAMES_PER_BLOCK_USIZE)]
}

/// Get the data of a block. `offset` tells us how far back to go
fn block(&self, offset: usize) -> &[f32] {
let index = FRAMES_PER_BLOCK_USIZE * self.block_index(offset);
&self.data[index..(index + FRAMES_PER_BLOCK_USIZE)]
/// Given an index from 0 to fft_size, convert it into an index into
/// the backing array
fn convert_index(&self, index: usize) -> usize {
let offset = self.fft_size - index;
let current_block_idx = self.current_block * FRAMES_PER_BLOCK_USIZE;
if offset > current_block_idx {
MAX_FFT_SIZE - offset + current_block_idx
} else {
current_block_idx - offset
}
}

/// Given an index into the backing array, increment it
fn advance_index(&self, index: &mut usize) {
*index += 1;
if *index >= MAX_FFT_SIZE {
*index = 0;
}
}

pub fn push(&mut self, mut block: Block) {
@@ -187,16 +201,13 @@ impl AnalysisEngine {

fn apply_blackman_window(&mut self) {
self.compute_blackman_windows();
// avoids conflicting borrows with data_mut
let mut windowed = mem::replace(&mut self.windowed, Vec::new());
windowed.resize(self.fft_size, 0.);
let mut n = 0;
for offset in (0..self.fft_size).rev() {
let data = self.block(offset);
windowed[n..n+FRAMES_PER_BLOCK_USIZE].copy_from_slice(&data);
n += FRAMES_PER_BLOCK_USIZE;
self.windowed.resize(self.fft_size, 0.);

let mut data_idx = self.convert_index(0);
for n in 0..self.fft_size {
self.windowed[n] = self.blackman_windows[n] * self.data[data_idx];
self.advance_index(&mut data_idx);
}
self.windowed = windowed;
}

fn compute_fft(&mut self) {
@@ -226,35 +237,21 @@ impl AnalysisEngine {
}

pub fn fill_time_domain_data(&self, dest: &mut [f32]) {
let mut n = 0;
for offset in (0..self.fft_size).rev() {
let data = self.block(offset);
let mut end = n + FRAMES_PER_BLOCK_USIZE;
if n >= dest.len() {
break;
} else if end > dest.len() {
end = dest.len();
};
let offset = end - n;
dest[n..end].copy_from_slice(&data[0..offset]);

n += FRAMES_PER_BLOCK_USIZE;
let mut data_idx = self.convert_index(0);
let end = cmp::min(self.fft_size, dest.len());
for n in 0..end {
dest[n] = self.data[data_idx];
self.advance_index(&mut data_idx);
}
}

pub fn fill_byte_time_domain_data(&self, dest: &mut [u8]) {
let mut n = 0;
for offset in (0..self.fft_size).rev() {
let data = self.block(offset);
if n >= dest.len() {
break;
}
let end = cmp::min(FRAMES_PER_BLOCK_USIZE, dest.len() - n - FRAMES_PER_BLOCK_USIZE);
for frame in 0..end {
let result = 128. * (1. + data[frame]);
dest[n] = clamp_255(result);
n += 1;
}
let mut data_idx = self.convert_index(0);
let end = cmp::min(self.fft_size, dest.len());
for n in 0..end {
let result = 128. * (1. + self.data[data_idx]);
dest[n] = clamp_255(result);
self.advance_index(&mut data_idx)
}
}

@@ -283,4 +280,4 @@ fn clamp_255(val: f32) -> u8 {
} else {
val as u8
}
}
}
@@ -45,7 +45,7 @@ impl Chunk {
/// We render audio in blocks of size FRAMES_PER_BLOCK
///
/// A single block may contain multiple channels
#[derive(Clone)]
#[derive(Clone, Serialize, Deserialize)]
pub struct Block {
/// The number of channels in this block
channels: u8,
@@ -1,3 +1,6 @@
#[macro_use]
extern crate serde_derive;

#[macro_use]
extern crate servo_media_derive;

ProTip! Use n and p to navigate between commits in a pull request.
You can’t perform that action at this time.