int ALSAMidiIn::getalsaid() { if(midi_handle) { snd_seq_client_info_t *seq_info; snd_seq_client_info_malloc(&seq_info); snd_seq_get_client_info(midi_handle, seq_info); int id = snd_seq_client_info_get_client(seq_info); snd_seq_client_info_free(seq_info); return id; } return -1; }
/* * Class: org_tritonus_lowlevel_alsa_AlsaSeqClientInfo * Method: malloc * Signature: ()I */ JNIEXPORT jint JNICALL Java_org_tritonus_lowlevel_alsa_AlsaSeqClientInfo_malloc (JNIEnv* env, jobject obj) { snd_seq_client_info_t* handle; int nReturn; if (debug_flag) { fprintf(debug_file, "Java_org_tritonus_lowlevel_alsa_AlsaSeqClientInfo_malloc(): begin\n"); } nReturn = snd_seq_client_info_malloc(&handle); if (debug_flag) { fprintf(debug_file, "Java_org_tritonus_lowlevel_alsa_AlsaSeqClientInfo_malloc(): handle: %p\n", handle); } setHandle(env, obj, handle); if (debug_flag) { fprintf(debug_file, "Java_org_tritonus_lowlevel_alsa_AlsaSeqClientInfo_malloc(): end\n"); } return nReturn; }
static QString __portName( snd_seq_t * _seq, const snd_seq_addr_t * _addr ) { snd_seq_client_info_t * cinfo; snd_seq_port_info_t * pinfo; snd_seq_client_info_malloc( &cinfo ); snd_seq_port_info_malloc( &pinfo ); snd_seq_get_any_port_info( _seq, _addr->client, _addr->port, pinfo ); snd_seq_get_any_client_info( _seq, _addr->client, cinfo ); const QString name = __portName( cinfo, pinfo ); snd_seq_client_info_free( cinfo ); snd_seq_port_info_free( pinfo ); return name; }
static AlsaPort iterateMidiDevices (const bool forInput, StringArray& deviceNamesFound, const int deviceIndexToOpen) { AlsaPort port; const AlsaClient::Ptr client (globalAlsaSequencer (forInput)); if (snd_seq_t* const seqHandle = client->get()) { snd_seq_system_info_t* systemInfo = nullptr; snd_seq_client_info_t* clientInfo = nullptr; if (snd_seq_system_info_malloc (&systemInfo) == 0) { if (snd_seq_system_info (seqHandle, systemInfo) == 0 && snd_seq_client_info_malloc (&clientInfo) == 0) { int numClients = snd_seq_system_info_get_cur_clients (systemInfo); while (--numClients >= 0 && ! port.isValid()) if (snd_seq_query_next_client (seqHandle, clientInfo) == 0) port = iterateMidiClient (client, clientInfo, forInput, deviceNamesFound, deviceIndexToOpen); snd_seq_client_info_free (clientInfo); } snd_seq_system_info_free (systemInfo); } } deviceNamesFound.appendNumbersToDuplicates (true, true); return port; }
int main(int argc, char **argv) { int i; int listen_port = -1; char *client_name = "net2alsamidi"; char *connect_client = NULL; int connect_port = -1; for (i = 1; i < argc; i++) { if (strcmp(argv[i], "--port") == 0) { if (++i == argc) usage(argv[0]); listen_port = atoi(argv[i]); } else if (strcmp(argv[i], "--name") == 0) { if (++i == argc) usage(argv[0]); client_name = argv[i]; } else if (strcmp(argv[i], "--connect") == 0) { if (++i == argc) usage(argv[0]); connect_client = argv[i]; if (++i == argc) usage(argv[0]); connect_port = atoi(argv[i]); } else { usage(argv[0]); } } if (listen_port > 0) { snd_seq_t *seq; int port; if (snd_seq_open(&seq, "default", SND_SEQ_OPEN_OUTPUT, 0) < 0) { fprintf(stderr, "Cannot open the ALSA sequencer.\n"); exit(1); } snd_seq_set_client_name(seq, client_name); port = snd_seq_create_simple_port(seq, "from NetMIDI client", SND_SEQ_PORT_CAP_READ | SND_SEQ_PORT_CAP_SUBS_READ, SND_SEQ_PORT_TYPE_MIDI_GENERIC | SND_SEQ_PORT_TYPE_APPLICATION); if ((connect_client != NULL) && (connect_port >= 0)) { int connect_client_id = -1; { snd_seq_client_info_t *client_info; snd_seq_client_info_malloc(&client_info); while (snd_seq_query_next_client(seq, client_info) == 0) { if (strcmp(snd_seq_client_info_get_name(client_info), connect_client) == 0) { connect_client_id = snd_seq_client_info_get_client(client_info); break; } } snd_seq_client_info_free(client_info); } if (connect_client_id < 0) connect_client_id = atoi(connect_client); snd_seq_connect_to(seq, port, connect_client_id, connect_port); } { int server_socket; struct sockaddr_in server_address; if ((server_socket = socket(AF_INET, SOCK_STREAM, 0)) < 0) { fprintf(stderr, "Cannot start a NetMIDI server on port %d.\n", listen_port); exit(1); } server_address.sin_family = AF_INET; server_address.sin_port = htons(listen_port); server_address.sin_addr.s_addr = INADDR_ANY; if (bind(server_socket, (struct sockaddr *)(&server_address), sizeof(server_address)) < 0) { fprintf(stderr, "Cannot start a NetMIDI server on port %d.\n", listen_port); exit(1); } if (listen(server_socket, 1) < 0) { fprintf(stderr, "Cannot start a NetMIDI server on port %d.\n", listen_port); exit(1); } while (1) { int socket_to_client; if ((socket_to_client = accept(server_socket, NULL, NULL)) >= 0) { snd_midi_event_t *midi_event_parser; snd_seq_event_t *event; unsigned char buffer[BUFFER_SIZE]; int bytes_read; { char one = 1; setsockopt(socket_to_client, IPPROTO_TCP, TCP_NODELAY, &one, sizeof(one)); } snd_midi_event_new(BUFFER_SIZE, &midi_event_parser); while ((bytes_read = recv(socket_to_client, buffer, BUFFER_SIZE, 0)) > 0) { for (i = 0; i < bytes_read; i++) { if (snd_midi_event_encode_byte(midi_event_parser, buffer[i], event) == 1) { snd_seq_event_output_direct(seq, event); } } } snd_midi_event_free(midi_event_parser); close(socket_to_client); } } close(server_socket); } snd_seq_delete_simple_port(seq, port); snd_seq_close(seq); } else { usage(argv[0]); } return 0; }
void sys_alsa_do_open_midi(int nmidiin, int *midiinvec, int nmidiout, int *midioutvec) { char portname[50]; int err = 0; int client; int i; snd_seq_client_info_t *alsainfo; alsa_nmidiin = 0; alsa_nmidiout = 0; if (nmidiout == 0 && nmidiin == 0) return; if(nmidiin>MAXMIDIINDEV ) { post("midi input ports reduced to maximum %d", MAXMIDIINDEV); nmidiin=MAXMIDIINDEV; } if(nmidiout>MAXMIDIOUTDEV) { post("midi output ports reduced to maximum %d", MAXMIDIOUTDEV); nmidiout=MAXMIDIOUTDEV; } if (nmidiin>0 && nmidiout>0) err = snd_seq_open(&midi_handle,"default",SND_SEQ_OPEN_DUPLEX,0); else if (nmidiin > 0) err = snd_seq_open(&midi_handle,"default",SND_SEQ_OPEN_INPUT,0); else if (nmidiout > 0) err = snd_seq_open(&midi_handle,"default",SND_SEQ_OPEN_OUTPUT,0); if (err!=0) { sys_setalarm(1000000); post("couldn't open alsa sequencer"); return; } for (i=0;i<nmidiin;i++) { int port; sprintf(portname,"Pure Data Midi-In %d",i+1); port = snd_seq_create_simple_port(midi_handle,portname, SND_SEQ_PORT_CAP_WRITE |SND_SEQ_PORT_CAP_SUBS_WRITE, SND_SEQ_PORT_TYPE_APPLICATION); alsa_midiinfd[i] = port; if (port < 0) goto error; } for (i=0;i<nmidiout;i++) { int port; sprintf(portname,"Pure Data Midi-Out %d",i+1); port = snd_seq_create_simple_port(midi_handle,portname, SND_SEQ_PORT_CAP_READ | SND_SEQ_PORT_CAP_SUBS_READ, SND_SEQ_PORT_TYPE_APPLICATION); alsa_midioutfd[i] = port; if (port < 0) goto error; } snd_seq_client_info_malloc(&alsainfo); snd_seq_get_client_info(midi_handle,alsainfo); snd_seq_client_info_set_name(alsainfo,"Pure Data"); client = snd_seq_client_info_get_client(alsainfo); snd_seq_set_client_info(midi_handle,alsainfo); snd_seq_client_info_free(alsainfo); post("Opened Alsa Client %d in:%d out:%d",client,nmidiin,nmidiout); sys_setalarm(0); snd_midi_event_new(ALSA_MAX_EVENT_SIZE,&midiev); alsa_nmidiout = nmidiout; alsa_nmidiin = nmidiin; return; error: sys_setalarm(1000000); post("couldn't open alsa MIDI output device"); return; }
void MidiAlsaSeq::updatePortList() { QStringList readablePorts; QStringList writablePorts; // get input- and output-ports snd_seq_client_info_t * cinfo; snd_seq_port_info_t * pinfo; snd_seq_client_info_malloc( &cinfo ); snd_seq_port_info_malloc( &pinfo ); snd_seq_client_info_set_client( cinfo, -1 ); m_seqMutex.lock(); while( snd_seq_query_next_client( m_seqHandle, cinfo ) >= 0 ) { int client = snd_seq_client_info_get_client( cinfo ); snd_seq_port_info_set_client( pinfo, client ); snd_seq_port_info_set_port( pinfo, -1 ); while( snd_seq_query_next_port( m_seqHandle, pinfo ) >= 0 ) { // we need both READ and SUBS_READ if( ( snd_seq_port_info_get_capability( pinfo ) & ( SND_SEQ_PORT_CAP_READ | SND_SEQ_PORT_CAP_SUBS_READ ) ) == ( SND_SEQ_PORT_CAP_READ | SND_SEQ_PORT_CAP_SUBS_READ ) ) { readablePorts.push_back( __portName( cinfo, pinfo ) ); } if( ( snd_seq_port_info_get_capability( pinfo ) & ( SND_SEQ_PORT_CAP_WRITE | SND_SEQ_PORT_CAP_SUBS_WRITE ) ) == ( SND_SEQ_PORT_CAP_WRITE | SND_SEQ_PORT_CAP_SUBS_WRITE ) ) { writablePorts.push_back( __portName( cinfo, pinfo ) ); } } } m_seqMutex.unlock(); snd_seq_client_info_free( cinfo ); snd_seq_port_info_free( pinfo ); if( m_readablePorts != readablePorts ) { m_readablePorts = readablePorts; emit readablePortsChanged(); } if( m_writablePorts != writablePorts ) { m_writablePorts = writablePorts; emit writablePortsChanged(); } }
struct a2j_port * a2j_port_create (alsa_midi_driver_t * driver, int dir, snd_seq_addr_t addr, const snd_seq_port_info_t * info) { struct a2j_port *port; int err; int client; snd_seq_client_info_t * client_info_ptr; int jack_caps; struct a2j_stream * stream_ptr; stream_ptr = &driver->stream[dir]; if ((err = snd_seq_client_info_malloc (&client_info_ptr)) != 0) { a2j_error("Failed to allocate client info"); goto fail; } client = snd_seq_port_info_get_client (info); err = snd_seq_get_any_client_info (driver->seq, client, client_info_ptr); if (err != 0) { a2j_error("Failed to get client info"); goto fail_free_client_info; } a2j_debug ("client name: '%s'", snd_seq_client_info_get_name(client_info_ptr)); a2j_debug ("port name: '%s'", snd_seq_port_info_get_name(info)); port = calloc (1, sizeof(struct a2j_port)); if (!port) { goto fail_free_client_info; } port->driver_ptr = driver; port->jack_port = JACK_INVALID_PORT; port->remote = addr; a2j_port_fill_name (port, dir, client_info_ptr, info, false); /* Add port to list early, before registering to JACK, so map functionality is guaranteed to work during port registration */ list_add_tail (&port->siblings, &stream_ptr->list); if (dir == A2J_PORT_CAPTURE) { jack_caps = JackPortIsOutput; } else { jack_caps = JackPortIsInput; } /* mark anything that looks like a hardware port as physical&terminal */ if (snd_seq_port_info_get_type (info) & (SND_SEQ_PORT_TYPE_HARDWARE|SND_SEQ_PORT_TYPE_PORT|SND_SEQ_PORT_TYPE_SPECIFIC)) { jack_caps |= JackPortIsPhysical|JackPortIsTerminal; } port->jack_port = jack_port_register (driver->jack_client, port->name, JACK_DEFAULT_MIDI_TYPE, jack_caps, 0); if (port->jack_port == JACK_INVALID_PORT) { a2j_error("jack_port_register() failed for '%s'", port->name); goto fail_free_port; } if (dir == A2J_PORT_CAPTURE) { err = a2j_alsa_connect_from (driver, port->remote.client, port->remote.port); } else { err = snd_seq_connect_to (driver->seq, driver->port_id, port->remote.client, port->remote.port); } if (err) { a2j_debug("port skipped: %s", port->name); goto fail_free_port; } port->inbound_events = jack_ringbuffer_create(MAX_EVENT_SIZE*16); a2j_debug("port created: %s", port->name); return port; fail_free_port: list_del (&port->siblings); a2j_port_free (port); fail_free_client_info: snd_seq_client_info_free (client_info_ptr); fail: return NULL; }
int create_midi_hardware(GenesisContext *context, const char *client_name, void (*events_signal)(struct MidiHardware *), void (*on_devices_change)(struct MidiHardware *), void *userdata, struct MidiHardware **out_midi_hardware) { *out_midi_hardware = nullptr; struct MidiHardware *midi_hardware = create_zero<MidiHardware>(); if (!midi_hardware) { destroy_midi_hardware(midi_hardware); return GenesisErrorNoMem; } midi_hardware->context = context; midi_hardware->on_buffer_overrun = default_on_buffer_overrun; midi_hardware->events_signal = events_signal; midi_hardware->on_devices_change = on_devices_change; midi_hardware->userdata = userdata; if (!(midi_hardware->mutex = os_mutex_create())) { destroy_midi_hardware(midi_hardware); return GenesisErrorNoMem; } if (snd_seq_open(&midi_hardware->seq, "default", SND_SEQ_OPEN_DUPLEX, 0) < 0) { destroy_midi_hardware(midi_hardware); return GenesisErrorOpeningMidiHardware; } if (snd_seq_set_client_name(midi_hardware->seq, client_name) < 0) { destroy_midi_hardware(midi_hardware); return GenesisErrorOpeningMidiHardware; } snd_seq_client_info_malloc(&midi_hardware->client_info); snd_seq_port_info_malloc(&midi_hardware->port_info); if (!midi_hardware->client_info || !midi_hardware->port_info) { destroy_midi_hardware(midi_hardware); return GenesisErrorNoMem; } if (snd_seq_create_simple_port(midi_hardware->seq, "genesis", SND_SEQ_PORT_CAP_WRITE | SND_SEQ_PORT_CAP_SUBS_WRITE, SND_SEQ_PORT_TYPE_MIDI_GENERIC | SND_SEQ_PORT_TYPE_APPLICATION) < 0) { destroy_midi_hardware(midi_hardware); return GenesisErrorOpeningMidiHardware; } int err = midi_hardware_refresh(midi_hardware); if (err) { destroy_midi_hardware(midi_hardware); return err; } if (!midi_hardware->system_announce_device) { destroy_midi_hardware(midi_hardware); return GenesisErrorOpeningMidiHardware; } if (snd_seq_connect_from(midi_hardware->seq, 0, midi_hardware->system_announce_device->client_id, midi_hardware->system_announce_device->port_id) < 0) { destroy_midi_hardware(midi_hardware); return GenesisErrorOpeningMidiHardware; } if (snd_seq_get_client_info(midi_hardware->seq, midi_hardware->client_info) < 0) { destroy_midi_hardware(midi_hardware); return GenesisErrorOpeningMidiHardware; } midi_hardware->client_id = snd_seq_client_info_get_client(midi_hardware->client_info); if (snd_seq_connect_from(midi_hardware->seq, 0, midi_hardware->client_id, 0) < 0) { destroy_midi_hardware(midi_hardware); return GenesisErrorOpeningMidiHardware; } if ((err = os_thread_create(midi_thread, midi_hardware, false, &midi_hardware->thread))) { destroy_midi_hardware(midi_hardware); return err; } *out_midi_hardware = midi_hardware; return 0; }
//============================================================================== static snd_seq_t* iterateDevices (const bool forInput, StringArray& deviceNamesFound, const int deviceIndexToOpen) { snd_seq_t* returnedHandle = 0; snd_seq_t* seqHandle; if (snd_seq_open (&seqHandle, "default", forInput ? SND_SEQ_OPEN_INPUT : SND_SEQ_OPEN_OUTPUT, 0) == 0) { snd_seq_system_info_t* systemInfo; snd_seq_client_info_t* clientInfo; if (snd_seq_system_info_malloc (&systemInfo) == 0) { if (snd_seq_system_info (seqHandle, systemInfo) == 0 && snd_seq_client_info_malloc (&clientInfo) == 0) { int numClients = snd_seq_system_info_get_cur_clients (systemInfo); while (--numClients >= 0 && returnedHandle == 0) { if (snd_seq_query_next_client (seqHandle, clientInfo) == 0) { snd_seq_port_info_t* portInfo; if (snd_seq_port_info_malloc (&portInfo) == 0) { int numPorts = snd_seq_client_info_get_num_ports (clientInfo); const int client = snd_seq_client_info_get_client (clientInfo); snd_seq_port_info_set_client (portInfo, client); snd_seq_port_info_set_port (portInfo, -1); while (--numPorts >= 0) { if (snd_seq_query_next_port (seqHandle, portInfo) == 0 && (snd_seq_port_info_get_capability (portInfo) & (forInput ? SND_SEQ_PORT_CAP_READ : SND_SEQ_PORT_CAP_WRITE)) != 0) { deviceNamesFound.add (snd_seq_client_info_get_name (clientInfo)); if (deviceNamesFound.size() == deviceIndexToOpen + 1) { const int sourcePort = snd_seq_port_info_get_port (portInfo); const int sourceClient = snd_seq_client_info_get_client (clientInfo); if (sourcePort != -1) { snd_seq_set_client_name (seqHandle, forInput ? "Juce Midi Input" : "Juce Midi Output"); const int portId = snd_seq_create_simple_port (seqHandle, forInput ? "Juce Midi In Port" : "Juce Midi Out Port", forInput ? (SND_SEQ_PORT_CAP_WRITE | SND_SEQ_PORT_CAP_SUBS_WRITE) : (SND_SEQ_PORT_CAP_READ | SND_SEQ_PORT_CAP_SUBS_READ), SND_SEQ_PORT_TYPE_MIDI_GENERIC); snd_seq_connect_from (seqHandle, portId, sourceClient, sourcePort); returnedHandle = seqHandle; } } } } snd_seq_port_info_free (portInfo); } } } snd_seq_client_info_free (clientInfo); } snd_seq_system_info_free (systemInfo); } if (returnedHandle == 0) snd_seq_close (seqHandle); } deviceNamesFound.appendNumbersToDuplicates (true, true); return returnedHandle; }
int main(int argc, char **argv) { int i; char *connect_client = NULL; int connect_port = -1; for (i = 1; i < argc; i++) { if (strcmp(argv[i], "--prefix") == 0) { if (++i == argc) usage(argv[0]); prefix = argv[i]; } else if (strcmp(argv[i], "--timeout") == 0) { if (++i == argc) usage(argv[0]); timeout = atoi(argv[i]); } else if (strcmp(argv[i], "--confirmation") == 0) { if (++i == argc) usage(argv[0]); confirmation_command_pattern = argv[i]; } else if (strcmp(argv[i], "--connect") == 0) { if (++i == argc) usage(argv[0]); connect_client = argv[i]; if (++i == argc) usage(argv[0]); connect_port = atoi(argv[i]); } else { usage(argv[0]); } } { snd_seq_t *seq; int port; if (snd_seq_open(&seq, "default", SND_SEQ_OPEN_INPUT, 0) < 0) { fprintf(stderr, "Cannot open the ALSA sequencer.\n"); exit(1); } snd_seq_set_client_name(seq, "Brainstorm"); port = snd_seq_create_simple_port(seq, "Brainstorm recording port", SND_SEQ_PORT_CAP_WRITE | SND_SEQ_PORT_CAP_SUBS_WRITE, SND_SEQ_PORT_TYPE_MIDI_GENERIC | SND_SEQ_PORT_TYPE_APPLICATION); if ((connect_client != NULL) && (connect_port >= 0)) { int connect_client_id = -1; { snd_seq_client_info_t *client_info; snd_seq_client_info_malloc(&client_info); while (snd_seq_query_next_client(seq, client_info) == 0) { if (strcmp(snd_seq_client_info_get_name(client_info), connect_client) == 0) { connect_client_id = snd_seq_client_info_get_client(client_info); break; } } snd_seq_client_info_free(client_info); } if (connect_client_id < 0) connect_client_id = atoi(connect_client); snd_seq_connect_from(seq, port, connect_client_id, connect_port); } signal(SIGALRM, alarm_handler); { snd_seq_event_t *event; while (snd_seq_event_input(seq, &event) >= 0) { switch (event->type) { case SND_SEQ_EVENT_NOTEOFF: { alarm(timeout); create_midi_file_for_first_event(); MidiFileTrack_createNoteOffEvent(track, get_tick(), event->data.note.channel, event->data.note.note, event->data.note.velocity); break; } case SND_SEQ_EVENT_NOTEON: { alarm(timeout); create_midi_file_for_first_event(); MidiFileTrack_createNoteOnEvent(track, get_tick(), event->data.note.channel, event->data.note.note, event->data.note.velocity); break; } case SND_SEQ_EVENT_KEYPRESS: { alarm(timeout); create_midi_file_for_first_event(); MidiFileTrack_createKeyPressureEvent(track, get_tick(), event->data.note.channel, event->data.note.note, event->data.note.velocity); break; } case SND_SEQ_EVENT_CONTROLLER: { alarm(timeout); create_midi_file_for_first_event(); MidiFileTrack_createControlChangeEvent(track, get_tick(), event->data.control.channel, event->data.control.param, event->data.control.value); break; } case SND_SEQ_EVENT_PGMCHANGE: { alarm(timeout); create_midi_file_for_first_event(); MidiFileTrack_createProgramChangeEvent(track, get_tick(), event->data.control.channel, event->data.control.value); break; } case SND_SEQ_EVENT_CHANPRESS: { alarm(timeout); create_midi_file_for_first_event(); MidiFileTrack_createChannelPressureEvent(track, get_tick(), event->data.control.channel, event->data.control.value); break; } case SND_SEQ_EVENT_PITCHBEND: { alarm(timeout); create_midi_file_for_first_event(); MidiFileTrack_createPitchWheelEvent(track, get_tick(), event->data.control.channel, event->data.control.value); break; } default: { /* I'm ignoring the pseudoevents which ALSA provides as convenience features (SND_SEQ_EVENT_NOTE, SND_SEQ_EVENT_CONTROL14, SND_SEQ_EVENT_NONREGPARAM, and SND_SEQ_EVENT_REGPARAM). Hopefully I can find some way to convince ALSA to normalize them into true MIDI events. */ break; } } } } } return 0; }