[PD-cvs] pd/portmidi/pm_linux README_LINUX.txt, 1.1, 1.2 pmlinux.c, 1.1, 1.2 pmlinuxalsa.c, 1.1, 1.2

Miller Puckette millerpuckette at users.sourceforge.net
Wed Jan 16 22:54:12 CET 2008


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;
!     }
  }





More information about the Pd-cvs mailing list