Beispiel #1
0
static
int alsa_seqmidi_attach(alsa_midi_t *m)
{
	alsa_seqmidi_t *self = (alsa_seqmidi_t*) m;
	int err;

	debug_log("midi: attach");

	if (self->seq)
		return -EALREADY;

	if ((err = snd_seq_open(&self->seq, "hw", SND_SEQ_OPEN_DUPLEX, 0)) < 0) {
		error_log("failed to open alsa seq");
		return err;
	}
	snd_seq_set_client_name(self->seq, self->alsa_name);
	self->port_id = snd_seq_create_simple_port(self->seq, "port",
		SND_SEQ_PORT_CAP_READ|SND_SEQ_PORT_CAP_WRITE
#ifndef JACK_MIDI_DEBUG
		|SND_SEQ_PORT_CAP_NO_EXPORT
#endif
		,SND_SEQ_PORT_TYPE_APPLICATION);
	self->client_id = snd_seq_client_id(self->seq);

  	self->queue = snd_seq_alloc_queue(self->seq);
  	snd_seq_start_queue(self->seq, self->queue, 0);

	stream_attach(self, PORT_INPUT);
	stream_attach(self, PORT_OUTPUT);

	snd_seq_nonblock(self->seq, 1);

	return 0;
}
Beispiel #2
0
static PyObject *
alsaseq_client(PyObject *self /* Not used */, PyObject *args)
{
  const char * client_name;

  if (!PyArg_ParseTuple(args, "siii", &client_name, &ninputports, &noutputports, &createqueue ) )
		return NULL;

  if ( ninputports > maximum_nports || noutputports > maximum_nports ) {
    printf( "Only %d ports of each are allowed.\n", maximum_nports );
    exit( 1 );
    }

  int portid, n;

  if (snd_seq_open(&seq_handle, "default", SND_SEQ_OPEN_DUPLEX, 0) < 0) {
    fprintf(stderr, "Error creating ALSA client.\n");
    exit(1);
  }
  snd_seq_set_client_name(seq_handle, client_name );

  if ( createqueue )
      queue_id = snd_seq_alloc_queue(seq_handle);
  else
      queue_id = SND_SEQ_QUEUE_DIRECT;

  for ( n=0; n < ninputports; n++ ) {
    if (( portid = snd_seq_create_simple_port(seq_handle, "Input port",
            SND_SEQ_PORT_CAP_WRITE|SND_SEQ_PORT_CAP_SUBS_WRITE,
            SND_SEQ_PORT_TYPE_APPLICATION)) < 0) {
    fprintf(stderr, "Error creating input port %d.\n", n );
    exit(1);
    }
    if( createqueue ) {
      /* set timestamp info of port  */
      snd_seq_port_info_t *pinfo;
      snd_seq_port_info_alloca(&pinfo);
      snd_seq_get_port_info( seq_handle, portid, pinfo );
      snd_seq_port_info_set_timestamping(pinfo, 1);
      snd_seq_port_info_set_timestamp_queue(pinfo, queue_id );
      snd_seq_port_info_set_timestamp_real( pinfo, 1 );
      snd_seq_set_port_info( seq_handle, portid, pinfo );
    }
  }

  for ( n=0; n < noutputports; n++ ) {
    if (( portid = snd_seq_create_simple_port(seq_handle, "Output port",
            SND_SEQ_PORT_CAP_READ|SND_SEQ_PORT_CAP_SUBS_READ,
            SND_SEQ_PORT_TYPE_APPLICATION)) < 0) {
      fprintf(stderr, "Error creating output port %d.\n", n );
      exit(1);
    }
  }
    firstoutputport = ninputports;
    lastoutputport  = noutputports + ninputports - 1;

    Py_INCREF(Py_None);
    return Py_None;
}
Beispiel #3
0
mastermidibus::mastermidibus ()
 :
    m_alsa_seq          (nullptr),  // one pointer
    m_num_out_buses     (0),        // or c_max_busses, or what?
    m_num_in_buses      (0),        // or c_max_busses, or 1, or what?
    m_buses_out         (),         // array of c_max_busses midibus pointers
    m_buses_in          (),         // array of c_max_busses midibus pointers
    m_bus_announce      (nullptr),  // one pointer
    m_buses_out_active  (),         // array of c_max_busses booleans
    m_buses_in_active   (),         // array of c_max_busses booleans
    m_buses_out_init    (),         // array of c_max_busses booleans
    m_buses_in_init     (),         // array of c_max_busses booleans
    m_init_clock        (),         // array of c_max_busses clock_e values
    m_init_input        (),         // array of c_max_busses booleans
    m_queue             (0),
    m_ppqn              (0),
    m_bpm               (0),
    m_num_poll_descriptors (0),
    m_poll_descriptors  (nullptr),
    m_dumping_input     (false),
    m_seq               (nullptr),
    m_mutex             ()
{
    for (int i = 0; i < c_max_busses; ++i)        // why the global?
    {
        m_buses_in_active[i] = false;
        m_buses_out_active[i] = false;
        m_buses_in_init[i] = false;
        m_buses_out_init[i] = false;
        m_init_clock[i] = e_clock_off;
        m_init_input[i] = false;
    }

#ifdef HAVE_LIBASOUND
    /* open the sequencer client */

    int result  = snd_seq_open(&m_alsa_seq, "default",  SND_SEQ_OPEN_DUPLEX, 0);
    if (result  < 0)
    {
        errprint("snd_seq_open() error");
        exit(1);
    }
    snd_seq_set_client_name(m_alsa_seq, "seq24");   /* client's name  */
    m_queue = snd_seq_alloc_queue(m_alsa_seq);      /* client's queue */
#endif

#ifdef LASH_SUPPORT
    /*
     * Notify LASH of our client ID so that it can restore connections.
     */

    if (not_nullptr(global_lash_driver))
        global_lash_driver->set_alsa_client_id(snd_seq_client_id(m_alsa_seq));
#endif
}
Beispiel #4
0
void MidiQueue::init(snd_seq_t* sequencer)
{
	if (_id == kInvalidId)
	{
		_sequencer = sequencer;
		_id = snd_seq_alloc_queue(sequencer);
	}
	else
	{
		std::cerr << "Queue is already initialized\n";
	}
}
Beispiel #5
0
int ALSADrv_MIDI_Init(midifuncs *funcs)
{
    int result;
    
    ALSADrv_MIDI_Shutdown();
    memset(funcs, 0, sizeof(midifuncs));

    result = snd_seq_open(&seq, "default", SND_SEQ_OPEN_DUPLEX, 0);
    if (result < 0) {
        fprintf(stderr, "ALSA snd_seq_open err %d\n", result);
        ErrorCode = ALSAErr_SeqOpen;
        return ALSAErr_Error;
    }
    
    seq_port = snd_seq_create_simple_port(seq, "output",
                  SND_SEQ_PORT_CAP_READ | SND_SEQ_PORT_CAP_WRITE,
                  SND_SEQ_PORT_TYPE_APPLICATION);
    if (seq_port < 0) {
        ALSADrv_MIDI_Shutdown();
        fprintf(stderr, "ALSA snd_seq_create_simple_port err %d\n", seq_port);
        ErrorCode = ALSAErr_CreateSimplePort;
        return ALSAErr_Error;
    }
    
    snd_seq_set_client_name(seq, "JFAudioLib application");

    seq_queue = snd_seq_alloc_queue(seq);
    if (seq_queue < 0) {
        ALSADrv_MIDI_Shutdown();
        fprintf(stderr, "ALSA snd_seq_alloc_queue err %d\n", seq_queue);
        ErrorCode = ALSAErr_AllocQueue;
        return ALSAErr_Error;
    }
    
    result = snd_seq_connect_to(seq, seq_port, 128, 0);
    if (result < 0) {
        ALSADrv_MIDI_Shutdown();
        fprintf(stderr, "ALSA snd_seq_connect_to err %d\n", result);
        ErrorCode = ALSAErr_ConnectTo;
        return ALSAErr_Error;
    }
    
    funcs->NoteOff = Func_NoteOff;
    funcs->NoteOn  = Func_NoteOn;
    funcs->PolyAftertouch = Func_PolyAftertouch;
    funcs->ControlChange = Func_ControlChange;
    funcs->ProgramChange = Func_ProgramChange;
    funcs->ChannelAftertouch = Func_ChannelAftertouch;
    funcs->PitchBend = Func_PitchBend;
    
    return ALSAErr_Ok;
}
MidiAlsaSeq::MidiAlsaSeq() :
	MidiClient(),
	m_seqMutex(),
	m_seqHandle( NULL ),
	m_queueID( -1 ),
	m_quit( false ),
	m_portListUpdateTimer( this )
{
	int err;
	if( ( err = snd_seq_open( &m_seqHandle,
					probeDevice().toLatin1().constData(),
						SND_SEQ_OPEN_DUPLEX, 0 ) ) < 0 )
	{
		fprintf( stderr, "cannot open sequencer: %s\n",
							snd_strerror( err ) );
		return;
	}
	snd_seq_set_client_name( m_seqHandle, "LMMS" );


	m_queueID = snd_seq_alloc_queue( m_seqHandle );
	snd_seq_queue_tempo_t * tempo;
	snd_seq_queue_tempo_malloc( &tempo );
	snd_seq_queue_tempo_set_tempo( tempo, 6000000 /
					Engine::getSong()->getTempo() );
	snd_seq_queue_tempo_set_ppq( tempo, 16 );
	snd_seq_set_queue_tempo( m_seqHandle, m_queueID, tempo );
	snd_seq_queue_tempo_free( tempo );

	snd_seq_start_queue( m_seqHandle, m_queueID, NULL );
	changeQueueTempo( Engine::getSong()->getTempo() );
	connect( Engine::getSong(), SIGNAL( tempoChanged( bpm_t ) ),
			this, SLOT( changeQueueTempo( bpm_t ) ) );

	// initial list-update
	updatePortList();

	connect( &m_portListUpdateTimer, SIGNAL( timeout() ),
					this, SLOT( updatePortList() ) );
	// we check for port-changes every second
	m_portListUpdateTimer.start( 1000 );

	// use a pipe to detect shutdown
	if( pipe( m_pipe ) == -1 )
	{
		perror( __FILE__ ": pipe" );
	}

	start( QThread::IdlePriority );
}
Beispiel #7
0
struct midi_handle *midi_open_alsa(unsigned char *name, int nports)
{
	int rc;
	int i;
	struct midi_handle_alsa *mh;
	unsigned char clientname[255], portname[255];

	sprintf(clientname, "Gneutronica (%d)", getpid());

	mh = (struct midi_handle_alsa *) malloc(sizeof(*mh));
	if (mh == NULL)
		return NULL;

	if (nports > MAX_PORTS)
		nports = MAX_PORTS;

	rc = snd_seq_open(&mh->seqp, name, SND_SEQ_OPEN_OUTPUT, 0666);
	if (rc < 0) {
		printf("snd_seq_open returns %d\n", rc);
		free(mh);
		return NULL;
	}
	rc = snd_seq_set_client_name(mh->seqp, clientname);
	if (rc < 0)
		printf("snd_seq_set_client_name failed \n");
	for (i=0;i<nports;i++) {
		sprintf(portname, "Gneutronica (%d) Track:%d", getpid(), i);
		mh->outputport[i] = snd_seq_create_simple_port(mh->seqp, portname,
				SND_SEQ_PORT_CAP_READ|SND_SEQ_PORT_CAP_SUBS_READ,
				SND_SEQ_PORT_TYPE_MIDI_GENERIC);
		if (mh->outputport < 0)
			printf("snd_seq_create_simple_port %d failed\n", i);
	}

	mh->queue = snd_seq_alloc_queue(mh->seqp);
	if (mh->queue < 0)
		printf("snd_seq_alloc_queue failed.\n");

	snd_seq_start_queue(mh->seqp, mh->queue, 0);

	return (struct midi_handle *) mh;
}
Beispiel #8
0
SeqContext::SeqContext()
{
	/*
	 * Create the sequencer context. Connected = 3 if all goes well
	 */	 
	connected = verbose = 0;

	handle = (snd_seq_t *)0;

	if (snd_seq_open(&handle, "hw", SND_SEQ_OPEN_DUPLEX, 0) < 0) {
		fprintf(stderr, "Could not open sequencer: %s", snd_strerror(errno));
		return;
		}
	
	connected++;

	if( (queue = snd_seq_alloc_queue(handle)) == 0 ) {
		fprintf(stderr, "Failure to allocate queue\n");
		return;		
	}
	if( (client = snd_seq_client_id(handle)) == 0 ) {
		fprintf(stderr, "Failure to get client address");
		return;		
	}
	
	connected++;

	destlist = new AddressList;
	source.client = client;
	source.port = 0;

	if( seq_new_port('e') < 0 ) {
		fprintf(stderr, "Could not open sequencer port: %s", snd_strerror(errno));
		return;
	}
	
	if( verbose ) {		
		fprintf(stderr, "Opened alsa sequencer for client %d and created queue\n", client );		
	}

	connected++;
}
Beispiel #9
0
/* queue is shared by both input and output, reference counted */
static PmError alsa_use_queue(void)
{
    if (queue_used == 0) {
        snd_seq_queue_tempo_t *tempo;

        queue = snd_seq_alloc_queue(seq);
        if (queue < 0) {
            pm_hosterror = queue;
            return pmHostError;
        }
        snd_seq_queue_tempo_alloca(&tempo);
        snd_seq_queue_tempo_set_tempo(tempo, 480000);
        snd_seq_queue_tempo_set_ppq(tempo, 480);
        pm_hosterror = snd_seq_set_queue_tempo(seq, queue, tempo);
        if (pm_hosterror < 0)
            return pmHostError;

        snd_seq_start_queue(seq, queue, NULL);
        snd_seq_drain_output(seq);
    }
    ++queue_used;
    return pmNoError;
}
Beispiel #10
0
/* fills the array with our buses */
mastermidibus::mastermidibus()
{
    /* temp return */
    int ret;
    
    /* set initial number buses */
    m_num_out_buses = 0;
    m_num_in_buses = 0;

    for( int i=0; i<c_maxBuses; ++i ){
        m_buses_in_active[i] = false;	
        m_buses_out_active[i] = false;
        m_buses_in_init[i] = false;	
        m_buses_out_init[i] = false;

        m_init_clock[i] = e_clock_off;
        m_init_input[i] = false;
    }
    
    /* open the sequencer client */
    ret = snd_seq_open(&m_alsa_seq, "default",  SND_SEQ_OPEN_DUPLEX, 0);
    
    if ( ret < 0 ){
	printf( "snd_seq_open() error\n");
	exit(1);
    }

    /* set our clients name */
    snd_seq_set_client_name(m_alsa_seq, "seq24");

    /* set up our clients queue */
    m_queue = snd_seq_alloc_queue( m_alsa_seq );

	/* notify lash of our client ID so it can restore connections */
	lash_driver->set_alsa_client_id(snd_seq_client_id(m_alsa_seq));
}
Beispiel #11
0
int
connect_to_alsa (struct a2j* self)
{
	int error;
	void * thread_status;

	self->port_add = jack_ringbuffer_create(2 * MAX_PORTS * sizeof(snd_seq_addr_t));
	if (self->port_add == NULL) {
		goto free_self;
	}

	self->port_del = jack_ringbuffer_create(2 * MAX_PORTS * sizeof(struct a2j_port *));
	if (self->port_del == NULL) {
		goto free_ringbuffer_add;
	}

	if (!a2j_stream_init(self)) {
		goto free_ringbuffer_outbound;
	}

	if ((error = snd_seq_open(&self->seq, "hw", SND_SEQ_OPEN_DUPLEX, 0)) < 0) {
		a2j_error("failed to open alsa seq");
		goto close_stream;
	}

	if ((error = snd_seq_set_client_name(self->seq, "midi_in")) < 0) {
		a2j_error("snd_seq_set_client_name() failed");
		goto close_seq_client;
	}

	if ((self->port_id = snd_seq_create_simple_port(
		self->seq,
		"port",
		SND_SEQ_PORT_CAP_READ|SND_SEQ_PORT_CAP_WRITE
#ifndef DEBUG
		|SND_SEQ_PORT_CAP_NO_EXPORT
#endif
		,SND_SEQ_PORT_TYPE_APPLICATION)) < 0) {

		a2j_error("snd_seq_create_simple_port() failed");
		goto close_seq_client;
	}

	if ((self->client_id = snd_seq_client_id(self->seq)) < 0) {
		a2j_error("snd_seq_client_id() failed");
		goto close_seq_client;
	}
	
	if ((self->queue = snd_seq_alloc_queue(self->seq)) < 0) {
		a2j_error("snd_seq_alloc_queue() failed");
		goto close_seq_client;
	}

	snd_seq_start_queue (self->seq, self->queue, 0); 

	a2j_stream_attach (&self->stream);

	if ((error = snd_seq_nonblock(self->seq, 1)) < 0) {
		a2j_error("snd_seq_nonblock() failed");
		goto close_seq_client;
	}

	snd_seq_drop_input (self->seq);

	a2j_add_ports(&self->stream);

	if (sem_init(&self->io_semaphore, 0, 0) < 0) {
		a2j_error("can't create IO semaphore");
		goto close_jack_client;
	}

	g_keep_alsa_walking = true;

	if (pthread_create(&self->alsa_io_thread, NULL, alsa_input_thread, self) < 0)
	{
		a2j_error("cannot start ALSA input thread");
		goto sem_destroy;
	}

	/* wake the poll loop in the alsa input thread so initial ports are fetched */
	if ((error = snd_seq_connect_from (self->seq, self->port_id, SND_SEQ_CLIENT_SYSTEM, SND_SEQ_PORT_SYSTEM_ANNOUNCE)) < 0) {
		a2j_error("snd_seq_connect_from() failed");
		goto join_io_thread;
	}

	return 0;

	g_keep_alsa_walking = false;  /* tell alsa threads to stop */
	snd_seq_disconnect_from(self->seq, self->port_id, SND_SEQ_CLIENT_SYSTEM, SND_SEQ_PORT_SYSTEM_ANNOUNCE);
  join_io_thread:
	pthread_join(self->alsa_io_thread, &thread_status);
  sem_destroy:
	sem_destroy(&self->io_semaphore);
  close_jack_client:
	if ((error = jack_client_close(self->jack_client)) < 0) {
		a2j_error("Cannot close jack client");
	}
  close_seq_client:
	snd_seq_close(self->seq);
  close_stream:
	a2j_stream_close(self);
  free_ringbuffer_outbound:
	jack_ringbuffer_free(self->outbound_events);
	jack_ringbuffer_free(self->port_del);
  free_ringbuffer_add:
	jack_ringbuffer_free(self->port_add);
  free_self:
	free(self);
	return -1;
}
mastermidibus::mastermidibus (int ppqn, int bpm)
 :
    m_alsa_seq          (nullptr),  // one pointer
    m_max_busses        (c_max_busses),
    m_num_out_buses     (0),        // or c_max_busses, or what?
    m_num_in_buses      (0),        // or c_max_busses, or 1, or what?
    m_buses_out         (),         // array of c_max_busses midibus pointers
    m_buses_in          (),         // array of c_max_busses midibus pointers
    m_bus_announce      (nullptr),  // one pointer
    m_buses_out_active  (),         // array of c_max_busses booleans
    m_buses_in_active   (),         // array of c_max_busses booleans
    m_buses_out_init    (),         // array of c_max_busses booleans
    m_buses_in_init     (),         // array of c_max_busses booleans
    m_init_clock        (),         // array of c_max_busses clock_e values
    m_init_input        (),         // array of c_max_busses booleans
    m_queue             (0),
    m_ppqn              (0),
    m_beats_per_minute  (bpm),      // beats per minute
    m_num_poll_descriptors (0),
    m_poll_descriptors  (nullptr),
    m_dumping_input     (false),
    m_vector_sequence   (),
    m_filter_by_channel (false),    // set below based on configuration
    m_seq               (nullptr),
    m_mutex             ()
{
    m_ppqn = choose_ppqn(ppqn);
    for (int i = 0; i < m_max_busses; ++i)
    {
        m_buses_in_active[i] =
            m_buses_out_active[i] =
            m_buses_in_init[i] =
            m_buses_out_init[i] =
            m_init_input[i] = false;

        m_init_clock[i] = e_clock_off;
    }

#ifdef SEQ64_HAVE_LIBASOUND

    /*
     * Open the sequencer client.  This line of code results in a loss of
     * 4 bytes somewhere in snd_seq_open(), as discovered via valgrind.
     */

    int result = snd_seq_open(&m_alsa_seq, "default",  SND_SEQ_OPEN_DUPLEX, 0);
    if (result < 0)
    {
        errprint("snd_seq_open() error");
        exit(1);
    }
    else
    {
        /*
         * Tried to reduce apparent memory leaks from libasound, but this call
         * changed nothing.
         *
         * (void) snd_config_update_free_global();
         */
    }

    /*
     * Set the client's name for ALSA.  It used to be "seq24".  Then set up our
     * ALSA client's queue.
     */

    snd_seq_set_client_name(m_alsa_seq, "sequencer64");
    m_queue = snd_seq_alloc_queue(m_alsa_seq);

#endif      // SEQ64_HAVE_LIBASOUND

#ifdef SEQ64_LASH_SUPPORT

    /*
     * Notify LASH of our client ID so that it can restore connections.
     */

    if (not_nullptr(lash_driver()))
        lash_driver()->set_alsa_client_id(snd_seq_client_id(m_alsa_seq));

#endif
}
Beispiel #13
0
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);
	}
}
Beispiel #14
0
static GstStateChangeReturn
gst_amidisrc_change_state (GstElement * element, GstStateChange transition )
{
  GstStateChangeReturn ret = GST_STATE_CHANGE_SUCCESS;
  GstaMIDISrc *src = GST_AMIDISRC (element);

  switch (transition) {
    case GST_STATE_CHANGE_NULL_TO_READY:
		 // TODO: Open our listen alsa ports
		//     1. Open sequencer
		//     2. If we have a client and port, connect to them
		printf("***Here: %s:%d\n",__FILE__,__LINE__);

		if ((snd_seq_open(&src->a_seq, src->device, SND_SEQ_OPEN_INPUT, 0)) < 0)
			return GST_STATE_CHANGE_FAILURE;
		if( src->a_seq == NULL )
			return GST_STATE_CHANGE_FAILURE;
		snd_seq_set_client_name(src->a_seq, "gstreamer");
		if ((src->a_port = snd_seq_create_simple_port(src->a_seq, "In",
						SND_SEQ_PORT_CAP_WRITE |
						SND_SEQ_PORT_CAP_SUBS_WRITE,
						SND_SEQ_PORT_TYPE_MIDI_GENERIC)) < 0)
		{
			return GST_STATE_CHANGE_FAILURE;
		}
		src->a_queue = snd_seq_alloc_queue(src->a_seq);
		if( src->a_queue < 0 )
			return GST_STATE_CHANGE_FAILURE;
		// Only connect if we have positive client/port
		if( src->client >= 0 && src->port >= 0 )
		{
			if( snd_seq_connect_to(src->a_seq, src->a_port, src->client, src->port) < 0 )
				return GST_STATE_CHANGE_FAILURE;
		}
      break;
    case GST_STATE_CHANGE_READY_TO_PAUSED:
		return GST_STATE_CHANGE_NO_PREROLL;
      break;
    default:
      break;
  }

  ret = GST_ELEMENT_CLASS (parent_class)->change_state (element, transition);
  if (ret == GST_STATE_CHANGE_FAILURE)
    return ret;

  switch (transition) {
    case GST_STATE_CHANGE_READY_TO_NULL:
		 // TODO: close our listening alsa ports
		 // disconnect from midi port
		printf("***Here: %s:%d\n",__FILE__,__LINE__);
		if( src->a_queue >= 0 ){
			if( snd_seq_free_queue( src->a_seq, src->a_queue ) < 0 )
				return GST_STATE_CHANGE_FAILURE;
		}
		if( src->a_port >= 0 && src->a_seq != NULL){
			if( snd_seq_delete_simple_port(src->a_seq,src->a_port) < 0 ){
				return GST_STATE_CHANGE_FAILURE;
			}
		}
		if( snd_seq_close( src->a_seq ) < 0 )
			return GST_STATE_CHANGE_FAILURE;
      break;
	 case GST_STATE_CHANGE_PLAYING_TO_PAUSED:
		return GST_STATE_CHANGE_NO_PREROLL;
		break;
    default:
      break;
  }

  return ret;
}