ejmahler / rust_dct Goto Github PK
View Code? Open in Web Editor NEWRust library to compute the main four discrete cosine transforms
License: Apache License 2.0
Rust library to compute the main four discrete cosine transforms
License: Apache License 2.0
Hello
Currently scratch lengths are checked within the library as assert_eq!(scratch.len(), self.get_scratch_len())
and this caught me out when reusing a scratch for DCTs of various lengths and sized to the largest required scratch. This can be worked around of course by slicing to the correct length, however I think it would be more ergonomic if this was moved inside the library. Are you open to these checks be changed to the form of:
assert!(scratch.len() >= self.get_scratch_len())
or
let scratch = &mut scratch[..self.get_scratch_len()]
depending on whether there is a need for a slice of exact length?
Would it be possible to update the rustfft
version to 3.0.0
as the current one depends on [email protected]
which uses rustc-serialize
which is deprecated (and can't be compiled to wasm
targets). The new version no longer uses rustc-serialize
but there might be some breaking changes to account for.
I apologize if this sounds too much like a "do my homework" kind of question, but I can explain.
I'm a semi-regular contributor to Ruffle (https://ruffle.rs), a Flash Player emulator.
When implementing the flash.media.SoundMixer.computeSpectrum
AS3 method, we were able to reverse-engineer the exact algorithm used to perform the "FFT": https://github.com/ruffle-rs/ruffle/blob/7c46fb207b2ec5e2a3e0d49f7050ef49575a1880/core/src/avm2/globals/flash/media/soundmixer.rs#L151-L179
However, for some content, cosf
takes up a considerable amount of runtime, so I thought of speeding up the implementation by switching to a "fast" algorithm.
I have extracted the relevant logic into a little stand-alone program for easier experimentation:
pub fn fft2(mut hist : [f32; 512]) -> [f32; 512]
{
use rustdct::DctPlanner;
let mut planner = DctPlanner::new();
let dct4 = planner.plan_dct1(512);
dct4.process_dct1(&mut hist);
hist
}
pub fn fft1(mut hist : [f32; 512]) -> [f32; 512]
{
// Need to make a copy of the samples used by the FFT, so they aren't
// modified in place.
let mut inp = [0.0; 512];
inp.copy_from_slice(&hist);
for (freq, h) in hist.iter_mut().enumerate() {
let mut sum = 0.0;
for (i, sample) in inp.iter().enumerate() {
let freq = freq as f32;
let i = i as f32;
let coeff = (std::f32::consts::PI * freq * i / 1024.0).cos();
sum += sample * coeff;
}
*h = sum;
}
hist
}
pub fn main() {
use rand::Rng;
let mut hist = [0.0; 512];
let mut rng = rand::thread_rng();
for i in 0..512 {
hist[i] = rng.gen_range(-1.0..=1.0);
}
let r1 = fft1(hist.clone());
let r2 = fft2(hist.clone());
let mut sum_diff = 0.0;
for (a, b) in r1.iter().zip(r2.iter()) {
sum_diff += (a - b).abs();
}
println!("sum_diff: {}", sum_diff);
}
Basically I'd like to have fft2
output the same thing as fft1
.
As developers of related algorithms, would you please be able to provide some insight as to what kind of transform is being implemented manually here, and how to replace it with something in rustdct
, if this is reasonable at all? Thanks in advance!
It would be very helpful for Fedora packaging purposes if rust_dct updated it's rand usage to 0.8. There are quite a lot of API changes though that I can't sort out - particularly as a non-Rust programmer. Thank you for your consideration.
Hi, and thanks for writing this library!
I'm writing an opus decoder library (link) and am right now wondering whether I can use your crate to provide me the (I)MDCT implementation, or whether using rustfft
directly would make more sense for me. The question is how much wrapper code I'll end up with, how much overhead that wrapper code would mean (eg whether I'd have to scale or not), and whether I can get the API to do what I need in the first place. Generally I would prefer using your library, as I don't think that duplication helps anyone.
The general approach I've chosen to implement my decoder library is to stay inside a "(almost) always working" more, where I start off with the C implementation from libopus, and then port piece to piece to Rust, while still keeping the test suite passing. Now the drawback is that I need to keep the ABI intact, and expose the same functions as C. The C function I need to replace is the following:
https://github.com/xiph/opus/blob/1b9be1a616f38f21f61f2c6b0d51e8763f0c785e/celt/mdct.h#L70-L75
I have some concerns that your API might not provide the needed parameters. e.g. your API seems to lack parameters like overlap
and stride
. Could you check whether its possible to support them?
Thanks in advance!
I'm looking to upgrade/replace the naive DCT implementation in my img_hash crate.
However, I need a 2 dimensional DCT, which I know I can implement with a row-column algorithm of 1D DCTs but I'm wondering if it's possible to produce an optimized 2D DCT.
I imagine, though, this would require RustFFT to implement a 2D FFT algorithm.
Currently, it is not very clear from the documentation how the different DCTs are normalized. Are the same normalization as in the Wikipedia article used?
Hi, I'm currently working on a photometric stereo project and in need of a 2D cosine transform to reconstruct the surface volume with normal integration. Basically I'm trying to port this matlab function: https://github.com/yqueau/normal_integration/blob/master/Toolbox/DCT_Poisson.m. I haven't done signal processing things like fft and dct in a while so I don't remember much what the different dct types of this crate refer to.
I was wondering if you could point me in the correct direction on how to use this crate to write the dct2
and idct2
matlab functions used here and there and if there might be normalization pitfalls I could avoid.
Btw, awesome performance work of rustfft!
The types returned by DctPlanner
cannot be shared with other threads via Arc
because they don't implement Send + Sync
. This should be as simple as adding these as supertraits to all the DCT*
traits in the crate.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.