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_update_alsa_seq_port_name(rtobject_t* rtobj){ snd_seq_port_info_t* port_info_ptr; int port_id; char *ret; port_id = rtobject_get_address(rtobj); if (port_id < 0){ return -1; } if (!port_id) printf("modifying master path ALSA seq port !\n"); ret = rtobject_get_absolute_pathname(rtobj); /*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, 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); /*set the port info in sequencer*/ if (snd_seq_set_port_info(alsa_seq_client_handle, port_id, port_info_ptr) > 0){ printf("error: couldn't update port info of object being moved\n"); return -1; } /*free port descriptor structure*/ snd_seq_port_info_free(port_info_ptr); free(ret); /*recursively update names of member objects for signal paths*/ if (RTOBJECT_MAJOR_TYPE_SIGNAL_PATH == rtobject_get_major_type(rtobj)){ node_t *temp_node; for (temp_node = ((signal_path_t*)rtobj->imp_struct)->object_list;\ temp_node; \ temp_node = temp_node->next){ rtobject_update_alsa_seq_port_name((rtobject_t*)temp_node->data); } } return 0; }
/** call-seq: capability = bits Set a combination of _SND_SEQ_PORT_CAP+ flags to indicate what this port can do */ static VALUE wrap_snd_seq_port_info_set_capability(VALUE v_port_info, VALUE v_bits) { snd_seq_port_info_t *port_info; Data_Get_Struct(v_port_info, snd_seq_port_info_t, port_info); snd_seq_port_info_set_capability(port_info, NUM2UINT(v_bits)); return Qnil; }
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; }
void MidiAlsaSeq::applyPortMode( MidiPort * _port ) { m_seqMutex.lock(); // determine port-capabilities unsigned int caps[2] = { 0, 0 }; switch( _port->mode() ) { case MidiPort::Duplex: caps[1] |= SND_SEQ_PORT_CAP_READ | SND_SEQ_PORT_CAP_SUBS_READ; case MidiPort::Input: caps[0] |= SND_SEQ_PORT_CAP_WRITE | SND_SEQ_PORT_CAP_SUBS_WRITE; break; case MidiPort::Output: caps[1] |= SND_SEQ_PORT_CAP_READ | SND_SEQ_PORT_CAP_SUBS_READ; break; default: break; } for( int i = 0; i < 2; ++i ) { if( caps[i] != 0 ) { // no port there yet? if( m_portIDs[_port][i] == -1 ) { // then create one; m_portIDs[_port][i] = snd_seq_create_simple_port( m_seqHandle, _port->displayName().toUtf8().constData(), caps[i], SND_SEQ_PORT_TYPE_MIDI_GENERIC | SND_SEQ_PORT_TYPE_APPLICATION ); continue; } snd_seq_port_info_t * port_info; snd_seq_port_info_malloc( &port_info ); snd_seq_get_port_info( m_seqHandle, m_portIDs[_port][i], port_info ); snd_seq_port_info_set_capability( port_info, caps[i] ); snd_seq_set_port_info( m_seqHandle, m_portIDs[_port][i], port_info ); snd_seq_port_info_free( port_info ); } // still a port there although no caps? ( = dummy port) else if( m_portIDs[_port][i] != -1 ) { // then remove this port snd_seq_delete_simple_port( m_seqHandle, m_portIDs[_port][i] ); m_portIDs[_port][i] = -1; } } m_seqMutex.unlock(); }
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); } }