void AlsaSeqMidiInDriver::open(device_id_t device) { if (this->is_open()) throw std::logic_error("Device already open"); int err; err = snd_seq_open(&m_impl->seq, "default", SND_SEQ_OPEN_INPUT, SND_SEQ_NONBLOCK); if ( err < 0) { throw std::runtime_error("Error opening ALSA sequencer."); } std::ostringstream os; os << "gephex input " << device; std::string device_name = os.str(); err = snd_seq_set_client_name(m_impl->seq, device_name.c_str()); err = snd_seq_create_simple_port(m_impl->seq, device_name.c_str(), SND_SEQ_PORT_CAP_WRITE| SND_SEQ_PORT_CAP_SUBS_WRITE, SND_SEQ_PORT_TYPE_APPLICATION); if (err < 0) { snd_seq_close (m_impl->seq); throw std::runtime_error("Error creating sequencer port."); } else { m_impl->portid = err; snd_seq_ev_clear (&m_impl->SEv); snd_seq_ev_set_source (&m_impl->SEv, m_impl->portid); snd_seq_ev_set_subs (&m_impl->SEv); snd_seq_ev_set_direct (&m_impl->SEv); } if( snd_midi_event_new (32, &m_impl->decoder) ) throw std::runtime_error ("Error creating midi event parser"); snd_midi_event_init(m_impl->decoder); snd_midi_event_no_status (m_impl->decoder,1); }
/* * register a new port if it doesn't exist yet */ int snd_seq_oss_midi_check_new_port(struct snd_seq_port_info *pinfo) { int i; struct seq_oss_midi *mdev; unsigned long flags; /* the port must include generic midi */ if (! (pinfo->type & SNDRV_SEQ_PORT_TYPE_MIDI_GENERIC)) return 0; /* either read or write subscribable */ if ((pinfo->capability & PERM_WRITE) != PERM_WRITE && (pinfo->capability & PERM_READ) != PERM_READ) return 0; /* * look for the identical slot */ if ((mdev = find_slot(pinfo->addr.client, pinfo->addr.port)) != NULL) { /* already exists */ snd_use_lock_free(&mdev->use_lock); return 0; } /* * allocate midi info record */ mdev = kzalloc(sizeof(*mdev), GFP_KERNEL); if (!mdev) return -ENOMEM; /* copy the port information */ mdev->client = pinfo->addr.client; mdev->port = pinfo->addr.port; mdev->flags = pinfo->capability; mdev->opened = 0; snd_use_lock_init(&mdev->use_lock); /* copy and truncate the name of synth device */ strlcpy(mdev->name, pinfo->name, sizeof(mdev->name)); /* create MIDI coder */ if (snd_midi_event_new(MAX_MIDI_EVENT_BUF, &mdev->coder) < 0) { pr_err("ALSA: seq_oss: can't malloc midi coder\n"); kfree(mdev); return -ENOMEM; } /* OSS sequencer adds running status to all sequences */ snd_midi_event_no_status(mdev->coder, 1); /* * look for en empty slot */ spin_lock_irqsave(®ister_lock, flags); for (i = 0; i < max_midi_devs; i++) { if (midi_devs[i] == NULL) break; } if (i >= max_midi_devs) { if (max_midi_devs >= SNDRV_SEQ_OSS_MAX_MIDI_DEVS) { spin_unlock_irqrestore(®ister_lock, flags); snd_midi_event_free(mdev->coder); kfree(mdev); return -ENOMEM; } max_midi_devs++; } mdev->seq_device = i; midi_devs[mdev->seq_device] = mdev; spin_unlock_irqrestore(®ister_lock, flags); return 0; }
int snd_rawmidi_virtual_open(snd_rawmidi_t **inputp, snd_rawmidi_t **outputp, const char *name, snd_seq_t *seq_handle, int port, int merge, int mode) { int err; snd_rawmidi_t *rmidi; snd_rawmidi_virtual_t *virt = NULL; struct pollfd pfd; if (inputp) *inputp = 0; if (outputp) *outputp = 0; virt = calloc(1, sizeof(*virt)); if (virt == NULL) { err = -ENOMEM; goto _err; } virt->handle = seq_handle; virt->port = port; err = snd_midi_event_new(256, &virt->midi_event); if (err < 0) goto _err; snd_midi_event_init(virt->midi_event); snd_midi_event_no_status(virt->midi_event, !merge); if (inputp) { rmidi = calloc(1, sizeof(*rmidi)); if (rmidi == NULL) { err = -ENOMEM; goto _err; } if (name) rmidi->name = strdup(name); rmidi->type = SND_RAWMIDI_TYPE_VIRTUAL; rmidi->stream = SND_RAWMIDI_STREAM_INPUT; rmidi->mode = mode; err = snd_seq_poll_descriptors(seq_handle, &pfd, 1, POLLIN); if (err < 0) goto _err; rmidi->poll_fd = pfd.fd; rmidi->ops = &snd_rawmidi_virtual_ops; rmidi->private_data = virt; virt->open++; *inputp = rmidi; } if (outputp) { rmidi = calloc(1, sizeof(*rmidi)); if (rmidi == NULL) { err = -ENOMEM; goto _err; } if (name) rmidi->name = strdup(name); rmidi->type = SND_RAWMIDI_TYPE_VIRTUAL; rmidi->stream = SND_RAWMIDI_STREAM_OUTPUT; rmidi->mode = mode; err = snd_seq_poll_descriptors(seq_handle, &pfd, 1, POLLOUT); if (err < 0) goto _err; rmidi->poll_fd = pfd.fd; rmidi->ops = &snd_rawmidi_virtual_ops; rmidi->private_data = virt; virt->open++; *outputp = rmidi; } return 0; _err: if (seq_handle) snd_seq_close(seq_handle); if (virt) { if (virt->midi_event) snd_midi_event_free(virt->midi_event); free(virt); } if (inputp) free(*inputp); if (outputp) free(*outputp); return err; }
int snd_seq_oss_midi_check_new_port(struct snd_seq_port_info *pinfo) { int i; struct seq_oss_midi *mdev; unsigned long flags; debug_printk(("check for MIDI client %d port %d\n", pinfo->addr.client, pinfo->addr.port)); /* */ if (! (pinfo->type & SNDRV_SEQ_PORT_TYPE_MIDI_GENERIC)) return 0; /* */ if ((pinfo->capability & PERM_WRITE) != PERM_WRITE && (pinfo->capability & PERM_READ) != PERM_READ) return 0; /* */ if ((mdev = find_slot(pinfo->addr.client, pinfo->addr.port)) != NULL) { /* */ snd_use_lock_free(&mdev->use_lock); return 0; } /* */ if ((mdev = kzalloc(sizeof(*mdev), GFP_KERNEL)) == NULL) { snd_printk(KERN_ERR "can't malloc midi info\n"); return -ENOMEM; } /* */ mdev->client = pinfo->addr.client; mdev->port = pinfo->addr.port; mdev->flags = pinfo->capability; mdev->opened = 0; snd_use_lock_init(&mdev->use_lock); /* */ strlcpy(mdev->name, pinfo->name, sizeof(mdev->name)); /* */ if (snd_midi_event_new(MAX_MIDI_EVENT_BUF, &mdev->coder) < 0) { snd_printk(KERN_ERR "can't malloc midi coder\n"); kfree(mdev); return -ENOMEM; } /* */ snd_midi_event_no_status(mdev->coder, 1); /* */ spin_lock_irqsave(®ister_lock, flags); for (i = 0; i < max_midi_devs; i++) { if (midi_devs[i] == NULL) break; } if (i >= max_midi_devs) { if (max_midi_devs >= SNDRV_SEQ_OSS_MAX_MIDI_DEVS) { spin_unlock_irqrestore(®ister_lock, flags); snd_midi_event_free(mdev->coder); kfree(mdev); return -ENOMEM; } max_midi_devs++; } mdev->seq_device = i; midi_devs[mdev->seq_device] = mdev; spin_unlock_irqrestore(®ister_lock, flags); return 0; }