Giter VIP home page Giter VIP logo

aubio-rs's Introduction

Safe bindings for aubio library

github crate docs GPL-3.0 CI

This crate provides safe Rust bindings to aubio C library.

Aubio is a library to label music and sounds.

It listens to audio signals and attempts to detect events. For instance, when a drum is hit, at which frequency is a note, or at what tempo is a rhythmic melody.

Its features include segmenting a sound file before each of its attacks, performing pitch detection, tapping the beat and producing midi streams from live audio.

Aubio provide several algorithms and routines, including:

  • several onset detection methods
  • different pitch detection methods
  • tempo tracking and beat detection
  • MFCC (mel-frequency cepstrum coefficients)
  • FFT and phase vocoder
  • up/down-sampling
  • digital filters (low pass, high pass, and more)
  • spectral filtering
  • transient/steady-state separation
  • sound file read and write access
  • various mathematics utilities for music applications

The name aubio comes from audio with a typo: some errors are likely to be found in the results.

Crate features

The following features can be used to customize configuration:

  • bindgen Force generate bindings itself instead of use pre-generated (useful for unsupported archs)
  • builtin Force compile builtin aubio C library
  • pkg-config Use pkg-config to find installed libraries
  • shared Build shared aubio C-library
  • static Build static aubio C-library
  • fftw3 Enable using fftw3 library
  • intelipp Enable using Intel IPP library
  • accelerate Enable using acceleration framework on apple platforms
  • blas Enable using blas library
  • atlas Enable using atlas library
  • double Enable double presicion of audio sample data

When pkg-config feature is used the installed aubio library will be used if found.

To force build and link builtin version you can use builtin feature.

The features such as fftw3, intelipp, accelerate, blas, atlas and double is take an effect only for builtin aubio C library.

aubio-rs's People

Contributors

katyo avatar kukuen avatar polochon-street avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar

aubio-rs's Issues

How do I import the aubio-rs crate in the main file and how do I get started with it?

So with this crate: https://docs.rs/aubio-rs/0.1.3/aubio_rs/

I already put it in the Cargo.toml file, but in the main.rs file how would I import this library?

I additionally want to know how do I get started with this as I am very lost. How would I import a music and start analysing the data on the song etc?

Another question is am I able to determine beats per second, the loudness in the current point of the music, the pitch/key signature and play the audio file or do I need another library/crate?

Build it for use inside swift project

Hi I'm trying to run this as part of a swift project.
I have added this
aubio = {version = "0.2.1", features = ["builtin", "bindgen"]}

But I get errors like this

linking with `cc` failed: exit status: 1
library not found for -lSystem
          clang: error: linker command failed with exit code 1 (use -v to see invocation)

Any idea what I'm doing wrong?

Tree borrows violation in `FMat<FMatVecs>`

I've been experimenting with a version of Miri that can execute foreign functions by interpreting the LLVM bytecode that is produced during a crate's build process.

Miri found an instance of undefined behavior in aubio-rs at version 0.2.1 when running the test filterbank::test::test_filterbank.

error: Borrowing Violation: deallocation through <113586> is forbidden
   --> .../rust/library/alloc/src/alloc.rs:117:14
    |
117 |     unsafe { __rust_dealloc(ptr, layout.size(), layout.align()) }
    |              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ deallocation through <113586> is forbidden
    |
    = help: this indicates a potential bug in the program: it performed an invalid operation, but the Tree Borrows rules it violated are still experimental
    = help: the accessed tag <113586> is a child of the conflicting tag <113523>
    = help: the conflicting tag <113523> has state Frozen which forbids this deallocation (acting as a child write access)
help: the accessed tag <113586> was created here
   --> src/filterbank.rs:65:5
    |
65  |     }
    |     ^
help: the conflicting tag <113523> was created here, in the initial state Reserved
   --> src/filterbank.rs:55:34
    |
55  |     pub fn set_coeffs(&mut self, filters: FMat<FMatVecs>) {
    |                                  ^^^^^^^
    = help: the conflicting tag <113523> later transitioned to Frozen due to a foreign read access at offsets [0x0..0x8]
    = help: this transition corresponds to a loss of write permissions
    = note: BACKTRACE (of the first span):
    = note: inside `std::alloc::dealloc` at .../rust/library/alloc/src/alloc.rs:117:14: 117:64
    = note: ...
    = note: inside `std::ptr::drop_in_place::<vec::FMat<'_, std::vec::Vec<*const f32>>> - shim(Some(vec::FMat<'_, std::vec::Vec<*const f32>>))` at .../rust/library/core/src/ptr/mod.rs:497:1: 497:56
note: inside `filterbank::FilterBank::set_coeffs`
   --> src/filterbank.rs:65:5
    |
65  |     }
    |     ^
note: inside `filterbank::test::test_filterbank_do`
   --> src/filterbank.rs:143:9
    |
143 |         filter_bank.set_coeffs(filters.into());
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
note: inside closure
   --> src/filterbank.rs:136:29
    |
135 |     #[test]
    |     ------- in this procedural macro expansion
136 |     fn test_filterbank_do() {
    |                             

I believe this is because FMat is a self-referential structure. Consider the implementation of From<T> on line 427 of src/vec.rs:

Self {
    fmat: ffi::fmat_t {
        height: data.len() as _,
        length: data[0].len() as _,
        data: array.as_ptr() as _,
    },
    _x: array,
    _pd: PhantomData,
}

When self.fmat.data is read, it counts as a “foreign read access” under Tree Borrows, which makes the field self._x have a read only permission. This means that when self._x is dropped, it counts as writing with a read-only permission, which is undefined behavior.

To fix this, you would need to modify FMat to only retain a single reference to array instead of having both array and data as aliases.

error: failed to run custom build command for `aubio-lib v0.1.3`

Hi, I've declared aubio-rs, aubio-lib dependencies like so in my Cargo.toml below.

[dependencies]
aubio-rs = "0.1.3"
aubio-lib = "0.1.3"

When I run cross build --target armv7-unknown-linux-gnueabihf; I get this error

   Compiling aubio-lib v0.1.3
error: failed to run custom build command for `aubio-lib v0.1.3`

Caused by:
  process didn't exit successfully: `/target/debug/build/aubio-lib-adc15eda5648b6ac/build-script-build` (exit code: 101)
  --- stderr
  Fetch aubio from https://github.com/katyo/aubio-rs/releases/download/aubio-0.5.0-git1f23a23d/aubio-0.5.0-git1f23a23d.tar.gz to /target/armv7-unknown-linux-gnueabihf/debug/build/aubio-lib-aca86f569eccc5b7/out/source/0.5.0-git1f23a23d
  Run command: "python" "waf" "--verbose" "--build-type" "debug" "--jobs" "16" "--disable-docs" "--disable-tests" "--disable-examples" "--disable-double" "--disable-fftw3f" "--disable-fftw3" "--disable-wavread" "--disable-wavwrite" "--disable-jack" "--disable-sndfile" "--disable-avcodec" "--disable-samplerate" "--out" "/target/armv7-unknown-linux-gnueabihf/debug/build/aubio-lib-aca86f569eccc5b7/out/build/0.5.0-git1f23a23d" "--prefix" "/target/armv7-unknown-linux-gnueabihf/debug/build/aubio-lib-aca86f569eccc5b7/out/build/0.5.0-git1f23a23d" "configure"
  thread 'main' panicked at 'Failed to run command '"python" "waf" "--verbose" "--build-type" "debug" "--jobs" "16" "--disable-docs" "--disable-tests" "--disable-examples" "--disable-double" "--disable-fftw3f" "--disable-fftw3" "--disable-wavread" "--disable-wavwrite" "--disable-jack" "--disable-sndfile" "--disable-avcodec" "--disable-samplerate" "--out" "/target/armv7-unknown-linux-gnueabihf/debug/build/aubio-lib-aca86f569eccc5b7/out/build/0.5.0-git1f23a23d" "--prefix" "/target/armv7-unknown-linux-gnueabihf/debug/build/aubio-lib-aca86f569eccc5b7/out/build/0.5.0-git1f23a23d" "configure"' due to: No such file or directory (os error 2)', /cargo/registry/src/github.com-1ecc6299db9ec823/aubio-lib-0.1.3/build.rs:191:17
  note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
./target/armv7-unknown-linux-gnueabihf/debug/ledstars: No such file or directory

I believe this is because the script assumes the build environment contains a Python executable in the path environment variable.

Windows support (mingw, travis)

Currently windows builds disabled due to strange error:

error: failed to run custom build command for `aubio-lib v0.1.2 (C:\Users\travis\build\katyo\aubio-rs\aubio-lib)`
Caused by:
  process didn't exit successfully: `C:\Users\travis\build\katyo\aubio-rs\target\release\build\aubio-lib-c16645850cc4bf39\build-script-build` (exit code: 101)
--- stderr
Fetch aubio from https://github.com/katyo/aubio-rs/releases/download/aubio-0.5.0-git1f23a23d/aubio-0.5.0-git1f23a23d.tar.gz to C:\Users\travis\build\katyo\aubio-rs\target\release\build\aubio-lib-bc0d25f50c988cce\out\source\0.5.0-git1f23a23d
Run command: "python" "waf" "--verbose" "--build-type" "release" "--jobs" "2" "--disable-docs" "--disable-tests" "--disable-examples" "--disable-double" "--disable-fftw3f" "--disable-fftw3" "--disable-wavread" "--disable-wavwrite" "--disable-jack" "--disable-sndfile" "--disable-avcodec" "--disable-samplerate" "--out" "C:\\Users\\travis\\build\\katyo\\aubio-rs\\target\\release\\build\\aubio-lib-bc0d25f50c988cce\\out\\build\\0.5.0-git1f23a23d" "--prefix" "C:\\Users\\travis\\build\\katyo\\aubio-rs\\target\\release\\build\\aubio-lib-bc0d25f50c988cce\\out\\build\\0.5.0-git1f23a23d" "configure"
thread 'main' panicked at 'Command '"python" "waf" "--verbose" "--build-type" "release" "--jobs" "2" "--disable-docs" "--disable-tests" "--disable-examples" "--disable-double" "--disable-fftw3f" "--disable-fftw3" "--disable-wavread" "--disable-wavwrite" "--disable-jack" "--disable-sndfile" "--disable-avcodec" "--disable-samplerate" "--out" "C:\\Users\\travis\\build\\katyo\\aubio-rs\\target\\release\\build\\aubio-lib-bc0d25f50c988cce\\out\\build\\0.5.0-git1f23a23d" "--prefix" "C:\\Users\\travis\\build\\katyo\\aubio-rs\\target\\release\\build\\aubio-lib-bc0d25f50c988cce\\out\\build\\0.5.0-git1f23a23d" "configure"' failed (stdout: Setting top to                           : C:\Users\travis\build\katyo\aubio-rs\target\release\build\aubio-lib-bc0d25f50c988cce\out\source\0.5.0-git1f23a23d 
Setting out to                           : C:\Users\travis\build\katyo\aubio-rs\target\release\build\aubio-lib-bc0d25f50c988cce\out\build\0.5.0-git1f23a23d 
Checking for 'msvc' (C compiler)         : 14:59:19 runner ['C:\\Program Files (x86)\\Microsoft Visual Studio\\Installer\\vswhere.exe', '-products', '*', '-legacy', '-format', 'json']
Traceback (most recent call last):
  File "C:\Users\travis\build\katyo\aubio-rs\target\release\build\aubio-lib-bc0d25f50c988cce\out\source\0.5.0-git1f23a23d/waflib/Scripting.py", line 119, in waf_entry_point
    run_commands()
  File "C:\Users\travis\build\katyo\aubio-rs\target\release\build\aubio-lib-bc0d25f50c988cce\out\source\0.5.0-git1f23a23d/waflib/Scripting.py", line 182, in run_commands
    ctx=run_command(cmd_name)
  File "C:\Users\travis\build\katyo\aubio-rs\target\release\build\aubio-lib-bc0d25f50c988cce\out\source\0.5.0-git1f23a23d/waflib/Scripting.py", line 173, in run_command
    ctx.execute()
  File "C:\Users\travis\build\katyo\aubio-rs\target\release\build\aubio-lib-bc0d25f50c988cce\out\source\0.5.0-git1f23a23d/waflib/Configure.py", line 85, in execute
    super(ConfigurationContext,self).execute()
  File "C:\Users\travis\build\katyo\aubio-rs\target\release\build\aubio-lib-bc0d25f50c988cce\out\source\0.5.0-git1f23a23d/waflib/Context.py", line 92, in execute
    self.recurse([os.path.dirname(g_module.root_path)])
  File "C:\Users\travis\build\katyo\aubio-rs\target\release\build\aubio-lib-bc0d25f50c988cce\out\source\0.5.0-git1f23a23d/waflib/Context.py", line 133, in recurse
    user_function(self)
  File "C:\Users\travis\build\katyo\aubio-rs\target\release\build\aubio-lib-bc0d25f50c988cce\out\source\0.5.0-git1f23a23d\wscript", line 134, in configure
    ctx.load('compiler_c')
  File "C:\Users\travis\build\katyo\aubio-rs\target\release\build\aubio-lib-bc0d25f50c988cce\out\source\0.5.0-git1f23a23d/waflib/Configure.py", line 156, in load
    func(self)
  File "C:\Users\travis\build\katyo\aubio-rs\target\release\build\aubio-lib-bc0d25f50c988cce\out\source\0.5.0-git1f23a23d/waflib/Tools/compiler_c.py", line 23, in configure
    conf.load(compiler)
  File "C:\Users\travis\build\katyo\aubio-rs\target\release\build\aubio-lib-bc0d25f50c988cce\out\source\0.5.0-git1f23a23d/waflib/Configure.py", line 156, in load
    func(self)
  File "C:\Users\travis\build\katyo\aubio-rs\target\release\build\aubio-lib-bc0d25f50c988cce\out\source\0.5.0-git1f23a23d/waflib/Tools/msvc.py", line 543, in configure
    conf.autodetect(True)
  File "C:\Users\travis\build\katyo\aubio-rs\target\release\build\aubio-lib-bc0d25f50c988cce\out\source\0.5.0-git1f23a23d/waflib/Configure.py", line 175, in fun
    return f(*k,**kw)
  File "C:\Users\travis\build\katyo\aubio-rs\target\release\build\aubio-lib-bc0d25f50c988cce\out\source\0.5.0-git1f23a23d/waflib/Tools/msvc.py", line 561, in autodetect
    compiler,version,path,includes,libdirs,cpu=conf.detect_msvc()
  File "C:\Users\travis\build\katyo\aubio-rs\target\release\build\aubio-lib-bc0d25f50c988cce\out\source\0.5.0-git1f23a23d/waflib/Configure.py", line 175, in fun
    return f(*k,**kw)
  File "C:\Users\travis\build\katyo\aubio-rs\target\release\build\aubio-lib-bc0d25f50c988cce\out\source\0.5.0-git1f23a23d/waflib/Tools/msvc.py", line 461, in detect_msvc
    return self.setup_msvc(self.get_msvc_versions())
  File "C:\Users\travis\build\katyo\aubio-rs\target\release\build\aubio-lib-bc0d25f50c988cce\out\source\0.5.0-git1f23a23d/waflib/Configure.py", line 175, in fun
    return f(*k,**kw)
  File "C:\Users\travis\build\katyo\aubio-rs\target\release\build\aubio-lib-bc0d25f50c988cce\out\source\0.5.0-git1f23a23d/waflib/Tools/msvc.py", line 469, in get_msvc_versions
    self.gather_vswhere_versions(dct)
  File "C:\Users\travis\build\katyo\aubio-rs\target\release\build\aubio-lib-bc0d25f50c988cce\out\source\0.5.0-git1f23a23d/waflib/Configure.py", line 175, in fun
    return f(*k,**kw)
  File "C:\Users\travis\build\katyo\aubio-rs\target\release\build\aubio-lib-bc0d25f50c988cce\out\source\0.5.0-git1f23a23d/waflib/Tools/msvc.py", line 311, in gather_vswhere_versions
    txt=txt.decode(Utils.console_encoding())
LookupError: unknown encoding: cp65001
) (stderr: )', aubio-lib\build.rs:195:21
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
 Downloading crates ...
  Downloaded hound v3.4.0
   Compiling hound v3.4.0
   Compiling aubio-rs v0.1.2 (C:\Users\travis\build\katyo\aubio-rs\aubio-rs)
   Compiling aubio-lib v0.1.2 (C:\Users\travis\build\katyo\aubio-rs\aubio-lib)
The command "(cd aubio-rs && cargo test --release)" exited with 101.
1.87s$ (cd aubio-rs && cargo test --release --features log)
error: failed to run custom build command for `aubio-lib v0.1.2 (C:\Users\travis\build\katyo\aubio-rs\aubio-lib)`

Because that related to waf (and particularly python) I temporarly disable windows support.
I tried to fix it using solutions from stackoverflow but nothing help me to do it.
I'm not an expert in windows so I don't understand what happens wrong and how it can be fixed.

Segmentation fault(core dumped)

I am trying to do tempo detection on a mp3 file decoded by symphonia, but everythime I do let tempo = tempo.do_result(samples).unwrap(); I get a segfault.

I tried to properly handling the result, which didn't help. I also tried the builtin for a standalone solution and pkg-config flags with aubio installed as a library package, which also didn't help. I guess the error is coming from the underlying C code? Maybe the formatting of the samples is wrong or something?

Example Code
   pub fn get_tempo(file_path: &str) -> f32 {
     // let mut reader = WavReader::open("./test.wav").unwrap();
     let mut reader = Player::new_reader(file_path);
     let track = reader.default_track().unwrap();
     let num_samples = track.codec_params.n_frames.unwrap();
     let sample_rate = track.codec_params.sample_rate.unwrap();
     // let sample_format = track.codec_params.sample_format.unwrap();
     let dec_opts: DecoderOptions = DecoderOptions {
         verify: true,
         ..Default::default()
     };
     let mut decoder = symphonia::default::get_codecs()
         .make(&track.codec_params, &dec_opts)
         .unwrap();
     let mut samples = vec![0 as f32; num_samples as usize];
     let mut tempo = Tempo::new(aubio::OnsetMode::Hfc, 1024, 512, sample_rate).unwrap();
     let mut sample_buf: Option<SampleBuffer<f32>> = None;
     while let Ok(p) = reader.next_packet() {
         let audio_buf = decoder.decode(&p).unwrap();
         // let num_samples = audio_buf.frames();
         // Copy the decoded audio buffer into the sample buffer in an interleaved format.
         match &mut sample_buf {
             Some(buf) => {
                 buf.copy_interleaved_ref(audio_buf);
                 let packet_samples = buf.samples();
                 // println!("{:#?}", packet_samples);
                 samples.extend_from_slice(packet_samples);
             }
             None => {
                 println!("init sample buffer!");
                 let spec = *audio_buf.spec();
                 // Get the capacity of the decoded buffer. Note: This is capacity, not length!
                 let duration = audio_buf.capacity() as u64;
                 // Create the f32 sample buffer.
                 sample_buf = Some(SampleBuffer::<f32>::new(duration, spec));
             }
         }
     }
     println!("starting analysis");
     let tempo = match tempo.do_result(samples) {
         Ok(x) => x,
         Err(err) => {
             println!("{:#?}", err);
             0 as f32
         }
     };
     tempo
 }

How to use the Resampler

Hey,
first of all thanks you for your work.

I am a bit confused about how to use some parts of your lib.

For example: I would like to resample some wav files. But I don't know which parameters I have use to call the function do_.

let output_sample_rate = 8000;
let mut reader = WavReader::open("./test.wav").unwrap();
let input_sample_rate = reader.spec().sample_rate;
let ratio = (output_sample_rate / input_sample_rate) as f32;
let mut rs = Resampler::new(ratio, ResampleMode::BestQuality).unwrap();

do_ takes structs from your library. One can construct them by calling FVec::from and FVecMut::from but I have a BufReader<File> as input and what as output? And how to pass/convert a BufReader<File> to [f32]

Maybe my question is stupid - but it would be really nice if you support me.

In general it would be a massiv improvement to have more examples :)
Best :)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.