.syx files in midish

From: Alexandre Ratchov <alex_at_caoua.org>
Date: Thu May 09 2013 - 13:28:48 CEST
Hey,

Here's a initial diff to handle .syx files. Julien, does this work
with your synths? Example:

xnew foo
xadd 0 {0xf0 0x78 0x78 0xf7}
xexport "foo.syx"

or

xnew foo
ximport 0 "foo.syx"

I have only few .syx files, so this needs testing with files
originating from other software/hardware.

thanks

-- Alexandre

Index: builtin.c
===================================================================
RCS file: /var/anoncvs/midish/midish/builtin.c,v
retrieving revision 1.90
diff -u -p -r1.90 builtin.c
--- builtin.c	17 Dec 2012 13:37:31 -0000	1.90
+++ builtin.c	9 May 2013 11:20:29 -0000
@@ -2829,6 +2829,70 @@ blt_xadd(struct exec *o, struct data **r
 }
 
 unsigned
+blt_ximport(struct exec *o, struct data **r)
+{
+	struct songsx *c;
+	struct sysex *x;
+	struct var *arg;
+	char *path;
+	long unit;
+
+	song_getcursx(usong, &c);
+	if (c == NULL) {
+		cons_errs(o->procname, "no current sysex");
+		return 0;
+	}
+	if (!exec_lookuplong(o, "devnum", &unit)) {
+		return 0;
+	}
+	if (unit < 0 || unit >= DEFAULT_MAXNDEVS) {
+		cons_errs(o->procname, "devnum out of range");
+		return 0;
+	}
+	arg = exec_varlookup(o, "path");
+	if (!arg) {
+		dbg_puts("blt_ximport: path: no such param\n");
+		return 0;
+	}
+	if (arg->data->type != DATA_STRING) {
+		cons_errs(o->procname, "path must be string");
+		return 0;
+	}
+	path = arg->data->val.str;
+	if (!syx_import(path, &c->sx, unit))
+		return 0;
+	return 1;
+}
+
+unsigned
+blt_xexport(struct exec *o, struct data **r)
+{
+	struct songsx *c;
+	struct sysex *x;
+	struct var *arg;
+	char *path;
+
+	song_getcursx(usong, &c);
+	if (c == NULL) {
+		cons_errs(o->procname, "no current sysex");
+		return 0;
+	}
+	arg = exec_varlookup(o, "path");
+	if (!arg) {
+		dbg_puts("blt_xexport: path: no such param\n");
+		return 0;
+	}
+	if (arg->data->type != DATA_STRING) {
+		cons_errs(o->procname, "path must be string");
+		return 0;
+	}
+	path = arg->data->val.str;
+	if (!syx_export(path, &c->sx))
+		return 0;
+	return 1;
+}
+
+unsigned
 blt_dlist(struct exec *o, struct data **r)
 {
 	struct data *d, *n;
Index: builtin.h
===================================================================
RCS file: /var/anoncvs/midish/midish/builtin.h,v
retrieving revision 1.33
diff -u -p -r1.33 builtin.h
--- builtin.h	17 Dec 2012 11:47:30 -0000	1.33
+++ builtin.h	9 May 2013 11:20:29 -0000
@@ -147,6 +147,8 @@ unsigned blt_xinfo(struct exec *, struct
 unsigned blt_xrm(struct exec *, struct data **);
 unsigned blt_xsetd(struct exec *, struct data **);
 unsigned blt_xadd(struct exec *, struct data **);
+unsigned blt_ximport(struct exec *, struct data **);
+unsigned blt_xexport(struct exec *, struct data **);
 
 unsigned blt_dlist(struct exec *, struct data **);
 unsigned blt_dnew(struct exec *, struct data **);
Index: manual.html
===================================================================
RCS file: /var/anoncvs/midish/midish/manual.html,v
retrieving revision 1.196
diff -u -p -r1.196 manual.html
--- manual.html	4 Mar 2013 07:51:26 -0000	1.196
+++ manual.html	9 May 2013 11:20:29 -0000
@@ -2581,6 +2581,10 @@ add diev
 and doev functions to control whether
 midish interprets bank select, NRPN/RPN and data entry controllers.
 
+<li>
+add ximport
+and xexport to export and import .syx files.
+
 </ul>
 
 <h2><a name="attributes">16 Project attributes</a></h2>
@@ -3775,6 +3779,19 @@ the message will be sent when performanc
 print all sysex messages of the current sysex bank. Messages that are
 too long to be desplayed on a single line are truncated and 
 the ``...'' string is displayed.
+
+<dt><a name="func_ximport">ximport devnum path</a>
+
+<dd>
+replace contents of the current sysex bank by
+contents of the given .syx file; messages are assigned
+to ``devnum'' device number.
+
+<dt><a name="func_xexport">xexport path</a>
+
+<dd>
+store contents of the current sysex bank in the
+given .syx file
 
 </dl>
 
Index: rmidish.c
===================================================================
RCS file: /var/anoncvs/midish/midish/rmidish.c,v
retrieving revision 1.41
diff -u -p -r1.41 rmidish.c
--- rmidish.c	17 Dec 2012 11:47:30 -0000	1.41
+++ rmidish.c	9 May 2013 11:20:29 -0000
@@ -292,12 +292,11 @@ char *builtins[] = {
 	"flist", "fnew", "fdel", "fren", "fexists", "finfo", "freset",
 	"fmap", "funmap", "ftransp", "fvcurve", "fchgin", "fchgout",
 	"fswapin", "fswapout", "xlist", "xexists", "xnew", "xdel", "xren",
-	"xinfo", "xrm", "xsetd", "xadd", "dlist", "dnew", "ddel", "dmtcrx",
-	"dmmctx", "dclkrx", "dclktx", "dclkrate", "dinfo", "dixctl", "doxctl",
-	"diev", "doev",
+	"xinfo", "xrm", "xsetd", "xadd", "ximport", "xexport", "dlist",
+	"dnew", "ddel", "dmtcrx", "dmmctx", "dclkrx", "dclktx", "dclkrate",
+	"dinfo", "dixctl", "doxctl", "diev", "doev",
 	NULL
 };
-
 
 char *
 genbuiltin(const char *text, int state)
Index: smf.c
===================================================================
RCS file: /var/anoncvs/midish/midish/smf.c,v
retrieving revision 1.49
diff -u -p -r1.49 smf.c
--- smf.c	17 Dec 2012 11:47:30 -0000	1.49
+++ smf.c	9 May 2013 11:20:29 -0000
@@ -933,3 +933,75 @@ bad3:	song_delete(o);
 bad2:	smf_close(&f);
 bad1:	return 0;
 }
+
+int
+syx_import(char *path, struct sysexlist *l, int unit)
+{
+	FILE *f;
+	struct sysex *sx = NULL;
+	int c;
+
+	f = fopen(path, "r");
+	if (f == NULL) {
+		cons_errs(path, "failed to open file");
+		return 0;
+	}
+	sysexlist_clear(l);
+	for (;;) {
+		c = fgetc(f);
+		if (c == EOF)
+			break;
+		if (c == 0xf0)
+			sx = sysex_new(unit);
+		if (sx == NULL) {
+			cons_errs(path, "corrupted .syx file");
+			goto err;
+		}
+		sysex_add(sx, c);
+		if (c == 0xf7) {
+			if (sysex_check(sx)) {
+				sysexlist_put(l, sx);
+				sx = NULL;
+				continue;
+			} else {
+				cons_err("corrupted sysex message, ignored");
+				sysex_del(sx);
+				goto err;
+			}
+		}
+	}
+	fclose(f);
+	return 1;
+err:
+	sysexlist_clear(l);
+	fclose(f);
+	return 0;
+}
+
+int
+syx_export(char *path, struct sysexlist *l)
+{
+	FILE *f;
+	struct sysex *x;
+	struct chunk *c;
+	ssize_t n;
+
+	f = fopen(path, "w");
+	if (f == NULL) {
+		cons_errs(path, "failed to open file");
+		return 0;
+	}
+	for (x = l->first; x != NULL; x = x->next) {
+		for (c = x->first; c != NULL; c = c->next) {
+			n = fwrite(c->data, 1, c->used, f);
+			if (n != c->used) {
+				cons_errs(path, "write failed");
+				fclose(f);
+				return 0;
+			}
+				
+		}
+	}
+	fclose(f);
+	return 1;
+}
Index: smf.h
===================================================================
RCS file: /var/anoncvs/midish/midish/smf.h,v
retrieving revision 1.16
diff -u -p -r1.16 smf.h
--- smf.h	30 Jun 2011 12:30:33 -0000	1.16
+++ smf.h	9 May 2013 11:20:29 -0000
@@ -19,7 +19,10 @@
 
 struct song;
 
-unsigned song_exportsmf(struct song *o, char *);
+unsigned song_exportsmf(struct song *, char *);
 struct song *song_importsmf(char *);
+
+int syx_import(char *, struct sysexlist *, int);
+int syx_export(char *, struct sysexlist *);
 
 #endif /* MIDISH_SMF_H */
Index: sysex.c
===================================================================
RCS file: /var/anoncvs/midish/midish/sysex.c,v
retrieving revision 1.19
diff -u -p -r1.19 sysex.c
--- sysex.c	30 Jun 2011 12:30:33 -0000	1.19
+++ sysex.c	9 May 2013 11:20:29 -0000
@@ -203,6 +203,17 @@ sysexlist_init(struct sysexlist *o)
 void
 sysexlist_done(struct sysexlist *o)
 {
+	sysexlist_clear(o);
+	o->first = (void *)0xdeadbeef;
+	o->lastptr = (void *)0xdeadbeef;
+}
+
+/*
+ * clear the sysex list
+ */
+void
+sysexlist_clear(struct sysexlist *o)
+{
 	struct sysex *i, *inext;
 
 	for (i = o->first; i != NULL; i = inext) {
@@ -225,12 +236,13 @@ sysexlist_put(struct sysexlist *o, struc
 }
 
 /*
- * detach the first sysex message on the list
+ * detach the first sysex message from the list
  */
 struct sysex *
 sysexlist_get(struct sysexlist *o)
 {
 	struct sysex *e;
+
 	if (o->first) {
 		e = o->first;
 		o->first = e->next;
Index: sysex.h
===================================================================
RCS file: /var/anoncvs/midish/midish/sysex.h,v
retrieving revision 1.17
diff -u -p -r1.17 sysex.h
--- sysex.h	30 Jun 2011 12:30:33 -0000	1.17
+++ sysex.h	9 May 2013 11:20:29 -0000
@@ -49,6 +49,7 @@ unsigned      sysex_check(struct sysex *
 
 void 	      sysexlist_init(struct sysexlist *);
 void	      sysexlist_done(struct sysexlist *);
+void	      sysexlist_clear(struct sysexlist *);
 void	      sysexlist_put(struct sysexlist *, struct sysex *);
 struct sysex *sysexlist_get(struct sysexlist *);
 void	      sysexlist_dbg(struct sysexlist *);
Index: user.c
===================================================================
RCS file: /var/anoncvs/midish/midish/user.c,v
retrieving revision 1.152
diff -u -p -r1.152 user.c
--- user.c	17 Dec 2012 11:47:30 -0000	1.152
+++ user.c	9 May 2013 11:20:29 -0000
@@ -1111,6 +1111,11 @@ user_mainloop(void)
 	exec_newbuiltin(exec, "xadd", blt_xadd,
 			name_newarg("devnum",
 			name_newarg("data", NULL)));
+	exec_newbuiltin(exec, "ximport", blt_ximport,
+		        name_newarg("devnum",
+			name_newarg("path", NULL)));
+	exec_newbuiltin(exec, "xexport", blt_xexport,
+			name_newarg("path", NULL));
 
 	exec_newbuiltin(exec, "shut", user_func_shut, NULL);
 	exec_newbuiltin(exec, "proclist", user_func_proclist, NULL);
Received on Thu, 9 May 2013 13:28:48 +0200

This archive was generated by hypermail 2.1.8 : Wed Nov 08 2017 - 16:32:25 CET