Start migrating from libglade to gtkbuilder.
[gmidimonitor.git] / sysex.c
blob3eaa1c10f8fbe329faddbed09e3112c2f4b67179
1 /* -*- Mode: C ; c-basic-offset: 2 -*- */
2 /*****************************************************************************
4 * This file is part of gmidimonitor
6 * Copyright (C) 2005,2006,2007,2008,2011 Nedko Arnaudov <nedko@arnaudov.name>
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; version 2 of the License
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 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
21 *****************************************************************************/
23 #include <gtk/gtk.h>
25 #include "sysex.h"
27 /* General MMC decoding, as seen at http://www.borg.com/~jglatt/tech/mmc.htm and
28 extended from "Advanced User Guide for MK-449C MIDI keyboard" info */
29 void
30 decode_sysex(
31 guint8 * buffer,
32 size_t buffer_size,
33 GString * msg_str_ptr)
35 const char * mmc_command_name;
36 size_t i;
38 if (buffer_size == 6 &&
39 buffer[0] == 0xF0 &&
40 buffer[1] == 0x7F &&
41 buffer[3] == 0x06 &&
42 buffer[5] == 0xF7)
44 switch (buffer[4])
46 case 1:
47 mmc_command_name = "Stop";
48 break;
49 case 2:
50 mmc_command_name = "Play";
51 break;
52 case 3:
53 mmc_command_name = "Deferred Play";
54 break;
55 case 4:
56 mmc_command_name = "Fast Forward";
57 break;
58 case 5:
59 mmc_command_name = "Rewind";
60 break;
61 case 6:
62 mmc_command_name = "Record Strobe (Punch In)";
63 break;
64 case 7:
65 mmc_command_name = "Record Exit (Punch Out)";
66 break;
67 case 8:
68 mmc_command_name = "Record Pause";
69 break;
70 case 9:
71 mmc_command_name = "Pause";
72 break;
73 case 10:
74 mmc_command_name = "Eject";
75 break;
76 case 11:
77 mmc_command_name = "Chase";
78 break;
79 case 12:
80 mmc_command_name = "Command Error Reset";
81 break;
82 case 13:
83 mmc_command_name = "Reset";
84 break;
85 default:
86 goto generic_sysex;
88 g_string_sprintf(
89 msg_str_ptr,
90 "MMC %s, for ",
91 mmc_command_name);
93 if (buffer[2] == 127)
95 g_string_append(
96 msg_str_ptr,
97 "all devices");
99 else
101 g_string_append_printf(
102 msg_str_ptr,
103 "device %u",
104 (unsigned int)(buffer[2]));
107 /* The goto MMC message, as seen at http://www.borg.com/~jglatt/tech/mmc.htm */
108 else if (buffer_size == 13 &&
109 buffer[0] == 0xF0 &&
110 buffer[1] == 0x7F &&
111 buffer[3] == 0x06 &&
112 buffer[4] == 0x44 &&
113 buffer[5] == 0x06 &&
114 buffer[6] == 0x01 &&
115 buffer[12] == 0xF7)
117 g_string_sprintf(
118 msg_str_ptr,
119 "MMC goto %u:%u:%u/%u:%u",
120 (unsigned int)(buffer[7] & 0x1F), /* fps encoding */
121 (unsigned int)(buffer[8]),
122 (unsigned int)(buffer[9]),
123 (unsigned int)(buffer[10] & 0x1F), /* no fps > 32, but bit 5 looks used for something */
124 (unsigned int)(buffer[11]));
126 switch (buffer[7] & 0x60)
128 case 0:
129 g_string_append(
130 msg_str_ptr,
131 ", 24 fps");
132 break;
133 case 1:
134 g_string_append(
135 msg_str_ptr,
136 ", 25 fps");
137 break;
138 case 2:
139 g_string_append(
140 msg_str_ptr,
141 ", 29.97 fps");
142 break;
143 case 3:
144 g_string_append(
145 msg_str_ptr,
146 ", 30 fps");
147 break;
150 if (buffer[2] == 127)
152 g_string_append(
153 msg_str_ptr,
154 ", for all devices");
156 else
158 g_string_append_printf(
159 msg_str_ptr,
160 ", for device %u",
161 (unsigned int)(buffer[2]));
164 else
166 generic_sysex:
167 g_string_sprintf(
168 msg_str_ptr,
169 "SYSEX with size %u:",
170 (unsigned int)buffer_size);
171 for (i = 0 ; i < buffer_size ; i++)
173 g_string_append_printf(
174 msg_str_ptr,
175 " %02X",
176 (unsigned int)(buffer[i]));