High-level PortMidi bindings and wrappers for Rust

Overview

portmidi-rs

Build Status Documentation

High-level PortMidi bindings for Rust.

PortMidi website: http://portmedia.sourceforge.net/portmidi/

Installation

Add this to your Cargo.toml.

[dependencies]
portmidi = "^0.2"

Prerequisites

You need to make sure you have the PortMidi library installed.

On Ubuntu / Debian:

apt-get install libportmidi-dev

Arch Linux:

pacman -S portmidi

On OSX (Homebrew):

brew install portmidi

On OSX, if you get a linker error ld: library not found for -lportmidi, either,

  • make sure you have the Xcode Command Line Tools installed, not just Xcode, or

  • make sure you have the PortMidi library in your $LIBRARY_PATH, e.g. for Homebrew:

    export LIBRARY_PATH="$LIBRARY_PATH:/usr/local/lib"

Examples

Examples can be run by cloning the repository and running cargo run --example <example name>.

  • play: demonstrates midi output by playing Twinkle Twinkle Little Star (forever...)
  • monitor: demonstrate midi input
  • monitor-all: listens on all-input devices and uses threads and channels

Example: cargo run --example play -- 1 --verbose

Both play and monitor need a device number supplied, run them without an argument to get a list of the connected devices, e.g.

License

Licensed under either of

Apache License, Version 2.0, (LICENSE-APACHE or http://www.apache.org/licenses/LICENSE-2.0)
MIT license (LICENSE-MIT or http://opensource.org/licenses/MIT)

at your option.

Contribution

Unless you explicitly state otherwise, any contribution intentionally submitted for inclusion in the work by you, as defined in the Apache-2.0 license, shall be dual licensed as above, without any additional terms or conditions.

Comments
  • Getting ready for rust 1.0

    Getting ready for rust 1.0

    Rust 1.0 is on the way, so I'm thinking now would be a good time to do any refactoring and tidying up before the masses arrive.

    I'm proposing the following changes:

    • Remove time.rs: it's not required by midi.rs, maybe it belongs in it's own crate? There is rust-event which might be a more full featured solution anyway.
    • Remove util.rs: again it's not required by midi.rs, I would have though most people would be better of with collections from the std lib rather than binding to portmidi's queue library.
    • Flatten midi.rs into lib.rs: this also simplifies the API.
    • Rename variables to conform to rust guidelines
    • 0 warnings

    I'm happy to do the work, but I just want to check to see if this is the direction you'd like to go it.

    opened by samdoshi 25
  • Relicense under dual MIT/Apache-2.0

    Relicense under dual MIT/Apache-2.0

    This issue was automatically generated. Feel free to close without ceremony if you do not agree with re-licensing or if it is not possible for other reasons. Respond to @cmr with any questions or concerns, or pop over to #rust-offtopic on IRC to discuss.

    You're receiving this because someone (perhaps the project maintainer) published a crates.io package with the license as "MIT" xor "Apache-2.0" and the repository field pointing here.

    TL;DR the Rust ecosystem is largely Apache-2.0. Being available under that license is good for interoperation. The MIT license as an add-on can be nice for GPLv2 projects to use your code.

    Why?

    The MIT license requires reproducing countless copies of the same copyright header with different names in the copyright field, for every MIT library in use. The Apache license does not have this drawback. However, this is not the primary motivation for me creating these issues. The Apache license also has protections from patent trolls and an explicit contribution licensing clause. However, the Apache license is incompatible with GPLv2. This is why Rust is dual-licensed as MIT/Apache (the "primary" license being Apache, MIT only for GPLv2 compat), and doing so would be wise for this project. This also makes this crate suitable for inclusion and unrestricted sharing in the Rust standard distribution and other projects using dual MIT/Apache, such as my personal ulterior motive, the Robigalia project.

    Some ask, "Does this really apply to binary redistributions? Does MIT really require reproducing the whole thing?" I'm not a lawyer, and I can't give legal advice, but some Google Android apps include open source attributions using this interpretation. Others also agree with it. But, again, the copyright notice redistribution is not the primary motivation for the dual-licensing. It's stronger protections to licensees and better interoperation with the wider Rust ecosystem.

    How?

    To do this, get explicit approval from each contributor of copyrightable work (as not all contributions qualify for copyright, due to not being a "creative work", e.g. a typo fix) and then add the following to your README:

    ## License
    
    Licensed under either of
    
     * Apache License, Version 2.0, ([LICENSE-APACHE](LICENSE-APACHE) or http://www.apache.org/licenses/LICENSE-2.0)
     * MIT license ([LICENSE-MIT](LICENSE-MIT) or http://opensource.org/licenses/MIT)
    
    at your option.
    
    ### Contribution
    
    Unless you explicitly state otherwise, any contribution intentionally submitted
    for inclusion in the work by you, as defined in the Apache-2.0 license, shall be dual licensed as above, without any
    additional terms or conditions.
    

    and in your license headers, if you have them, use the following boilerplate (based on that used in Rust):

    // Copyright 2016 portmidi-rs Developers
    //
    // Licensed under the Apache License, Version 2.0, <LICENSE-APACHE or
    // http://apache.org/licenses/LICENSE-2.0> or the MIT license <LICENSE-MIT or
    // http://opensource.org/licenses/MIT>, at your option. This file may not be
    // copied, modified, or distributed except according to those terms.
    

    It's commonly asked whether license headers are required. I'm not comfortable making an official recommendation either way, but the Apache license recommends it in their appendix on how to use the license.

    Be sure to add the relevant LICENSE-{MIT,APACHE} files. You can copy these from the Rust repo for a plain-text version.

    And don't forget to update the license metadata in your Cargo.toml to:

    license = "MIT OR Apache-2.0"
    

    I'll be going through projects which agree to be relicensed and have approval by the necessary contributors and doing this changes, so feel free to leave the heavy lifting to me!

    Contributor checkoff

    To agree to relicensing, comment with :

    I license past and future contributions under the dual MIT/Apache-2.0 license, allowing licensees to chose either at their option.
    

    Or, if you're a contributor, you can check the box in this repo next to your name. My scripts will pick this exact phrase up and check your checkbox, but I'll come through and manually review this issue later as well.

    • [ ] @hansjorg
    • [x] @irh
    • [x] @musitdev
    • [x] @samdoshi
    • [x] @steveklabnik
    • [x] @suhr
    • [x] @thenyeguy
    opened by emberian 15
  • On `initialize` and `terminate`

    On `initialize` and `terminate`

    In my opinion it would be more rusty to provide a trait object with something like PortMidi::new() which implements Drop and calls portmidi::terminate when dropped. Both initalize as well as terminate should not be part of the public interface.

    opened by klingtnet 11
  • Add documentation

    Add documentation

    I've generated documentation and added the few shim files needed to make it work with github pages, but I can't make a PR into a new branch, can someone with contribute access here make a gh-pages branch to put the documentation in?

    I've got the documentation in this repo: https://github.com/porglezomp/rust-portmidi/tree/gh-pages, and here's it being hosted on github pages: https://porglezomp.github.io/rust-portmidi

    opened by porglezomp 6
  • Implement Send trait for pm::InputPort and pm::OutputPort

    Implement Send trait for pm::InputPort and pm::OutputPort

    When trying to use portmidi in a multithreaded environment, for example to implement a callback functionality, it is not possible to launch a thread and moving something into that thread that contains an InputPort or OutputPort. The error is: the trait core::marker::Send is not implemented for the type *const libc::c_void

    opened by jonas-k 4
  • Refactor

    Refactor

    I've basically rewritten the complete portmidi bindings crate and updated the examples. If you don't like the changes, don't merge it, otherwise I could use the fork as its own cargo crate. There are still somethings left todo, all in front ~~are unit tests~~ more unit tests and a wrapper for raw midi messages. I don't have much time at the moment, so this will be left as an exercise for other contributors.

    opened by klingtnet 3
  • duration API changes

    duration API changes

    Looks like the duration API was changed recently: https://github.com/rust-lang/rust/issues/16466

    In particular:

    fn milliseconds(millis: i32) -> Duration
    

    to

    fn milliseconds(milliseconds: i64) -> Duration
    
    opened by samdoshi 2
  • Add lifetimes to prevent segfault

    Add lifetimes to prevent segfault

    Sorry for the delay. As announced, the following PR adds some extra lifetime constraint, s.t. the example mentioned in #33 stops compiling. It is, however, not a waterproof solution. The library can still segfault if you create two PortMidi instances, drop one of them and continue to work with the remaining one. Fixing this would require some global state that keeps track of how many PortMidi instances are currently active.

    opened by Woyten 1
  • Add basic wrapper for sysex write

    Add basic wrapper for sysex write

    Hey, I added a wrapper for Pm_WriteSysEx. I tested it on my Novation Launchpad, and it works as intended.

    I am not very familiar with PortMidi or MIDI in general, so let me know if I am missing something important.

    I added a check for the terminator, because looking at the C code here: http://portmedia.sourceforge.net/portmidi/doxygen/portmidi_8c-source.html, it looks like PortMidi will happily write off the edge of the buffer until it hits a terminator.

    opened by jamesmunns 1
  • Implements `Send` for ports

    Implements `Send` for ports

    I've implemented the Send marker trait for the in- and output ports so they can be moved between threads. I've (re-)wrote a test and added an example that uses threads and channels to monitors all available input ports.

    opened by klingtnet 1
  • Fix documentation

    Fix documentation

    It seems as though the documentation on rust-ci is no longer updating: http://www.rust-ci.org/musitdev/rust-portmidi I think quite a lot of people are having similar problems.

    I'm using the following script to manually upload the docs to gh-pages for my midi crate: https://github.com/samdoshi/midi-rs/blob/master/other/update-gh-pages.sh

    It uses https://github.com/davisp/ghp-import which is available via pypi or apt.

    opened by samdoshi 1
  • Some code is unsafe but not marked as unsafe

    Some code is unsafe but not marked as unsafe

    This example segfaults:

    let output_port = {
        let context = PortMidi::new().unwrap();
        let device = context.device(device_number).unwrap();
        context.output_port(device, 1024).unwrap()
    };
    
    output_port.write_message(message); // SEGFAULT
    

    The problem is that output_port outlives context. To be more precise, context calls Pm_Terminate in its destructor rendering output_port invalid. But, unfortunately, outport_port is still accessible after the scope braces. The problem can be solved by adding an artificial lifetime to the DeviceInfo struct, s.t. Rust knows that output_port depends on a DeviceInfo instance which depends on context. Also, DeviceInfo::new should be unsafe and PortMidi::device should validate the device number.

    opened by Woyten 7
  • Running examples without arguments

    Running examples without arguments

    Running cargo run --example play or cargo run --example monitor on master with no arguments displays this error:

    Invalid arguments. Usage: play [-v | --verbose] error: Process didn't exit successfully: target/debug/examples/play (exit code: 1)

    Did I miss something?

    opened by rap2hpoutre 11
  • Basic SysEx support

    Basic SysEx support

    I'm trying to do some SysEx stuff, but it requires a binding for Pm_WriteSysEx and needs to be able to read the full 32 bits that is written to the buffer by the portmidi C library. Is this possible?

    opened by smosher 6
Owner
Philippe Delrieu
Philippe Delrieu
PortAudio bindings and wrappers for Rust.

rust-portaudio PortAudio bindings and wrappers for Rust. PortAudio is a free, cross-platform, open-source, audio I/O library. rust-portaudio is still

null 332 Dec 30, 2022
Thin but safe ALSA wrappers for Rust

ALSA bindings for Rust Thin but safe wrappers for ALSA, the most common API for accessing audio devices on Linux. The ALSA API is rather big, so every

null 91 Dec 26, 2022
A library for constructing Groth-Sahai proofs using pre-built wrappers

Groth-Sahai Wrappers A Rust library containing wrappers that facilitate the construction of non-interactive witness-indistinguishable and zero-knowled

Jacob White 1 Mar 7, 2022
A low-level windowing system geared towards making audio plugin UIs.

baseview A low-level windowing system geared towards making audio plugin UIs. baseview abstracts the platform-specific windowing APIs (winapi, cocoa,

null 155 Dec 30, 2022
Idiomatic Rust bindings for OpenAL 1.1 and extensions (including EFX).

alto alto provides idiomatic Rust bindings for OpenAL 1.1 and extensions (including EFX). WARNING Because Alto interacts with global C state via dynam

null 80 Aug 7, 2022
Rust bindings for the soloud audio engine library

soloud-rs A crossplatform Rust bindings for the soloud audio engine library. Supported formats: wav, mp3, ogg, flac. The library also comes with a spe

Mohammed Alyousef 38 Dec 8, 2022
minimp3 rust bindings + wrapper

minimp3 Rust bindings Usage example # Cargo.toml [dependencies] minimp3 = "0.5" use minimp3::{Decoder, Frame, Error}; use std::fs::File; fn main()

german gömez 52 Dec 2, 2022
Symphonia is a pure Rust audio decoding and media demuxing library supporting AAC, FLAC, MP3, MP4, OGG, Vorbis, and WAV.

Pure Rust multimedia format demuxing, tag reading, and audio decoding library

Philip Deljanov 1k Jan 2, 2023
A library and application for lossless, format-preserving, two-pass optimization and repair of Vorbis data, reducing its size without altering any audio information.

OptiVorbis A library and application for lossless, format-preserving, two-pass optimization and repair of Vorbis data, reducing its size without alter

OptiVorbis 27 Jan 3, 2023
A CLI and library to convert data to sound, and vice versa (dependency-free)

Data to sound A simple crate to convert data to sound, and sound to data. The sound file format is wave (.wav). You can use it as a library or as a co

Awiteb 8 Feb 28, 2023
A Rust environment for sound synthesis and algorithmic composition.

Sorceress A Rust environment for sound synthesis and algorithmic composition, powered by SuperCollider. Overview Sorceress is a Rust crate that provid

Wesley Merkel 82 Dec 26, 2022
Implements the free and open audio codec Opus in Rust.

opus-native Overview Implements the free and open audio codec Opus in Rust. Status This crate is under heavy development. Most functionality is not wo

Nils Hasenbanck 9 Nov 28, 2022
Auritia is a DAW coded in Rust and Vue in hopes of having cross platform compatability, while also providing enough features for anyone to use professionally

Steps Install WebView if you're not on Windows 11 Install Node deps npm i To run the dev server do npm run tauri dev Compiling Linux You will need to

Auritia 20 Aug 27, 2022
Loopers is graphical live looper, written in Rust, designed for ease of use and rock-solid stability

Loopers Loopers is a graphical live looper, written in Rust, designed for ease of use and rock-solid stability. It can be used as a practice tool, com

Micah Wylde 81 Dec 29, 2022
Simple examples to demonstrate full-stack Rust audio plugin dev with baseplug and iced_audio

iced baseplug examples Simple examples to demonstrate full-stack Rust audio plugin dev with baseplug and iced_audio WIP (The GUI knobs do nothing curr

Billy Messenger 10 Sep 12, 2022
A wav encoding and decoding library in Rust

Hound A wav encoding and decoding library in Rust. Hound can read and write the WAVE audio format, an ubiquitous format for raw, uncompressed audio. T

Ruud van Asseldonk 345 Dec 27, 2022
Rust task runner and build tool.

cargo-make Rust task runner and build tool. Overview Installation Binary Release Usage Simple Example Tasks, Dependencies and Aliases Commands, Script

Sagie Gur-Ari 1.8k Jan 7, 2023
ears is a simple library to play Sounds and Musics in Rust

ears ears is a simple library to play Sounds and Musics in Rust. ears is build on the top of OpenAL and libsndfile. Provides an access to the OpenAL s

Jeremy Letang 56 Dec 1, 2022
DSP real time audio synthesis, effect algorithms and utilities for Rust

synfx-dsp synfx-dsp DSP real time audio synthesis, effect algorithms and utilities for Rust Most of the algorithms and implementations in this library

Weird Constructor 8 Nov 23, 2022