From alsa-devel-owner@alsa.jcu.cz  Fri Jul  3 21:29:05 1998
Received: from altrade.nijmegen.inter.nl.net (altrade.nijmegen.inter.nl.net [193.67.237.6])
	by marvin.jcu.cz (8.8.8/8.8.8) with ESMTP id VAA13186
	for <alsa-devel@jcu.cz>; Fri, 3 Jul 1998 21:28:59 +0200
Received: from obelix.fvdpol.inter.nl.net by altrade.nijmegen.inter.nl.net
	via bd99-13.Breda.NL.net [193.79.246.238] with ESMTP for <alsa-devel@jcu.cz>
	id VAA21995 (8.8.8/3.28); Fri, 3 Jul 1998 21:28:56 +0200 (MET DST)
Received: (from frank@localhost) by obelix.fvdpol.inter.nl.net (8.8.7/8.7.3) id VAA00479 for alsa-devel@jcu.cz; Fri, 3 Jul 1998 21:24:45 +0200
From: Frank van de Pol <F.K.W.van.de.Pol@inter.nl.net>
Message-Id: <199807031924.VAA00479@obelix.fvdpol.inter.nl.net>
Subject: Problem with GUS MIDI ???
To: alsa-devel@jcu.cz (alsa)
Date: Fri, 3 Jul 1998 21:24:45 +0200 (MET DST)
Content-Type: text
Reply-To: alsa-devel@alsa.jcu.cz
Sender: alsa-devel-owner@alsa.jcu.cz
Precedence: list

Hi,

Some good news and some bad news...

During my work on a prototype for the sequencer I got into a situation where
my (Linux) system crashed while playing a midi file through the ALSA
sequencer. 

The good news is that the sequencer prototype (for proof of concept) is
making quick progress.

The bad news news is that I spend 2 whole days chasing a bug that 'seems' to
be caused by the ALSA midi driver for the Gravis Ultrasound MAX. 

	o most times the sequencer client that drives the midi synth sends
	  out midi bytes (open("/dev/sndmidi00",RDONLY); write(...)) I get a
	  hard lockup:
		"page fault from irq handler 0000"
	  and a kernel panic. On other occasions I get a similar lockup, but
	  see lots of garbage scrolling over the console and even sometimes
	  a instant reboot (after a few seconds)... 

	o After tracing every bit in my sequencer modules, and being unable
	  to find the thing that triggers the lockups (I thought that my 
	  experimental modules were causing the trouble) I decided to remove
	  the MIDI output code, and tada, no locks anymore.

	o Odd thing is that that same MIDI output code has been working for
	  me with an older 'version' of the ALSA sequencer. 

	o Finally found the ghost that triggered the lockups and reboots: 
		===> My MIDI patchbay.
	  This device was accidently configured that all data received from 
	  the GUS card was direcly send back to the GUS. Ie. same as if one
	  connects a MIDI out to the MIDI in.

Such a hardware configuration should NEVER crash the system. (Okay, it does
on Cubase/Atari ST, but we're talking about Linux here so our standards
should be much higher :-)

Other remark on the MIDI driver for the GUS MAX: 
It works much better for processing MIDI bulk dumps than the OSS drivers.
When dumping the memory of my reverb (which is 45 kB of MIDI data) I suffer
lost bytes on the OSS, but the ALSA didn't miss a single bit! The 4kB
MIDI buffers do make sense.
Congratulations Jaroslav!



fragment of my program accessing the MIDI port (and causing instant death for my
machine):

initialisation:
	        

	/* open sequencer */
        fd = open("/dev/sndseq",O_RDWR);
        if (fd < 0) {
                perror("open /dev/sndseq");
                exit(1);
        }
        
        /* open midi device */
        midi_fd = open("/dev/sndmidi00",O_WRONLY);
                if (fd < 0) {
                perror("open /dev/sndmidi00");
                exit(1);
        }

	/* set client name */
        name = "MIDI Synth";
        if (ioctl(fd, SND_SEQ_IOCTL_SET_NAME, name) < 0) {
                perror("ioctl");
                exit(1);
        }


 	while (1) {
                FD_ZERO(&reads);
                FD_ZERO(&writes);
                
                FD_SET(fd, &reads);

                time.tv_sec  = 1;
                time.tv_usec = 0;
                if (select(fd+1, &reads, &writes, NULL, &time)==-1) {
                        perror("select");
                        exit(-1);
                }

                if (FD_ISSET(fd, &reads))
                {
                   l=read(fd, &ev, sizeof(ev));
                   if (l==sizeof(ev)) {
                        //decode_event(&ev);
                        play_event(midi_fd, &ev);
                   }
                }
	}




and when an event is received....


        switch (ev->type) {
                case SND_SEQ_EVENT_NOTEOFF:
                        msg[0] = (channel & 0x0f) | 0x80;       /* note on */
                        msg[1] = ev->data.note.note & 0x7f;
                        msg[2] = ev->data.note.velocity & 0x7f;
                        written = write(midi_fd, &msg, 3);
                        break;

                case SND_SEQ_EVENT_PGMCHANGE:
                        msg[0] = (channel & 0x0f) | 0xc0;       /* program change */
                        msg[1] = ev->data.control.value & 0x7f;
                        written = write(midi_fd, &msg, 2);
                        break;

                case SND_SEQ_EVENT_CONTROLLER:
                        msg[0] = (channel & 0x0f) | 0xb0;       /* control change */
                        msg[1] = ev->data.control.param & 0x7f;
                        msg[2] = ev->data.control.value & 0x7f;
                        written = write(midi_fd, &msg, 3);
                        break;


(no flames please, I know it doesn't handle running state et al, but I had a
need for a simple test program.)


Regards,
Frank.



+---- --- -- -  -   -    - 
|Frank van de Pol                  -o)
|F.K.W.van.de.Pol@inter.NL.net     /\\
|                                 _\_v
|Linux - Why use Windows, since there is a door?

