From mboxrd@z Thu Jan 1 00:00:00 1970 Path: news.gmane.org!not-for-mail From: David Kastrup Newsgroups: gmane.emacs.devel Subject: Integrating Midi into Emacs Date: Fri, 02 Jan 2015 12:28:14 +0100 Message-ID: <87fvbttoa9.fsf@fencepost.gnu.org> NNTP-Posting-Host: plane.gmane.org Mime-Version: 1.0 Content-Type: text/plain X-Trace: ger.gmane.org 1420198130 16311 80.91.229.3 (2 Jan 2015 11:28:50 GMT) X-Complaints-To: usenet@ger.gmane.org NNTP-Posting-Date: Fri, 2 Jan 2015 11:28:50 +0000 (UTC) To: emacs-devel@gnu.org Original-X-From: emacs-devel-bounces+ged-emacs-devel=m.gmane.org@gnu.org Fri Jan 02 12:28:44 2015 Return-path: Envelope-to: ged-emacs-devel@m.gmane.org Original-Received: from lists.gnu.org ([208.118.235.17]) by plane.gmane.org with esmtp (Exim 4.69) (envelope-from ) id 1Y70PL-0005Bn-RD for ged-emacs-devel@m.gmane.org; Fri, 02 Jan 2015 12:28:43 +0100 Original-Received: from localhost ([::1]:50869 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1Y70PL-0008ID-53 for ged-emacs-devel@m.gmane.org; Fri, 02 Jan 2015 06:28:43 -0500 Original-Received: from eggs.gnu.org ([2001:4830:134:3::10]:57273) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1Y70PG-0008Hv-NY for emacs-devel@gnu.org; Fri, 02 Jan 2015 06:28:39 -0500 Original-Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1Y70P7-00063e-V6 for emacs-devel@gnu.org; Fri, 02 Jan 2015 06:28:38 -0500 Original-Received: from fencepost.gnu.org ([2001:4830:134:3::e]:43971) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1Y70P7-00063a-Sg for emacs-devel@gnu.org; Fri, 02 Jan 2015 06:28:29 -0500 Original-Received: from localhost ([127.0.0.1]:51147 helo=lola) by fencepost.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1Y70P7-0006oV-Ev for emacs-devel@gnu.org; Fri, 02 Jan 2015 06:28:29 -0500 Original-Received: by lola (Postfix, from userid 1000) id EB804DF8CA; Fri, 2 Jan 2015 12:28:14 +0100 (CET) User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/25.0.50 (gnu/linux) X-detected-operating-system: by eggs.gnu.org: Error: Malformed IPv6 address (bad octet value). X-Received-From: 2001:4830:134:3::e X-BeenThere: emacs-devel@gnu.org X-Mailman-Version: 2.1.14 Precedence: list List-Id: "Emacs development discussions." List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: emacs-devel-bounces+ged-emacs-devel=m.gmane.org@gnu.org Original-Sender: emacs-devel-bounces+ged-emacs-devel=m.gmane.org@gnu.org Xref: news.gmane.org gmane.emacs.devel:180921 Archived-At: Hi, I've been meddling with CCL programs and stuff for integrating Midi input received via make-serial-process into Emacs. I've encountered several puzzling design decisions and drawbacks. There are several crucial ones, however. At its core, pressing keys on a musical keyboard will result in the insertion of note names into the current buffer. This basically is similar to an input method. Here are several respects causing a bad fit: a) user expectation will be to have music keyboard keys insert into the selected window. make-serial-process can not really have the process be tied into one editing buffer since those editing buffers run processes of their own (viewer, compilation with LilyPond etc) and get-buffer-process is used for checking for conflicts. Also, one cannot reattach the process to different buffers when buffers are getting switched. So basically make-serial-process happens for a buffer of its own, and this buffer distributes the received information through its process filter. This process filter then does something akin to (defun notename-filter (process string) (with-current-buffer (window-buffer) (if (= (aref string 0) ?\ ) (if (and (= (window-point) (process-mark process)) (eq (current-buffer) (marker-buffer (process-mark process)))) (insert string) (insert (substring string 1))) (insert string)) (move-marker (process-mark process) (window-point) (current-buffer)))) Apart from the complications arising from trying to put spaces between successive entries only if no editing happened in between, the thing to note is that this works on (window-buffer), the currently selected buffer. It is not clear how many save-excursions may intervene, and when a process filter actually gets triggered. So point and mark in the buffer may or may not terminally advance. One really would want to feed this through the regular input queue instead of going directly into some buffer. Which gets us to point b) Ultimately, input should be time-stamped. It's reasonably easy to do this using the process-filter, tacking on appropriate text properties, but the timestamp may be slightly stale when Emacs is busy as process filters are only run at appropriately idle times. c) the inserted text actually depends on buffer-local variables, for example the current notename language (English writes cs for c-sharp, Dutch writes cis, Italian writes dod), and the current key (the Midi event for c-sharp is indistinguishable from d flat, and the decision is made based on the current key in the current piece). Switching CCL programs in the decoder is tricky as they do not lend themselves to closures with internal states. Also, one would need one closure per language/key pairing currently active. This kind of flexible back-and-forth mapping is actually better accomplished by swapping around keymaps rather than encodings. What this leads up to is that a better approach would be to have Midi events in the Emacs event queue. They would want timestamps like mouse events, they would want some identifiable nice names/identifications for binding them to actions. Since they are primarily going to be used as an input method with one hand on the computer keyboard and one hand on the Midi keyboard, it might even make sense to allow for keyboard modifiers like shift/alt/control in order to signify particular modified actions. So basically it would seem nice to extend the Emacs input events. That, in itself, feels like something that Emacs should support out of the box without recompilation. If it doesn't, it might be worth thinking about what might be necessary to make it do so. There is also a chance that an implementation along that lines could be made to work with XEmacs without requiring compilation. However, to really get timestamps with the accuracy of the arriving input, it would make sense to use the binary ALSA API for communicating with Midi input devices. One advantage of tieing Midi input in at a basic level might also be that one can use it to convey modifiers like Hyper and Super that avid Emacs typists might want to enter using foot pedals. The number of USB computer keyboards providing for Emacs-friendly foot pedals is minuscule. Midi-capable footpedals, however, are not exactly a dime a dozen but they are quite ubiquitous. So being able to exploit Midi signals with a timing accuracy making it possible to match them to computer keyboard input would make it much easier to acquire workable modifier pedals even for regular non-musician uses. Thoughts? -- David Kastrup