To create a rawmidi device, call the snd_rawmidi_new function:

  struct snd_rawmidi *rmidi;
  err = snd_rawmidi_new(chip->card, "MyMIDI", 0, outs, ins, &rmidi);
  if (err < 0)
          return err;
  rmidi->private_data = chip;
  strcpy(rmidi->name, "My MIDI");
  rmidi->info_flags = SNDRV_RAWMIDI_INFO_OUTPUT |
                      SNDRV_RAWMIDI_INFO_INPUT |


The first argument is the card pointer, the second argument is the ID string.

The third argument is the index of this component. You can create up to 8 rawmidi devices.

The fourth and fifth arguments are the number of output and input substreams, respectively, of this device (a substream is the equivalent of a MIDI port).

Set the info_flags field to specify the capabilities of the device. Set SNDRV_RAWMIDI_INFO_OUTPUT if there is at least one output port, SNDRV_RAWMIDI_INFO_INPUT if there is at least one input port, and SNDRV_RAWMIDI_INFO_DUPLEX if the device can handle output and input at the same time.

After the rawmidi device is created, you need to set the operators (callbacks) for each substream. There are helper functions to set the operators for all the substreams of a device:

  snd_rawmidi_set_ops(rmidi, SNDRV_RAWMIDI_STREAM_OUTPUT, &snd_mymidi_output_ops);
  snd_rawmidi_set_ops(rmidi, SNDRV_RAWMIDI_STREAM_INPUT, &snd_mymidi_input_ops);


The operators are usually defined like this:

  static struct snd_rawmidi_ops snd_mymidi_output_ops = {
          .open =    snd_mymidi_output_open,
          .close =   snd_mymidi_output_close,
          .trigger = snd_mymidi_output_trigger,


These callbacks are explained in the Callbacks section.

If there are more than one substream, you should give a unique name to each of them:

  struct snd_rawmidi_substream *substream;
                      list {
          sprintf(substream->name, "My MIDI Port %d", substream->number + 1);