void DeviceManager::scanDevices()
{
    snd_seq_client_info_t *cinfo;
    snd_seq_port_info_t *pinfo;

    snd_seq_client_info_alloca(&cinfo);
    snd_seq_port_info_alloca(&pinfo);

    snd_seq_client_info_set_client(cinfo, -1);
    while (snd_seq_query_next_client(handle, 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(handle, pinfo) >= 0) {
            Device *d = new Device(cinfo, pinfo);
            if(d->isValid()){
                snd_seq_connect_from(handle, 0, d->clientId, d->portId);
                list.push_back(d);
            }else{
                delete d;
            }
        }
    }

    D("Device list contain %d elements.", (int) list.size());

}
Exemple #2
0
static
int alsa_seqmidi_start(alsa_midi_t *m)
{
	alsa_seqmidi_t *self = (alsa_seqmidi_t*) m;
	int err;

	debug_log("midi: start");

	if (!self->seq)
		return -EBADF;

	if (self->keep_walking)
		return -EALREADY;

	snd_seq_connect_from(self->seq, self->port_id, SND_SEQ_CLIENT_SYSTEM, SND_SEQ_PORT_SYSTEM_ANNOUNCE);
	snd_seq_drop_input(self->seq);

	add_existing_ports(self);
	update_ports(self);
	add_ports(&self->stream[PORT_INPUT]);
	add_ports(&self->stream[PORT_OUTPUT]);

	self->keep_walking = 1;

	if ((err = pthread_create(&self->port_thread, NULL, port_thread, self))) {
		self->keep_walking = 0;
		return -errno;
	}

	return 0;
}
static void connect_ports(void)
{
	int i, err;

	for (i = 0; i < port_count; ++i) {
		err = snd_seq_connect_from(seq, 0, ports[i].client, ports[i].port);
		if (err < 0)
			fatal("Cannot connect from port %d:%d - %s",
			      ports[i].client, ports[i].port, snd_strerror(err));
	}
}
Exemple #4
0
static PyObject *
alsaseq_connectfrom(PyObject *self, PyObject *args)
{
  int myport, dest_client, dest_port;
        
	if (!PyArg_ParseTuple(args, "iii", &myport, &dest_client, &dest_port ))
		return NULL;
        snd_seq_connect_from( seq_handle, myport, dest_client, dest_port);

	Py_INCREF(Py_None);
	return Py_None;
}
void midi_open(void)
{
    snd_seq_open(&seq_handle, "default", SND_SEQ_OPEN_INPUT, 0);

    snd_seq_set_client_name(seq_handle, "LightOrgan8");
    in_port = snd_seq_create_simple_port(seq_handle, "listen:in",
                      SND_SEQ_PORT_CAP_WRITE|SND_SEQ_PORT_CAP_SUBS_WRITE,
                      SND_SEQ_PORT_TYPE_APPLICATION);
 
    if( snd_seq_connect_from(seq_handle, in_port, THRUPORTCLIENT, THRUPORTPORT) == -1) {
       perror("Can't connect to thru port");
       exit(-1);
    } 
}
Exemple #6
0
int open_midi_device(struct GenesisMidiDevice *device) {
    if (device->open)
        return GenesisErrorInvalidState;

    if (snd_seq_connect_from(device->midi_hardware->seq, 0, device->client_id, device->port_id) < 0)
        return GenesisErrorOpeningMidiHardware;
    device->open = true;

    int set_index = device->midi_hardware->open_devices.length();
    if (device->midi_hardware->open_devices.append(device)) {
        close_midi_device(device);
        return GenesisErrorNoMem;
    }
    genesis_midi_device_ref(device);
    device->set_index = set_index;

    return 0;
}
Exemple #7
0
static PyObject *
alsaseq_connectfrom(PyObject *self, PyObject *args)
{
  int myport, dest_client, dest_port;
        
	if (!PyArg_ParseTuple(args, "iii", &myport, &dest_client, &dest_port ))
		return NULL;

        if (!seq_handle) {
                PyErr_SetString(PyExc_RuntimeError, "Must initialize module with alsaseq.client() before using it");
                return NULL;
        }

        snd_seq_connect_from( seq_handle, myport, dest_client, dest_port);

	Py_INCREF(Py_None);
	return Py_None;
}
Exemple #8
0
static PyObject *setup(PyObject *self, PyObject *args)
{
    if (!PyArg_ParseTuple(args, "i", &dest_client_id))
        return NULL;

    // open client
    err = snd_seq_open(&seq, "default", SND_SEQ_OPEN_DUPLEX, 0);
    if (err < 0)
        RAISE("couldnt open sequencer connection\n");

    // get client id
    my_client_id = snd_seq_client_id(seq);

    // create readable port for sending events
    readable_port = snd_seq_create_simple_port(
                                               seq, "my readable port",
                                               SND_SEQ_PORT_CAP_READ | SND_SEQ_PORT_CAP_SUBS_READ,
                                               SND_SEQ_PORT_TYPE_MIDI_GENERIC);

    // create writable port for receiving events
    writable_port = snd_seq_create_simple_port(
                                               seq, "my writable port",
                                               SND_SEQ_PORT_CAP_WRITE | SND_SEQ_PORT_CAP_SUBS_WRITE,
                                               SND_SEQ_PORT_TYPE_MIDI_GENERIC);

    // make subscription for sending events to device
    if (snd_seq_connect_to(seq, readable_port, dest_client_id, 0) < 0)
        RAISE("Unable to subscribe to MIDI port for writing.\n");

    // make subscription for capturing events from midi device
    if (snd_seq_connect_from(seq, writable_port, dest_client_id, 0) < 0)
        RAISE("Unable to subscribe to MIDI port for reading.\n");

    Py_INCREF(Py_None);
    return Py_None;
}
Exemple #9
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;
}
Exemple #10
0
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;
}
Exemple #11
0
/**************************************************************************
 * 			midOpen					[internal]
 */
static DWORD midOpen(WORD wDevID, LPMIDIOPENDESC lpDesc, DWORD dwFlags)
{
    TRACE("(%04X, %p, %08lX);\n", wDevID, lpDesc, dwFlags);

    if (lpDesc == NULL) {
	WARN("Invalid Parameter !\n");
	return MMSYSERR_INVALPARAM;
    }

    /* FIXME :
     *	how to check that content of lpDesc is correct ?
     */
    if (wDevID >= MIDM_NumDevs) {
	WARN("wDevID too large (%u) !\n", wDevID);
	return MMSYSERR_BADDEVICEID;
    }
    if (MidiInDev[wDevID].state == -1) {        
        WARN("device disabled\n");
        return MIDIERR_NODEVICE;
    }
    if (MidiInDev[wDevID].midiDesc.hMidi != 0) {
	WARN("device already open !\n");
	return MMSYSERR_ALLOCATED;
    }
    if ((dwFlags & MIDI_IO_STATUS) != 0) {
	WARN("No support for MIDI_IO_STATUS in dwFlags yet, ignoring it\n");
	dwFlags &= ~MIDI_IO_STATUS;
    }
    if ((dwFlags & ~CALLBACK_TYPEMASK) != 0) {
	FIXME("Bad dwFlags\n");
	return MMSYSERR_INVALFLAG;
    }

    if (midiOpenSeq(1) < 0) {
	return MMSYSERR_ERROR;
    }

    /* Connect our app port to the device port */
    if (snd_seq_connect_from(midiSeq, port_in, MidiInDev[wDevID].addr.client, MidiInDev[wDevID].addr.port) < 0)
	return MMSYSERR_NOTENABLED;

    TRACE("input port connected %d %d %d\n",port_in,MidiInDev[wDevID].addr.client,MidiInDev[wDevID].addr.port);

    if (numStartedMidiIn++ == 0) {
	end_thread = 0;
	hThread = CreateThread(NULL, 0, midRecThread, NULL, 0, NULL);
	if (!hThread) {
	    numStartedMidiIn = 0;
	    WARN("Couldn't create thread for midi-in\n");
	    midiCloseSeq();
	    return MMSYSERR_ERROR;
	}
        SetThreadPriority(hThread, THREAD_PRIORITY_TIME_CRITICAL);
	TRACE("Created thread for midi-in\n");
    }

    MidiInDev[wDevID].wFlags = HIWORD(dwFlags & CALLBACK_TYPEMASK);

    MidiInDev[wDevID].lpQueueHdr = NULL;
    MidiInDev[wDevID].dwTotalPlayed = 0;
    MidiInDev[wDevID].bufsize = 0x3FFF;
    MidiInDev[wDevID].midiDesc = *lpDesc;
    MidiInDev[wDevID].state = 0;
    MidiInDev[wDevID].incLen = 0;
    MidiInDev[wDevID].startTime = 0;

    if (MIDI_NotifyClient(wDevID, MIM_OPEN, 0L, 0L) != MMSYSERR_NOERROR) {
	WARN("can't notify client !\n");
	return MMSYSERR_INVALPARAM;
    }
    return MMSYSERR_NOERROR;
}
//==============================================================================
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;
}
Exemple #13
0
int main (int argc, char *argv[])
{

	snd_seq_t *seq_handle;
	int npfd;
	struct pollfd *pfd;

	seq_handle = open_seq();
	npfd = snd_seq_poll_descriptors_count(seq_handle, POLLIN);
	pfd = malloc(npfd * sizeof(*pfd));
	snd_seq_poll_descriptors(seq_handle, pfd, npfd, POLLIN);

	if (argc >= 2) {
		snd_seq_addr_t addr;
		if (snd_seq_parse_address(seq_handle, &addr, argv[1]) == 0) {
			if (snd_seq_connect_from(seq_handle, portid, addr.client, addr.port) == 0) {
				printf("Connected to %s\n", argv[1]);
			}
		}
	}

	int i;
	for (i=2; i<argc; i++)
		channels |= 1<<(atoi(argv[i])-1);

	OLRenderParams params;

	memset(&params, 0, sizeof params);
	params.rate = 48000;
	params.on_speed = 2.0/50.0;
	params.off_speed = 2.0/35.0;
	params.start_wait = 6;
	params.start_dwell = 1;
	params.curve_dwell = 0;
	params.corner_dwell = 0;
	params.curve_angle = cosf(30.0*(M_PI/180.0)); // 30 deg
	params.end_dwell = 0;
	params.end_wait = 7;
	params.flatness = 0.00001;
	params.snap = 1/100000.0;
	params.render_flags = RENDER_GRAYSCALE;

	if(olInit(3, 30000) < 0)
		return 1;

	olSetRenderParams(&params);

	float time = 0;
	float ftime;

	int frames = 0;

	float nps = 0;
	avgnotes = 5;
	
	while(1) {
		olLoadIdentity();

		int drawn = draw();
		if (drawn < 2)
			draw();

		ftime = olRenderFrame(100);

		float t = powf(0.3, ftime);
		avgnotes = avgnotes * t + (nps+2) * (1.0f-t);

		animate(ftime);

		int notes = 0;
		if (poll(pfd, npfd, 0) > 0)
			notes = midi_action(seq_handle);

		int pnotes = (notes+2)/3;

		nps = pnotes / ftime * 1.2;

		frames++;
		time += ftime;
		printf("Frame time: %f, Avg FPS:%f, Cur FPS:%f, %d, nps:%3d, avgnotes:%f\n", ftime, frames/time, 1/ftime, notes, (int)nps, avgnotes);
	}

	olShutdown();
	exit (0);
}
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;
}