Browse Source

Add the midi module

The `midi' module is intended to serve as a thin abstraction layer
for writing and reading to a MIDI interface. It currently only
supports ALSA, but should be extended to transparently support any
other MIDI API (at least OSS and Jack, and maybe PortMIDI, WinAPI,
...).
master
Damien Goutte-Gattat 9 years ago
parent
commit
4386b5ed07
  1. 6
      configure.ac
  2. 2
      src/Makefile.am
  3. 154
      src/midi.c
  4. 55
      src/midi.h

6
configure.ac

@ -18,6 +18,12 @@ AC_PROG_INSTALL
dnl Check for some non-ubiquitous functions
ICP_CHECK_NOTCH_FUNCS
dnl Check for ALSA
dnl TODO: Search for other MIDI APIs
AM_PATH_ALSA([1.0.0],
[AC_DEFINE([USE_ALSA_MIDI_API], [1],
[Define whether to use the ALSA MIDI API.])])
dnl Output files
AC_CONFIG_FILES([Makefile lib/Makefile src/Makefile])
AC_OUTPUT

2
src/Makefile.am

@ -1,6 +1,6 @@
bin_PROGRAMS = asysex
asysex_SOURCES = asysex.c
asysex_SOURCES = asysex.c midi.h midi.c
AM_CPPFLAGS = -I$(top_srcdir)/lib
AM_LDFLAGS = -L$(top_builddir)/lib

154
src/midi.c

@ -0,0 +1,154 @@
/*
* asysex - A SysEx Utility
* Copyright (C) 2012 Damien Goutte-Gattat
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
#include <midi.h>
#include <stdlib.h>
#include <assert.h>
#include <xmem.h>
#ifdef USE_ALSA_MIDI_API
/* Linux ALSA API */
#include <alsa/asoundlib.h>
#define MIDI_IO_BUFFER_SIZE 256
struct midi_io
{
snd_rawmidi_t *in;
snd_rawmidi_t *out;
int error;
unsigned char buffer[MIDI_IO_BUFFER_SIZE];
size_t pos;
size_t len;
unsigned char status;
};
midi_io_t *
midi_open(const char *name)
{
midi_io_t *midi;
assert(name != NULL);
midi = xmalloc(sizeof(*midi));
midi->in = midi->out = NULL;
midi->error = midi->pos = midi->len = midi->status = 0;
if ( snd_rawmidi_open(&(midi->in), &(midi->out), name,
SND_RAWMIDI_NONBLOCK) < 0 ) {
free(midi);
midi = NULL;
}
else if ( snd_rawmidi_nonblock(midi->out, 0) < 0 ) {
midi_close(midi);
midi = NULL;
}
return midi;
}
int
midi_close(midi_io_t *midi)
{
assert(midi != NULL);
snd_rawmidi_close(midi->in);
snd_rawmidi_close(midi->out);
free(midi);
return 0;
}
ssize_t
midi_write(midi_io_t *midi, unsigned char *buffer, size_t len)
{
assert(midi != NULL);
assert(buffer != NULL);
/* Flush reading buffer. */
midi->pos = midi->len = 0;
midi->error = snd_rawmidi_write(midi->out, buffer, len);
return midi->error;
}
ssize_t
midi_read(midi_io_t *midi, unsigned char *buffer, size_t len)
{
assert(midi != NULL);
assert(buffer != NULL);
midi->error = snd_rawmidi_read(midi->in, buffer, len);
return midi->error;
}
int
midi_next(midi_io_t *midi)
{
unsigned char b;
assert(midi != NULL);
if ( midi->pos >= midi->len ) {
ssize_t n;
n = midi_read(midi, midi->buffer, MIDI_IO_BUFFER_SIZE);
if ( n < 0 )
return n;
midi->len = n;
midi->pos = 0;
}
b = (unsigned char) midi->buffer[midi->pos++];
if ( b >= 0x80 && b < 0xF8 ) /* Status byte? */
midi->status = b;
return b;
}
inline unsigned char
midi_status(midi_io_t *midi)
{
return midi->status;
}
const char *
midi_error(midi_io_t *midi)
{
assert(midi != NULL);
if ( midi->error > 0 )
return NULL;
else
return snd_strerror(midi->error);
}
#else
#error "No MIDI API available"
/* TODO: Support for others MIDI APIs (OSS, JackMIDI?, WinAPI?, ...) */
#endif

55
src/midi.h

@ -0,0 +1,55 @@
/*
* asysex - A SysEx Utility
* Copyright (C) 2012 Damien Goutte-Gattat
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef ICP20120401_MIDI_H
#define ICP20120401_MIDI_H
#include <stdlib.h>
typedef struct midi_io midi_io_t;
#ifdef __cpluscplus
extern "C" {
#endif
midi_io_t *
midi_open(const char *);
int
midi_close(midi_io_t *);
ssize_t
midi_write(midi_io_t *, unsigned char *, size_t);
ssize_t
midi_read(midi_io_t *, unsigned char *, size_t);
int
midi_next(midi_io_t *);
unsigned char
midi_status(midi_io_t *);
const char *
midi_error(midi_io_t *);
#ifdef __cplusplus
}
#endif
#endif /* !ICP20120401_MIDI_H */
Loading…
Cancel
Save