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; }
void MidiInputDeviceAlsa::MidiInputPortAlsa::ParameterName::OnSetValue(String s) throw (Exception) { if (s.size() > 16) throw Exception("Name too long for ALSA MIDI input port (max. 16 characters)"); snd_seq_port_info_t* hInfo; snd_seq_port_info_malloc(&hInfo); snd_seq_get_port_info(((MidiInputDeviceAlsa*)pPort->GetDevice())->hAlsaSeq, pPort->GetPortNumber(), hInfo); snd_seq_port_info_set_name(hInfo, s.c_str()); snd_seq_set_port_info(((MidiInputDeviceAlsa*)pPort->GetDevice())->hAlsaSeq, pPort->GetPortNumber(), hInfo); snd_seq_port_info_free(hInfo); }
/* * Class: org_tritonus_lowlevel_alsa_AlsaSeqPortInfo * Method: malloc * Signature: ()I */ JNIEXPORT jint JNICALL Java_org_tritonus_lowlevel_alsa_AlsaSeqPortInfo_malloc (JNIEnv* env, jobject obj) { snd_seq_port_info_t* handle; int nReturn; if (debug_flag) { fprintf(debug_file, "Java_org_tritonus_lowlevel_alsa_AlsaSeqPortInfo_malloc(): begin\n"); } nReturn = snd_seq_port_info_malloc(&handle); if (debug_flag) { fprintf(debug_file, "Java_org_tritonus_lowlevel_alsa_AlsaSeqPortInfo_malloc(): handle: %p\n", handle); } setHandle(env, obj, handle); if (debug_flag) { fprintf(debug_file, "Java_org_tritonus_lowlevel_alsa_AlsaSeqPortInfo_malloc(): end\n"); } return nReturn; }
//============================================================================== static AlsaPort iterateMidiClient (const AlsaClient::Ptr& seq, snd_seq_client_info_t* clientInfo, const bool forInput, StringArray& deviceNamesFound, const int deviceIndexToOpen) { AlsaPort port; snd_seq_t* seqHandle = seq->get(); snd_seq_port_info_t* portInfo = nullptr; 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) { const String name (forInput ? JUCE_ALSA_MIDI_INPUT_NAME : JUCE_ALSA_MIDI_OUTPUT_NAME); seq->setName (name); port.createPort (seq, name, forInput); port.connectWith (sourceClient, sourcePort); } } } } snd_seq_port_info_free (portInfo); } return 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; }
void MidiAlsaSeq::subscribeWritablePort( MidiPort * _port, const QString & _dest, bool _subscribe ) { if( !m_portIDs.contains( _port ) ) { return; } const int pid = m_portIDs[_port][1] < 0 ? m_portIDs[_port][0] : m_portIDs[_port][1]; if( pid < 0 ) { return; } m_seqMutex.lock(); snd_seq_addr_t dest; if( snd_seq_parse_address( m_seqHandle, &dest, _dest.section( ' ', 0, 0 ).toLatin1().constData() ) ) { fprintf( stderr, "error parsing dest-address!\n" ); m_seqMutex.unlock(); return; } snd_seq_port_info_t * port_info; snd_seq_port_info_malloc( &port_info ); snd_seq_get_port_info( m_seqHandle, pid, port_info ); const snd_seq_addr_t * sender = snd_seq_port_info_get_addr( port_info ); snd_seq_port_subscribe_t * subs; snd_seq_port_subscribe_malloc( &subs ); snd_seq_port_subscribe_set_sender( subs, sender ); snd_seq_port_subscribe_set_dest( subs, &dest ); if( _subscribe ) { snd_seq_subscribe_port( m_seqHandle, subs ); } else { snd_seq_unsubscribe_port( m_seqHandle, subs ); } snd_seq_port_subscribe_free( subs ); snd_seq_port_info_free( port_info ); m_seqMutex.unlock(); }
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; }
/** Document-method: RRTS::Driver::AlsaPortInfo_i#copy_to call-seq: copy_to([other = nil]) -> clone Make a copy of this record. Without an argument it returns a copy, otherwise the information of +self+ is copied into +other+. */ static VALUE wrap_snd_seq_port_info_copy_to(int argc, VALUE *argv, VALUE v_port_info) { VALUE v_dst; rb_scan_args(argc, argv, "01", &v_dst); snd_seq_port_info_t *port_info, *dst; VALUE retval = v_port_info; if (NIL_P(v_dst)) { const int r = snd_seq_port_info_malloc(&dst); if (r < 0) RAISE_MIDI_ERROR("allocating port_info", r); v_dst = Data_Wrap_Struct(alsaPortInfoClass, 0/*mark*/, snd_seq_port_info_free/*free*/, dst); retval = v_dst; } Data_Get_Struct(v_port_info, snd_seq_port_info_t, port_info); Data_Get_Struct(v_dst, snd_seq_port_info_t, dst); snd_seq_port_info_copy(dst, port_info); return retval; }
aseq_output_t *create_aseq_output(snd_seq_t *handle, const char *name, bool_t *ev_to_drain, bool_t *is_running) { aseq_output_t *aseqoutput = myalloc(sizeof (aseq_output_t)); aseqoutput->ev_to_drain = ev_to_drain; aseqoutput->is_running = is_running; aseqoutput->handle = handle; aseqoutput->port = snd_seq_create_simple_port(aseqoutput->handle, name, SND_SEQ_PORT_CAP_READ|SND_SEQ_PORT_CAP_SUBS_READ, SND_SEQ_PORT_TYPE_APPLICATION); snd_seq_port_info_malloc(&(aseqoutput->info)); snd_seq_get_port_info(handle, aseqoutput->port, aseqoutput->info); return aseqoutput; }
void MidiAlsaSeq::applyPortName( MidiPort * _port ) { m_seqMutex.lock(); for( int i = 0; i < 2; ++i ) { if( m_portIDs[_port][i] == -1 ) { 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_name( port_info, _port->displayName().toUtf8().constData() ); snd_seq_set_port_info( m_seqHandle, m_portIDs[_port][i], port_info ); snd_seq_port_info_free( port_info ); } m_seqMutex.unlock(); }
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(); } }
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(); }
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; }