From e2de64d6f1beb9e492daf5b886e19933c1fa41dd Mon Sep 17 00:00:00 2001 From: toma Date: Wed, 25 Nov 2009 17:56:58 +0000 Subject: Copy the KDE 3.5 branch to branches/trinity for new KDE 3.5 features. BUG:215923 git-svn-id: svn://anonsvn.kde.org/home/kde/branches/trinity/kdemultimedia@1054174 283d02a7-25f6-0310-bc7c-ecb5cbfe19da --- arts/midi/midimsg.c | 177 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 177 insertions(+) create mode 100644 arts/midi/midimsg.c (limited to 'arts/midi/midimsg.c') diff --git a/arts/midi/midimsg.c b/arts/midi/midimsg.c new file mode 100644 index 00000000..7032fba8 --- /dev/null +++ b/arts/midi/midimsg.c @@ -0,0 +1,177 @@ + +#include +#include + +#include +#include +#include +#include +#include + +#include "midimsg.h" + +#define STATUS_MASK 0x80 +#define MESSAGE_TYPE_MASK 0xf0 +#define CHANNEL_MASK 0x0f + +Byte midiReadByte(int fd) +{ + Byte current_byte; + /* + ** for now ignore all realtime-messages (0xF8 .. 0xFF), which may get + ** embedded *inside* every other message + */ + do { + /* + ** read() is wrapped in a while() in order to handle interruption + ** by a signal. In the normal case, read() is only called once. + */ + while (read(/* fd = */ fd, /* buf = */ (void *)(¤t_byte), + /* count = */ 1) < 1) {} + + } while(current_byte >= 0xf8); + + return current_byte; +} + +int midimsgGetMessageType(Byte *message) +{ + return (message[0] & MESSAGE_TYPE_MASK); +} + +void midimsgSetMessageType(Byte *message_inout, int message_type) +{ + message_inout[0] = (message_inout[0] & ~MESSAGE_TYPE_MASK) | message_type; +} + +int midimsgGetChannel(Byte *message) +{ + return (message[0] & CHANNEL_MASK); +} + +void midimsgSetChannel(Byte *message_inout, int channel) +{ + message_inout[0] = (message_inout[0] & ~CHANNEL_MASK) | channel; +} + +int midimsgGetPitch(Byte *message) +{ + return (message[1]); +} + +void midimsgSetPitch(Byte *message_inout, int pitch) +{ + message_inout[1] = pitch; +} + +int midimsgGetVelocity(Byte *message) +{ + return (message[2]); +} + +void midimsgSetVelocity(Byte *message_inout, int velocity) +{ + message_inout[2] = velocity; +} + +int midimsgGetParameterNumber(Byte *message) +{ + return (message[1]); +} + +void midimsgSetParameterNumber(Byte *message_inout, int number) +{ + message_inout[1] = number; +} + +int midimsgGetParameterValue(Byte *message) +{ + return (message[2]); +} + +void midimsgSetParameterValue(Byte *message_inout, int value) +{ + message_inout[2] = value; +} + +int midimsgGetPitchWheelValue(Byte *message) +{ + return (((int)(message[2]) << 7) + message[1]); +} + +void midimsgRead(int fd, Byte *message_return) +{ + Byte current_byte; + static Byte last_status_byte; + + current_byte = midiReadByte(fd); + + if ((current_byte & STATUS_MASK) == 0) + { + /* + ** must be a running status, unless we're picking up mid-message + ** (which would be an unhandled error) + */ + + message_return[0] = last_status_byte; + } + else + { + message_return[0] = current_byte; + last_status_byte = current_byte; + + current_byte = midiReadByte(fd); + } + + switch (midimsgGetMessageType(/* message = */ message_return)) + { + case MIDIMSG_NOTE_ON: + case MIDIMSG_NOTE_OFF: + case MIDIMSG_KEY_PRESSURE: + case MIDIMSG_PARAMETER: + case MIDIMSG_PITCH_WHEEL: + + message_return[1] = current_byte; + + current_byte = midiReadByte(fd); + message_return[2] = current_byte; + + if ((midimsgGetMessageType(/* message = */ message_return) == + MIDIMSG_NOTE_ON) && (midimsgGetVelocity(/* message = */ + message_return) == 0)) + { + /* note-on with velocity of zero is equivalent to note-off */ + + midimsgSetMessageType(/* message_inout = */ message_return, + /* message_type = */ MIDIMSG_NOTE_OFF); + } + + return; + + case MIDIMSG_PROGRAM: + case MIDIMSG_CHANNEL_PRESSURE: + + message_return[1] = current_byte; + + return; + } +} + +void midimsgWrite(int fd, Byte *message) +{ + switch (midimsgGetMessageType(/* message = */ message)) + { + case MIDIMSG_NOTE_ON: + case MIDIMSG_NOTE_OFF: + case MIDIMSG_KEY_PRESSURE: + case MIDIMSG_PARAMETER: + case MIDIMSG_PITCH_WHEEL: + write(fd, message, 3); + break; + case MIDIMSG_PROGRAM: + case MIDIMSG_CHANNEL_PRESSURE: + write(fd, message, 2); + break; + } +} + -- cgit v1.2.3