void JVlibForm::connect_port() { if (seq && strlen(SEQ_dev)) { // create_source_port snd_seq_port_info_t *pinfo; snd_seq_port_info_alloca(&pinfo); // the first created port is 0 anyway, but let's make sure ... snd_seq_port_info_set_port(pinfo, 0); snd_seq_port_info_set_port_specified(pinfo, 1); snd_seq_port_info_set_name(pinfo, "midi_player"); snd_seq_port_info_set_capability(pinfo, 0); snd_seq_port_info_set_type(pinfo, SND_SEQ_PORT_TYPE_MIDI_GENERIC | SND_SEQ_PORT_TYPE_APPLICATION); int err = snd_seq_create_port(seq, pinfo); check_snd("create port", err); ports = (snd_seq_addr_t *)realloc(ports, sizeof(snd_seq_addr_t)); err = snd_seq_parse_address(seq, &ports[0], SEQ_dev); if (err < 0) { QMessageBox::critical(this, "MIDI Player", QString("Invalid port%1\n%2") .arg(SEQ_dev) .arg(snd_strerror(err))); return; } err = snd_seq_connect_to(seq, 0, ports[0].client, ports[0].port); if (err < 0 && err!= -16) QMessageBox::critical(this, "MIDI Player", QString("%4 Cannot connect to port %1:%2 - %3") .arg(ports[0].client) .arg(ports[0].port) .arg(strerror(errno)) .arg(err)); } } // end connect_port
int rtobject_create_alsa_seq_port(rtobject_t* rtobj){ snd_seq_port_info_t* port_info_ptr; int port_id; char *ret; port_id = rtobject_get_address(rtobj); if ((RTOBJECT_MAJOR_TYPE_SIGNAL_PATH == rtobject_get_major_type(rtobj))&&\ (!(strcmp("main", rtobject_get_name(rtobj))))){ ret = strdup("main"); }else{ ret = rtobject_get_absolute_pathname(rtobj); } /*alsa only allows ports from 0 to 256, this is silly but we can only work around*/ if ((port_id < 0)||(port_id > 256)) return -1; /*create an empty port descriptor structure*/ if ((snd_seq_port_info_malloc(&port_info_ptr)) < 0) return -1; /*set port id*/ snd_seq_port_info_set_port(port_info_ptr, port_id); /*set port name*/ snd_seq_port_info_set_name(port_info_ptr, (const char*)ret); /*set capabilities*/ snd_seq_port_info_set_capability(port_info_ptr,\ SND_SEQ_PORT_CAP_WRITE|SND_SEQ_PORT_CAP_SUBS_WRITE); /*set type*/ snd_seq_port_info_set_type(port_info_ptr,SND_SEQ_PORT_TYPE_MIDI_GENERIC); /*create the port*/ if ((snd_seq_create_port(alsa_seq_client_handle, port_info_ptr)) < 0) return -1; /*free port descriptor structure*/ snd_seq_port_info_free(port_info_ptr); free(ret); return 0; }
/** * \brief create a port - simple version * \param seq sequencer handle * \param name the name of the port * \param caps capability bits * \param type type bits * \return the created port number or negative error code * * Creates a port with the given capability and type bits. * * \sa snd_seq_create_port(), snd_seq_delete_simple_port() */ int snd_seq_create_simple_port(snd_seq_t *seq, const char *name, unsigned int caps, unsigned int type) { snd_seq_port_info_t pinfo; int result; memset(&pinfo, 0, sizeof(pinfo)); if (name) strncpy(pinfo.name, name, sizeof(pinfo.name) - 1); pinfo.capability = caps; pinfo.type = type; pinfo.midi_channels = 16; pinfo.midi_voices = 64; /* XXX */ pinfo.synth_voices = 0; /* XXX */ result = snd_seq_create_port(seq, &pinfo); if (result < 0) return result; else return pinfo.addr.port; }
void event_decoder(snd_seq_t *handle, int argc, char *argv[]) { snd_seq_event_t *ev; snd_seq_port_info_t *pinfo; snd_seq_port_subscribe_t *sub; snd_seq_addr_t addr; int client, port, queue, max, err, v1, v2; char *ptr; struct pollfd *pfds; if ((client = snd_seq_client_id(handle))<0) { fprintf(stderr, "Cannot determine client number: %s\n", snd_strerror(client)); return; } printf("Client ID = %i\n", client); if ((queue = snd_seq_alloc_queue(handle))<0) { fprintf(stderr, "Cannot allocate queue: %s\n", snd_strerror(queue)); return; } printf("Queue ID = %i\n", queue); if ((err = snd_seq_nonblock(handle, 1))<0) fprintf(stderr, "Cannot set nonblock mode: %s\n", snd_strerror(err)); snd_seq_port_info_alloca(&pinfo); snd_seq_port_info_set_name(pinfo, "Input"); snd_seq_port_info_set_type(pinfo, SND_SEQ_PORT_TYPE_MIDI_GENERIC); snd_seq_port_info_set_capability(pinfo, SND_SEQ_PORT_CAP_WRITE | SND_SEQ_PORT_CAP_READ | SND_SEQ_PORT_CAP_SUBS_WRITE); /* Enable timestamping for events sent by external subscribers. */ snd_seq_port_info_set_timestamping(pinfo, 1); snd_seq_port_info_set_timestamp_real(pinfo, 1); snd_seq_port_info_set_timestamp_queue(pinfo, queue); if ((err = snd_seq_create_port(handle, pinfo)) < 0) { fprintf(stderr, "Cannot create input port: %s\n", snd_strerror(err)); return; } port = snd_seq_port_info_get_port(pinfo); event_decoder_start_timer(handle, queue, client, port); snd_seq_port_subscribe_alloca(&sub); addr.client = SND_SEQ_CLIENT_SYSTEM; addr.port = SND_SEQ_PORT_SYSTEM_ANNOUNCE; snd_seq_port_subscribe_set_sender(sub, &addr); addr.client = client; addr.port = port; snd_seq_port_subscribe_set_dest(sub, &addr); snd_seq_port_subscribe_set_queue(sub, queue); snd_seq_port_subscribe_set_time_update(sub, 1); snd_seq_port_subscribe_set_time_real(sub, 1); if ((err = snd_seq_subscribe_port(handle, sub))<0) { fprintf(stderr, "Cannot subscribe announce port: %s\n", snd_strerror(err)); return; } addr.client = SND_SEQ_CLIENT_SYSTEM; addr.port = SND_SEQ_PORT_SYSTEM_TIMER; snd_seq_port_subscribe_set_sender(sub, &addr); if ((err = snd_seq_subscribe_port(handle, sub))<0) { fprintf(stderr, "Cannot subscribe timer port: %s\n", snd_strerror(err)); return; } for (max = 0; max < argc; max++) { ptr = argv[max]; if (!ptr) continue; snd_seq_port_subscribe_set_time_real(sub, 0); if (tolower(*ptr) == 'r') { snd_seq_port_subscribe_set_time_real(sub, 1); ptr++; } if (sscanf(ptr, "%i.%i", &v1, &v2) != 2) { fprintf(stderr, "Wrong argument '%s'...\n", argv[max]); return; } addr.client = v1; addr.port = v2; snd_seq_port_subscribe_set_sender(sub, &addr); if ((err = snd_seq_subscribe_port(handle, sub))<0) { fprintf(stderr, "Cannot subscribe port %i from client %i: %s\n", v2, v1, snd_strerror(err)); return; } } max = snd_seq_poll_descriptors_count(handle, POLLIN); pfds = alloca(sizeof(*pfds) * max); while (1) { snd_seq_poll_descriptors(handle, pfds, max, POLLIN); if (poll(pfds, max, -1) < 0) break; do { if ((err = snd_seq_event_input(handle, &ev))<0) break; if (!ev) continue; decode_event(ev); snd_seq_free_event(ev); } while (err > 0); } }
void midi_init() { int rc; snd_seq_port_info_t port; snd_seq_port_subscribe_t sub; int client; if (midi_handle != NULL ) { if (IS_MIDI_DEBUG_ON) { g_print( "Reinitializing MIDI input\n"); } if (midi_file_tag >= 0) { gdk_input_remove( midi_file_tag); midi_file_tag = -1; } close_handle( midi_handle); midi_handle = NULL; } /* Open the sequencer device, in non-block mode. Don't use O_NONBLOCK here, it crashes the application as for ALSA 0.5.5. (LT 15-mar-2000) */ rc = snd_seq_open( &midi_handle, SND_SEQ_OPEN_IN); if (rc < 0) { g_warning( "error opening ALSA MIDI input stream (%s)\n", snd_strerror(rc)); return; } /* Set nonblock mode i.e. enable==0. */ rc = snd_seq_block_mode( midi_handle, 0); if (rc < 0) { close_handle( midi_handle); midi_handle = NULL; g_warning( "error disabling sequencer block mode (%s)\n", snd_strerror(rc)); return; } /* Get client id. Needed to subscribe to the kernel-level client. */ client = snd_seq_client_id( midi_handle); if (client < 0) { close_handle( midi_handle); midi_handle = NULL; g_warning( "error naming sequencer client (%s)\n", snd_strerror(client)); return; } /* Set client name. Visible with 'cat /proc/asound/seq/clients'. */ rc = set_seq_name( midi_handle); if (rc < 0) { close_handle( midi_handle); midi_handle = NULL; g_warning( "error naming sequencer client (%s)\n",snd_strerror(rc)); return; } /* Create a port for our user-level client. */ memset( &port, 0, sizeof(port)); strcpy( port.name, "tracker"); port.capability = SND_SEQ_PORT_CAP_READ | SND_SEQ_PORT_CAP_WRITE; port.capability |= SND_SEQ_PORT_CAP_SUBS_WRITE; /* necessary??? */ port.type = SND_SEQ_PORT_TYPE_APPLICATION; rc = snd_seq_create_port( midi_handle, &port); if (rc < 0) { close_handle( midi_handle); midi_handle = NULL; g_warning( "error creating sequencer port (%s)\n", snd_strerror(rc)); return; } /* Subscribe to the kernel client. */ memset( &sub, 0, sizeof(sub)); sub.sender.client = midi_settings.input.client; sub.sender.port = midi_settings.input.port; sub.dest.client = client; sub.dest.port = port.port; rc = snd_seq_subscribe_port( midi_handle, &sub); if (rc < 0) { close_handle( midi_handle); midi_handle = NULL; g_warning( "error subscribing to client %d port %d (%s)\n", sub.sender.client, sub.sender.port, snd_strerror(rc)); return; } /* Install callback to process MIDI input. */ midi_file_tag = gdk_input_add( snd_seq_file_descriptor( midi_handle), GDK_INPUT_READ, (GdkInputFunction)midi_in_cb, midi_handle); if (midi_file_tag < 0) { close_handle( midi_handle); midi_handle = NULL; g_warning( "error installing MIDI input callback (%s)\n", g_strerror(midi_file_tag)); return; } if (IS_MIDI_DEBUG_ON) { g_print( "MIDI input initialized\n"); } return; } /* midi_init() */