Update of /cvsroot/pure-data/pd/portmidi/pm_linux
In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv5166/pd/portmidi/pm_linux
Modified Files:
README_LINUX.txt pmlinux.c pmlinuxalsa.c
Log Message:
0.41-0 test 11
Index: pmlinux.c
===================================================================
RCS file: /cvsroot/pure-data/pd/portmidi/pm_linux/pmlinux.c,v
retrieving revision 1.1
retrieving revision 1.2
diff -C2 -d -r1.1 -r1.2
*** pmlinux.c 15 Dec 2005 00:56:57 -0000 1.1
--- pmlinux.c 16 Jan 2008 21:54:10 -0000 1.2
***************
*** 6,9 ****
--- 6,12 ----
dependent, and it is separate from, pmlinuxalsa.c, because it
might need to register non-alsa devices as well.
+
+ NOTE: if you add non-ALSA support, you need to fix :alsa_poll()
+ in pmlinuxalsa.c, which assumes all input devices are ALSA.
*/
***************
*** 20,23 ****
--- 23,31 ----
PmError pm_init()
{
+ /* Note: it is not an error for PMALSA to fail to initialize.
+ * It may be a design error that the client cannot query what subsystems
+ * are working properly other than by looking at the list of available
+ * devices.
+ */
#ifdef PMALSA
pm_linuxalsa_init();
***************
*** 26,29 ****
--- 34,38 ----
pm_linuxnull_init();
#endif
+ return pmNoError;
}
Index: README_LINUX.txt
===================================================================
RCS file: /cvsroot/pure-data/pd/portmidi/pm_linux/README_LINUX.txt,v
retrieving revision 1.1
retrieving revision 1.2
diff -C2 -d -r1.1 -r1.2
*** README_LINUX.txt 15 Dec 2005 00:56:57 -0000 1.1
--- README_LINUX.txt 16 Jan 2008 21:54:10 -0000 1.2
***************
*** 1,8 ****
README_LINUX.txt for PortMidi
Roger Dannenberg
! 8 June 2004
To make PortMidi and PortTime, go back up to the portmidi
! directory and type make.
The Makefile will build all test programs and the portmidi
--- 1,13 ----
README_LINUX.txt for PortMidi
Roger Dannenberg
! 29 Aug 2006
To make PortMidi and PortTime, go back up to the portmidi
! directory and type
!
! make -f pm_linux/Makefile
!
! (You can also copy pm_linux/Makefile to the portmidi
! directory and just type "make".)
The Makefile will build all test programs and the portmidi
***************
*** 22,25 ****
--- 27,36 ----
CHANGELOG
+ 29-aug-2006 Roger B. Dannenberg
+ Fixed PortTime to join with time thread for clean exit.
+
+ 28-aug-2006 Roger B. Dannenberg
+ Updated this documentation.
+
08-Jun-2004 Roger B. Dannenberg
Updated code to use new system abstraction.
Index: pmlinuxalsa.c
===================================================================
RCS file: /cvsroot/pure-data/pd/portmidi/pm_linux/pmlinuxalsa.c,v
retrieving revision 1.1
retrieving revision 1.2
diff -C2 -d -r1.1 -r1.2
*** pmlinuxalsa.c 15 Dec 2005 00:56:57 -0000 1.1
--- pmlinuxalsa.c 16 Jan 2008 21:54:10 -0000 1.2
***************
*** 10,13 ****
--- 10,16 ----
#include "stdlib.h"
#include "portmidi.h"
+ #ifdef NEWBUFFER
+ #include "pmutil.h"
+ #endif
#include "pminternal.h"
#include "pmlinuxalsa.h"
***************
*** 42,46 ****
extern pm_fns_node pm_linuxalsa_out_dictionary;
! static snd_seq_t *seq; // all input comes here, output queue allocated on seq
static int queue, queue_used; /* one for all ports, reference counted */
--- 45,50 ----
extern pm_fns_node pm_linuxalsa_out_dictionary;
! static snd_seq_t *seq = NULL; // all input comes here,
! // output queue allocated on seq
static int queue, queue_used; /* one for all ports, reference counted */
***************
*** 209,213 ****
if (when < 0) when = 0;
VERBOSE printf("timestamp %d now %d latency %d, ",
! timestamp, now, midi->latency);
VERBOSE printf("scheduling event after %d\n", when);
/* message is sent in relative ticks, where 1 tick = 1 ms */
--- 213,217 ----
if (when < 0) when = 0;
VERBOSE printf("timestamp %d now %d latency %d, ",
! (int) timestamp, (int) now, midi->latency);
VERBOSE printf("scheduling event after %d\n", when);
/* message is sent in relative ticks, where 1 tick = 1 ms */
***************
*** 239,243 ****
static PmError alsa_out_close(PmInternal *midi)
{
- int err;
alsa_descriptor_type desc = (alsa_descriptor_type) midi->descriptor;
if (!desc) return pmBadPtr;
--- 243,246 ----
***************
*** 253,256 ****
--- 256,260 ----
if (midi->latency > 0) alsa_unuse_queue();
snd_midi_event_free(desc->parser);
+ midi->descriptor = NULL; /* destroy the pointer to signify "closed" */
pm_free(desc);
if (pm_hosterror) {
***************
*** 330,334 ****
static PmError alsa_in_close(PmInternal *midi)
{
- int err;
alsa_descriptor_type desc = (alsa_descriptor_type) midi->descriptor;
if (!desc) return pmBadPtr;
--- 334,337 ----
***************
*** 352,357 ****
static PmError alsa_abort(PmInternal *midi)
{
alsa_descriptor_type desc = (alsa_descriptor_type) midi->descriptor;
! /* This is supposed to flush any pending output. */
printf("WARNING: alsa_abort not implemented\n");
return pmNoError;
--- 355,382 ----
static PmError alsa_abort(PmInternal *midi)
{
+ /* NOTE: ALSA documentation is vague. This is supposed to
+ * remove any pending output messages. If you can test and
+ * confirm this code is correct, please update this comment. -RBD
+ */
+ /* Unfortunately, I can't even compile it -- my ALSA version
+ * does not implement snd_seq_remove_events_t, so this does
+ * not compile. I'll try again, but it looks like I'll need to
+ * upgrade my entire Linux OS -RBD
+ */
+ /*
alsa_descriptor_type desc = (alsa_descriptor_type) midi->descriptor;
! snd_seq_remove_events_t info;
! snd_seq_addr_t addr;
! addr.client = desc->client;
! addr.port = desc->port;
! snd_seq_remove_events_set_dest(&info, &addr);
! snd_seq_remove_events_set_condition(&info, SND_SEQ_REMOVE_DEST);
! pm_hosterror = snd_seq_remove_events(seq, &info);
! if (pm_hosterror) {
! get_alsa_error_text(pm_hosterror_text, PM_HOST_ERROR_MSG_LEN,
! pm_hosterror);
! return pmHostError;
! }
! */
printf("WARNING: alsa_abort not implemented\n");
return pmNoError;
***************
*** 409,416 ****
! static PmError alsa_write_flush(PmInternal *midi)
{
alsa_descriptor_type desc = (alsa_descriptor_type) midi->descriptor;
! VERBOSE printf("snd_seq_drain_output: 0x%x\n", seq);
desc->error = snd_seq_drain_output(seq);
if (desc->error < 0) return pmHostError;
--- 434,441 ----
! static PmError alsa_write_flush(PmInternal *midi, PmTimestamp timestamp)
{
alsa_descriptor_type desc = (alsa_descriptor_type) midi->descriptor;
! VERBOSE printf("snd_seq_drain_output: 0x%x\n", (unsigned int) seq);
desc->error = snd_seq_drain_output(seq);
if (desc->error < 0) return pmHostError;
***************
*** 584,595 ****
case SND_SEQ_EVENT_SYSEX: {
const BYTE *ptr = (const BYTE *) ev->data.ext.ptr;
! int i;
! long msg = 0;
! int shift = 0;
! if (!(midi->filters & PM_FILT_SYSEX)) {
! for (i = 0; i < ev->data.ext.len; i++) {
! pm_read_byte(midi, *ptr++, timestamp);
! }
! }
break;
}
--- 609,614 ----
case SND_SEQ_EVENT_SYSEX: {
const BYTE *ptr = (const BYTE *) ev->data.ext.ptr;
! /* assume there is one sysex byte to process */
! pm_read_bytes(midi, ptr, ev->data.ext.len, timestamp);
break;
}
***************
*** 597,606 ****
}
static PmError alsa_poll(PmInternal *midi)
{
snd_seq_event_t *ev;
! while (snd_seq_event_input(seq, &ev) >= 0) {
! if (ev) {
! handle_event(ev);
}
}
--- 616,648 ----
}
+
static PmError alsa_poll(PmInternal *midi)
{
snd_seq_event_t *ev;
! /* expensive check for input data, gets data from device: */
! while (snd_seq_event_input_pending(seq, TRUE) > 0) {
! /* cheap check on local input buffer */
! while (snd_seq_event_input_pending(seq, FALSE) > 0) {
! /* check for and ignore errors, e.g. input overflow */
! /* note: if there's overflow, this should be reported
! * all the way through to client. Since input from all
! * devices is merged, we need to find all input devices
! * and set all to the overflow state.
! * NOTE: this assumes every input is ALSA based.
! */
! int rslt = snd_seq_event_input(seq, &ev);
! if (rslt >= 0) {
! handle_event(ev);
! } else if (rslt == -ENOSPC) {
! int i;
! for (i = 0; i < pm_descriptor_index; i++) {
! if (descriptors[i].pub.input) {
! PmInternal *midi = (PmInternal *)
! descriptors[i].internalDescriptor;
! /* careful, device may not be open! */
! if (midi) Pm_SetOverflow(midi->queue);
! }
! }
! }
}
}
***************
*** 678,683 ****
unsigned int caps;
! err = snd_seq_open(&seq, "default", SND_SEQ_OPEN_DUPLEX, SND_SEQ_NONBLOCK);
! if (err < 0) return;
snd_seq_client_info_alloca(&cinfo);
--- 720,734 ----
unsigned int caps;
! /* Previously, the last parameter was SND_SEQ_NONBLOCK, but this
! * would cause messages to be dropped if the ALSA buffer fills up.
! * The correct behavior is for writes to block until there is
! * room to send all the data. The client should normally allocate
! * a large enough buffer to avoid blocking on output.
! * Now that blocking is enabled, the seq_event_input() will block
! * if there is no input data. This is not what we want, so must
! * call seq_event_input_pending() to avoid blocking.
! */
! err = snd_seq_open(&seq, "default", SND_SEQ_OPEN_DUPLEX, 0);
! if (err < 0) return err;
snd_seq_client_info_alloca(&cinfo);
***************
*** 716,719 ****
--- 767,771 ----
}
}
+ return pmNoError;
}
***************
*** 721,724 ****
void pm_linuxalsa_term(void)
{
! snd_seq_close(seq);
}
--- 773,782 ----
void pm_linuxalsa_term(void)
{
! if (seq) {
! snd_seq_close(seq);
! pm_free(descriptors);
! descriptors = NULL;
! pm_descriptor_index = 0;
! pm_descriptor_max = 0;
! }
}