rimd icon indicating copy to clipboard operation
rimd copied to clipboard

Need an example to readme

Open anton-okolelov opened this issue 10 years ago • 5 comments

Thank you for writing rimd lib!

Could you please add an example of creating midi-file that plays a note (for example to readme)? It would be really helpful, because it's too complicated to puzzle out midi format, rust language and rimd library simultaneously.

anton-okolelov avatar Nov 16 '15 19:11 anton-okolelov

Sure. So, rimd doesn't really deal with playing midi notes, just the midi files. There are a number of other libraries for playing notes like the portaudio ones, or rust-jack. I've tried to keep the format that rimd stores midi notes very simple so it's easy to inter-operate with those libraries.

That said, you're right, this will usually be used in the context of a bigger library and I should add an example of using it somehow. I'm swamped right now, but will get to that in the near future.

nicklan avatar Nov 16 '15 21:11 nicklan

This might be fun to use for the example?

mitchmindtree avatar Nov 17 '15 01:11 mitchmindtree

Thank you for the response.

I'd like to explain. I'm trying to write a program that is some kind of composer. It compose music and write it to midi file. And I have trouble doing it. Here is my try:

extern crate rimd;

use rimd::{MidiMessage,SMFBuilder,SMFWriter,TrackEvent,Event};
use std::path::Path;

fn main() {

    let note_on = MidiMessage::note_on(69,100,0);
    let note_off = MidiMessage::note_off(69,100,0);


    let mut builder = SMFBuilder::new();
    builder.add_track();

    builder.add_event(0, TrackEvent{vtime: 5, event: Event::Midi(note_on)});
    builder.add_event(0, TrackEvent{vtime: 0, event: Event::Midi(note_off)});

    let mut smf = builder.result();

    smf.division = 96;
   let writer = SMFWriter::from_smf(smf);
   let result = writer.write_to_file(Path::new("/home/user/file.smf"));

}

It creates file.smf, but when I run timidity file.smf I hear nothing. So, I don't understand what I'm doing wrong. Maybe I don't understand midi format, maybe I know rust too bad, maybe there is something that I had to do in rimd api.

If there was a start point ( a simple example with one note wrote to midi file) I would easily extend it to my program

anton-okolelov avatar Nov 17 '15 04:11 anton-okolelov

Sorry for the super long delay in getting back to you! Anyway, there were two issues here. rimd was indeed broken, but the way you were using it was as well. If you want to add those events you'd want to do:

    builder.add_event(0, TrackEvent{vtime: 0, event: Event::Midi(note_on)});
    builder.add_event(0, TrackEvent{vtime: 5, event: Event::Midi(note_off)});

Note the switch of the 0 and the 5 in the first parameter. add_event like that adds the event with the number of ticks after the current last event in the track. Doing first 5 then 0 would add, at time 5, two events, a note on and a note off, which is why you didn't hear anything. Doing 0 and then 5 will play the note for 5 ticks. (that order was causing a panic before which was a real bug in rimd which is fixed and pushed)

BTW, for simple smf creation you might find using the add_midi_rel and add_meta_rel functions a bit easier since they allow thinking in relative time.

If things are working for you now, please close this, otherwise, let me know what's broken now :)

nicklan avatar Feb 09 '16 06:02 nicklan

Is there still interest in this issue?

If so, I have managed to create a working demo of the library at https://github.com/Benjamin-Davies/rimd-demo/blob/master/src/main.rs. It feels a bit bulky to put into a README though, so maybe we should reduce it to just a single note without any of the meta-events.

I would be happy to alter the example and create a pull request.

Benjamin-Davies avatar Dec 06 '19 20:12 Benjamin-Davies