controller-midi.c 25.7 KB
Newer Older
1 2
/* GIMP - The GNU Image Manipulation Program
 * Copyright (C) 1995-1997 Spencer Kimball and Peter Mattis
3 4
 *
 * controller_midi.c
5
 * Copyright (C) 2004-2007 Michael Natterer <mitch@gimp.org>
6
 *
7
 * This program is free software: you can redistribute it and/or modify
8
 * it under the terms of the GNU General Public License as published by
9
 * the Free Software Foundation; either version 3 of the License, or
10
 * (at your option) any later version.
11
 *
12
 * This program is distributed in the hope that it will be useful,
13
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 15
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
16
 *
17
 * You should have received a copy of the GNU General Public License
18
 * along with this program.  If not, see <https://www.gnu.org/licenses/>.
19 20 21 22
 */

#include "config.h"

23
#define _GNU_SOURCE  /* the ALSA headers need this */
24

25 26
#include <errno.h>
#include <fcntl.h>
27 28 29
#include <string.h>
#include <sys/stat.h>
#include <sys/types.h>
30
#include <time.h>
31

32 33
#include <glib/gstdio.h>

34 35
#ifdef HAVE_ALSA
#include <alsa/asoundlib.h>
36 37
#endif

38
#include <gegl.h>
39 40
#include <gtk/gtk.h>

41
#include "libgimpconfig/gimpconfig.h"
42 43 44
#include "libgimpmodule/gimpmodule.h"
#include "libgimpwidgets/gimpwidgets.h"

45
#define GIMP_ENABLE_CONTROLLER_UNDER_CONSTRUCTION
46 47 48 49 50 51 52 53 54 55 56 57 58 59 60
#include "libgimpwidgets/gimpcontroller.h"

#include "libgimp/libgimp-intl.h"


typedef struct
{
  gchar *name;
  gchar *blurb;
} MidiEvent;


enum
{
  PROP_0,
61 62
  PROP_DEVICE,
  PROP_CHANNEL
63 64 65
};


66
#define CONTROLLER_TYPE_MIDI            (controller_midi_get_type ())
67 68 69 70 71 72 73 74 75 76 77 78 79 80
#define CONTROLLER_MIDI(obj)            (G_TYPE_CHECK_INSTANCE_CAST ((obj), CONTROLLER_TYPE_MIDI, ControllerMidi))
#define CONTROLLER_MIDI_CLASS(klass)    (G_TYPE_CHECK_CLASS_CAST ((klass), CONTROLLER_TYPE_MIDI, ControllerMidiClass))
#define CONTROLLER_IS_MIDI(obj)         (G_TYPE_CHECK_INSTANCE_TYPE ((obj), CONTROLLER_TYPE_MIDI))
#define CONTROLLER_IS_MIDI_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), CONTROLLER_TYPE_MIDI))


typedef struct _ControllerMidi      ControllerMidi;
typedef struct _ControllerMidiClass ControllerMidiClass;

struct _ControllerMidi
{
  GimpController  parent_instance;

  gchar          *device;
81 82
  gint            midi_channel;

83
  GIOChannel     *io;
84
  guint           io_id;
85

86
#ifdef HAVE_ALSA
87 88 89 90
  snd_seq_t      *sequencer;
  guint           seq_id;
#endif

91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106
  /* midi status */
  gboolean        swallow;
  gint            command;
  gint            channel;
  gint            key;
  gint            velocity;
  gint            msb;
  gint            lsb;
};

struct _ControllerMidiClass
{
  GimpControllerClass  parent_class;
};


107
static GType         controller_midi_get_type (void);
108

109 110 111 112 113 114 115 116 117
static void          midi_dispose             (GObject        *object);
static void          midi_set_property        (GObject        *object,
                                               guint           property_id,
                                               const GValue   *value,
                                               GParamSpec     *pspec);
static void          midi_get_property        (GObject        *object,
                                               guint           property_id,
                                               GValue         *value,
                                               GParamSpec     *pspec);
118

119 120 121 122 123
static gint          midi_get_n_events        (GimpController *controller);
static const gchar * midi_get_event_name      (GimpController *controller,
                                               gint            event_id);
static const gchar * midi_get_event_blurb     (GimpController *controller,
                                               gint            event_id);
124

125 126 127 128 129 130
static gboolean      midi_set_device          (ControllerMidi *controller,
                                               const gchar    *device);
static void          midi_event               (ControllerMidi *midi,
                                               gint            channel,
                                               gint            event_id,
                                               gdouble         value);
131

132 133 134
static gboolean      midi_read_event          (GIOChannel     *io,
                                               GIOCondition    cond,
                                               gpointer        data);
135

136
#ifdef HAVE_ALSA
137 138 139 140 141 142
static gboolean      midi_alsa_prepare        (GSource        *source,
                                               gint           *timeout);
static gboolean      midi_alsa_check          (GSource        *source);
static gboolean      midi_alsa_dispatch       (GSource        *source,
                                               GSourceFunc     callback,
                                               gpointer        user_data);
143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158

static GSourceFuncs alsa_source_funcs =
{
  midi_alsa_prepare,
  midi_alsa_check,
  midi_alsa_dispatch,
  NULL
};

typedef struct _GAlsaSource GAlsaSource;

struct _GAlsaSource
{
  GSource         source;
  ControllerMidi *controller;
};
159
#endif /* HAVE_ALSA */
160 161 162 163

static const GimpModuleInfo midi_info =
{
  GIMP_MODULE_ABI_VERSION,
164
  N_("MIDI event controller"),
165
  "Michael Natterer <mitch@gimp.org>",
166 167 168
  "v0.2",
  "(c) 2004-2007, released under the GPL",
  "2004-2007"
169 170 171
};


172 173
G_DEFINE_DYNAMIC_TYPE (ControllerMidi, controller_midi,
                       GIMP_TYPE_CONTROLLER)
174

175
static MidiEvent midi_events[128 + 128 + 128];
176 177 178 179 180 181 182 183 184 185 186


G_MODULE_EXPORT const GimpModuleInfo *
gimp_module_query (GTypeModule *module)
{
  return &midi_info;
}

G_MODULE_EXPORT gboolean
gimp_module_register (GTypeModule *module)
{
187
  controller_midi_register_type (module);
188 189 190 191 192

  return TRUE;
}

static void
193
controller_midi_class_init (ControllerMidiClass *klass)
194 195 196
{
  GimpControllerClass *controller_class = GIMP_CONTROLLER_CLASS (klass);
  GObjectClass        *object_class     = G_OBJECT_CLASS (klass);
197
  gchar               *blurb;
198 199 200 201 202

  object_class->dispose            = midi_dispose;
  object_class->get_property       = midi_get_property;
  object_class->set_property       = midi_set_property;

203 204 205 206 207 208 209
  blurb = g_strconcat (_("The name of the device to read MIDI events from."),
#ifdef HAVE_ALSA
                       "\n",
                       _("Enter 'alsa' to use the ALSA sequencer."),
#endif
                       NULL);

210
  g_object_class_install_property (object_class, PROP_DEVICE,
211
                                   g_param_spec_string ("device",
212
                                                        _("Device:"),
213
                                                        blurb,
214
                                                        NULL,
215
                                                        GIMP_CONFIG_PARAM_FLAGS));
216 217 218

  g_free (blurb);

219 220 221 222 223
  g_object_class_install_property (object_class, PROP_CHANNEL,
                                   g_param_spec_int ("channel",
                                                     _("Channel:"),
                                                     _("The MIDI channel to read events from. Set to -1 for reading from all MIDI channels."),
                                                     -1, 15, -1,
224
                                                     GIMP_CONFIG_PARAM_FLAGS));
225

226 227
  controller_class->name            = _("MIDI");
  controller_class->help_id         = "gimp-controller-midi";
228
  controller_class->icon_name       = GIMP_ICON_CONTROLLER_MIDI;
229 230 231 232 233 234 235

  controller_class->get_n_events    = midi_get_n_events;
  controller_class->get_event_name  = midi_get_event_name;
  controller_class->get_event_blurb = midi_get_event_blurb;
}

static void
236 237 238 239 240 241
controller_midi_class_finalize (ControllerMidiClass *klass)
{
}

static void
controller_midi_init (ControllerMidi *midi)
242
{
243 244 245 246
  midi->device       = NULL;
  midi->midi_channel = -1;
  midi->io           = NULL;
  midi->io_id        = 0;
247
#ifdef HAVE_ALSA
248 249 250
  midi->sequencer    = NULL;
  midi->seq_id       = 0;
#endif
251 252 253 254 255 256 257 258

  midi->swallow      = TRUE; /* get rid of data bytes at start of stream */
  midi->command      = 0x0;
  midi->channel      = 0x0;
  midi->key          = -1;
  midi->velocity     = -1;
  midi->msb          = -1;
  midi->lsb          = -1;
259 260 261 262 263 264 265 266 267
}

static void
midi_dispose (GObject *object)
{
  ControllerMidi *midi = CONTROLLER_MIDI (object);

  midi_set_device (midi, NULL);

268
  G_OBJECT_CLASS (controller_midi_parent_class)->dispose (object);
269 270 271 272 273 274 275 276 277 278 279 280 281 282 283
}

static void
midi_set_property (GObject      *object,
                   guint         property_id,
                   const GValue *value,
                   GParamSpec   *pspec)
{
  ControllerMidi *midi = CONTROLLER_MIDI (object);

  switch (property_id)
    {
    case PROP_DEVICE:
      midi_set_device (midi, g_value_get_string (value));
      break;
284 285 286
    case PROP_CHANNEL:
      midi->midi_channel = g_value_get_int (value);
      break;
287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305
    default:
      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
      break;
    }
}

static void
midi_get_property (GObject    *object,
                   guint       property_id,
                   GValue     *value,
                   GParamSpec *pspec)
{
  ControllerMidi *midi = CONTROLLER_MIDI (object);

  switch (property_id)
    {
    case PROP_DEVICE:
      g_value_set_string (value, midi->device);
      break;
306 307 308
    case PROP_CHANNEL:
      g_value_set_int (value, midi->midi_channel);
      break;
309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324
    default:
      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
      break;
    }
}

static gint
midi_get_n_events (GimpController *controller)
{
  return 128 + 128 + 128;
}

static const gchar *
midi_get_event_name (GimpController *controller,
                     gint            event_id)
{
325
  if (event_id < (128 + 128 + 128))
326 327 328 329 330 331
    {
      if (! midi_events[event_id].name)
        {
          if (event_id < 128)
            midi_events[event_id].name = g_strdup_printf ("note-on-%02x",
                                                          event_id);
332
          else if (event_id < (128 + 128))
333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354
            midi_events[event_id].name = g_strdup_printf ("note-off-%02x",
                                                          event_id - 128);
          else if (event_id < (128 + 128 + 128))
            midi_events[event_id].name = g_strdup_printf ("controller-%03d",
                                                          event_id - 256);
        }

      return midi_events[event_id].name;
    }

  return NULL;
}

static const gchar *
midi_get_event_blurb (GimpController *controller,
                      gint            event_id)
{
  if (event_id <= 383)
    {
      if (! midi_events[event_id].blurb)
        {
          if (event_id <= 127)
355
            midi_events[event_id].blurb = g_strdup_printf (_("Note %02x on"),
356 357
                                                           event_id);
          else if (event_id <= 255)
358
            midi_events[event_id].blurb = g_strdup_printf (_("Note %02x off"),
359 360
                                                           event_id - 128);
          else if (event_id <= 383)
361
            midi_events[event_id].blurb = g_strdup_printf (_("Controller %03d"),
362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384
                                                           event_id - 256);
        }

      return midi_events[event_id].blurb;
    }

  return NULL;
}

static gboolean
midi_set_device (ControllerMidi *midi,
                 const gchar    *device)
{
  midi->swallow  = TRUE;
  midi->command  = 0x0;
  midi->channel  = 0x0;
  midi->key      = -1;
  midi->velocity = -1;
  midi->msb      = -1;
  midi->lsb      = -1;

  if (midi->io)
    {
385 386 387
      g_source_remove (midi->io_id);
      midi->io_id = 0;

388 389 390 391
      g_io_channel_unref (midi->io);
      midi->io = NULL;
    }

392
#ifdef HAVE_ALSA
393 394 395 396 397 398 399 400
  if (midi->seq_id)
    {
      g_source_remove (midi->seq_id);
      midi->seq_id = 0;

      snd_seq_close (midi->sequencer);
      midi->sequencer = NULL;
    }
401
#endif /* HAVE_ALSA */
402

403 404 405 406 407
  if (midi->device)
    g_free (midi->device);

  midi->device = g_strdup (device);

408 409
  g_object_set (midi, "name", _("MIDI Events"), NULL);

410
  if (midi->device && strlen (midi->device))
411 412 413
    {
      gint fd;

414
#ifdef HAVE_ALSA
415 416
      if (! g_ascii_strcasecmp (midi->device, "alsa"))
        {
Sven Neumann's avatar
Sven Neumann committed
417 418 419 420
          GSource *event_source;
          gchar   *alsa;
          gchar   *state;
          gint     ret;
421 422 423 424 425

          ret = snd_seq_open (&midi->sequencer, "default",
                              SND_SEQ_OPEN_INPUT, 0);
          if (ret >= 0)
            {
426
              snd_seq_set_client_name (midi->sequencer, _("GIMP"));
427
              ret = snd_seq_create_simple_port (midi->sequencer,
428
                                                _("GIMP MIDI Input Controller"),
429 430 431 432 433 434 435
                                                SND_SEQ_PORT_CAP_WRITE |
                                                SND_SEQ_PORT_CAP_SUBS_WRITE,
                                                SND_SEQ_PORT_TYPE_APPLICATION);
            }

          if (ret < 0)
            {
436 437 438 439
              state = g_strdup_printf (_("Device not available: %s"),
                                       snd_strerror (ret));
              g_object_set (midi, "state", state, NULL);
              g_free (state);
440 441 442 443 444 445 446 447 448 449 450

              if (midi->sequencer)
                {
                  snd_seq_close (midi->sequencer);
                  midi->sequencer = NULL;
                }

              return FALSE;
            }

          /* hack to avoid new message to translate */
451
          alsa = g_strdup_printf ("ALSA (%d:%d)",
452 453
                                  snd_seq_client_id (midi->sequencer),
                                  ret);
454
          state = g_strdup_printf (_("Reading from %s"), alsa);
455 456
          g_free (alsa);

457
          g_object_set (midi, "state", state, NULL);
458 459
          g_free (state);

Sven Neumann's avatar
Sven Neumann committed
460 461 462 463 464 465
          event_source = g_source_new (&alsa_source_funcs,
                                       sizeof (GAlsaSource));

          ((GAlsaSource *) event_source)->controller = midi;

          midi->seq_id = g_source_attach (event_source, NULL);
466
          g_source_unref (event_source);
467

468 469
          return TRUE;
        }
470
#endif /* HAVE_ALSA */
471

472
#ifdef G_OS_WIN32
473
      fd = g_open (midi->device, O_RDONLY, 0);
474
#else
475
      fd = g_open (midi->device, O_RDONLY | O_NONBLOCK, 0);
476 477
#endif

478 479
      if (fd >= 0)
        {
480 481 482
          gchar *state = g_strdup_printf (_("Reading from %s"), midi->device);
          g_object_set (midi, "state", state, NULL);
          g_free (state);
483 484 485 486 487

          midi->io = g_io_channel_unix_new (fd);
          g_io_channel_set_close_on_unref (midi->io, TRUE);
          g_io_channel_set_encoding (midi->io, NULL, NULL);

488
          midi->io_id = g_io_add_watch (midi->io,
489 490
                                        G_IO_IN  | G_IO_ERR |
                                        G_IO_HUP | G_IO_NVAL,
491 492
                                        midi_read_event,
                                        midi);
493 494 495 496
          return TRUE;
        }
      else
        {
497 498 499 500
          gchar *state = g_strdup_printf (_("Device not available: %s"),
                                          g_strerror (errno));
          g_object_set (midi, "state", state, NULL);
          g_free (state);
501 502 503 504
        }
    }
  else
    {
505
      g_object_set (midi, "state", _("No device configured"), NULL);
506 507 508 509 510
    }

  return FALSE;
}

511 512
static void
midi_event (ControllerMidi *midi,
513
            gint            channel,
514 515 516
            gint            event_id,
            gdouble         value)
{
517 518 519 520 521
  if (channel == -1            ||
      midi->midi_channel == -1 ||
      channel == midi->midi_channel)
    {
      GimpControllerEvent event = { 0, };
522

523 524 525
      event.any.type     = GIMP_CONTROLLER_EVENT_VALUE;
      event.any.source   = GIMP_CONTROLLER (midi);
      event.any.event_id = event_id;
526

527 528
      g_value_init (&event.value.value, G_TYPE_DOUBLE);
      g_value_set_double (&event.value.value, value);
529

530
      gimp_controller_event (GIMP_CONTROLLER (midi), &event);
531

532 533
      g_value_unset (&event.value.value);
    }
534 535
}

536 537 538 539 540 541 542 543 544

#define D(stmnt) stmnt;

gboolean
midi_read_event (GIOChannel   *io,
                 GIOCondition  cond,
                 gpointer      data)
{
  ControllerMidi *midi = CONTROLLER_MIDI (data);
545 546
  GIOStatus       status;
  GError         *error = NULL;
547 548
  guchar          buf[0xf];
  gsize           size;
549
  gint            pos = 0;
550

551 552 553 554 555 556
  status = g_io_channel_read_chars (io,
                                    (gchar *) buf,
                                    sizeof (buf), &size,
                                    &error);

  switch (status)
557
    {
558 559 560 561 562 563 564 565 566 567
    case G_IO_STATUS_ERROR:
    case G_IO_STATUS_EOF:
      g_source_remove (midi->io_id);
      midi->io_id = 0;

      g_io_channel_unref (midi->io);
      midi->io = NULL;

      if (error)
        {
568 569 570 571
          gchar *state = g_strdup_printf (_("Device not available: %s"),
                                          error->message);
          g_object_set (midi, "state", state, NULL);
          g_free (state);
572

573
          g_clear_error (&error);
574 575
        }
      else
576
        {
577
          g_object_set (midi, "state", _("End of file"), NULL);
578 579 580 581 582 583 584 585 586 587 588 589 590
        }
      return FALSE;
      break;

    case G_IO_STATUS_AGAIN:
      return TRUE;

    default:
      break;
    }

  while (pos < size)
    {
591
#if 0
592
      gint i;
593

594
      g_print ("MIDI IN (%d bytes), command 0x%02x: ", size, midi->command);
595

596 597 598
      for (i = 0; i < size; i++)
        g_print ("%02x ", buf[i]);
      g_print ("\n");
599 600
#endif

601 602 603
      if (buf[pos] & 0x80)  /* status byte */
        {
          if (buf[pos] >= 0xf8)  /* realtime messages */
604
            {
605
              switch (buf[pos])
606
                {
607 608 609 610 611 612 613 614 615
                case 0xf8:  /* timing clock   */
                case 0xf9:  /* (undefined)    */
                case 0xfa:  /* start          */
                case 0xfb:  /* continue       */
                case 0xfc:  /* stop           */
                case 0xfd:  /* (undefined)    */
                case 0xfe:  /* active sensing */
                case 0xff:  /* system reset   */
                  /* nop */
616
#if 0
617
                  g_print ("MIDI: realtime message (%02x)\n", buf[pos]);
618
#endif
619
                  break;
620
                }
621 622 623 624
            }
          else
            {
              midi->swallow = FALSE;  /* any status bytes ends swallowing */
625

626 627 628
              if (buf[pos] >= 0xf0)  /* system messages */
                {
                  switch (buf[pos])
629
                    {
630 631
                    case 0xf0:  /* sysex start */
                      midi->swallow = TRUE;
632

633 634
                      D (g_print ("MIDI: sysex start\n"));
                      break;
635

636 637
                    case 0xf1:              /* time code   */
                      midi->swallow = TRUE; /* type + data */
638

639 640
                      D (g_print ("MIDI: time code\n"));
                      break;
641

642 643
                    case 0xf2:              /* song position */
                      midi->swallow = TRUE; /* lsb + msb     */
644

645 646
                      D (g_print ("MIDI: song position\n"));
                      break;
647

648 649
                    case 0xf3:              /* song select */
                      midi->swallow = TRUE; /* song number */
650

651 652
                      D (g_print ("MIDI: song select\n"));
                      break;
653

654 655 656 657
                    case 0xf4:  /* (undefined) */
                    case 0xf5:  /* (undefined) */
                      D (g_print ("MIDI: undefined system message\n"));
                      break;
658

659 660 661
                    case 0xf6:  /* tune request */
                      D (g_print ("MIDI: tune request\n"));
                      break;
662

663 664 665
                    case 0xf7:  /* sysex end */
                      D (g_print ("MIDI: sysex end\n"));
                      break;
666
                    }
667
                }
668 669 670 671 672 673 674 675 676 677 678
              else  /* channel messages */
                {
                  midi->command = buf[pos] >> 4;
                  midi->channel = buf[pos] & 0xf;

                  /* reset running status */
                  midi->key      = -1;
                  midi->velocity = -1;
                  midi->msb      = -1;
                  midi->lsb      = -1;
                }
679 680
            }

681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697
          pos++;  /* status byte consumed */
          continue;
        }

      if (midi->swallow)
        {
          pos++;  /* consume any data byte */
          continue;
        }

      switch (midi->command)
        {
        case 0x8:  /* note off   */
        case 0x9:  /* note on    */
        case 0xa:  /* aftertouch */

          if (midi->key == -1)
698
            {
699
              midi->key = buf[pos++];  /* key byte consumed */
700 701 702
              continue;
            }

703 704
          if (midi->velocity == -1)
            midi->velocity = buf[pos++];  /* velocity byte consumed */
705

706 707 708
          /* note on with velocity = 0 means note off */
          if (midi->command == 0x9 && midi->velocity == 0x0)
            midi->command = 0x8;
709

710 711 712 713 714
          if (midi->command == 0x9)
            {
              D (g_print ("MIDI (ch %02d): note on  (%02x vel %02x)\n",
                          midi->channel,
                          midi->key, midi->velocity));
715

716 717 718 719 720 721 722
              midi_event (midi, midi->channel, midi->key,
                          (gdouble) midi->velocity / 127.0);
            }
          else if (midi->command == 0x8)
            {
              D (g_print ("MIDI (ch %02d): note off (%02x vel %02x)\n",
                          midi->channel, midi->key, midi->velocity));
723

724 725 726 727 728 729 730 731
              midi_event (midi, midi->channel, midi->key + 128,
                          (gdouble) midi->velocity / 127.0);
            }
          else
            {
              D (g_print ("MIDI (ch %02d): polyphonic aftertouch (%02x pressure %02x)\n",
                          midi->channel, midi->key, midi->velocity));
            }
732

733 734 735
          midi->key      = -1;
          midi->velocity = -1;
          break;
736

737
        case 0xb:  /* controllers, sustain */
738

739 740 741 742 743
          if (midi->key == -1)
            {
              midi->key = buf[pos++];
              continue;
            }
744

745 746
          if (midi->velocity == -1)
            midi->velocity = buf[pos++];
747

748 749
          D (g_print ("MIDI (ch %02d): controller %d (value %d)\n",
                      midi->channel, midi->key, midi->velocity));
750

751 752
          midi_event (midi, midi->channel, midi->key + 128 + 128,
                      (gdouble) midi->velocity / 127.0);
753

754 755 756
          midi->key      = -1;
          midi->velocity = -1;
          break;
757

758 759
        case 0xc:  /* program change */
          midi->key = buf[pos++];
760

761 762
          D (g_print ("MIDI (ch %02d): program change (%d)\n",
                      midi->channel, midi->key));
763

764 765
          midi->key = -1;
          break;
766

767 768
        case 0xd:  /* channel key pressure */
          midi->velocity = buf[pos++];
769

770 771
          D (g_print ("MIDI (ch %02d): channel aftertouch (%d)\n",
                      midi->channel, midi->velocity));
772

773 774
          midi->velocity = -1;
          break;
775

776 777 778 779 780 781
        case 0xe:  /* pitch bend */
          if (midi->lsb == -1)
            {
              midi->lsb = buf[pos++];
              continue;
            }
782

783 784
          if (midi->msb == -1)
            midi->msb = buf[pos++];
785

786
          midi->velocity = midi->lsb | (midi->msb << 7);
787

788 789
          D (g_print ("MIDI (ch %02d): pitch (%d)\n",
                      midi->channel, midi->velocity));
790

791 792 793 794
          midi->msb      = -1;
          midi->lsb      = -1;
          midi->velocity = -1;
          break;
795 796 797 798 799
        }
    }

  return TRUE;
}
800

801
#ifdef HAVE_ALSA
802 803 804 805 806 807 808 809 810 811 812 813 814 815 816 817 818 819 820 821 822 823 824 825 826 827
static gboolean
midi_alsa_prepare (GSource *source,
                   gint    *timeout)
{
  ControllerMidi *midi = CONTROLLER_MIDI (((GAlsaSource *) source)->controller);
  gboolean        ready;

  ready = snd_seq_event_input_pending (midi->sequencer, 1) > 0;
  *timeout = ready ? 1 : 10;

  return ready;
}

static gboolean
midi_alsa_check (GSource *source)
{
  ControllerMidi *midi = CONTROLLER_MIDI (((GAlsaSource *) source)->controller);

  return snd_seq_event_input_pending (midi->sequencer, 1) > 0;
}

static gboolean
midi_alsa_dispatch (GSource     *source,
                    GSourceFunc  callback,
                    gpointer     user_data)
{
828 829
  ControllerMidi *midi = CONTROLLER_MIDI (((GAlsaSource *) source)->controller);

830 831 832
  snd_seq_event_t       *event;
  snd_seq_client_info_t *client_info;
  snd_seq_port_info_t   *port_info;
833 834 835 836

  if (snd_seq_event_input_pending (midi->sequencer, 1) > 0)
    {
      snd_seq_event_input (midi->sequencer, &event);
837

838 839 840 841 842 843 844
      if (event->type == SND_SEQ_EVENT_NOTEON &&
          event->data.note.velocity == 0)
        event->type = SND_SEQ_EVENT_NOTEOFF;

      switch (event->type)
        {
        case SND_SEQ_EVENT_NOTEON:
845 846
          midi_event (midi, event->data.note.channel,
                      event->data.note.note,
847 848 849 850
                      (gdouble) event->data.note.velocity / 127.0);
          break;

        case SND_SEQ_EVENT_NOTEOFF:
851 852
          midi_event (midi, event->data.note.channel,
                      event->data.note.note + 128,
853 854 855 856
                      (gdouble) event->data.note.velocity / 127.0);
          break;

        case SND_SEQ_EVENT_CONTROLLER:
857 858
          midi_event (midi, event->data.control.channel,
                      event->data.control.param + 256,
859 860 861
                      (gdouble) event->data.control.value / 127.0);
          break;

862 863 864 865 866 867 868 869 870 871 872 873 874 875 876 877 878 879 880 881 882 883
        case SND_SEQ_EVENT_PORT_SUBSCRIBED:
          snd_seq_client_info_alloca (&client_info);
          snd_seq_port_info_alloca (&port_info);
          snd_seq_get_any_client_info (midi->sequencer,
                                       event->data.connect.sender.client,
                                       client_info);
          snd_seq_get_any_port_info (midi->sequencer,
                                     event->data.connect.sender.client,
                                     event->data.connect.sender.port,
                                     port_info);
          /*
           * g_printerr ("subscribed to \"%s:%s\"\n",
           *             snd_seq_client_info_get_name (client_info),
           *             snd_seq_port_info_get_name (port_info));
           */
          break;

        case SND_SEQ_EVENT_PORT_UNSUBSCRIBED:
          /* g_printerr ("unsubscribed\n");
           */
          break;

884 885 886 887 888 889 890 891 892
        default:
          break;
        }

      return TRUE;
    }

  return FALSE;
}
893
#endif /* HAVE_ALSA */