Compare commits
82 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
0bb0f6db71 | ||
|
|
dcf66adfa9 | ||
|
|
0886ba00c1 | ||
|
|
e12de97fab | ||
|
|
59753a61dc | ||
|
|
ff0be8230e | ||
|
|
07cfd70941 | ||
|
|
2523b27205 | ||
|
|
530dd397c5 | ||
|
|
158fd081a5 | ||
|
|
a8bac07f68 | ||
|
|
87bb59f43a | ||
|
|
cdeb821deb | ||
|
|
ce463b29d8 | ||
|
|
159bca158e | ||
|
|
6ae750c4fb | ||
|
|
5f21c62a2f | ||
|
|
08b20b398f | ||
|
|
1be664e82f | ||
|
|
3ab55054c1 | ||
|
|
97b8c9fd6d | ||
|
|
211df27cf8 | ||
|
|
dfe28ac81d | ||
|
|
3da458d370 | ||
|
|
ba04930133 | ||
|
|
18f137636d | ||
|
|
eba8bbe5aa | ||
|
|
7a6e3b159c | ||
|
|
cc85da9c71 | ||
|
|
9586f6cd31 | ||
|
|
4a7ab848e7 | ||
|
|
2703e79d39 | ||
|
|
dbab804d52 | ||
|
|
c3f82416f5 | ||
|
|
145b41cb6c | ||
|
|
26d1db9e4f | ||
|
|
cc311f4f18 | ||
|
|
d85e83c89e | ||
|
|
55b9b08230 | ||
|
|
400e221a4f | ||
|
|
5b93c91bfe | ||
|
|
cbd07a9709 | ||
|
|
def4917a07 | ||
|
|
e9c0ed8b38 | ||
|
|
400a7d41f8 | ||
|
|
40a9d06e4c | ||
|
|
e820ce0cc4 | ||
|
|
ebc603143e | ||
|
|
c74290d8e1 | ||
|
|
295e932bf1 | ||
|
|
1a65deb8d5 | ||
|
|
4509c14bbc | ||
|
|
d7f10eb509 | ||
|
|
b1a8d69dba | ||
|
|
20769ace01 | ||
|
|
2633bac5d8 | ||
|
|
af1d3a2906 | ||
|
|
06fd3eee66 | ||
|
|
acb1c1e273 | ||
|
|
7bf55352b8 | ||
|
|
6a1d1de390 | ||
|
|
b798d6ee39 | ||
|
|
ba810bf4f8 | ||
|
|
24a1c2718b | ||
|
|
31a635839a | ||
|
|
d7b3f7a3d6 | ||
|
|
6512696240 | ||
|
|
f1359d18e4 | ||
|
|
85ce157bb8 | ||
|
|
6daaf47cd8 | ||
|
|
3a849de954 | ||
|
|
a06c5dc07e | ||
|
|
29124043ba | ||
|
|
e93e6bd16b | ||
|
|
f7ddd5e0d6 | ||
|
|
6a082acc53 | ||
|
|
1abcc82829 | ||
|
|
c964d38c17 | ||
|
|
12c2ccc87f | ||
|
|
a6d07fd802 | ||
|
|
215683b167 | ||
|
|
741482afd4 |
@@ -6,3 +6,7 @@ syntax: glob
|
|||||||
*.o
|
*.o
|
||||||
*.patch
|
*.patch
|
||||||
*.diff
|
*.diff
|
||||||
|
*.m
|
||||||
|
*.orig
|
||||||
|
knob.h
|
||||||
|
gdigi
|
||||||
|
|||||||
12
HACKING
12
HACKING
@@ -3,7 +3,7 @@ In general everything brings down to figure out:
|
|||||||
-Position
|
-Position
|
||||||
-Possible value range
|
-Possible value range
|
||||||
|
|
||||||
There seems to be two possible ways to figure that out.
|
There seems to be three possible ways to figure that out.
|
||||||
1) Use USB sniffer together with X-Edit
|
1) Use USB sniffer together with X-Edit
|
||||||
Once you set up X-Edit and usb sniffer, set some option.
|
Once you set up X-Edit and usb sniffer, set some option.
|
||||||
USB sniffer should report something like this being sent to device:
|
USB sniffer should report something like this being sent to device:
|
||||||
@@ -66,3 +66,13 @@ There seems to be two possible ways to figure that out.
|
|||||||
save new patch
|
save new patch
|
||||||
check patch file and note the change
|
check patch file and note the change
|
||||||
while you don't have all possible values
|
while you don't have all possible values
|
||||||
|
3) Use gdigi
|
||||||
|
After starting gdigi turn the knobs on your device.
|
||||||
|
Check out console output, you should notice something like this:
|
||||||
|
** Message: Received parameter change ID: 210 Position: 4 Value: 0
|
||||||
|
ID is ID, Position is Position and Value is one of possible values.
|
||||||
|
To get all possible values keep turning knobs and watch the output.
|
||||||
|
If you change effect type usually there's more messages - where,
|
||||||
|
usually the first one is type change, and rest are default values.
|
||||||
|
This way you *CANNOT* gather all information (there're X-Edit only
|
||||||
|
controlled values, check device manual for more information).
|
||||||
|
|||||||
58
Makefile
58
Makefile
@@ -1,35 +1,47 @@
|
|||||||
CC = gcc
|
CC = gcc
|
||||||
CFLAGS = `pkg-config --cflags glib-2.0 gio-2.0 gtk+-2.0` -Wall -g -ansi -std=c99
|
EXTRA_CFLAGS ?=
|
||||||
OFLAG = -o
|
EXTRA_LDFLAGS ?=
|
||||||
LIBS = `pkg-config --libs glib-2.0 gio-2.0 gtk+-2.0 alsa` -lexpat
|
CFLAGS := $(shell pkg-config --cflags glib-2.0 gio-2.0 gtk+-2.0) -Wall -g -ansi -std=c99 $(EXTRA_CFLAGS)
|
||||||
|
LDFLAGS = $(EXTRA_LDFLAGS) -Wl,--as-needed
|
||||||
|
LDADD := $(shell pkg-config --libs glib-2.0 gio-2.0 gtk+-2.0 gthread-2.0 alsa) -lexpat
|
||||||
|
OBJECTS = gdigi.o gui.o effects.o preset.o gtkknob.o
|
||||||
|
DEPFILES = $(foreach m,$(OBJECTS:.o=),.$(m).m)
|
||||||
|
|
||||||
.SUFFIXES : .o .c
|
.PHONY : clean distclean all
|
||||||
.c.o :
|
%.o : %.c
|
||||||
$(CC) $(CFLAGS) -c $<
|
$(CC) $(CFLAGS) -c $<
|
||||||
|
|
||||||
|
.%.m : %.c
|
||||||
|
$(CC) $(CFLAGS) -M -MF $@ -MG $<
|
||||||
|
|
||||||
all: gdigi
|
all: gdigi
|
||||||
|
|
||||||
gdigi: knob.h gdigi.o tests.o gui.o effects.o preset.o gtkknob.o
|
gdigi: $(OBJECTS)
|
||||||
$(CC) $(LIBS) $(OFLAG) gdigi gdigi.o tests.o gui.o effects.o preset.o gtkknob.o
|
$(CC) $(LDFLAGS) -o $@ $+ $(LDADD)
|
||||||
|
|
||||||
gdigi.o: gdigi.c
|
knob.h: knob.png
|
||||||
|
|
||||||
tests.o: tests.c
|
|
||||||
|
|
||||||
gui.o: gui.c
|
|
||||||
|
|
||||||
effects.o: effects.c
|
|
||||||
|
|
||||||
preset.o: preset.c
|
|
||||||
|
|
||||||
gtkknob.o: gtkknob.c
|
|
||||||
|
|
||||||
gtkknob.o: gtkknob.c
|
|
||||||
|
|
||||||
knob.h:
|
|
||||||
gdk-pixbuf-csource --name=knob_pixbuf knob.png > $@
|
gdk-pixbuf-csource --name=knob_pixbuf knob.png > $@
|
||||||
|
|
||||||
clean:
|
clean:
|
||||||
rm *.o
|
rm -f *.o
|
||||||
|
rm -f knob.h
|
||||||
|
|
||||||
|
distclean : clean
|
||||||
|
rm -f .*.m
|
||||||
|
rm -f gdigi
|
||||||
|
|
||||||
|
install: gdigi
|
||||||
|
install gdigi $(DESTDIR)/usr/bin
|
||||||
|
|
||||||
|
NODEP_TARGETS := clean distclean
|
||||||
|
depinc := 1
|
||||||
|
ifneq (,$(filter $(NODEP_TARGETS),$(MAKECMDGOALS)))
|
||||||
|
depinc := 0
|
||||||
|
endif
|
||||||
|
ifneq (,$(fitler-out $(NODEP_TARGETS),$(MAKECMDGOALS)))
|
||||||
|
depinc := 1
|
||||||
|
endif
|
||||||
|
|
||||||
|
ifeq ($(depinc),1)
|
||||||
|
-include $(DEPFILES)
|
||||||
|
endif
|
||||||
|
|||||||
8
TODO
8
TODO
@@ -1,6 +1,6 @@
|
|||||||
-make complete gui
|
-make complete gui (expression pedal settings, usb settings, effect level, preset level)
|
||||||
-effects level
|
|
||||||
-handling presets (saving, exporting to xml patches)
|
-handling presets (saving, exporting to xml patches)
|
||||||
-buildsystem (install knob.png to share dir, don't use inline knob pixbuf)
|
-buildsystem (install knob.png to share dir, don't use inline knob pixbuf)
|
||||||
-add expression pedal settings to gui
|
-various fixes to MIDI IN messages handling
|
||||||
-read asynchronously from MIDI IN
|
-guess device port when user doesn't explicitly provide it (don't use hardcoded "hw:1,0,0")
|
||||||
|
-optimizations
|
||||||
|
|||||||
56
effects.h
56
effects.h
@@ -17,12 +17,32 @@
|
|||||||
#ifndef GDIGI_EFFECTS_H
|
#ifndef GDIGI_EFFECTS_H
|
||||||
#define GDIGI_EFFECTS_H
|
#define GDIGI_EFFECTS_H
|
||||||
|
|
||||||
#include <glib/gtypes.h>
|
#include <glib.h>
|
||||||
|
|
||||||
typedef struct {
|
enum {
|
||||||
|
VALUE_TYPE_PLAIN = 0, /**< value displayed directly */
|
||||||
|
VALUE_TYPE_SUFFIX = 1 << 0, /**< use suffix for displaying */
|
||||||
|
VALUE_TYPE_OFFSET = 1 << 1, /**< use value offset */
|
||||||
|
VALUE_TYPE_STEP = 1 << 2, /**< use value step different than 1 */
|
||||||
|
VALUE_TYPE_LABEL = 1 << 3, /**< use value labels (overrides any other option) */
|
||||||
|
VALUE_TYPE_EXTRA = 1 << 4, /**< use extra values */
|
||||||
|
VALUE_TYPE_DECIMAL= 1 << 5, /**< display decimal places */
|
||||||
|
} ValueType;
|
||||||
|
|
||||||
|
typedef struct _EffectValues {
|
||||||
gdouble min; /**< Minumum value */
|
gdouble min; /**< Minumum value */
|
||||||
gdouble max; /**< Maximum value */
|
gdouble max; /**< Maximum value */
|
||||||
|
gint type; /**< value type bitmask (ValueType) */
|
||||||
|
|
||||||
GStrv labels; /**< value labels */
|
GStrv labels; /**< value labels */
|
||||||
|
gint offset; /**< value offset */
|
||||||
|
gdouble step; /**< value step */
|
||||||
|
gchar *suffix; /**< value suffix */
|
||||||
|
|
||||||
|
struct _EffectValues *extra;
|
||||||
|
/**< additional value range,
|
||||||
|
use it when there're different range types */
|
||||||
|
gint decimal; /**< amount of decimal places to display */
|
||||||
} EffectValues;
|
} EffectValues;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
@@ -35,8 +55,6 @@ typedef struct {
|
|||||||
typedef struct {
|
typedef struct {
|
||||||
guint type; /**< value (type) */
|
guint type; /**< value (type) */
|
||||||
gchar *label; /**< Effect name */
|
gchar *label; /**< Effect name */
|
||||||
guint id; /**< ID (to set effect type) */
|
|
||||||
guint position; /**< position */
|
|
||||||
EffectSettings *settings; /**< possible parameters */
|
EffectSettings *settings; /**< possible parameters */
|
||||||
gint settings_amt; /**< possible parameters length */
|
gint settings_amt; /**< possible parameters length */
|
||||||
} EffectGroup;
|
} EffectGroup;
|
||||||
@@ -44,6 +62,7 @@ typedef struct {
|
|||||||
typedef struct {
|
typedef struct {
|
||||||
gchar *label; /**< Group label */
|
gchar *label; /**< Group label */
|
||||||
guint id; /**< ID to set effect on/off, or if it isn't on/off group then -1 */
|
guint id; /**< ID to set effect on/off, or if it isn't on/off group then -1 */
|
||||||
|
guint type; /**< ID to set effect type */
|
||||||
guint position; /**< position */
|
guint position; /**< position */
|
||||||
EffectGroup *group; /**< possible effect types */
|
EffectGroup *group; /**< possible effect types */
|
||||||
gint group_amt; /**< possible effect types length */
|
gint group_amt; /**< possible effect types length */
|
||||||
@@ -56,11 +75,40 @@ typedef struct {
|
|||||||
} EffectList;
|
} EffectList;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
|
guint type; /**< ID to set effect type */
|
||||||
|
guint position;
|
||||||
EffectGroup *group;
|
EffectGroup *group;
|
||||||
gint group_amt;
|
gint group_amt;
|
||||||
} ModifierGroup;
|
} ModifierGroup;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
gchar *name;
|
||||||
|
EffectList *effects;
|
||||||
|
gint n_effects;
|
||||||
|
gint n_rows;
|
||||||
|
} EffectPage;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
gchar *name;
|
||||||
|
PresetBank bank;
|
||||||
|
} Banks;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
gchar *name;
|
||||||
|
unsigned char family_id;
|
||||||
|
unsigned char product_id;
|
||||||
|
EffectPage *pages;
|
||||||
|
gint n_pages;
|
||||||
|
Banks *banks;
|
||||||
|
gint n_banks;
|
||||||
|
} Device;
|
||||||
|
|
||||||
ModifierGroup *modifier_linkable_list();
|
ModifierGroup *modifier_linkable_list();
|
||||||
void modifier_group_free(ModifierGroup *modifier_group);
|
void modifier_group_free(ModifierGroup *modifier_group);
|
||||||
|
void get_values_info(EffectValues *values,
|
||||||
|
gdouble *min, gdouble *max, gboolean *custom);
|
||||||
|
gboolean get_device_info(unsigned char device_id, unsigned char family_id,
|
||||||
|
unsigned char product_id,
|
||||||
|
Device **device);
|
||||||
|
|
||||||
#endif /* GDIGI_EFFECTS_H */
|
#endif /* GDIGI_EFFECTS_H */
|
||||||
|
|||||||
74
gdigi.1
Normal file
74
gdigi.1
Normal file
@@ -0,0 +1,74 @@
|
|||||||
|
.\" Hey, EMACS: -*- nroff -*-
|
||||||
|
.\" First parameter, NAME, should be all caps
|
||||||
|
.\" Second parameter, SECTION, should be 1-8, maybe w/ subsection
|
||||||
|
.\" other parameters are allowed: see man(7), man(1)
|
||||||
|
.TH GDIGI 1 "October 07, 2010"
|
||||||
|
.\" Please adjust this date whenever revising the manpage.
|
||||||
|
.\"
|
||||||
|
.\" Some roff macros, for reference:
|
||||||
|
.\" .nh disable hyphenation
|
||||||
|
.\" .hy enable hyphenation
|
||||||
|
.\" .ad l left justify
|
||||||
|
.\" .ad b justify to both left and right margins
|
||||||
|
.\" .nf disable filling
|
||||||
|
.\" .fi enable filling
|
||||||
|
.\" .br insert line break
|
||||||
|
.\" .sp <n> insert n+1 empty lines
|
||||||
|
.\" for manpage-specific macros, see man(7)
|
||||||
|
.SH NAME
|
||||||
|
gdigi \- utility to control DigiTech effect pedals
|
||||||
|
.SH SYNOPSIS
|
||||||
|
.B gdigi
|
||||||
|
.RI [OPTION...]
|
||||||
|
.SH DESCRIPTION
|
||||||
|
gdigi is a tool aimed to provide X-Edit functionality to Linux users
|
||||||
|
.PP
|
||||||
|
Supported devices:
|
||||||
|
.IP \(bu
|
||||||
|
RP250
|
||||||
|
.IP \(bu
|
||||||
|
RP255
|
||||||
|
.IP \(bu
|
||||||
|
RP355
|
||||||
|
.IP \(bu
|
||||||
|
RP500
|
||||||
|
.IP \(bu
|
||||||
|
RP1000
|
||||||
|
.IP \(bu
|
||||||
|
GNX3000
|
||||||
|
.IP \(bu
|
||||||
|
GNX4K
|
||||||
|
.PP
|
||||||
|
.SH OPTIONS
|
||||||
|
These programs follow the usual GNU command line syntax, with long
|
||||||
|
options starting with two dashes (`\-').
|
||||||
|
A summary of options is included below.
|
||||||
|
For a complete description, see the Info files.
|
||||||
|
.TP
|
||||||
|
.B \-?, \-\-help
|
||||||
|
Show summary of options.
|
||||||
|
.TP
|
||||||
|
.B \-\-help\-all
|
||||||
|
Show all help options.
|
||||||
|
.TP
|
||||||
|
.B \-\-help\-gtk
|
||||||
|
Show GTK+ options.
|
||||||
|
.TP
|
||||||
|
.B \-\-display=\fIDISPLAY\fR
|
||||||
|
X display to use.
|
||||||
|
.TP
|
||||||
|
.B \-d, \-\-device
|
||||||
|
MIDI device port to use.
|
||||||
|
.SH AUTHOR
|
||||||
|
gdigi was written by Tomasz Moń <desowin@gmail.com>.
|
||||||
|
.PP
|
||||||
|
Send comments, bug reports and patches to gdigi
|
||||||
|
mailinglist at Google Groups.
|
||||||
|
.PP
|
||||||
|
This manual page was written by Andrew O. Shadoura <bugzilla@tut.by>,
|
||||||
|
for the Debian project (but may be used by others).
|
||||||
|
.PP
|
||||||
|
Permission is granted to copy, distribute and/or modify this document under the
|
||||||
|
terms of the GNU General Public License as published by the Free Software
|
||||||
|
Foundation, under version 3 of the License.
|
||||||
|
|
||||||
748
gdigi.c
748
gdigi.c
@@ -16,6 +16,7 @@
|
|||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <gtk/gtk.h>
|
#include <gtk/gtk.h>
|
||||||
|
#include <gio/gio.h>
|
||||||
#include <getopt.h>
|
#include <getopt.h>
|
||||||
#include <alsa/asoundlib.h>
|
#include <alsa/asoundlib.h>
|
||||||
#include <alloca.h>
|
#include <alloca.h>
|
||||||
@@ -28,7 +29,27 @@ static unsigned char product_id = 0x7F;
|
|||||||
|
|
||||||
static snd_rawmidi_t *output = NULL;
|
static snd_rawmidi_t *output = NULL;
|
||||||
static snd_rawmidi_t *input = NULL;
|
static snd_rawmidi_t *input = NULL;
|
||||||
static char *device = "hw:1,0,0";
|
static char *device_port = "hw:1,0,0";
|
||||||
|
|
||||||
|
static GQueue *message_queue = NULL;
|
||||||
|
static GMutex *message_queue_mutex = NULL;
|
||||||
|
static GCond *message_queue_cond = NULL;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Registers an error quark for gdigi if necessary.
|
||||||
|
*
|
||||||
|
* \return error quark used for gdigi errors
|
||||||
|
**/
|
||||||
|
static GQuark gdigi_error_quark()
|
||||||
|
{
|
||||||
|
static GQuark quark = 0;
|
||||||
|
|
||||||
|
if (quark == 0) {
|
||||||
|
quark = g_quark_from_static_string("gdigi-error");
|
||||||
|
}
|
||||||
|
|
||||||
|
return quark;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* \param array data to calculate checksum
|
* \param array data to calculate checksum
|
||||||
@@ -59,9 +80,9 @@ gboolean open_device()
|
|||||||
{
|
{
|
||||||
int err;
|
int err;
|
||||||
|
|
||||||
err = snd_rawmidi_open(&input, &output, device, SND_RAWMIDI_NONBLOCK);
|
err = snd_rawmidi_open(&input, &output, device_port, SND_RAWMIDI_SYNC);
|
||||||
if (err) {
|
if (err) {
|
||||||
fprintf(stderr, "snd_rawmidi_open %s failed: %d\n", device, err);
|
fprintf(stderr, "snd_rawmidi_open %s failed: %d\n", device_port, err);
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -125,6 +146,11 @@ GString *pack_data(gchar *data, gint len)
|
|||||||
return packed;
|
return packed;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void message_free_func(GString *msg, gpointer user_data)
|
||||||
|
{
|
||||||
|
g_string_free(msg, TRUE);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* \param msg message to unpack
|
* \param msg message to unpack
|
||||||
*
|
*
|
||||||
@@ -150,36 +176,118 @@ static void unpack_message(GString *msg)
|
|||||||
do {
|
do {
|
||||||
offset += 8;
|
offset += 8;
|
||||||
status = str[offset-1];
|
status = str[offset-1];
|
||||||
for (x=0; x<7; x++) {
|
for (x=0; x<7 && !stop; x++) {
|
||||||
if (offset+x >= msg->len) {
|
if (offset+x >= msg->len) {
|
||||||
|
i++;
|
||||||
stop = TRUE;
|
stop = TRUE;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (str[offset+x] == 0xF7) {
|
if (str[offset+x] == 0xF7) {
|
||||||
|
if (x == 0) {
|
||||||
|
str[i] = status;
|
||||||
|
i++;
|
||||||
|
}
|
||||||
str[i] = 0xF7;
|
str[i] = 0xF7;
|
||||||
|
i++;
|
||||||
stop = TRUE;
|
stop = TRUE;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
str[i] = (((status << (x+1)) & 0x80) | str[x+offset]);
|
str[i] = (((status << (x+1)) & 0x80) | str[x+offset]);
|
||||||
i++;
|
i++;
|
||||||
}
|
}
|
||||||
} while (!stop && (offset+x < msg->len));
|
} while (!stop);
|
||||||
|
|
||||||
g_string_truncate(msg, i);
|
g_string_truncate(msg, i);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Reads data from MIDI IN. This function uses global input variable.
|
* \param msg SysEx message
|
||||||
*
|
*
|
||||||
* \return GString containing data, or NULL when no data was read.
|
* Checks message ID.
|
||||||
|
*
|
||||||
|
* \return MessageID, or -1 on error.
|
||||||
**/
|
**/
|
||||||
GString* read_data()
|
MessageID get_message_id(GString *msg)
|
||||||
|
{
|
||||||
|
/** \todo check if msg is valid SysEx message */
|
||||||
|
g_return_val_if_fail(msg != NULL, -1);
|
||||||
|
g_return_val_if_fail(msg->str != NULL, -1);
|
||||||
|
|
||||||
|
if (msg->len > 7) {
|
||||||
|
return (unsigned char)msg->str[7];
|
||||||
|
}
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
void push_message(GString *msg)
|
||||||
|
{
|
||||||
|
if (((unsigned char)msg->str[0] == 0xF0) && ((unsigned char)msg->str[msg->len-1] == 0xF7))
|
||||||
|
g_message("Pushing correct message!");
|
||||||
|
else
|
||||||
|
g_warning("Pushing incorrect message!");
|
||||||
|
|
||||||
|
int x;
|
||||||
|
for (x = 0; x<msg->len; x++)
|
||||||
|
printf("%02x ", (unsigned char)msg->str[x]);
|
||||||
|
printf("\n");
|
||||||
|
|
||||||
|
switch (get_message_id(msg)) {
|
||||||
|
case ACK:
|
||||||
|
g_message("Received ACK");
|
||||||
|
g_string_free(msg, TRUE);
|
||||||
|
return;
|
||||||
|
|
||||||
|
case NACK:
|
||||||
|
g_message("Received NACK");
|
||||||
|
g_string_free(msg, TRUE);
|
||||||
|
return;
|
||||||
|
|
||||||
|
case RECEIVE_PARAMETER_VALUE:
|
||||||
|
unpack_message(msg);
|
||||||
|
SettingParam *param = setting_param_new_from_data(&msg->str[8], NULL);
|
||||||
|
g_message("Received parameter change ID: %d Position: %d Value: %d", param->id, param->position, param->value);
|
||||||
|
|
||||||
|
GDK_THREADS_ENTER();
|
||||||
|
apply_setting_param_to_gui(param);
|
||||||
|
GDK_THREADS_LEAVE();
|
||||||
|
|
||||||
|
setting_param_free(param);
|
||||||
|
g_string_free(msg, TRUE);
|
||||||
|
return;
|
||||||
|
|
||||||
|
case RECEIVE_DEVICE_NOTIFICATION:
|
||||||
|
unpack_message(msg);
|
||||||
|
unsigned char *str = (unsigned char*)msg->str;
|
||||||
|
switch (str[8]) {
|
||||||
|
case NOTIFY_PRESET_MOVED:
|
||||||
|
if (str[11] == PRESETS_EDIT_BUFFER && str[12] == 0) {
|
||||||
|
g_message("Loaded preset %d from bank %d", str[10], str[9]);
|
||||||
|
|
||||||
|
GDK_THREADS_ENTER();
|
||||||
|
g_timeout_add(0, apply_current_preset_to_gui, NULL);
|
||||||
|
GDK_THREADS_LEAVE();
|
||||||
|
} else
|
||||||
|
g_message("%d %d moved to %d %d", str[9], str[10], str[11], str[12]);
|
||||||
|
default:
|
||||||
|
g_message("Received unhandled device notification");
|
||||||
|
}
|
||||||
|
g_string_free(msg, TRUE);
|
||||||
|
return;
|
||||||
|
default:
|
||||||
|
g_mutex_lock(message_queue_mutex);
|
||||||
|
g_queue_push_tail(message_queue, msg);
|
||||||
|
g_cond_signal(message_queue_cond);
|
||||||
|
g_mutex_unlock(message_queue_mutex);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
gpointer read_data_thread(gboolean *stop)
|
||||||
{
|
{
|
||||||
/* This is mostly taken straight from alsa-utils-1.0.19 amidi/amidi.c
|
/* This is mostly taken straight from alsa-utils-1.0.19 amidi/amidi.c
|
||||||
by Clemens Ladisch <clemens@ladisch.de> */
|
by Clemens Ladisch <clemens@ladisch.de> */
|
||||||
int err;
|
int err;
|
||||||
int npfds;
|
int npfds;
|
||||||
gboolean stop = FALSE;
|
|
||||||
struct pollfd *pfds;
|
struct pollfd *pfds;
|
||||||
GString *string = NULL;
|
GString *string = NULL;
|
||||||
|
|
||||||
@@ -188,10 +296,14 @@ GString* read_data()
|
|||||||
snd_rawmidi_poll_descriptors(input, pfds, npfds);
|
snd_rawmidi_poll_descriptors(input, pfds, npfds);
|
||||||
|
|
||||||
do {
|
do {
|
||||||
char buf[20];
|
unsigned char buf[256];
|
||||||
int i, length;
|
int i, length;
|
||||||
unsigned short revents;
|
unsigned short revents;
|
||||||
|
|
||||||
|
/* SysEx messages can't contain bytes with 8th bit set.
|
||||||
|
memset our buffer to 0xFF, so if for some reason we'll get out of reply bounds, we'll catch it */
|
||||||
|
memset(buf, sizeof(buf), 0xFF);
|
||||||
|
|
||||||
err = poll(pfds, npfds, 200);
|
err = poll(pfds, npfds, 200);
|
||||||
if (err < 0 && errno == EINTR)
|
if (err < 0 && errno == EINTR)
|
||||||
break;
|
break;
|
||||||
@@ -218,22 +330,47 @@ GString* read_data()
|
|||||||
|
|
||||||
length = 0;
|
length = 0;
|
||||||
for (i = 0; i < err; ++i)
|
for (i = 0; i < err; ++i)
|
||||||
if (buf[i] != 0xFE) /* ignore active sensing */
|
if ((unsigned char)buf[i] != 0xFE) /* ignore active sensing */
|
||||||
buf[length++] = buf[i];
|
buf[length++] = buf[i];
|
||||||
|
|
||||||
if ((unsigned char)buf[length-1] == 0xF7)
|
i = 0;
|
||||||
stop = TRUE;
|
|
||||||
|
while (i < length) {
|
||||||
|
int pos;
|
||||||
|
int bytes;
|
||||||
|
|
||||||
if (length != 0) {
|
|
||||||
if (string == NULL) {
|
if (string == NULL) {
|
||||||
string = g_string_new_len(buf, length);
|
while (buf[i] != 0xF0 && i < length)
|
||||||
} else {
|
i++;
|
||||||
string = g_string_append_len(string, buf, length);
|
}
|
||||||
|
|
||||||
|
pos = i;
|
||||||
|
|
||||||
|
for (bytes = 0; (bytes<length-i) && (buf[i+bytes] != 0xF7); bytes++);
|
||||||
|
|
||||||
|
if (buf[i+bytes] == 0xF7) bytes++;
|
||||||
|
|
||||||
|
i += bytes;
|
||||||
|
|
||||||
|
if (string == NULL)
|
||||||
|
string = g_string_new_len((gchar*)&buf[pos], bytes);
|
||||||
|
else
|
||||||
|
g_string_append_len(string, (gchar*)&buf[pos], bytes);
|
||||||
|
|
||||||
|
if ((unsigned char)string->str[string->len-1] == 0xF7) {
|
||||||
|
/* push message on stack */
|
||||||
|
push_message(string);
|
||||||
|
string = NULL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} while ((err != 0) && (stop == FALSE));
|
} while (*stop == FALSE);
|
||||||
|
|
||||||
return string;
|
if (string) {
|
||||||
|
g_string_free(string, TRUE);
|
||||||
|
string = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -268,40 +405,36 @@ void send_message(gint procedure, gchar *data, gint len)
|
|||||||
g_string_free(msg, TRUE);
|
g_string_free(msg, TRUE);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* \param msg SysEx message
|
|
||||||
*
|
|
||||||
* Checks message ID.
|
|
||||||
*
|
|
||||||
* \return MessageID, or -1 on error.
|
|
||||||
**/
|
|
||||||
static MessageID get_message_id(GString *msg)
|
|
||||||
{
|
|
||||||
/** \todo check if msg is valid SysEx message */
|
|
||||||
g_return_val_if_fail(msg != NULL, -1);
|
|
||||||
|
|
||||||
if (msg->len > 7) {
|
|
||||||
return (unsigned char)msg->str[7];
|
|
||||||
}
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* \param id MessageID of requested message
|
* \param id MessageID of requested message
|
||||||
*
|
*
|
||||||
* Reads data from MIDI IN until message with matching id is found.
|
* Reads data from message queue until message with matching id is found.
|
||||||
*
|
*
|
||||||
* \return GString containing unpacked message.
|
* \return GString containing unpacked message.
|
||||||
**/
|
**/
|
||||||
GString *get_message_by_id(MessageID id)
|
GString *get_message_by_id(MessageID id)
|
||||||
{
|
{
|
||||||
GString *data = NULL;
|
GString *data = NULL;
|
||||||
|
guint x, len;
|
||||||
|
gboolean found = FALSE;
|
||||||
|
|
||||||
|
g_mutex_lock(message_queue_mutex);
|
||||||
do {
|
do {
|
||||||
if (data)
|
len = g_queue_get_length(message_queue);
|
||||||
g_string_free(data, TRUE);
|
for (x = 0; x<len; x++) {
|
||||||
data = read_data();
|
data = g_queue_peek_nth(message_queue, x);
|
||||||
} while (get_message_id(data) != id);
|
if (get_message_id(data) == id) {
|
||||||
|
found = TRUE;
|
||||||
|
g_queue_pop_nth(message_queue, x);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (found == FALSE)
|
||||||
|
g_cond_wait(message_queue_cond, message_queue_mutex);
|
||||||
|
|
||||||
|
} while (found == FALSE);
|
||||||
|
g_mutex_unlock(message_queue_mutex);
|
||||||
|
|
||||||
unpack_message(data);
|
unpack_message(data);
|
||||||
|
|
||||||
@@ -341,6 +474,158 @@ void append_value(GString *msg, guint value)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \param str pointer to value to unpack
|
||||||
|
* \param len return location for how many bytes value is encoded on (length is added to current value)
|
||||||
|
*
|
||||||
|
* Unpacks value using scheme used on all newer DigiTech products.
|
||||||
|
*
|
||||||
|
* \return unpacked value
|
||||||
|
**/
|
||||||
|
guint unpack_value(gchar *str, int *len)
|
||||||
|
{
|
||||||
|
guint value;
|
||||||
|
gint tmp;
|
||||||
|
|
||||||
|
value = (unsigned char)str[0];
|
||||||
|
if (len != NULL)
|
||||||
|
*len += 1;
|
||||||
|
|
||||||
|
if (value > 0x80) {
|
||||||
|
tmp = value & 0x7F;
|
||||||
|
value = 0;
|
||||||
|
gint i;
|
||||||
|
for (i = 0; i<tmp; i++) {
|
||||||
|
value |= ((unsigned char)str[1+i] << (8*(tmp-i-1)));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (len != NULL)
|
||||||
|
*len += tmp;
|
||||||
|
}
|
||||||
|
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Allocates memory for SettingParam.
|
||||||
|
*
|
||||||
|
* \return SettingParam which must be freed using setting_param_free.
|
||||||
|
**/
|
||||||
|
SettingParam *setting_param_new()
|
||||||
|
{
|
||||||
|
SettingParam *param = g_slice_new(SettingParam);
|
||||||
|
param->id = -1;
|
||||||
|
param->position = -1;
|
||||||
|
param->value = -1;
|
||||||
|
|
||||||
|
return param;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \param str pointer to setting param in message
|
||||||
|
* \param len return location for how many bytes value is encoded on (length is added to current value)
|
||||||
|
*
|
||||||
|
* Creates SettingParam basing on data.
|
||||||
|
* This function expects str to point on:
|
||||||
|
* -Parameter ID - 2 bytes
|
||||||
|
* -Parameter position - 1 byte
|
||||||
|
* -Parameter value - var
|
||||||
|
*
|
||||||
|
* \return newly created SettingParam which must be freed using setting_param_free.
|
||||||
|
**/
|
||||||
|
SettingParam *setting_param_new_from_data(gchar *str, gint *len)
|
||||||
|
{
|
||||||
|
gint id;
|
||||||
|
gint position;
|
||||||
|
guint value;
|
||||||
|
|
||||||
|
id = ((unsigned char)str[0] << 8) | (unsigned char)str[1];
|
||||||
|
position = (unsigned char)str[2];
|
||||||
|
if (len != NULL)
|
||||||
|
*len += 3;
|
||||||
|
|
||||||
|
value = unpack_value(&str[3], len);
|
||||||
|
|
||||||
|
SettingParam *param = g_slice_new(SettingParam);
|
||||||
|
param->id = id;
|
||||||
|
param->position = position;
|
||||||
|
param->value = value;
|
||||||
|
|
||||||
|
return param;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \param param SettingParam to be freed
|
||||||
|
*
|
||||||
|
* Frees all memory used by SettingParam.
|
||||||
|
**/
|
||||||
|
void setting_param_free(SettingParam *param)
|
||||||
|
{
|
||||||
|
g_slice_free(SettingParam, param);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Allocates memory for SettingGenetx.
|
||||||
|
*
|
||||||
|
* \return SettingGenetx which must be freed using setting_genetx_free.
|
||||||
|
**/
|
||||||
|
SettingGenetx *setting_genetx_new()
|
||||||
|
{
|
||||||
|
SettingGenetx *genetx = g_slice_new(SettingGenetx);
|
||||||
|
/* Older patches don't specify GeNetX version */
|
||||||
|
genetx->version = GENETX_VERSION_1;
|
||||||
|
genetx->type = GENETX_TYPE_NOT_SET;
|
||||||
|
genetx->channel = -1;
|
||||||
|
genetx->name = NULL;
|
||||||
|
genetx->data = NULL;
|
||||||
|
|
||||||
|
return genetx;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \param genetx SettingGenetx to be freed
|
||||||
|
*
|
||||||
|
* Frees all memory used by SettingGenetx.
|
||||||
|
**/
|
||||||
|
void setting_genetx_free(SettingGenetx *genetx)
|
||||||
|
{
|
||||||
|
g_free(genetx->name);
|
||||||
|
if (genetx->data != NULL) {
|
||||||
|
g_string_free(genetx->data, TRUE);
|
||||||
|
}
|
||||||
|
g_slice_free(SettingGenetx, genetx);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \param version GeNetX version
|
||||||
|
* \param type GeNetX type
|
||||||
|
*
|
||||||
|
* Retrieves SectionID for specified GeNetX version and type.
|
||||||
|
*
|
||||||
|
* \return SectionID specified by version and type, or -1 on error.
|
||||||
|
**/
|
||||||
|
SectionID get_genetx_section_id(gint version, gint type)
|
||||||
|
{
|
||||||
|
if (version == GENETX_VERSION_1) {
|
||||||
|
if (type == GENETX_TYPE_AMP) {
|
||||||
|
return SECTION_GENETX_AMP;
|
||||||
|
} else if (type == GENETX_TYPE_CABINET) {
|
||||||
|
return SECTION_GENETX_CABINET;
|
||||||
|
}
|
||||||
|
} else if (version == GENETX_VERSION_2) {
|
||||||
|
if (type == GENETX_TYPE_AMP) {
|
||||||
|
return SECTION_GENETX2_AMP;
|
||||||
|
} else if (type == GENETX_TYPE_CABINET) {
|
||||||
|
return SECTION_GENETX2_CABINET;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
g_message("This version of gdigi don't know what to do with this "
|
||||||
|
"GeNetX version (%d) and type (%d)", version, type);
|
||||||
|
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* \param id Parameter ID
|
* \param id Parameter ID
|
||||||
* \param position Parameter position
|
* \param position Parameter position
|
||||||
@@ -359,6 +644,68 @@ void set_option(guint id, guint position, guint value)
|
|||||||
g_string_free(msg, TRUE);
|
g_string_free(msg, TRUE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \param section data section ID
|
||||||
|
* \param bank section-specific bank number
|
||||||
|
* \param index index of the desired object within the bank
|
||||||
|
* \param name object name
|
||||||
|
* \param data GString containing object data
|
||||||
|
*
|
||||||
|
* Forms RECEIVE_OBJECT SysEx message then sends it to device.
|
||||||
|
**/
|
||||||
|
void send_object(SectionID section, guint bank, guint index,
|
||||||
|
gchar *name, GString *data)
|
||||||
|
{
|
||||||
|
GString *msg = g_string_new(NULL);
|
||||||
|
|
||||||
|
gint len = data->len;
|
||||||
|
|
||||||
|
g_string_append_printf(msg,
|
||||||
|
"%c%c%c%c%s%c%c%c",
|
||||||
|
section, bank,
|
||||||
|
((index & 0xFF00) >> 8), (index & 0xFF),
|
||||||
|
name, 0 /* NULL terminated string */,
|
||||||
|
((len & 0xFF00) >> 8), (len & 0xFF));
|
||||||
|
|
||||||
|
g_string_append_len(msg, data->str, data->len);
|
||||||
|
|
||||||
|
send_message(RECEIVE_OBJECT, msg->str, msg->len);
|
||||||
|
|
||||||
|
g_string_free(msg, TRUE);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \param params GList containing SettingParam
|
||||||
|
*
|
||||||
|
* Forms RECEIVE_PRESET_PARAMETERS SysEx message then sends it to device.
|
||||||
|
**/
|
||||||
|
void send_preset_parameters(GList *params)
|
||||||
|
{
|
||||||
|
GString *msg = g_string_sized_new(500);
|
||||||
|
GList *iter = params;
|
||||||
|
gint len = g_list_length(iter);
|
||||||
|
|
||||||
|
g_string_append_printf(msg, "%c%c",
|
||||||
|
((len & 0xFF00) >> 8),
|
||||||
|
(len & 0xFF));
|
||||||
|
|
||||||
|
while (iter) {
|
||||||
|
SettingParam *param = (SettingParam *) iter->data;
|
||||||
|
iter = iter->next;
|
||||||
|
|
||||||
|
g_string_append_printf(msg, "%c%c%c",
|
||||||
|
((param->id & 0xFF00) >> 8),
|
||||||
|
(param->id & 0xFF),
|
||||||
|
param->position);
|
||||||
|
|
||||||
|
append_value(msg, param->value);
|
||||||
|
};
|
||||||
|
|
||||||
|
send_message(RECEIVE_PRESET_PARAMETERS, msg->str, msg->len);
|
||||||
|
|
||||||
|
g_string_free(msg, TRUE);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* \param bank preset bank
|
* \param bank preset bank
|
||||||
* \param x preset index
|
* \param x preset index
|
||||||
@@ -441,7 +788,7 @@ GStrv query_preset_names(gchar bank)
|
|||||||
}
|
}
|
||||||
|
|
||||||
for (x=10; ((x<data->len) && (n<n_total)); x++) {
|
for (x=10; ((x<data->len) && (n<n_total)); x++) {
|
||||||
if (data->str[x] == 0xF7) /* every message ends with 0xF7 */
|
if ((unsigned char)data->str[x] == 0xF7) /* every message ends with 0xF7 */
|
||||||
break;
|
break;
|
||||||
|
|
||||||
str_array[n] = g_strdup(&data->str[x]);
|
str_array[n] = g_strdup(&data->str[x]);
|
||||||
@@ -454,20 +801,242 @@ GStrv query_preset_names(gchar bank)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Queries current edit buffer.
|
* Reads multiple messages and puts them into GList.
|
||||||
*
|
*
|
||||||
* \return GString containing RECEIVE_PRESET_PARAMETERS SysEx message.
|
* \param id MessageID starting message sequence
|
||||||
|
*
|
||||||
|
* \return GList with SysEx messages, which must be freed using message_list_free.
|
||||||
**/
|
**/
|
||||||
GString *get_current_preset()
|
GList *get_message_list(MessageID id)
|
||||||
{
|
{
|
||||||
GString *data = NULL;
|
GString *data = NULL;
|
||||||
|
GList *list = NULL;
|
||||||
|
guint x, len;
|
||||||
|
gboolean found = FALSE;
|
||||||
|
gboolean done = FALSE;
|
||||||
|
|
||||||
send_message(REQUEST_PRESET, "\x04\x00", 3);
|
g_mutex_lock(message_queue_mutex);
|
||||||
|
do {
|
||||||
|
len = g_queue_get_length(message_queue);
|
||||||
|
|
||||||
/* read reply */
|
for (x = 0; x<len && (found == FALSE); x++) {
|
||||||
data = get_message_by_id(RECEIVE_PRESET_PARAMETERS);
|
data = g_queue_peek_nth(message_queue, x);
|
||||||
|
if (get_message_id(data) == id) {
|
||||||
|
found = TRUE;
|
||||||
|
g_queue_pop_nth(message_queue, x);
|
||||||
|
unpack_message(data);
|
||||||
|
list = g_list_append(list, data);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return data;
|
if (found == TRUE) {
|
||||||
|
int i;
|
||||||
|
int amt;
|
||||||
|
|
||||||
|
switch (id) {
|
||||||
|
case RECEIVE_PRESET_START:
|
||||||
|
for (i = 10; (i < data->len) && data->str[i]; i++);
|
||||||
|
amt = (unsigned char)data->str[i+2];
|
||||||
|
break;
|
||||||
|
case RECEIVE_BULK_DUMP_START:
|
||||||
|
amt = ((unsigned char)data->str[8] << 8) | (unsigned char)data->str[9];
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
g_error("get_message_list() doesn't support followning id: %d", id);
|
||||||
|
g_string_free(data, TRUE);
|
||||||
|
g_list_free(list);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
while (amt) {
|
||||||
|
g_message("%d messages left", amt);
|
||||||
|
data = g_queue_pop_nth(message_queue, x);
|
||||||
|
if (data == NULL) {
|
||||||
|
g_cond_wait(message_queue_cond, message_queue_mutex);
|
||||||
|
} else {
|
||||||
|
unpack_message(data);
|
||||||
|
list = g_list_append(list, data);
|
||||||
|
amt--;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
done = TRUE;
|
||||||
|
} else {
|
||||||
|
/* id not found in message queue */
|
||||||
|
g_cond_wait(message_queue_cond, message_queue_mutex);
|
||||||
|
}
|
||||||
|
} while (done == FALSE);
|
||||||
|
g_mutex_unlock(message_queue_mutex);
|
||||||
|
|
||||||
|
return list;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \param list list to be freed
|
||||||
|
*
|
||||||
|
* Frees all memory used by message list.
|
||||||
|
**/
|
||||||
|
void message_list_free(GList *list)
|
||||||
|
{
|
||||||
|
g_return_if_fail(list != NULL);
|
||||||
|
|
||||||
|
g_list_foreach(list, (GFunc) message_free_func, NULL);
|
||||||
|
g_list_free(list);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Queries current edit buffer.
|
||||||
|
*
|
||||||
|
* \return GList with preset SysEx messages, which must be freed using message_list_free.
|
||||||
|
**/
|
||||||
|
GList *get_current_preset()
|
||||||
|
{
|
||||||
|
send_message(REQUEST_PRESET, "\x04\x00", 2);
|
||||||
|
return get_message_list(RECEIVE_PRESET_START);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates backup file.
|
||||||
|
*
|
||||||
|
* \param file backup file handle
|
||||||
|
* \param error a GError
|
||||||
|
*
|
||||||
|
* \return FALSE on success, TRUE on error.
|
||||||
|
**/
|
||||||
|
static gboolean create_backup_file(GFile *file, GError **error)
|
||||||
|
{
|
||||||
|
GFileOutputStream *output = NULL;
|
||||||
|
GList *list = NULL, *iter = NULL;
|
||||||
|
const gchar header[] = {'\x01', '\x00'};
|
||||||
|
gsize written;
|
||||||
|
gboolean val;
|
||||||
|
|
||||||
|
if (error)
|
||||||
|
*error = NULL;
|
||||||
|
output = g_file_create(file, G_FILE_CREATE_NONE, NULL, error);
|
||||||
|
if (output == NULL)
|
||||||
|
return TRUE;
|
||||||
|
|
||||||
|
if (error)
|
||||||
|
*error = NULL;
|
||||||
|
val = g_output_stream_write_all(G_OUTPUT_STREAM(output), header,
|
||||||
|
sizeof(header), &written, NULL, error);
|
||||||
|
if (val == FALSE) {
|
||||||
|
g_object_unref(output);
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
send_message(REQUEST_BULK_DUMP, "\x00", 1);
|
||||||
|
list = get_message_list(RECEIVE_BULK_DUMP_START);
|
||||||
|
|
||||||
|
for (iter = list; iter; iter = g_list_next(iter)) {
|
||||||
|
GString *str;
|
||||||
|
guchar id; /* message id */
|
||||||
|
guint32 len; /* message length */
|
||||||
|
|
||||||
|
str = (GString*) iter->data;
|
||||||
|
|
||||||
|
id = get_message_id(str);
|
||||||
|
if (error)
|
||||||
|
*error = NULL;
|
||||||
|
val = g_output_stream_write_all(G_OUTPUT_STREAM(output), &id,
|
||||||
|
sizeof(id), &written, NULL, error);
|
||||||
|
if (val == FALSE) {
|
||||||
|
message_list_free(list);
|
||||||
|
g_object_unref(output);
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
len = GUINT32_TO_LE(str->len - 10);
|
||||||
|
if (error)
|
||||||
|
*error = NULL;
|
||||||
|
val = g_output_stream_write_all(G_OUTPUT_STREAM(output), &len,
|
||||||
|
sizeof(len), &written, NULL, error);
|
||||||
|
if (val == FALSE) {
|
||||||
|
message_list_free(list);
|
||||||
|
g_object_unref(output);
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (error)
|
||||||
|
*error = NULL;
|
||||||
|
val = g_output_stream_write_all(G_OUTPUT_STREAM(output), &str->str[8],
|
||||||
|
str->len - 10, &written, NULL, error);
|
||||||
|
if (val == FALSE) {
|
||||||
|
message_list_free(list);
|
||||||
|
g_object_unref(output);
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
message_list_free(list);
|
||||||
|
|
||||||
|
if (error)
|
||||||
|
*error = NULL;
|
||||||
|
val = g_output_stream_close(G_OUTPUT_STREAM(output), NULL, error);
|
||||||
|
g_object_unref(output);
|
||||||
|
return !val;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Restores backup file.
|
||||||
|
*
|
||||||
|
* \param filename backup filename
|
||||||
|
* \param error a GError
|
||||||
|
*
|
||||||
|
* \return FALSE on success, TRUE on error.
|
||||||
|
**/
|
||||||
|
static gboolean restore_backup_file(const gchar *filename, GError **error)
|
||||||
|
{
|
||||||
|
gchar *data;
|
||||||
|
gsize length;
|
||||||
|
gsize x;
|
||||||
|
|
||||||
|
if (g_file_get_contents(filename, &data, &length, error) == FALSE)
|
||||||
|
return TRUE;
|
||||||
|
|
||||||
|
if (error)
|
||||||
|
*error = NULL;
|
||||||
|
|
||||||
|
if (!(data[0] == 0x01 && data[1] == 0x00)) {
|
||||||
|
g_free(data);
|
||||||
|
g_set_error_literal(error, gdigi_error_quark(), 0,
|
||||||
|
"Magic byte doesn't match");
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
x = 0x02;
|
||||||
|
while (x < length) {
|
||||||
|
gchar id;
|
||||||
|
guint32 len;
|
||||||
|
|
||||||
|
id = data[x];
|
||||||
|
x++;
|
||||||
|
|
||||||
|
if (x+4 <= length) {
|
||||||
|
len = GUINT32_FROM_LE(*((guint32*) &data[x]));
|
||||||
|
x += 4;
|
||||||
|
} else {
|
||||||
|
g_free(data);
|
||||||
|
g_set_error_literal(error, gdigi_error_quark(), 0,
|
||||||
|
"Unexpected end of data");
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (x+len <= length) {
|
||||||
|
send_message(id, &data[x], len);
|
||||||
|
x += len;
|
||||||
|
} else {
|
||||||
|
g_free(data);
|
||||||
|
g_set_error_literal(error, gdigi_error_quark(), 0,
|
||||||
|
"Unexpected end of data");
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
g_free(data);
|
||||||
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -482,18 +1051,15 @@ GString *get_current_preset()
|
|||||||
static gboolean request_who_am_i(unsigned char *device_id, unsigned char *family_id,
|
static gboolean request_who_am_i(unsigned char *device_id, unsigned char *family_id,
|
||||||
unsigned char *product_id)
|
unsigned char *product_id)
|
||||||
{
|
{
|
||||||
send_message(REQUEST_WHO_AM_I, NULL, 0);
|
send_message(REQUEST_WHO_AM_I, "\x7F\x7F\x7F", 3);
|
||||||
|
|
||||||
GString *data = read_data();
|
GString *data = get_message_by_id(RECEIVE_WHO_AM_I);
|
||||||
if (data != NULL) {
|
if ((data != NULL) && (data->len > 11)) {
|
||||||
if ((data->len == 15) && (data->str[7] == RECEIVE_WHO_AM_I)) {
|
*device_id = data->str[8];
|
||||||
*device_id = data->str[9];
|
*family_id = data->str[9];
|
||||||
*family_id = data->str[10];
|
*product_id = data->str[10];
|
||||||
*product_id = data->str[11];
|
|
||||||
g_string_free(data, TRUE);
|
|
||||||
return TRUE;
|
|
||||||
}
|
|
||||||
g_string_free(data, TRUE);
|
g_string_free(data, TRUE);
|
||||||
|
return TRUE;
|
||||||
}
|
}
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
@@ -538,7 +1104,7 @@ static void request_device_configuration()
|
|||||||
#ifndef DOXYGEN_SHOULD_SKIP_THIS
|
#ifndef DOXYGEN_SHOULD_SKIP_THIS
|
||||||
|
|
||||||
static GOptionEntry options[] = {
|
static GOptionEntry options[] = {
|
||||||
{"device", 'd', G_OPTION_FLAG_IN_MAIN, G_OPTION_ARG_STRING, &device, "MIDI device port to use", NULL},
|
{"device", 'd', G_OPTION_FLAG_IN_MAIN, G_OPTION_ARG_STRING, &device_port, "MIDI device port to use", NULL},
|
||||||
{NULL}
|
{NULL}
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -547,6 +1113,12 @@ static GOptionEntry options[] = {
|
|||||||
int main(int argc, char *argv[]) {
|
int main(int argc, char *argv[]) {
|
||||||
GError *error = NULL;
|
GError *error = NULL;
|
||||||
GOptionContext *context;
|
GOptionContext *context;
|
||||||
|
static gboolean stop_read_thread = FALSE;
|
||||||
|
GThread *read_thread = NULL;
|
||||||
|
|
||||||
|
g_thread_init(NULL);
|
||||||
|
gdk_threads_init();
|
||||||
|
|
||||||
context = g_option_context_new(NULL);
|
context = g_option_context_new(NULL);
|
||||||
g_option_context_add_main_entries(context, options, NULL);
|
g_option_context_add_main_entries(context, options, NULL);
|
||||||
g_option_context_add_group(context, gtk_get_option_group(TRUE));
|
g_option_context_add_group(context, gtk_get_option_group(TRUE));
|
||||||
@@ -563,19 +1135,63 @@ int main(int argc, char *argv[]) {
|
|||||||
if (open_device() == TRUE) {
|
if (open_device() == TRUE) {
|
||||||
show_error_message(NULL, "Failed to open MIDI device");
|
show_error_message(NULL, "Failed to open MIDI device");
|
||||||
} else {
|
} else {
|
||||||
|
message_queue = g_queue_new();
|
||||||
|
message_queue_mutex = g_mutex_new();
|
||||||
|
message_queue_cond = g_cond_new();
|
||||||
|
read_thread = g_thread_create((GThreadFunc)read_data_thread,
|
||||||
|
&stop_read_thread,
|
||||||
|
TRUE, NULL);
|
||||||
|
|
||||||
if (request_who_am_i(&device_id, &family_id, &product_id) == FALSE) {
|
if (request_who_am_i(&device_id, &family_id, &product_id) == FALSE) {
|
||||||
show_error_message(NULL, "No suitable reply from device");
|
show_error_message(NULL, "No suitable reply from device");
|
||||||
} else {
|
} else {
|
||||||
gui_create();
|
Device *device = NULL;
|
||||||
gtk_main();
|
|
||||||
gui_free();
|
if (get_device_info(device_id, family_id, product_id, &device) == FALSE) {
|
||||||
|
if (unsupported_device_dialog(&device) == FALSE) {
|
||||||
|
g_message("Shutting down");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (device != NULL) {
|
||||||
|
/* enable GUI mode */
|
||||||
|
set_option(GUI_MODE_ON_OFF, USB_POSITION, 1);
|
||||||
|
|
||||||
|
gui_create(device);
|
||||||
|
gtk_main();
|
||||||
|
gui_free();
|
||||||
|
|
||||||
|
/* disable GUI mode */
|
||||||
|
set_option(GUI_MODE_ON_OFF, USB_POSITION, 0);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (output != NULL)
|
if (read_thread != NULL) {
|
||||||
|
stop_read_thread = TRUE;
|
||||||
|
g_thread_join(read_thread);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (message_queue_mutex != NULL) {
|
||||||
|
g_mutex_free(message_queue_mutex);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (message_queue != NULL) {
|
||||||
|
g_message("%d unread messages in queue",
|
||||||
|
g_queue_get_length(message_queue));
|
||||||
|
g_queue_foreach(message_queue, (GFunc) message_free_func, NULL);
|
||||||
|
g_queue_free(message_queue);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (output != NULL) {
|
||||||
|
snd_rawmidi_drain(output);
|
||||||
snd_rawmidi_close(output);
|
snd_rawmidi_close(output);
|
||||||
if (input != NULL)
|
}
|
||||||
|
|
||||||
|
if (input != NULL) {
|
||||||
|
snd_rawmidi_drain(input);
|
||||||
snd_rawmidi_close(input);
|
snd_rawmidi_close(input);
|
||||||
|
}
|
||||||
|
|
||||||
return EXIT_SUCCESS;
|
return EXIT_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|||||||
6
gdigi.desktop
Normal file
6
gdigi.desktop
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
[Desktop Entry]
|
||||||
|
Version=1.0
|
||||||
|
Type=Application
|
||||||
|
Name=gdigi
|
||||||
|
Exec=gdigi
|
||||||
|
|
||||||
55
gtkknob.c
55
gtkknob.c
@@ -20,12 +20,10 @@
|
|||||||
* along with this program; if not, write to the Free Software
|
* along with this program; if not, write to the Free Software
|
||||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||||
*****************************************************************************/
|
*****************************************************************************/
|
||||||
#include <math.h>
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <gtk/gtkmain.h>
|
|
||||||
#include <gtk/gtksignal.h>
|
|
||||||
#include <gdk/gdkkeysyms.h>
|
|
||||||
|
|
||||||
|
#include <math.h>
|
||||||
|
#include <gtk/gtk.h>
|
||||||
|
#include <gdk/gdkkeysyms.h>
|
||||||
#include "gtkknob.h"
|
#include "gtkknob.h"
|
||||||
|
|
||||||
|
|
||||||
@@ -103,14 +101,14 @@ gtk_knob_get_type(void) {
|
|||||||
*
|
*
|
||||||
*****************************************************************************/
|
*****************************************************************************/
|
||||||
static void
|
static void
|
||||||
gtk_knob_class_init (GtkKnobClass *class) {
|
gtk_knob_class_init (GtkKnobClass *klass) {
|
||||||
GtkObjectClass *object_class;
|
GtkObjectClass *object_class;
|
||||||
GtkWidgetClass *widget_class;
|
GtkWidgetClass *widget_class;
|
||||||
|
|
||||||
object_class = (GtkObjectClass*) class;
|
object_class = (GtkObjectClass*) klass;
|
||||||
widget_class = (GtkWidgetClass*) class;
|
widget_class = (GtkWidgetClass*) klass;
|
||||||
|
|
||||||
parent_class = g_type_class_ref (GTK_TYPE_WIDGET);
|
parent_class = g_type_class_peek_parent(klass);
|
||||||
|
|
||||||
object_class->destroy = gtk_knob_destroy;
|
object_class->destroy = gtk_knob_destroy;
|
||||||
|
|
||||||
@@ -190,10 +188,7 @@ gtk_knob_destroy(GtkObject *object) {
|
|||||||
|
|
||||||
knob = GTK_KNOB (object);
|
knob = GTK_KNOB (object);
|
||||||
|
|
||||||
if (knob->adjustment) {
|
gtk_knob_set_adjustment (knob, NULL);
|
||||||
g_object_unref (knob->adjustment);
|
|
||||||
knob->adjustment = NULL;
|
|
||||||
}
|
|
||||||
/* FIXME: needs ref counting for automatic GtkKnobAnim cleanup
|
/* FIXME: needs ref counting for automatic GtkKnobAnim cleanup
|
||||||
if (knob->anim) {
|
if (knob->anim) {
|
||||||
gtk_knob_anim_unref (knob->anim);
|
gtk_knob_anim_unref (knob->anim);
|
||||||
@@ -271,21 +266,22 @@ gtk_knob_set_adjustment(GtkKnob *knob, GtkAdjustment *adjustment) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
knob->adjustment = adjustment;
|
knob->adjustment = adjustment;
|
||||||
g_object_ref (GTK_OBJECT (knob->adjustment));
|
if (adjustment) {
|
||||||
g_object_ref_sink (GTK_OBJECT (knob->adjustment));
|
g_object_ref_sink (adjustment);
|
||||||
|
|
||||||
g_signal_connect (adjustment, "changed",
|
g_signal_connect (adjustment, "changed",
|
||||||
(GCallback) gtk_knob_adjustment_changed,
|
G_CALLBACK(gtk_knob_adjustment_changed),
|
||||||
knob);
|
knob);
|
||||||
g_signal_connect (adjustment, "value_changed",
|
g_signal_connect (adjustment, "value_changed",
|
||||||
(GCallback) gtk_knob_adjustment_value_changed,
|
G_CALLBACK(gtk_knob_adjustment_value_changed),
|
||||||
knob);
|
knob);
|
||||||
|
|
||||||
knob->old_value = adjustment->value;
|
knob->old_value = adjustment->value;
|
||||||
knob->old_lower = adjustment->lower;
|
knob->old_lower = adjustment->lower;
|
||||||
knob->old_upper = adjustment->upper;
|
knob->old_upper = adjustment->upper;
|
||||||
|
|
||||||
gtk_knob_update (knob);
|
gtk_knob_update (knob);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -398,6 +394,7 @@ gtk_knob_expose(GtkWidget *widget, GdkEventExpose *event) {
|
|||||||
g_return_val_if_fail (widget != NULL, FALSE);
|
g_return_val_if_fail (widget != NULL, FALSE);
|
||||||
g_return_val_if_fail (GTK_IS_KNOB (widget), FALSE);
|
g_return_val_if_fail (GTK_IS_KNOB (widget), FALSE);
|
||||||
g_return_val_if_fail (event != NULL, FALSE);
|
g_return_val_if_fail (event != NULL, FALSE);
|
||||||
|
g_return_val_if_fail (GTK_IS_ADJUSTMENT (GTK_KNOB (widget)->adjustment), FALSE);
|
||||||
|
|
||||||
if (event->count > 0)
|
if (event->count > 0)
|
||||||
return FALSE;
|
return FALSE;
|
||||||
@@ -436,6 +433,7 @@ gtk_knob_scroll(GtkWidget *widget, GdkEventScroll *event) {
|
|||||||
g_return_val_if_fail (widget != NULL, FALSE);
|
g_return_val_if_fail (widget != NULL, FALSE);
|
||||||
g_return_val_if_fail (GTK_IS_KNOB (widget), FALSE);
|
g_return_val_if_fail (GTK_IS_KNOB (widget), FALSE);
|
||||||
g_return_val_if_fail (event != NULL, FALSE);
|
g_return_val_if_fail (event != NULL, FALSE);
|
||||||
|
g_return_val_if_fail (GTK_IS_ADJUSTMENT (GTK_KNOB (widget)->adjustment), FALSE);
|
||||||
|
|
||||||
knob = GTK_KNOB (widget);
|
knob = GTK_KNOB (widget);
|
||||||
|
|
||||||
@@ -468,6 +466,7 @@ gtk_knob_button_press(GtkWidget *widget, GdkEventButton *event) {
|
|||||||
g_return_val_if_fail (widget != NULL, FALSE);
|
g_return_val_if_fail (widget != NULL, FALSE);
|
||||||
g_return_val_if_fail (GTK_IS_KNOB (widget), FALSE);
|
g_return_val_if_fail (GTK_IS_KNOB (widget), FALSE);
|
||||||
g_return_val_if_fail (event != NULL, FALSE);
|
g_return_val_if_fail (event != NULL, FALSE);
|
||||||
|
g_return_val_if_fail (GTK_IS_ADJUSTMENT (GTK_KNOB (widget)->adjustment), FALSE);
|
||||||
|
|
||||||
knob = GTK_KNOB (widget);
|
knob = GTK_KNOB (widget);
|
||||||
|
|
||||||
@@ -508,6 +507,7 @@ gtk_knob_button_release(GtkWidget *widget, GdkEventButton *event) {
|
|||||||
g_return_val_if_fail (widget != NULL, FALSE);
|
g_return_val_if_fail (widget != NULL, FALSE);
|
||||||
g_return_val_if_fail (GTK_IS_KNOB (widget), FALSE);
|
g_return_val_if_fail (GTK_IS_KNOB (widget), FALSE);
|
||||||
g_return_val_if_fail (event != NULL, FALSE);
|
g_return_val_if_fail (event != NULL, FALSE);
|
||||||
|
g_return_val_if_fail (GTK_IS_ADJUSTMENT (GTK_KNOB (widget)->adjustment), FALSE);
|
||||||
|
|
||||||
knob = GTK_KNOB (widget);
|
knob = GTK_KNOB (widget);
|
||||||
|
|
||||||
@@ -544,6 +544,7 @@ static gint gtk_knob_key_press(GtkWidget *widget, GdkEventKey *event)
|
|||||||
g_return_val_if_fail (widget != NULL, FALSE);
|
g_return_val_if_fail (widget != NULL, FALSE);
|
||||||
g_return_val_if_fail (GTK_IS_KNOB (widget), FALSE);
|
g_return_val_if_fail (GTK_IS_KNOB (widget), FALSE);
|
||||||
g_return_val_if_fail (event != NULL, FALSE);
|
g_return_val_if_fail (event != NULL, FALSE);
|
||||||
|
g_return_val_if_fail (GTK_IS_ADJUSTMENT (GTK_KNOB (widget)->adjustment), FALSE);
|
||||||
|
|
||||||
knob = GTK_KNOB (widget);
|
knob = GTK_KNOB (widget);
|
||||||
|
|
||||||
@@ -629,6 +630,7 @@ gtk_knob_timer(GtkKnob *knob) {
|
|||||||
|
|
||||||
g_return_val_if_fail (knob != NULL, FALSE);
|
g_return_val_if_fail (knob != NULL, FALSE);
|
||||||
g_return_val_if_fail (GTK_IS_KNOB (knob), FALSE);
|
g_return_val_if_fail (GTK_IS_KNOB (knob), FALSE);
|
||||||
|
g_return_val_if_fail (GTK_IS_ADJUSTMENT (knob->adjustment), FALSE);
|
||||||
|
|
||||||
if (knob->policy == GTK_UPDATE_DELAYED) {
|
if (knob->policy == GTK_UPDATE_DELAYED) {
|
||||||
g_signal_emit_by_name (knob->adjustment, "value_changed");
|
g_signal_emit_by_name (knob->adjustment, "value_changed");
|
||||||
@@ -646,6 +648,7 @@ gtk_knob_timer(GtkKnob *knob) {
|
|||||||
*****************************************************************************/
|
*****************************************************************************/
|
||||||
static void
|
static void
|
||||||
gtk_knob_update_mouse_update(GtkKnob *knob) {
|
gtk_knob_update_mouse_update(GtkKnob *knob) {
|
||||||
|
g_return_if_fail(GTK_IS_ADJUSTMENT (knob->adjustment));
|
||||||
|
|
||||||
if (knob->policy == GTK_UPDATE_CONTINUOUS) {
|
if (knob->policy == GTK_UPDATE_CONTINUOUS) {
|
||||||
g_signal_emit_by_name (knob->adjustment, "value_changed");
|
g_signal_emit_by_name (knob->adjustment, "value_changed");
|
||||||
@@ -677,6 +680,7 @@ gtk_knob_update_mouse(GtkKnob *knob, gint x, gint y, gboolean step) {
|
|||||||
|
|
||||||
g_return_if_fail (knob != NULL);
|
g_return_if_fail (knob != NULL);
|
||||||
g_return_if_fail (GTK_IS_KNOB (knob));
|
g_return_if_fail (GTK_IS_KNOB (knob));
|
||||||
|
g_return_if_fail (GTK_IS_ADJUSTMENT (knob->adjustment));
|
||||||
|
|
||||||
old_value = knob->adjustment->value;
|
old_value = knob->adjustment->value;
|
||||||
|
|
||||||
@@ -722,6 +726,7 @@ gtk_knob_update(GtkKnob *knob) {
|
|||||||
|
|
||||||
g_return_if_fail (knob != NULL);
|
g_return_if_fail (knob != NULL);
|
||||||
g_return_if_fail (GTK_IS_KNOB (knob));
|
g_return_if_fail (GTK_IS_KNOB (knob));
|
||||||
|
g_return_if_fail (GTK_IS_ADJUSTMENT (knob->adjustment));
|
||||||
|
|
||||||
if (knob->adjustment->step_increment == 1) {
|
if (knob->adjustment->step_increment == 1) {
|
||||||
new_value = floor (knob->adjustment->value + 0.5);
|
new_value = floor (knob->adjustment->value + 0.5);
|
||||||
|
|||||||
@@ -3,7 +3,7 @@
|
|||||||
* Most of this code comes from gAlan 0.2.0, copyright (C) 1999
|
* Most of this code comes from gAlan 0.2.0, copyright (C) 1999
|
||||||
* Tony Garnock-Jones, with modifications by Sean Bolton,
|
* Tony Garnock-Jones, with modifications by Sean Bolton,
|
||||||
* copyright (C) 2004, and minor modifications by William Weston,
|
* copyright (C) 2004, and minor modifications by William Weston,
|
||||||
* copyright (C) 2007.
|
* copyright (C) 2007, Tomasz Moń, copyright (C) 2009
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or
|
* This program is free software; you can redistribute it and/or
|
||||||
* modify it under the terms of the GNU General Public License
|
* modify it under the terms of the GNU General Public License
|
||||||
@@ -22,9 +22,7 @@
|
|||||||
#ifndef __GTK_KNOB_H__
|
#ifndef __GTK_KNOB_H__
|
||||||
#define __GTK_KNOB_H__
|
#define __GTK_KNOB_H__
|
||||||
|
|
||||||
#include <gdk/gdk.h>
|
#include <gtk/gtk.h>
|
||||||
#include <gtk/gtkadjustment.h>
|
|
||||||
#include <gtk/gtkwidget.h>
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
extern "C" {
|
extern "C" {
|
||||||
|
|||||||
606
gui.c
606
gui.c
@@ -15,6 +15,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include <gtk/gtk.h>
|
#include <gtk/gtk.h>
|
||||||
|
#include <string.h>
|
||||||
#include "gdigi.h"
|
#include "gdigi.h"
|
||||||
#include "gui.h"
|
#include "gui.h"
|
||||||
#include "effects.h"
|
#include "effects.h"
|
||||||
@@ -22,27 +23,18 @@
|
|||||||
#include "gtkknob.h"
|
#include "gtkknob.h"
|
||||||
#include "knob.h"
|
#include "knob.h"
|
||||||
|
|
||||||
#ifndef DOXYGEN_SHOULD_SKIP_THIS
|
|
||||||
|
|
||||||
extern EffectList effects[];
|
|
||||||
extern int n_effects;
|
|
||||||
|
|
||||||
#endif /* DOXYGEN_SHOULD_SKIP_THIS */
|
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
GtkObject *widget;
|
GtkObject *widget;
|
||||||
gint id;
|
|
||||||
gint position;
|
|
||||||
|
|
||||||
/* used for combo boxes, if widget isn't combo box, then both value and x are -1 */
|
/* used for combo boxes, if widget isn't combo box, then both value and x are -1 */
|
||||||
gint value; /**< effect type value */
|
gint value; /**< effect type value */
|
||||||
gint x; /**< combo box item number */
|
gint x; /**< combo box item number */
|
||||||
} WidgetListElem;
|
} WidgetTreeElem;
|
||||||
|
|
||||||
#ifndef DOXYGEN_SHOULD_SKIP_THIS
|
#ifndef DOXYGEN_SHOULD_SKIP_THIS
|
||||||
static GtkKnobAnim *knob_anim = NULL; /* animation used by knobs */
|
static GtkKnobAnim *knob_anim = NULL; /* animation used by knobs */
|
||||||
#endif /* DOXYGEN_SHOULD_SKIP_THIS */
|
#endif /* DOXYGEN_SHOULD_SKIP_THIS */
|
||||||
static GList *widget_list = NULL; /**< this list contains WidgetListElem data elements */
|
static GTree *widget_tree = NULL; /**< this tree contains lists containing WidgetTreeElem data elements */
|
||||||
static gboolean allow_send = FALSE; /**< if FALSE GUI parameter changes won't be sent to device */
|
static gboolean allow_send = FALSE; /**< if FALSE GUI parameter changes won't be sent to device */
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -65,6 +57,169 @@ void show_error_message(GtkWidget *parent, gchar *message)
|
|||||||
gtk_widget_destroy(msg);
|
gtk_widget_destroy(msg);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \param value value to examine
|
||||||
|
* \param values EffectValues to check value against
|
||||||
|
*
|
||||||
|
* Examines whether value fits inside values range for given EffectValues.
|
||||||
|
*
|
||||||
|
* \return TRUE is value fits inside range, otherwise FALSE.
|
||||||
|
**/
|
||||||
|
static gboolean check_value_range(gint value, EffectValues *values)
|
||||||
|
{
|
||||||
|
if (((gint) values->min <= value) && (value <= (gint) values->max))
|
||||||
|
return TRUE;
|
||||||
|
else
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \param spin a GtkSpinButton
|
||||||
|
* \param new_val return value for valid input
|
||||||
|
* \param values signal user data, EffectValues for this parameter
|
||||||
|
*
|
||||||
|
* Custom GtkSpinButton "input" handler for EffectValues with non plain type.
|
||||||
|
*
|
||||||
|
* \return TRUE if new_val was set, otherwise FALSE.
|
||||||
|
**/
|
||||||
|
static gboolean custom_value_input_cb(GtkSpinButton *spin, gdouble *new_val, EffectValues *values)
|
||||||
|
{
|
||||||
|
gchar *text = g_strdup(gtk_entry_get_text(GTK_ENTRY(spin)));
|
||||||
|
gchar *err = NULL;
|
||||||
|
gdouble value;
|
||||||
|
|
||||||
|
for (;;) {
|
||||||
|
if (values->type & VALUE_TYPE_LABEL) {
|
||||||
|
/** search labels for value */
|
||||||
|
gint n;
|
||||||
|
for (n = 0; values->labels[n] != NULL; n++) {
|
||||||
|
if (g_strcmp0(values->labels[n], text) == 0) {
|
||||||
|
/* Value found */
|
||||||
|
*new_val = values->min + (gdouble)n;
|
||||||
|
g_free(text);
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Value not found */
|
||||||
|
if (values->type & VALUE_TYPE_EXTRA) {
|
||||||
|
values = values->extra;
|
||||||
|
continue;
|
||||||
|
} else {
|
||||||
|
g_free(text);
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (values->type & VALUE_TYPE_SUFFIX) {
|
||||||
|
/* remove suffix from entry text */
|
||||||
|
gchar *tmp;
|
||||||
|
|
||||||
|
tmp = strstr(text, values->suffix);
|
||||||
|
if (tmp != NULL) {
|
||||||
|
gchar *temp = g_strndup(text, tmp - text);
|
||||||
|
g_free(text);
|
||||||
|
text = temp;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
g_strstrip(text);
|
||||||
|
|
||||||
|
value = g_strtod(text, &err);
|
||||||
|
if (*err) {
|
||||||
|
if (values->type & VALUE_TYPE_EXTRA) {
|
||||||
|
values = values->extra;
|
||||||
|
continue;
|
||||||
|
} else {
|
||||||
|
g_free(text);
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (values->type & VALUE_TYPE_STEP) {
|
||||||
|
value /= values->step;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (values->type & VALUE_TYPE_OFFSET) {
|
||||||
|
value -= values->offset;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (check_value_range((gint) value, values) == FALSE) {
|
||||||
|
if (values->type & VALUE_TYPE_EXTRA) {
|
||||||
|
values = values->extra;
|
||||||
|
continue;
|
||||||
|
} else {
|
||||||
|
g_free(text);
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
*new_val = value;
|
||||||
|
|
||||||
|
g_free(text);
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \param spin a GtkSpinButton
|
||||||
|
* \param values signal user data, EffectValues for this parameter
|
||||||
|
*
|
||||||
|
* Custom GtkSpinButton "output" handler for EffectValues with non plain type.
|
||||||
|
*
|
||||||
|
* \return TRUE if text was set, otherwise FALSE.
|
||||||
|
**/
|
||||||
|
static gboolean custom_value_output_cb(GtkSpinButton *spin, EffectValues *values)
|
||||||
|
{
|
||||||
|
GtkAdjustment *adj;
|
||||||
|
gchar *text;
|
||||||
|
gdouble value;
|
||||||
|
|
||||||
|
adj = gtk_spin_button_get_adjustment(spin);
|
||||||
|
value = gtk_adjustment_get_value(adj);
|
||||||
|
|
||||||
|
while (check_value_range(value, values) == FALSE) {
|
||||||
|
if (values->type & VALUE_TYPE_EXTRA) {
|
||||||
|
values = values->extra;
|
||||||
|
} else {
|
||||||
|
g_message("custom_value_output_cb called with out of bounds value");
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (values->type & VALUE_TYPE_LABEL) {
|
||||||
|
gtk_entry_set_text(GTK_ENTRY(spin), values->labels[(gint) value - (gint) values->min]);
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (values->type & VALUE_TYPE_OFFSET) {
|
||||||
|
value += (gdouble) values->offset;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (values->type & VALUE_TYPE_STEP) {
|
||||||
|
value *= values->step;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (values->type & VALUE_TYPE_DECIMAL) {
|
||||||
|
text = g_strdup_printf("%.*f", values->decimal, value);
|
||||||
|
} else {
|
||||||
|
text = g_strdup_printf("%d", (gint) value);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (values->type & VALUE_TYPE_SUFFIX) {
|
||||||
|
gchar *tmp;
|
||||||
|
tmp = g_strdup_printf("%s %s", text, values->suffix);
|
||||||
|
g_free(text);
|
||||||
|
text = tmp;
|
||||||
|
}
|
||||||
|
|
||||||
|
gtk_entry_set_text(GTK_ENTRY(spin), text);
|
||||||
|
g_free(text);
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* \param adj the object which emitted the signal
|
* \param adj the object which emitted the signal
|
||||||
* \param setting setting controlled by adj
|
* \param setting setting controlled by adj
|
||||||
@@ -80,20 +235,6 @@ void value_changed_option_cb(GtkAdjustment *adj, EffectSettings *setting)
|
|||||||
g_object_get(G_OBJECT(adj), "value", &val, NULL);
|
g_object_get(G_OBJECT(adj), "value", &val, NULL);
|
||||||
set_option(setting->id, setting->position, (gint)val);
|
set_option(setting->id, setting->position, (gint)val);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (setting->values != NULL && setting->values->labels != NULL) {
|
|
||||||
GtkWidget *label;
|
|
||||||
gint x;
|
|
||||||
gdouble val = -1.0;
|
|
||||||
g_object_get(G_OBJECT(adj), "value", &val, NULL);
|
|
||||||
|
|
||||||
x = (gint)val;
|
|
||||||
|
|
||||||
if ((x >= setting->values->min) && (x <= setting->values->max)) {
|
|
||||||
label = g_object_get_data(G_OBJECT(adj), "label");
|
|
||||||
gtk_label_set_text(GTK_LABEL(label), setting->values->labels[x]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -113,49 +254,79 @@ void toggled_cb(GtkToggleButton *button, Effect *effect)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* \param widget GtkObject to add to widget list
|
* \param widget GtkObject to add to widget tree
|
||||||
* \param id object controlled ID
|
* \param id object controlled ID
|
||||||
* \param position object controlled position
|
* \param position object controlled position
|
||||||
* \param value effect value type (if widget is GtkComboBox, otherwise -1)
|
* \param value effect value type (if widget is GtkComboBox, otherwise -1)
|
||||||
* \param x combo box item number (if widget is GtkComboBox, otherwise -1)
|
* \param x combo box item number (if widget is GtkComboBox, otherwise -1)
|
||||||
*
|
*
|
||||||
* Adds widget to widget list.
|
* Adds widget to widget tree.
|
||||||
**/
|
**/
|
||||||
static void widget_list_add(GtkObject *widget, gint id, gint position, gint value, gint x)
|
static WidgetTreeElem *widget_tree_add(GtkObject *widget, gint id, gint position, gint value, gint x)
|
||||||
{
|
{
|
||||||
WidgetListElem *el;
|
GList *list;
|
||||||
|
WidgetTreeElem *el;
|
||||||
|
gpointer key;
|
||||||
|
|
||||||
el = g_slice_new(WidgetListElem);
|
el = g_slice_new(WidgetTreeElem);
|
||||||
el->widget = widget;
|
el->widget = widget;
|
||||||
el->id = id;
|
|
||||||
el->position = position;
|
|
||||||
el->value = value;
|
el->value = value;
|
||||||
el->x = x;
|
el->x = x;
|
||||||
|
|
||||||
widget_list = g_list_prepend(widget_list, el);
|
key = GINT_TO_POINTER((position << 16) | id);
|
||||||
|
|
||||||
|
list = g_tree_lookup(widget_tree, key);
|
||||||
|
|
||||||
|
if (list == NULL) {
|
||||||
|
list = g_list_append(list, el);
|
||||||
|
g_tree_insert(widget_tree, key, list);
|
||||||
|
} else {
|
||||||
|
list = g_list_append(list, el);
|
||||||
|
|
||||||
|
/* replace the list pointer */
|
||||||
|
g_tree_steal(widget_tree, key);
|
||||||
|
g_tree_insert(widget_tree, key, list);
|
||||||
|
}
|
||||||
|
|
||||||
|
return el;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* \param el widget list element
|
* \param el widget tree element
|
||||||
* \param param parameter to set
|
* \param param parameter to set
|
||||||
*
|
*
|
||||||
* Sets widget list element value to param value.
|
* Sets widget tree element value to param value.
|
||||||
**/
|
**/
|
||||||
static void apply_widget_setting(WidgetListElem *el, SettingParam *param)
|
static void apply_widget_setting(WidgetTreeElem *el, SettingParam *param)
|
||||||
{
|
{
|
||||||
if ((el->id == param->id) && (el->position == param->position)) {
|
if (el->value == -1) {
|
||||||
if (el->value == -1) {
|
if (GTK_IS_TOGGLE_BUTTON(el->widget))
|
||||||
if (GTK_IS_TOGGLE_BUTTON(el->widget))
|
gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(el->widget), (param->value == 0) ? FALSE : TRUE);
|
||||||
gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(el->widget), (param->value == 0) ? FALSE : TRUE);
|
else if (GTK_IS_ADJUSTMENT(el->widget))
|
||||||
else if (GTK_IS_ADJUSTMENT(el->widget))
|
gtk_adjustment_set_value(GTK_ADJUSTMENT(el->widget), (gdouble)param->value);
|
||||||
gtk_adjustment_set_value(GTK_ADJUSTMENT(el->widget), (gdouble)param->value);
|
} else { /* combo box */
|
||||||
} else { /* combo box */
|
if (el->value == param->value)
|
||||||
if (el->value == param->value)
|
gtk_combo_box_set_active(GTK_COMBO_BOX(el->widget), el->x);
|
||||||
gtk_combo_box_set_active(GTK_COMBO_BOX(el->widget), el->x);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \param param SettingParam to apply to GUI
|
||||||
|
*
|
||||||
|
* Applies SettingParam to GUI
|
||||||
|
**/
|
||||||
|
void apply_setting_param_to_gui(SettingParam *param)
|
||||||
|
{
|
||||||
|
gpointer key;
|
||||||
|
g_return_if_fail(param != NULL);
|
||||||
|
|
||||||
|
allow_send = FALSE;
|
||||||
|
key = GINT_TO_POINTER((param->position << 16) | param->id);
|
||||||
|
GList *list = g_tree_lookup(widget_tree, key);
|
||||||
|
g_list_foreach(list, (GFunc)apply_widget_setting, param);
|
||||||
|
allow_send = TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* \param preset preset to sync
|
* \param preset preset to sync
|
||||||
*
|
*
|
||||||
@@ -164,17 +335,22 @@ static void apply_widget_setting(WidgetListElem *el, SettingParam *param)
|
|||||||
static void apply_preset_to_gui(Preset *preset)
|
static void apply_preset_to_gui(Preset *preset)
|
||||||
{
|
{
|
||||||
g_return_if_fail(preset != NULL);
|
g_return_if_fail(preset != NULL);
|
||||||
g_return_if_fail(widget_list != NULL);
|
g_return_if_fail(widget_tree != NULL);
|
||||||
|
|
||||||
allow_send = FALSE;
|
allow_send = FALSE;
|
||||||
|
|
||||||
GList *iter = preset->params;
|
GList *iter = preset->params;
|
||||||
while (iter) {
|
while (iter) {
|
||||||
|
gpointer key;
|
||||||
|
|
||||||
SettingParam *param = iter->data;
|
SettingParam *param = iter->data;
|
||||||
iter = iter->next;
|
iter = iter->next;
|
||||||
|
|
||||||
if (param != NULL)
|
if (param != NULL) {
|
||||||
g_list_foreach(widget_list, (GFunc)apply_widget_setting, param);
|
key = GINT_TO_POINTER((param->position << 16) | param->id);
|
||||||
|
GList *list = g_tree_lookup(widget_tree, key);
|
||||||
|
g_list_foreach(list, (GFunc)apply_widget_setting, param);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
allow_send = TRUE;
|
allow_send = TRUE;
|
||||||
@@ -185,52 +361,73 @@ static void apply_preset_to_gui(Preset *preset)
|
|||||||
**/
|
**/
|
||||||
static void apply_current_preset()
|
static void apply_current_preset()
|
||||||
{
|
{
|
||||||
GString *msg = get_current_preset();
|
GList *list = get_current_preset();
|
||||||
Preset *preset = create_preset_from_data(msg);
|
Preset *preset = create_preset_from_data(list);
|
||||||
g_string_free(msg, TRUE);
|
message_list_free(list);
|
||||||
apply_preset_to_gui(preset);
|
apply_preset_to_gui(preset);
|
||||||
preset_free(preset);
|
preset_free(preset);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
gboolean apply_current_preset_to_gui(gpointer data)
|
||||||
|
{
|
||||||
|
apply_current_preset();
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* \param settings effect parameters
|
* \param settings effect parameters
|
||||||
* \param amt amount of effect parameters
|
* \param amt amount of effect parameters
|
||||||
|
* \param widget_table hash table matching settings pointer with created table (may be NULL)
|
||||||
*
|
*
|
||||||
* Creates knobs that allow user to set effect parameters.
|
* Creates knobs that allow user to set effect parameters.
|
||||||
*
|
*
|
||||||
* \return GtkTable containing necessary widgets to set effect parameters.
|
* \return GtkTable containing necessary widgets to set effect parameters.
|
||||||
**/
|
**/
|
||||||
GtkWidget *create_table(EffectSettings *settings, gint amt)
|
GtkWidget *create_table(EffectSettings *settings, gint amt, GHashTable *widget_table)
|
||||||
{
|
{
|
||||||
GtkWidget *table, *label, *widget, *knob;
|
GtkWidget *table, *label, *widget, *knob;
|
||||||
GtkObject *adj;
|
GtkObject *adj;
|
||||||
int x;
|
int x;
|
||||||
|
|
||||||
|
if (widget_table != NULL) {
|
||||||
|
table = g_hash_table_lookup(widget_table, settings);
|
||||||
|
if (table != NULL)
|
||||||
|
return table;
|
||||||
|
}
|
||||||
|
|
||||||
table = gtk_table_new(3, amt, FALSE);
|
table = gtk_table_new(3, amt, FALSE);
|
||||||
|
|
||||||
for (x = 0; x<amt; x++) {
|
for (x = 0; x<amt; x++) {
|
||||||
|
gdouble min, max;
|
||||||
|
gboolean custom;
|
||||||
|
|
||||||
|
get_values_info(settings[x].values, &min, &max, &custom);
|
||||||
|
|
||||||
label = gtk_label_new(settings[x].label);
|
label = gtk_label_new(settings[x].label);
|
||||||
adj = gtk_adjustment_new(0.0, settings[x].values->min, settings[x].values->max,
|
adj = gtk_adjustment_new(0.0, min, max,
|
||||||
1.0, /* step increment */
|
1.0, /* step increment */
|
||||||
MAX((settings[x].values->max / 100), 5.0), /* page increment */
|
MAX((max / 100), 5.0), /* page increment */
|
||||||
0.0);
|
0.0);
|
||||||
knob = gtk_knob_new(GTK_ADJUSTMENT(adj), knob_anim);
|
knob = gtk_knob_new(GTK_ADJUSTMENT(adj), knob_anim);
|
||||||
|
|
||||||
if (settings[x].values->labels == NULL) {
|
widget = gtk_spin_button_new(GTK_ADJUSTMENT(adj), 1.0, 0);
|
||||||
widget = gtk_spin_button_new(GTK_ADJUSTMENT(adj), 1.0, 0);
|
gtk_spin_button_set_numeric(GTK_SPIN_BUTTON(widget), FALSE);
|
||||||
gtk_spin_button_set_numeric(GTK_SPIN_BUTTON(widget), TRUE);
|
gtk_spin_button_set_update_policy(GTK_SPIN_BUTTON(widget), GTK_UPDATE_IF_VALID);
|
||||||
gtk_spin_button_set_update_policy(GTK_SPIN_BUTTON(widget), GTK_UPDATE_IF_VALID);
|
if (custom == TRUE) {
|
||||||
} else {
|
g_signal_connect(G_OBJECT(widget), "input", G_CALLBACK(custom_value_input_cb), settings[x].values);
|
||||||
widget = gtk_label_new(settings[x].values->labels[0]);
|
g_signal_connect(G_OBJECT(widget), "output", G_CALLBACK(custom_value_output_cb), settings[x].values);
|
||||||
g_object_set_data(G_OBJECT(adj), "label", widget);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
widget_list_add(adj, settings[x].id, settings[x].position, -1, -1);
|
widget_tree_add(adj, settings[x].id, settings[x].position, -1, -1);
|
||||||
gtk_table_attach(GTK_TABLE(table), label, 0, 1, x, x+1, GTK_SHRINK, GTK_SHRINK, 2, 2);
|
gtk_table_attach(GTK_TABLE(table), label, 0, 1, x, x+1, GTK_SHRINK, GTK_SHRINK, 2, 2);
|
||||||
gtk_table_attach(GTK_TABLE(table), knob, 1, 2, x, x+1, GTK_SHRINK, GTK_SHRINK, 2, 2);
|
gtk_table_attach(GTK_TABLE(table), knob, 1, 2, x, x+1, GTK_SHRINK, GTK_SHRINK, 2, 2);
|
||||||
gtk_table_attach(GTK_TABLE(table), widget, 2, 3, x, x+1, GTK_SHRINK, GTK_SHRINK, 2, 2);
|
gtk_table_attach(GTK_TABLE(table), widget, 2, 3, x, x+1, GTK_SHRINK, GTK_SHRINK, 2, 2);
|
||||||
|
|
||||||
g_signal_connect(G_OBJECT(adj), "value-changed", G_CALLBACK(value_changed_option_cb), &settings[x]);
|
g_signal_connect(G_OBJECT(adj), "value-changed", G_CALLBACK(value_changed_option_cb), &settings[x]);
|
||||||
|
|
||||||
|
if (widget_table != NULL) {
|
||||||
|
g_hash_table_insert(widget_table, settings, table);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return table;
|
return table;
|
||||||
@@ -245,10 +442,14 @@ GtkWidget *create_table(EffectSettings *settings, gint amt)
|
|||||||
**/
|
**/
|
||||||
GtkWidget *create_on_off_button(Effect *effect)
|
GtkWidget *create_on_off_button(Effect *effect)
|
||||||
{
|
{
|
||||||
GtkWidget *button = gtk_check_button_new();
|
GtkWidget *button;
|
||||||
|
if (effect->label == NULL)
|
||||||
|
button = gtk_check_button_new();
|
||||||
|
else
|
||||||
|
button = gtk_check_button_new_with_label(effect->label);
|
||||||
gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(button), FALSE);
|
gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(button), FALSE);
|
||||||
g_signal_connect(G_OBJECT(button), "toggled", G_CALLBACK(toggled_cb), effect);
|
g_signal_connect(G_OBJECT(button), "toggled", G_CALLBACK(toggled_cb), effect);
|
||||||
widget_list_add(GTK_OBJECT(button), effect->id, effect->position, -1, -1);
|
widget_tree_add(GTK_OBJECT(button), effect->id, effect->position, -1, -1);
|
||||||
return button;
|
return button;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -303,6 +504,10 @@ void combo_box_changed_cb(GtkComboBox *widget, gpointer data)
|
|||||||
set_option(settings->id, settings->position, settings->type);
|
set_option(settings->id, settings->position, settings->type);
|
||||||
|
|
||||||
child = g_object_get_data(G_OBJECT(widget), "active_child");
|
child = g_object_get_data(G_OBJECT(widget), "active_child");
|
||||||
|
if (child == settings->child) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (child != NULL) {
|
if (child != NULL) {
|
||||||
gtk_container_remove(GTK_CONTAINER(gtk_widget_get_parent(gtk_widget_get_parent(vbox))), child);
|
gtk_container_remove(GTK_CONTAINER(gtk_widget_get_parent(gtk_widget_get_parent(vbox))), child);
|
||||||
}
|
}
|
||||||
@@ -318,16 +523,19 @@ void combo_box_changed_cb(GtkComboBox *widget, gpointer data)
|
|||||||
/**
|
/**
|
||||||
* \param group Effect type groups
|
* \param group Effect type groups
|
||||||
* \param amt amount of effect groups
|
* \param amt amount of effect groups
|
||||||
|
* \param id ID to set effect type
|
||||||
|
* \param position position
|
||||||
*
|
*
|
||||||
* Creates widget allowing user to choose effect type.
|
* Creates widget allowing user to choose effect type.
|
||||||
*
|
*
|
||||||
* \return widget that allow user to set effect type.
|
* \return widget that allow user to set effect type.
|
||||||
**/
|
**/
|
||||||
GtkWidget *create_widget_container(EffectGroup *group, gint amt)
|
GtkWidget *create_widget_container(EffectGroup *group, gint amt, gint id, gint position)
|
||||||
{
|
{
|
||||||
GtkWidget *vbox;
|
GtkWidget *vbox;
|
||||||
GtkWidget *widget;
|
GtkWidget *widget;
|
||||||
GtkWidget *combo_box = NULL;
|
GtkWidget *combo_box = NULL;
|
||||||
|
GHashTable *widget_table;
|
||||||
EffectSettingsGroup *settings = NULL;
|
EffectSettingsGroup *settings = NULL;
|
||||||
gchar *name = NULL;
|
gchar *name = NULL;
|
||||||
gint x;
|
gint x;
|
||||||
@@ -335,6 +543,8 @@ GtkWidget *create_widget_container(EffectGroup *group, gint amt)
|
|||||||
|
|
||||||
vbox = gtk_vbox_new(FALSE, 0);
|
vbox = gtk_vbox_new(FALSE, 0);
|
||||||
|
|
||||||
|
widget_table = g_hash_table_new(g_direct_hash, g_direct_equal);
|
||||||
|
|
||||||
for (x = 0; x<amt; x++) {
|
for (x = 0; x<amt; x++) {
|
||||||
if (group[x].label) {
|
if (group[x].label) {
|
||||||
if (combo_box == NULL) {
|
if (combo_box == NULL) {
|
||||||
@@ -346,29 +556,33 @@ GtkWidget *create_widget_container(EffectGroup *group, gint amt)
|
|||||||
gtk_combo_box_append_text(GTK_COMBO_BOX(combo_box), group[x].label);
|
gtk_combo_box_append_text(GTK_COMBO_BOX(combo_box), group[x].label);
|
||||||
cmbox_no++;
|
cmbox_no++;
|
||||||
|
|
||||||
if ((group[x].settings != NULL) && (group[x].settings > 0)) {
|
if ((group[x].settings != NULL) && (group[x].settings_amt > 0)) {
|
||||||
widget = create_table(group[x].settings, group[x].settings_amt);
|
widget = create_table(group[x].settings, group[x].settings_amt, widget_table);
|
||||||
g_object_ref_sink(widget);
|
g_object_ref_sink(widget);
|
||||||
} else
|
} else
|
||||||
widget = NULL;
|
widget = NULL;
|
||||||
|
|
||||||
settings = g_slice_new(EffectSettingsGroup);
|
settings = g_slice_new(EffectSettingsGroup);
|
||||||
settings->id = group[x].id;
|
settings->id = id;
|
||||||
settings->type = group[x].type;
|
settings->type = group[x].type;
|
||||||
settings->position = group[x].position;
|
settings->position = position;
|
||||||
settings->child = widget;
|
settings->child = widget;
|
||||||
|
|
||||||
widget_list_add(GTK_OBJECT(combo_box), group[x].id, group[x].position, group[x].type, x);
|
widget_tree_add(GTK_OBJECT(combo_box), id, position, group[x].type, x);
|
||||||
|
|
||||||
name = g_strdup_printf("SettingsGroup%d", cmbox_no);
|
name = g_strdup_printf("SettingsGroup%d", cmbox_no);
|
||||||
g_object_set_data_full(G_OBJECT(combo_box), name, settings, ((GDestroyNotify)effect_settings_group_free));
|
g_object_set_data_full(G_OBJECT(combo_box), name, settings, ((GDestroyNotify)effect_settings_group_free));
|
||||||
g_free(name);
|
g_free(name);
|
||||||
} else {
|
} else {
|
||||||
widget = create_table(group[x].settings, group[x].settings_amt);
|
if ((group[x].settings != NULL) && (group[x].settings_amt > 0)) {
|
||||||
gtk_container_add(GTK_CONTAINER(vbox), widget);
|
widget = create_table(group[x].settings, group[x].settings_amt, widget_table);
|
||||||
|
gtk_container_add(GTK_CONTAINER(vbox), widget);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
g_hash_table_destroy(widget_table);
|
||||||
|
|
||||||
return vbox;
|
return vbox;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -389,6 +603,7 @@ GtkWidget *create_vbox(Effect *widgets, gint amt, gchar *label)
|
|||||||
GtkWidget *container;
|
GtkWidget *container;
|
||||||
GtkWidget *frame;
|
GtkWidget *frame;
|
||||||
int x;
|
int x;
|
||||||
|
int y;
|
||||||
|
|
||||||
frame = gtk_frame_new(label);
|
frame = gtk_frame_new(label);
|
||||||
|
|
||||||
@@ -401,13 +616,24 @@ GtkWidget *create_vbox(Effect *widgets, gint amt, gchar *label)
|
|||||||
if ((widgets[x].id != -1) && (widgets[x].position != -1)) {
|
if ((widgets[x].id != -1) && (widgets[x].position != -1)) {
|
||||||
widget = create_on_off_button(&widgets[x]);
|
widget = create_on_off_button(&widgets[x]);
|
||||||
gtk_table_attach_defaults(GTK_TABLE(table), widget, 0, 1, x, x+1);
|
gtk_table_attach_defaults(GTK_TABLE(table), widget, 0, 1, x, x+1);
|
||||||
|
|
||||||
|
if (widgets[x].label)
|
||||||
|
y = 1;
|
||||||
|
else
|
||||||
|
y = 0;
|
||||||
|
|
||||||
} else if (widgets[x].label) {
|
} else if (widgets[x].label) {
|
||||||
widget = gtk_label_new(widgets[x].label);
|
widget = gtk_label_new(widgets[x].label);
|
||||||
gtk_table_attach_defaults(GTK_TABLE(table), widget, 0, 1, x, x+1);
|
gtk_table_attach_defaults(GTK_TABLE(table), widget, 0, 1, x, x+1);
|
||||||
|
y = 0;
|
||||||
|
} else {
|
||||||
|
/* Default to 1 */
|
||||||
|
if (x == 0)
|
||||||
|
y = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
container = create_widget_container(widgets[x].group, widgets[x].group_amt);
|
container = create_widget_container(widgets[x].group, widgets[x].group_amt, widgets[x].type, widgets[x].position);
|
||||||
gtk_table_attach_defaults(GTK_TABLE(table), container, 1, 2, x, x+1);
|
gtk_table_attach_defaults(GTK_TABLE(table), container, 1-y, 2-y, x+y, x+y+1);
|
||||||
}
|
}
|
||||||
gtk_box_pack_start(GTK_BOX(vbox), table, FALSE, FALSE, 2);
|
gtk_box_pack_start(GTK_BOX(vbox), table, FALSE, FALSE, 2);
|
||||||
|
|
||||||
@@ -489,22 +715,32 @@ static void fill_store_with_presets(GtkTreeStore *model, guint bank, gchar *name
|
|||||||
**/
|
**/
|
||||||
static void fill_store(GtkTreeStore *model)
|
static void fill_store(GtkTreeStore *model)
|
||||||
{
|
{
|
||||||
fill_store_with_presets(model, PRESETS_USER, "User Presets");
|
Device *device = g_object_get_data(G_OBJECT(model), "device");
|
||||||
fill_store_with_presets(model, PRESETS_SYSTEM, "System Presets");
|
|
||||||
|
g_return_if_fail(device != NULL);
|
||||||
|
|
||||||
|
gint i;
|
||||||
|
for (i=0; i<device->n_banks; i++)
|
||||||
|
fill_store_with_presets(model,
|
||||||
|
device->banks[i].bank,
|
||||||
|
device->banks[i].name);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
* \param device device information
|
||||||
|
*
|
||||||
* Creates treeview showing list of presets available on device.
|
* Creates treeview showing list of presets available on device.
|
||||||
*
|
*
|
||||||
* \return treeview containing all preset names found on device.
|
* \return treeview containing all preset names found on device.
|
||||||
**/
|
**/
|
||||||
GtkWidget *create_preset_tree()
|
GtkWidget *create_preset_tree(Device *device)
|
||||||
{
|
{
|
||||||
GtkWidget *treeview;
|
GtkWidget *treeview;
|
||||||
GtkTreeStore *store;
|
GtkTreeStore *store;
|
||||||
GtkCellRenderer *renderer;
|
GtkCellRenderer *renderer;
|
||||||
|
|
||||||
store = gtk_tree_store_new(NUM_COLUMNS, G_TYPE_STRING, G_TYPE_INT, G_TYPE_INT);
|
store = gtk_tree_store_new(NUM_COLUMNS, G_TYPE_STRING, G_TYPE_INT, G_TYPE_INT);
|
||||||
|
g_object_set_data(G_OBJECT(store), "device", device);
|
||||||
fill_store(store);
|
fill_store(store);
|
||||||
|
|
||||||
treeview = gtk_tree_view_new_with_model(GTK_TREE_MODEL(store));
|
treeview = gtk_tree_view_new_with_model(GTK_TREE_MODEL(store));
|
||||||
@@ -531,7 +767,7 @@ GtkWidget *create_preset_tree()
|
|||||||
**/
|
**/
|
||||||
static void show_store_preset_window(GtkWidget *window, gchar *default_name)
|
static void show_store_preset_window(GtkWidget *window, gchar *default_name)
|
||||||
{
|
{
|
||||||
GtkWidget *dialog, *cmbox, *entry, *table, *label;
|
GtkWidget *dialog, *cmbox, *entry, *table, *label, *vbox;
|
||||||
GStrv names;
|
GStrv names;
|
||||||
int x;
|
int x;
|
||||||
|
|
||||||
@@ -542,8 +778,10 @@ static void show_store_preset_window(GtkWidget *window, gchar *default_name)
|
|||||||
GTK_STOCK_OK, GTK_RESPONSE_ACCEPT,
|
GTK_STOCK_OK, GTK_RESPONSE_ACCEPT,
|
||||||
NULL);
|
NULL);
|
||||||
|
|
||||||
|
vbox = gtk_dialog_get_content_area(GTK_DIALOG(dialog));
|
||||||
|
|
||||||
table = gtk_table_new(2, 2, FALSE);
|
table = gtk_table_new(2, 2, FALSE);
|
||||||
gtk_container_add(GTK_CONTAINER(GTK_DIALOG(dialog)->vbox), table);
|
gtk_container_add(GTK_CONTAINER(vbox), table);
|
||||||
|
|
||||||
cmbox = gtk_combo_box_new_text();
|
cmbox = gtk_combo_box_new_text();
|
||||||
names = query_preset_names(PRESETS_USER);
|
names = query_preset_names(PRESETS_USER);
|
||||||
@@ -566,7 +804,7 @@ static void show_store_preset_window(GtkWidget *window, gchar *default_name)
|
|||||||
label = gtk_label_new("Preset name:");
|
label = gtk_label_new("Preset name:");
|
||||||
gtk_table_attach_defaults(GTK_TABLE(table), label, 0, 1, 1, 2);
|
gtk_table_attach_defaults(GTK_TABLE(table), label, 0, 1, 1, 2);
|
||||||
|
|
||||||
gtk_widget_show_all(GTK_DIALOG(dialog)->vbox);
|
gtk_widget_show_all(vbox);
|
||||||
if (gtk_dialog_run(GTK_DIALOG(dialog)) == GTK_RESPONSE_ACCEPT) {
|
if (gtk_dialog_run(GTK_DIALOG(dialog)) == GTK_RESPONSE_ACCEPT) {
|
||||||
gint number = gtk_combo_box_get_active(GTK_COMBO_BOX(cmbox));
|
gint number = gtk_combo_box_get_active(GTK_COMBO_BOX(cmbox));
|
||||||
if (number != -1) {
|
if (number != -1) {
|
||||||
@@ -620,6 +858,12 @@ typedef struct {
|
|||||||
|
|
||||||
static SupportedFileTypes file_types[] = {
|
static SupportedFileTypes file_types[] = {
|
||||||
{"RP250Preset", "*.rp250p"},
|
{"RP250Preset", "*.rp250p"},
|
||||||
|
{"RP255Preset", "*.rp255p"},
|
||||||
|
{"RP355Preset", "*.rp355p"},
|
||||||
|
{"RP500Preset", "*.rp500p"},
|
||||||
|
{"RP1000Preset", "*.rp1000p"},
|
||||||
|
{"GNX4 Preset", "*.g4p"},
|
||||||
|
{"GNX3kPreset", "*.g3kp"},
|
||||||
};
|
};
|
||||||
|
|
||||||
static guint n_file_types = G_N_ELEMENTS(file_types);
|
static guint n_file_types = G_N_ELEMENTS(file_types);
|
||||||
@@ -677,41 +921,77 @@ static void action_open_preset_cb(GtkAction *action)
|
|||||||
|
|
||||||
gtk_widget_hide(dialog);
|
gtk_widget_hide(dialog);
|
||||||
|
|
||||||
GString *msg = g_string_sized_new(500);
|
|
||||||
GList *iter = preset->params;
|
|
||||||
gint len = g_list_length(iter);
|
|
||||||
|
|
||||||
g_string_append_printf(msg, "%c%c",
|
|
||||||
((len & 0xFF00) >> 8),
|
|
||||||
(len & 0xFF));
|
|
||||||
|
|
||||||
while (iter) {
|
|
||||||
SettingParam *param = iter->data;
|
|
||||||
iter = iter->next;
|
|
||||||
|
|
||||||
g_string_append_printf(msg, "%c%c%c",
|
|
||||||
((param->id & 0xFF00) >> 8),
|
|
||||||
(param->id & 0xFF),
|
|
||||||
param->position);
|
|
||||||
|
|
||||||
append_value(msg, param->value);
|
|
||||||
};
|
|
||||||
|
|
||||||
GString *start = g_string_new(NULL);
|
GString *start = g_string_new(NULL);
|
||||||
g_string_append_printf(start,
|
g_string_append_printf(start,
|
||||||
"%c%c%s%c%c%c",
|
"%c%c%s%c%c%c",
|
||||||
PRESETS_EDIT_BUFFER, 0,
|
PRESETS_EDIT_BUFFER, 0,
|
||||||
preset->name, 0 /* NULL terminated string */,
|
preset->name, 0 /* NULL terminated string */,
|
||||||
0 /* modified */, 2 /* messages to follow */);
|
0 /* modified */,
|
||||||
|
/* messages to follow */
|
||||||
|
preset->genetxs ? 10 : 2);
|
||||||
|
|
||||||
send_message(RECEIVE_PRESET_START, start->str, start->len);
|
send_message(RECEIVE_PRESET_START, start->str, start->len);
|
||||||
send_message(RECEIVE_PRESET_PARAMETERS, msg->str, msg->len);
|
send_preset_parameters(preset->params);
|
||||||
|
if (preset->genetxs != NULL) {
|
||||||
|
gint i;
|
||||||
|
|
||||||
|
/* GNX4 sends messages in following order:
|
||||||
|
* Section Bank Index
|
||||||
|
* 0x00 0x04 0x0000
|
||||||
|
* 0x00 0x04 0x0001
|
||||||
|
* 0x01 0x04 0x0000
|
||||||
|
* 0x01 0x04 0x0001
|
||||||
|
* 0x00 0x04 0x0002
|
||||||
|
* 0x00 0x04 0x0003
|
||||||
|
* 0x01 0x04 0x0002
|
||||||
|
* 0x01 0x04 0x0003
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* GNX3000 sends messages in following order:
|
||||||
|
* Section Bank Index
|
||||||
|
* 0x07 0x04 0x0000
|
||||||
|
* 0x07 0x04 0x0001
|
||||||
|
* 0x08 0x04 0x0000
|
||||||
|
* 0x08 0x04 0x0001
|
||||||
|
* 0x07 0x04 0x0002
|
||||||
|
* 0x07 0x04 0x0003
|
||||||
|
* 0x08 0x04 0x0002
|
||||||
|
* 0x08 0x04 0x0003
|
||||||
|
*/
|
||||||
|
for (i = 0; i < 2; i++) {
|
||||||
|
GList *iter = preset->genetxs;
|
||||||
|
|
||||||
|
while (iter) {
|
||||||
|
SectionID section;
|
||||||
|
guint bank, index;
|
||||||
|
|
||||||
|
SettingGenetx *genetx = (SettingGenetx *) iter->data;
|
||||||
|
iter = iter->next;
|
||||||
|
|
||||||
|
section = get_genetx_section_id(genetx->version,
|
||||||
|
genetx->type);
|
||||||
|
bank = 0x04;
|
||||||
|
|
||||||
|
if (i == 0) {
|
||||||
|
index = genetx->channel;
|
||||||
|
} else {
|
||||||
|
if (genetx->channel == GENETX_CHANNEL1) {
|
||||||
|
index = GENETX_CHANNEL1_CUSTOM;
|
||||||
|
} else if (genetx->channel == GENETX_CHANNEL2) {
|
||||||
|
index = GENETX_CHANNEL2_CUSTOM;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
send_object(section, bank, index,
|
||||||
|
genetx->name, genetx->data);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
send_message(RECEIVE_PRESET_END, NULL, 0);
|
send_message(RECEIVE_PRESET_END, NULL, 0);
|
||||||
|
|
||||||
show_store_preset_window(window, preset->name);
|
show_store_preset_window(window, preset->name);
|
||||||
|
|
||||||
g_string_free(start, TRUE);
|
g_string_free(start, TRUE);
|
||||||
g_string_free(msg, TRUE);
|
|
||||||
preset_free(preset);
|
preset_free(preset);
|
||||||
loaded = TRUE;
|
loaded = TRUE;
|
||||||
}
|
}
|
||||||
@@ -723,15 +1003,15 @@ static void action_open_preset_cb(GtkAction *action)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* \param list widget list to be freed
|
* \param list widget tree list to be freed
|
||||||
*
|
*
|
||||||
* Frees all memory used by widget list.
|
* Frees all memory used by widget tree list.
|
||||||
*/
|
*/
|
||||||
static void widget_list_free(GList *list)
|
static void widget_tree_elem_free(GList *list)
|
||||||
{
|
{
|
||||||
GList *iter;
|
GList *iter;
|
||||||
for (iter = list; iter; iter = iter->next) {
|
for (iter = list; iter; iter = iter->next) {
|
||||||
g_slice_free(WidgetListElem, iter->data);
|
g_slice_free(WidgetTreeElem, iter->data);
|
||||||
}
|
}
|
||||||
g_list_free(list);
|
g_list_free(list);
|
||||||
}
|
}
|
||||||
@@ -835,17 +1115,34 @@ static void add_menubar(GtkWidget *window, GtkWidget *vbox)
|
|||||||
g_object_unref(ui);
|
g_object_unref(ui);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static gint widget_tree_key_compare_func(gconstpointer a, gconstpointer b, gpointer data)
|
||||||
|
{
|
||||||
|
gint position_a = GPOINTER_TO_INT(a) & 0xFF0000;
|
||||||
|
gint position_b = GPOINTER_TO_INT(b) & 0xFF0000;
|
||||||
|
|
||||||
|
if (position_a > position_b) {
|
||||||
|
return 1;
|
||||||
|
} else if (position_a == position_b) {
|
||||||
|
gint val_a = GPOINTER_TO_INT(a) & 0xFFFF;
|
||||||
|
gint val_b = GPOINTER_TO_INT(b) & 0xFFFF;
|
||||||
|
return val_a - val_b;
|
||||||
|
} else
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates main window.
|
* Creates main window.
|
||||||
**/
|
**/
|
||||||
void gui_create()
|
void gui_create(Device *device)
|
||||||
{
|
{
|
||||||
GtkWidget *window;
|
GtkWidget *window;
|
||||||
GtkWidget *vbox;
|
GtkWidget *vbox;
|
||||||
GtkWidget *hbox;
|
GtkWidget *hbox;
|
||||||
GtkWidget *widget;
|
GtkWidget *widget;
|
||||||
|
GtkWidget *notebook;
|
||||||
GtkWidget *sw; /* scrolled window to carry preset treeview */
|
GtkWidget *sw; /* scrolled window to carry preset treeview */
|
||||||
gint x;
|
gint x;
|
||||||
|
gint i;
|
||||||
|
|
||||||
window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
|
window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
|
||||||
gtk_window_set_title(GTK_WINDOW(window), "gdigi");
|
gtk_window_set_title(GTK_WINDOW(window), "gdigi");
|
||||||
@@ -862,21 +1159,36 @@ void gui_create()
|
|||||||
gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(sw), GTK_POLICY_NEVER, GTK_POLICY_AUTOMATIC);
|
gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(sw), GTK_POLICY_NEVER, GTK_POLICY_AUTOMATIC);
|
||||||
gtk_box_pack_start(GTK_BOX(hbox), sw, FALSE, FALSE, 0);
|
gtk_box_pack_start(GTK_BOX(hbox), sw, FALSE, FALSE, 0);
|
||||||
|
|
||||||
widget = create_preset_tree();
|
widget = create_preset_tree(device);
|
||||||
gtk_container_add(GTK_CONTAINER(sw), widget);
|
gtk_container_add(GTK_CONTAINER(sw), widget);
|
||||||
|
|
||||||
vbox = gtk_vbox_new(FALSE, 0);
|
notebook = gtk_notebook_new();
|
||||||
gtk_box_pack_start(GTK_BOX(hbox), vbox, TRUE, TRUE, 2);
|
gtk_box_pack_start(GTK_BOX(hbox), notebook, TRUE, TRUE, 2);
|
||||||
|
|
||||||
knob_anim = gtk_knob_animation_new_from_inline(knob_pixbuf);
|
knob_anim = gtk_knob_animation_new_from_inline(knob_pixbuf);
|
||||||
|
|
||||||
for (x = 0; x<n_effects; x++) {
|
widget_tree = g_tree_new_full(widget_tree_key_compare_func,
|
||||||
if ((x % ((n_effects+1)/2)) == 0) {
|
NULL, /* key compare data */
|
||||||
hbox = gtk_hbox_new(FALSE, 0);
|
NULL, /* key destroy func */
|
||||||
gtk_box_pack_start(GTK_BOX(vbox), hbox, TRUE, TRUE, 2);
|
(GDestroyNotify) widget_tree_elem_free);
|
||||||
|
|
||||||
|
gtk_notebook_set_show_tabs(GTK_NOTEBOOK(notebook), device->n_pages > 1 ? TRUE : FALSE);
|
||||||
|
|
||||||
|
for (i = 0; i<device->n_pages; i++) {
|
||||||
|
GtkWidget *label = NULL;
|
||||||
|
vbox = gtk_vbox_new(FALSE, 0);
|
||||||
|
label = gtk_label_new(device->pages[i].name);
|
||||||
|
|
||||||
|
gtk_notebook_append_page(GTK_NOTEBOOK(notebook), vbox, label);
|
||||||
|
|
||||||
|
for (x = 0; x<device->pages[i].n_effects; x++) {
|
||||||
|
if ((x % ((device->pages[i].n_effects+1)/device->pages[i].n_rows)) == 0) {
|
||||||
|
hbox = gtk_hbox_new(FALSE, 0);
|
||||||
|
gtk_box_pack_start(GTK_BOX(vbox), hbox, TRUE, TRUE, 2);
|
||||||
|
}
|
||||||
|
widget = create_vbox(device->pages[i].effects[x].effect, device->pages[i].effects[x].amt, device->pages[i].effects[x].label);
|
||||||
|
gtk_box_pack_start(GTK_BOX(hbox), widget, TRUE, TRUE, 2);
|
||||||
}
|
}
|
||||||
widget = create_vbox(effects[x].effect, effects[x].amt, effects[x].label);
|
|
||||||
gtk_box_pack_start(GTK_BOX(hbox), widget, TRUE, TRUE, 2);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
apply_current_preset();
|
apply_current_preset();
|
||||||
@@ -890,9 +1202,63 @@ void gui_create()
|
|||||||
**/
|
**/
|
||||||
void gui_free()
|
void gui_free()
|
||||||
{
|
{
|
||||||
widget_list_free(widget_list);
|
g_tree_destroy(widget_tree);
|
||||||
widget_list = NULL;
|
widget_tree = NULL;
|
||||||
|
|
||||||
gtk_knob_animation_free(knob_anim);
|
gtk_knob_animation_free(knob_anim);
|
||||||
knob_anim = NULL;
|
knob_anim = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \param device Variable to hold device information
|
||||||
|
*
|
||||||
|
* Displays dialogbox stating that device is unsupported.
|
||||||
|
*
|
||||||
|
* \return TRUE if user selects "compability mode", otherwise FALSE.
|
||||||
|
**/
|
||||||
|
gboolean unsupported_device_dialog(Device **device)
|
||||||
|
{
|
||||||
|
extern Device* supported_devices[];
|
||||||
|
extern int n_supported_devices;
|
||||||
|
|
||||||
|
GtkWidget *dialog;
|
||||||
|
GtkWidget *label;
|
||||||
|
GtkWidget *combo_box;
|
||||||
|
GtkWidget *vbox;
|
||||||
|
int x;
|
||||||
|
|
||||||
|
dialog = gtk_dialog_new_with_buttons("Unsupported device",
|
||||||
|
NULL, GTK_DIALOG_MODAL,
|
||||||
|
GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
|
||||||
|
GTK_STOCK_OK, GTK_RESPONSE_ACCEPT,
|
||||||
|
NULL);
|
||||||
|
|
||||||
|
vbox = gtk_dialog_get_content_area(GTK_DIALOG(dialog));
|
||||||
|
|
||||||
|
label = gtk_label_new("Your device appears to be unsupported by gdigi.\n"
|
||||||
|
"As some of the settings may be common between different devices,\n"
|
||||||
|
"you can now select compability mode with one of the supported devices.\n"
|
||||||
|
"Please take a look at gdigi's HACKING file.");
|
||||||
|
gtk_container_add(GTK_CONTAINER(vbox), label);
|
||||||
|
|
||||||
|
combo_box = gtk_combo_box_new_text();
|
||||||
|
for (x=0; x<n_supported_devices; x++) {
|
||||||
|
gtk_combo_box_append_text(GTK_COMBO_BOX(combo_box), supported_devices[x]->name);
|
||||||
|
}
|
||||||
|
|
||||||
|
gtk_container_add(GTK_CONTAINER(vbox), combo_box);
|
||||||
|
|
||||||
|
gtk_widget_show_all(vbox);
|
||||||
|
if (gtk_dialog_run(GTK_DIALOG(dialog)) == GTK_RESPONSE_ACCEPT) {
|
||||||
|
gint number = gtk_combo_box_get_active(GTK_COMBO_BOX(combo_box));
|
||||||
|
if (number != -1 && number <n_supported_devices) {
|
||||||
|
g_message("Starting %s compability mode", supported_devices[number]->name);
|
||||||
|
*device = supported_devices[number];
|
||||||
|
gtk_widget_destroy(dialog);
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
gtk_widget_destroy(dialog);
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|||||||
8
gui.h
8
gui.h
@@ -17,8 +17,14 @@
|
|||||||
#ifndef GDIGI_GUI_H
|
#ifndef GDIGI_GUI_H
|
||||||
#define GDIGI_GUI_H
|
#define GDIGI_GUI_H
|
||||||
|
|
||||||
|
#include <glib.h>
|
||||||
|
#include "effects.h"
|
||||||
|
|
||||||
void show_error_message(GtkWidget *parent, gchar *message);
|
void show_error_message(GtkWidget *parent, gchar *message);
|
||||||
void gui_create();
|
void apply_setting_param_to_gui(SettingParam *param);
|
||||||
|
gboolean apply_current_preset_to_gui(gpointer data);
|
||||||
|
void gui_create(Device *device);
|
||||||
void gui_free();
|
void gui_free();
|
||||||
|
gboolean unsupported_device_dialog(Device **device);
|
||||||
|
|
||||||
#endif /* GDIGI_GUI_H */
|
#endif /* GDIGI_GUI_H */
|
||||||
|
|||||||
244
preset.c
244
preset.c
@@ -18,6 +18,7 @@
|
|||||||
#include <expat.h>
|
#include <expat.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include "preset.h"
|
#include "preset.h"
|
||||||
|
#include "gdigi.h"
|
||||||
|
|
||||||
#ifndef DOXYGEN_SHOULD_SKIP_THIS
|
#ifndef DOXYGEN_SHOULD_SKIP_THIS
|
||||||
|
|
||||||
@@ -28,12 +29,24 @@ enum {
|
|||||||
PARSER_TYPE_PARAM_POSITION,
|
PARSER_TYPE_PARAM_POSITION,
|
||||||
PARSER_TYPE_PARAM_VALUE,
|
PARSER_TYPE_PARAM_VALUE,
|
||||||
PARSER_TYPE_PARAM_NAME,
|
PARSER_TYPE_PARAM_NAME,
|
||||||
PARSER_TYPE_PARAM_TEXT
|
PARSER_TYPE_PARAM_TEXT,
|
||||||
|
PARSER_TYPE_GENETX_VERSION,
|
||||||
|
PARSER_TYPE_GENETX_TYPE,
|
||||||
|
PARSER_TYPE_GENETX_CHANNEL,
|
||||||
|
PARSER_TYPE_GENETX_NAME,
|
||||||
|
PARSER_TYPE_GENETX_DATA
|
||||||
|
};
|
||||||
|
|
||||||
|
enum {
|
||||||
|
SECTION_NOT_SET = -1,
|
||||||
|
SECTION_PARAMS,
|
||||||
|
SECTION_GENETX
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
int depth;
|
int depth;
|
||||||
int id;
|
int id;
|
||||||
|
int section;
|
||||||
Preset *preset;
|
Preset *preset;
|
||||||
} AppData;
|
} AppData;
|
||||||
|
|
||||||
@@ -45,18 +58,20 @@ static void XMLCALL start(void *data, const char *el, const char **attr) {
|
|||||||
if (ad->depth == 1) {
|
if (ad->depth == 1) {
|
||||||
ad->id = PARSER_TYPE_PRESET_NAME;
|
ad->id = PARSER_TYPE_PRESET_NAME;
|
||||||
} else if (ad->depth == 3) {
|
} else if (ad->depth == 3) {
|
||||||
ad->id = PARSER_TYPE_PARAM_NAME;
|
if (ad->section == SECTION_PARAMS) {
|
||||||
|
ad->id = PARSER_TYPE_PARAM_NAME;
|
||||||
|
} else if (ad->section == SECTION_GENETX) {
|
||||||
|
ad->id = PARSER_TYPE_GENETX_NAME;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (g_strcmp0(el, "Params") == 0) {
|
if (g_strcmp0(el, "Params") == 0) {
|
||||||
|
ad->section = SECTION_PARAMS;
|
||||||
if (ad->preset->params != NULL)
|
if (ad->preset->params != NULL)
|
||||||
g_message("Params aleady exists!");
|
g_message("Params aleady exists!");
|
||||||
} else if (g_strcmp0(el, "Param") == 0) {
|
} else if (g_strcmp0(el, "Param") == 0) {
|
||||||
SettingParam *param = g_slice_new(SettingParam);
|
SettingParam *param = setting_param_new();
|
||||||
param->id = -1;
|
|
||||||
param->position = -1;
|
|
||||||
param->value = -1;
|
|
||||||
ad->preset->params = g_list_prepend(ad->preset->params, param);
|
ad->preset->params = g_list_prepend(ad->preset->params, param);
|
||||||
} else if (g_strcmp0(el, "ID") == 0) {
|
} else if (g_strcmp0(el, "ID") == 0) {
|
||||||
ad->id = PARSER_TYPE_PARAM_ID;
|
ad->id = PARSER_TYPE_PARAM_ID;
|
||||||
@@ -66,6 +81,21 @@ static void XMLCALL start(void *data, const char *el, const char **attr) {
|
|||||||
ad->id = PARSER_TYPE_PARAM_VALUE;
|
ad->id = PARSER_TYPE_PARAM_VALUE;
|
||||||
} else if (g_strcmp0(el, "Text") == 0) {
|
} else if (g_strcmp0(el, "Text") == 0) {
|
||||||
ad->id = PARSER_TYPE_PARAM_TEXT;
|
ad->id = PARSER_TYPE_PARAM_TEXT;
|
||||||
|
} else if (g_strcmp0(el, "Genetx") == 0) {
|
||||||
|
ad->section = SECTION_GENETX;
|
||||||
|
if (ad->preset->genetxs != NULL)
|
||||||
|
g_message("Genetx already exists!");
|
||||||
|
} else if (g_strcmp0(el, "GenetxModel") == 0) {
|
||||||
|
SettingGenetx *genetx = setting_genetx_new();
|
||||||
|
ad->preset->genetxs = g_list_prepend(ad->preset->genetxs, genetx);
|
||||||
|
} else if (g_strcmp0(el, "Version") == 0) {
|
||||||
|
ad->id = PARSER_TYPE_GENETX_VERSION;
|
||||||
|
} else if (g_strcmp0(el, "Type") == 0) {
|
||||||
|
ad->id = PARSER_TYPE_GENETX_TYPE;
|
||||||
|
} else if (g_strcmp0(el, "Channel") == 0) {
|
||||||
|
ad->id = PARSER_TYPE_GENETX_CHANNEL;
|
||||||
|
} else if (g_strcmp0(el, "Data") == 0) {
|
||||||
|
ad->id = PARSER_TYPE_GENETX_DATA;
|
||||||
}
|
}
|
||||||
|
|
||||||
ad->depth++;
|
ad->depth++;
|
||||||
@@ -90,28 +120,87 @@ static void XMLCALL text_cb(void *data, const char* text, int len)
|
|||||||
ad->preset->name = g_strndup(text, len);
|
ad->preset->name = g_strndup(text, len);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ad->preset->params == NULL)
|
if (ad->section == SECTION_PARAMS) {
|
||||||
return;
|
if (ad->preset->params == NULL)
|
||||||
|
return;
|
||||||
|
|
||||||
SettingParam *param = (SettingParam *) ad->preset->params->data;
|
SettingParam *param = (SettingParam *) ad->preset->params->data;
|
||||||
if (param == NULL)
|
if (param == NULL)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
gchar *value = g_strndup(text, len);
|
gchar *value = g_strndup(text, len);
|
||||||
|
|
||||||
switch (ad->id) {
|
switch (ad->id) {
|
||||||
case PARSER_TYPE_PARAM_ID:
|
case PARSER_TYPE_PARAM_ID:
|
||||||
param->id = atoi(value);
|
param->id = atoi(value);
|
||||||
break;
|
break;
|
||||||
case PARSER_TYPE_PARAM_POSITION:
|
case PARSER_TYPE_PARAM_POSITION:
|
||||||
param->position = atoi(value);
|
param->position = atoi(value);
|
||||||
break;
|
break;
|
||||||
case PARSER_TYPE_PARAM_VALUE:
|
case PARSER_TYPE_PARAM_VALUE:
|
||||||
param->value = atoi(value);
|
param->value = atoi(value);
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
g_free(value);
|
||||||
|
} else if (ad->section == SECTION_GENETX) {
|
||||||
|
if (ad->preset->genetxs == NULL)
|
||||||
|
return;
|
||||||
|
|
||||||
|
SettingGenetx *genetx = (SettingGenetx *) ad->preset->genetxs->data;
|
||||||
|
if (genetx == NULL)
|
||||||
|
return;
|
||||||
|
|
||||||
|
gchar *value = g_strndup(text, len);
|
||||||
|
|
||||||
|
switch (ad->id) {
|
||||||
|
case PARSER_TYPE_GENETX_VERSION:
|
||||||
|
if (g_strcmp0(value, "Version1") == 0) {
|
||||||
|
genetx->version = GENETX_VERSION_1;
|
||||||
|
} else if (g_strcmp0(value, "Version2") == 0) {
|
||||||
|
genetx->version = GENETX_VERSION_2;
|
||||||
|
} else {
|
||||||
|
g_message("Unknown GeNetX version: %s", value);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case PARSER_TYPE_GENETX_TYPE:
|
||||||
|
if (g_strcmp0(value, "Amp") == 0) {
|
||||||
|
genetx->type = GENETX_TYPE_AMP;
|
||||||
|
} else if (g_strcmp0(value, "Cabinet") == 0) {
|
||||||
|
genetx->type = GENETX_TYPE_CABINET;
|
||||||
|
} else {
|
||||||
|
g_message("Unknown GeNetX type: %s", value);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case PARSER_TYPE_GENETX_CHANNEL:
|
||||||
|
if (g_strcmp0(value, "Channel1") == 0) {
|
||||||
|
genetx->channel = GENETX_CHANNEL1;
|
||||||
|
} else if (g_strcmp0(value, "Channel2") == 0) {
|
||||||
|
genetx->channel = GENETX_CHANNEL2;
|
||||||
|
} else {
|
||||||
|
g_message("Unknown GeNetX channel: %s", value);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case PARSER_TYPE_GENETX_NAME:
|
||||||
|
/* reassign pointer */
|
||||||
|
genetx->name = value;
|
||||||
|
value = NULL;
|
||||||
|
break;
|
||||||
|
case PARSER_TYPE_GENETX_DATA:
|
||||||
|
{
|
||||||
|
guchar *data = NULL;
|
||||||
|
gsize length = 0;
|
||||||
|
|
||||||
|
data = g_base64_decode(value, &length);
|
||||||
|
genetx->data = g_string_new_len((gchar *) data, length);
|
||||||
|
|
||||||
|
g_free(data);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
g_free(value);
|
||||||
}
|
}
|
||||||
|
|
||||||
g_free(value);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif /* DOXYGEN_SHOULD_SKIP_THIS */
|
#endif /* DOXYGEN_SHOULD_SKIP_THIS */
|
||||||
@@ -126,16 +215,13 @@ static void XMLCALL text_cb(void *data, const char* text, int len)
|
|||||||
**/
|
**/
|
||||||
Preset *create_preset_from_xml_file(gchar *filename, GError **error)
|
Preset *create_preset_from_xml_file(gchar *filename, GError **error)
|
||||||
{
|
{
|
||||||
GFile *file;
|
|
||||||
GError *err = NULL;
|
GError *err = NULL;
|
||||||
gchar *contents;
|
gchar *contents;
|
||||||
|
|
||||||
file = g_file_new_for_path(filename);
|
|
||||||
if (g_file_get_contents(filename, &contents, NULL, &err) == FALSE) {
|
if (g_file_get_contents(filename, &contents, NULL, &err) == FALSE) {
|
||||||
g_message("Failed to get %s contents: %s", filename, err->message);
|
g_message("Failed to get %s contents: %s", filename, err->message);
|
||||||
*error = g_error_copy(err);
|
*error = g_error_copy(err);
|
||||||
g_error_free(err);
|
g_error_free(err);
|
||||||
g_object_unref(file);
|
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -144,6 +230,7 @@ Preset *create_preset_from_xml_file(gchar *filename, GError **error)
|
|||||||
ad->preset = g_slice_new(Preset);
|
ad->preset = g_slice_new(Preset);
|
||||||
ad->preset->name = NULL;
|
ad->preset->name = NULL;
|
||||||
ad->preset->params = NULL;
|
ad->preset->params = NULL;
|
||||||
|
ad->preset->genetxs = NULL;
|
||||||
ad->id = PARSER_TYPE_NOT_SET;
|
ad->id = PARSER_TYPE_NOT_SET;
|
||||||
|
|
||||||
XML_Parser p;
|
XML_Parser p;
|
||||||
@@ -159,72 +246,82 @@ Preset *create_preset_from_xml_file(gchar *filename, GError **error)
|
|||||||
preset_free(ad->preset);
|
preset_free(ad->preset);
|
||||||
g_slice_free(AppData, ad);
|
g_slice_free(AppData, ad);
|
||||||
g_free(contents);
|
g_free(contents);
|
||||||
g_object_unref(file);
|
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
Preset *preset = ad->preset;
|
Preset *preset = ad->preset;
|
||||||
preset->params = g_list_reverse(preset->params);
|
preset->params = g_list_reverse(preset->params);
|
||||||
|
preset->genetxs = g_list_reverse(preset->genetxs);
|
||||||
|
|
||||||
XML_ParserFree(p);
|
XML_ParserFree(p);
|
||||||
g_slice_free(AppData, ad);
|
g_slice_free(AppData, ad);
|
||||||
|
|
||||||
g_free(contents);
|
g_free(contents);
|
||||||
g_object_unref(file);
|
|
||||||
return preset;
|
return preset;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* \param data unpacked RECEIVE_PRESET_PARAMETERS message
|
* \param list list containing unpacked preset SysEx messages.
|
||||||
*
|
*
|
||||||
* Parses message
|
* Parses message
|
||||||
*
|
*
|
||||||
* \return Preset which must be freed using preset_free, or NULL on error.
|
* \return Preset which must be freed using preset_free, or NULL on error.
|
||||||
**/
|
**/
|
||||||
Preset *create_preset_from_data(GString *data)
|
Preset *create_preset_from_data(GList *list)
|
||||||
{
|
{
|
||||||
gint total;
|
GString *data;
|
||||||
gint n;
|
GList *iter;
|
||||||
gint id;
|
gint total, n, x;
|
||||||
gint position;
|
gint bank, number, modified;
|
||||||
guint value;
|
gchar *name;
|
||||||
gint x;
|
|
||||||
gint tmp;
|
|
||||||
|
|
||||||
x = 0x09;
|
g_return_val_if_fail(list != NULL, NULL);
|
||||||
n = 0;
|
|
||||||
total = (unsigned char)data->str[x];
|
|
||||||
x++;
|
|
||||||
|
|
||||||
Preset *preset = g_slice_new(Preset);
|
Preset *preset = g_slice_new(Preset);
|
||||||
preset->name = NULL; /* TODO */
|
preset->name = NULL;
|
||||||
preset->params = NULL;
|
preset->params = NULL;
|
||||||
|
preset->genetxs = NULL;
|
||||||
|
|
||||||
do {
|
iter = list;
|
||||||
id = ((unsigned char)data->str[x] << 8) | (unsigned char)data->str[x+1];
|
for (iter = list; iter; iter = g_list_next(iter)) {
|
||||||
position = (unsigned char)data->str[x+2];
|
data = (GString*) iter->data;
|
||||||
x+=3;
|
switch (get_message_id(data)) {
|
||||||
value = data->str[x];
|
case RECEIVE_PRESET_START:
|
||||||
x++;
|
bank = (unsigned char)data->str[8];
|
||||||
if (value > 0x80) {
|
number = (unsigned char)data->str[9];
|
||||||
tmp = value & 0x7F;
|
name = g_strdup(&data->str[10]);
|
||||||
value = 0;
|
modified = (unsigned char)data->str[11+strlen(name)];
|
||||||
gint i;
|
|
||||||
for (i=0; i<tmp; i++) {
|
if ((bank == PRESETS_EDIT_BUFFER) && (number == 0)) {
|
||||||
value |= ((unsigned char)data->str[x+i] << (8*(tmp-i-1)));
|
g_message("Received current edit buffer");
|
||||||
}
|
} else {
|
||||||
x+=tmp;
|
g_message("Received preset %d from bank %d", number, bank);
|
||||||
|
}
|
||||||
|
|
||||||
|
g_message("Modified flag: %d Name: %s", modified, name);
|
||||||
|
preset->name = name;
|
||||||
|
break;
|
||||||
|
case RECEIVE_PRESET_PARAMETERS:
|
||||||
|
x = 0x09;
|
||||||
|
n = 0;
|
||||||
|
total = (unsigned char)data->str[x];
|
||||||
|
x++;
|
||||||
|
|
||||||
|
do {
|
||||||
|
SettingParam *param = setting_param_new_from_data(&data->str[x], &x);
|
||||||
|
n++;
|
||||||
|
preset->params = g_list_prepend(preset->params, param);
|
||||||
|
g_message("%d ID %d Position %d Value %d", n, param->id, param->position, param->value);
|
||||||
|
} while ((x < data->len) && n<total);
|
||||||
|
g_message("TOTAL %d", total);
|
||||||
|
preset->params = g_list_reverse(preset->params);
|
||||||
|
break;
|
||||||
|
case RECEIVE_PRESET_END:
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
g_message("Unhandled message in preset messages list");
|
||||||
}
|
}
|
||||||
n++;
|
}
|
||||||
SettingParam *param = g_slice_new(SettingParam);
|
|
||||||
param->id = id;
|
|
||||||
param->position = position;
|
|
||||||
param->value = value;
|
|
||||||
preset->params = g_list_prepend(preset->params, param);
|
|
||||||
g_message("%d ID %d Position %d Value %d", n, id, position, value);
|
|
||||||
} while ((x < data->len) && n<total);
|
|
||||||
g_message("TOTAL %d", total);
|
|
||||||
preset->params = g_list_reverse(preset->params);
|
|
||||||
|
|
||||||
return preset;
|
return preset;
|
||||||
}
|
}
|
||||||
@@ -241,13 +338,20 @@ void preset_free(Preset *preset)
|
|||||||
if (preset->params != NULL) {
|
if (preset->params != NULL) {
|
||||||
GList *iter;
|
GList *iter;
|
||||||
for (iter = preset->params; iter; iter = iter->next) {
|
for (iter = preset->params; iter; iter = iter->next) {
|
||||||
g_slice_free(SettingParam, iter->data);
|
setting_param_free((SettingParam*)iter->data);
|
||||||
}
|
}
|
||||||
g_list_free(preset->params);
|
g_list_free(preset->params);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (preset->name != NULL)
|
if (preset->genetxs != NULL) {
|
||||||
g_free(preset->name);
|
GList *iter;
|
||||||
|
for (iter = preset->genetxs; iter; iter = iter->next) {
|
||||||
|
setting_genetx_free((SettingGenetx*)iter->data);
|
||||||
|
}
|
||||||
|
g_list_free(preset->genetxs);
|
||||||
|
}
|
||||||
|
|
||||||
|
g_free(preset->name);
|
||||||
|
|
||||||
g_slice_free(Preset, preset);
|
g_slice_free(Preset, preset);
|
||||||
}
|
}
|
||||||
|
|||||||
9
preset.h
9
preset.h
@@ -19,19 +19,14 @@
|
|||||||
|
|
||||||
#include <glib.h>
|
#include <glib.h>
|
||||||
|
|
||||||
typedef struct {
|
|
||||||
int id;
|
|
||||||
int position;
|
|
||||||
int value;
|
|
||||||
} SettingParam;
|
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
gchar *name;
|
gchar *name;
|
||||||
GList *params;
|
GList *params;
|
||||||
|
GList *genetxs;
|
||||||
} Preset;
|
} Preset;
|
||||||
|
|
||||||
Preset *create_preset_from_xml_file(gchar *filename, GError **error);
|
Preset *create_preset_from_xml_file(gchar *filename, GError **error);
|
||||||
Preset *create_preset_from_data(GString *data);
|
Preset *create_preset_from_data(GList *list);
|
||||||
void preset_free(Preset *preset);
|
void preset_free(Preset *preset);
|
||||||
|
|
||||||
#endif /* GDIGI_PRESET_H */
|
#endif /* GDIGI_PRESET_H */
|
||||||
|
|||||||
644
tests.c
644
tests.c
@@ -1,644 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (c) 2009 Tomasz Moń <desowin@gmail.com>
|
|
||||||
*
|
|
||||||
* 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; under version 3 of the License.
|
|
||||||
*
|
|
||||||
* 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>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "gdigi.h"
|
|
||||||
|
|
||||||
void test_wah()
|
|
||||||
{
|
|
||||||
int x;
|
|
||||||
|
|
||||||
set_option(WAH_TYPE, WAH_POSITION, WAH_TYPE_CRY);
|
|
||||||
for (x=0; x<=99; x++)
|
|
||||||
set_option(WAH_MIN, WAH_POSITION_MIN_MAX, x);
|
|
||||||
|
|
||||||
for (x=0; x<=99; x++)
|
|
||||||
set_option(WAH_MAX, WAH_POSITION_MIN_MAX, x);
|
|
||||||
|
|
||||||
for (x=0; x<=12; x++)
|
|
||||||
set_option(WAH_LEVEL, WAH_POSITION, x);
|
|
||||||
|
|
||||||
set_option(WAH_TYPE, WAH_POSITION, WAH_TYPE_FULLRANGE);
|
|
||||||
for (x=0; x<=99; x++)
|
|
||||||
set_option(WAH_MIN, WAH_POSITION_MIN_MAX, x);
|
|
||||||
|
|
||||||
for (x=0; x<=99; x++)
|
|
||||||
set_option(WAH_MAX, WAH_POSITION_MIN_MAX, x);
|
|
||||||
|
|
||||||
for (x=0; x<=12; x++)
|
|
||||||
set_option(WAH_LEVEL, WAH_POSITION, x);
|
|
||||||
|
|
||||||
set_option(WAH_TYPE, WAH_POSITION, WAH_TYPE_CLYDE);
|
|
||||||
for (x=0; x<=99; x++)
|
|
||||||
set_option(WAH_MIN, WAH_POSITION_MIN_MAX, x);
|
|
||||||
|
|
||||||
for (x=0; x<=99; x++)
|
|
||||||
set_option(WAH_MAX, WAH_POSITION_MIN_MAX, x);
|
|
||||||
|
|
||||||
for (x=0; x<=12; x++)
|
|
||||||
set_option(WAH_LEVEL, WAH_POSITION, x);
|
|
||||||
|
|
||||||
set_option(WAH_ON_OFF, WAH_POSITION, 1);
|
|
||||||
set_option(WAH_ON_OFF, WAH_POSITION, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
void test_compressor()
|
|
||||||
{
|
|
||||||
int x;
|
|
||||||
|
|
||||||
set_option(COMP_TYPE, COMP_POSITION, COMP_TYPE_DIGI);
|
|
||||||
for (x=0; x<=99; x++)
|
|
||||||
set_option(COMP_SUSTAIN, COMP_POSITION, x);
|
|
||||||
|
|
||||||
for (x=0; x<=99; x++)
|
|
||||||
set_option(COMP_TONE, COMP_POSITION, x);
|
|
||||||
|
|
||||||
for (x=0; x<=99; x++)
|
|
||||||
set_option(COMP_ATTACK, COMP_POSITION, x);
|
|
||||||
|
|
||||||
for (x=0; x<=99; x++)
|
|
||||||
set_option(COMP_LEVEL, COMP_POSITION, x);
|
|
||||||
|
|
||||||
set_option(COMP_TYPE, COMP_POSITION, COMP_TYPE_CS);
|
|
||||||
for (x=0; x<=99; x++)
|
|
||||||
set_option(COMP_SUSTAIN, COMP_POSITION, x);
|
|
||||||
|
|
||||||
for (x=0; x<=99; x++)
|
|
||||||
set_option(COMP_ATTACK, COMP_POSITION, x);
|
|
||||||
|
|
||||||
for (x=0; x<=99; x++)
|
|
||||||
set_option(COMP_LEVEL, COMP_POSITION, x);
|
|
||||||
|
|
||||||
set_option(COMP_ON_OFF, COMP_POSITION, 1);
|
|
||||||
set_option(COMP_ON_OFF, COMP_POSITION, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
void test_dist()
|
|
||||||
{
|
|
||||||
int x;
|
|
||||||
|
|
||||||
set_option(DIST_TYPE, DIST_POSITION, DIST_TYPE_SCREAMER);
|
|
||||||
for (x=0; x<=99; x++)
|
|
||||||
set_option(DIST_SCREAMER_DRIVE, DIST_POSITION, x);
|
|
||||||
for (x=0; x<=99; x++)
|
|
||||||
set_option(DIST_SCREAMER_TONE, DIST_POSITION, x);
|
|
||||||
for (x=0; x<=99; x++)
|
|
||||||
set_option(DIST_SCREAMER_LVL, DIST_POSITION, x);
|
|
||||||
|
|
||||||
set_option(DIST_TYPE, DIST_POSITION, DIST_TYPE_808);
|
|
||||||
for (x=0; x<=99; x++)
|
|
||||||
set_option(DIST_808_OVERDRIVE, DIST_POSITION, x);
|
|
||||||
for (x=0; x<=99; x++)
|
|
||||||
set_option(DIST_808_TONE, DIST_POSITION, x);
|
|
||||||
for (x=0; x<=99; x++)
|
|
||||||
set_option(DIST_808_LVL, DIST_POSITION, x);
|
|
||||||
|
|
||||||
set_option(DIST_TYPE, DIST_POSITION, DIST_TYPE_GUYOD);
|
|
||||||
for (x=0; x<=99; x++)
|
|
||||||
set_option(DIST_GUYOD_DRIVE, DIST_POSITION, x);
|
|
||||||
for (x=0; x<=99; x++)
|
|
||||||
set_option(DIST_GUYOD_LVL, DIST_POSITION, x);
|
|
||||||
|
|
||||||
set_option(DIST_TYPE, DIST_POSITION, DIST_TYPE_DOD250);
|
|
||||||
for (x=0; x<=99; x++)
|
|
||||||
set_option(DIST_DOD250_GAIN, DIST_POSITION, x);
|
|
||||||
for (x=0; x<=99; x++)
|
|
||||||
set_option(DIST_DOD250_LVL, DIST_POSITION, x);
|
|
||||||
|
|
||||||
set_option(DIST_TYPE, DIST_POSITION, DIST_TYPE_RODENT);
|
|
||||||
for (x=0; x<=99; x++)
|
|
||||||
set_option(DIST_RODENT_DIST, DIST_POSITION, x);
|
|
||||||
for (x=0; x<=99; x++)
|
|
||||||
set_option(DIST_RODENT_FILTER, DIST_POSITION, x);
|
|
||||||
for (x=0; x<=99; x++)
|
|
||||||
set_option(DIST_RODENT_LVL, DIST_POSITION, x);
|
|
||||||
|
|
||||||
set_option(DIST_TYPE, DIST_POSITION, DIST_TYPE_MX);
|
|
||||||
for (x=0; x<=99; x++)
|
|
||||||
set_option(DIST_MX_DIST, DIST_POSITION, x);
|
|
||||||
for (x=0; x<=99; x++)
|
|
||||||
set_option(DIST_MX_OUTPUT, DIST_POSITION, x);
|
|
||||||
|
|
||||||
set_option(DIST_TYPE, DIST_POSITION, DIST_TYPE_DS);
|
|
||||||
for (x=0; x<=99; x++)
|
|
||||||
set_option(DIST_DS_GAIN, DIST_POSITION, x);
|
|
||||||
for (x=0; x<=99; x++)
|
|
||||||
set_option(DIST_DS_TONE, DIST_POSITION, x);
|
|
||||||
for (x=0; x<=99; x++)
|
|
||||||
set_option(DIST_DS_LVL, DIST_POSITION, x);
|
|
||||||
|
|
||||||
set_option(DIST_TYPE, DIST_POSITION, DIST_TYPE_GRUNGE);
|
|
||||||
for (x=0; x<=99; x++)
|
|
||||||
set_option(DIST_GRUNGE_GRUNGE, DIST_POSITION, x);
|
|
||||||
for (x=0; x<=99; x++)
|
|
||||||
set_option(DIST_GRUNGE_FACE, DIST_POSITION, x);
|
|
||||||
for (x=0; x<=99; x++)
|
|
||||||
set_option(DIST_GRUNGE_LOUD, DIST_POSITION, x);
|
|
||||||
for (x=0; x<=99; x++)
|
|
||||||
set_option(DIST_GRUNGE_BUTT, DIST_POSITION, x);
|
|
||||||
|
|
||||||
set_option(DIST_TYPE, DIST_POSITION, DIST_TYPE_ZONE);
|
|
||||||
for (x=0; x<=99; x++)
|
|
||||||
set_option(DIST_ZONE_GAIN, DIST_POSITION, x);
|
|
||||||
for (x=0; x<=99; x++)
|
|
||||||
set_option(DIST_ZONE_LOW, DIST_POSITION, x);
|
|
||||||
for (x=0; x<=99; x++)
|
|
||||||
set_option(DIST_ZONE_MID_LVL, DIST_POSITION, x);
|
|
||||||
for (x=0; x<=99; x++)
|
|
||||||
set_option(DIST_ZONE_MID_FREQ, DIST_POSITION, x);
|
|
||||||
for (x=0; x<=99; x++)
|
|
||||||
set_option(DIST_ZONE_HIGH, DIST_POSITION, x);
|
|
||||||
for (x=0; x<=99; x++)
|
|
||||||
set_option(DIST_ZONE_LEVEL, DIST_POSITION, x);
|
|
||||||
|
|
||||||
set_option(DIST_TYPE, DIST_POSITION, DIST_TYPE_DEATH);
|
|
||||||
for (x=0; x<=99; x++)
|
|
||||||
set_option(DIST_DEATH_LOW, DIST_POSITION, x);
|
|
||||||
for (x=0; x<=99; x++)
|
|
||||||
set_option(DIST_DEATH_MID, DIST_POSITION, x);
|
|
||||||
for (x=0; x<=99; x++)
|
|
||||||
set_option(DIST_DEATH_HIGH, DIST_POSITION, x);
|
|
||||||
for (x=0; x<=99; x++)
|
|
||||||
set_option(DIST_DEATH_LVL, DIST_POSITION, x);
|
|
||||||
|
|
||||||
set_option(DIST_TYPE, DIST_POSITION, DIST_TYPE_GONK);
|
|
||||||
for (x=0; x<=99; x++)
|
|
||||||
set_option(DIST_GONK_GONK, DIST_POSITION, x);
|
|
||||||
for (x=0; x<=99; x++)
|
|
||||||
set_option(DIST_GONK_SMEAR, DIST_POSITION, x);
|
|
||||||
for (x=0; x<=99; x++)
|
|
||||||
set_option(DIST_GONK_SUCK, DIST_POSITION, x);
|
|
||||||
for (x=0; x<=99; x++)
|
|
||||||
set_option(DIST_GONK_HEAVE, DIST_POSITION, x);
|
|
||||||
|
|
||||||
set_option(DIST_TYPE, DIST_POSITION, DIST_TYPE_FUZZY);
|
|
||||||
for (x=0; x<=99; x++)
|
|
||||||
set_option(DIST_FUZZY_FUZZ, DIST_POSITION, x);
|
|
||||||
for (x=0; x<=99; x++)
|
|
||||||
set_option(DIST_FUZZY_VOLUME, DIST_POSITION, x);
|
|
||||||
|
|
||||||
set_option(DIST_TYPE, DIST_POSITION, DIST_TYPE_MP);
|
|
||||||
for (x=0; x<=99; x++)
|
|
||||||
set_option(DIST_MP_SUSTAIN, DIST_POSITION, x);
|
|
||||||
for (x=0; x<=99; x++)
|
|
||||||
set_option(DIST_MP_TONE, DIST_POSITION, x);
|
|
||||||
for (x=0; x<=99; x++)
|
|
||||||
set_option(DIST_MP_VOLUME, DIST_POSITION, x);
|
|
||||||
|
|
||||||
set_option(DIST_ON_OFF, DIST_POSITION, 1);
|
|
||||||
set_option(DIST_ON_OFF, DIST_POSITION, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
void test_presets()
|
|
||||||
{
|
|
||||||
int x;
|
|
||||||
|
|
||||||
for (x=0; x<=60; x++)
|
|
||||||
switch_preset(PRESETS_USER, x);
|
|
||||||
|
|
||||||
for (x=0; x<=60; x++)
|
|
||||||
switch_preset(PRESETS_SYSTEM, x);
|
|
||||||
}
|
|
||||||
|
|
||||||
void test_pickups()
|
|
||||||
{
|
|
||||||
set_option(PICKUP_TYPE, PICKUP_POSITION, PICKUP_TYPE_HB_SC);
|
|
||||||
set_option(PICKUP_TYPE, PICKUP_POSITION, PICKUP_TYPE_SC_HB);
|
|
||||||
|
|
||||||
set_option(PICKUP_ON_OFF, PICKUP_POSITION, 1);
|
|
||||||
set_option(PICKUP_ON_OFF, PICKUP_POSITION, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
void test_eq()
|
|
||||||
{
|
|
||||||
int x;
|
|
||||||
|
|
||||||
set_option(EQ_TYPE, EQ_POSITION, EQ_TYPE_BRIGHT);
|
|
||||||
set_option(EQ_TYPE, EQ_POSITION, EQ_TYPE_MIDBOOST);
|
|
||||||
set_option(EQ_TYPE, EQ_POSITION, EQ_TYPE_SCOOP);
|
|
||||||
set_option(EQ_TYPE, EQ_POSITION, EQ_TYPE_WARM);
|
|
||||||
|
|
||||||
for (x=0; x<=99; x++)
|
|
||||||
set_option(AMP_GAIN, AMP_POSITION, x);
|
|
||||||
for (x=0; x<=99; x++)
|
|
||||||
set_option(AMP_LEVEL, AMP_POSITION, x);
|
|
||||||
|
|
||||||
for (x=0; x<=0x18; x++)
|
|
||||||
set_option(EQ_BASS, EQ_POSITION, x);
|
|
||||||
for (x=0; x<=0x18; x++)
|
|
||||||
set_option(EQ_MID, EQ_POSITION, x);
|
|
||||||
for (x=0; x<=4700; x++)
|
|
||||||
set_option(EQ_MID_HZ, EQ_POSITION, x);
|
|
||||||
for (x=0; x<=0x18; x++)
|
|
||||||
set_option(EQ_TREBLE, EQ_POSITION, x);
|
|
||||||
for (x=0; x<=7500; x++)
|
|
||||||
set_option(EQ_TREBLE_HZ, EQ_POSITION, x);
|
|
||||||
|
|
||||||
set_option(EQ_ON_OFF, EQ_POSITION, 1);
|
|
||||||
set_option(EQ_ON_OFF, EQ_POSITION, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
void test_noisegate()
|
|
||||||
{
|
|
||||||
int x;
|
|
||||||
|
|
||||||
set_option(NOISEGATE_TYPE, NOISEGATE_POSITION, NOISEGATE_GATE);
|
|
||||||
for (x=0; x<=99; x++)
|
|
||||||
set_option(NOISEGATE_GATE_TRESHOLD, NOISEGATE_POSITION, x);
|
|
||||||
for (x=0; x<=99; x++)
|
|
||||||
set_option(NOISEGATE_ATTACK, NOISEGATE_POSITION, x);
|
|
||||||
for (x=0; x<=99; x++)
|
|
||||||
set_option(NOISEGATE_RELEASE, NOISEGATE_POSITION, x);
|
|
||||||
for (x=0; x<=99; x++)
|
|
||||||
set_option(NOISEGATE_ATTN, NOISEGATE_POSITION, x);
|
|
||||||
|
|
||||||
set_option(NOISEGATE_TYPE, NOISEGATE_POSITION, NOISEGATE_SWELL);
|
|
||||||
for (x=0; x<=99; x++)
|
|
||||||
set_option(NOISEGATE_SWELL_SENS, NOISEGATE_POSITION, x);
|
|
||||||
for (x=0; x<=99; x++)
|
|
||||||
set_option(NOISEGATE_ATTACK, NOISEGATE_POSITION, x);
|
|
||||||
for (x=0; x<=99; x++)
|
|
||||||
set_option(NOISEGATE_RELEASE, NOISEGATE_POSITION, x);
|
|
||||||
for (x=0; x<=99; x++)
|
|
||||||
set_option(NOISEGATE_ATTN, NOISEGATE_POSITION, x);
|
|
||||||
|
|
||||||
set_option(NOISEGATE_ON_OFF, NOISEGATE_POSITION, 1);
|
|
||||||
set_option(NOISEGATE_ON_OFF, NOISEGATE_POSITION, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
void test_chorusfx()
|
|
||||||
{
|
|
||||||
int x;
|
|
||||||
|
|
||||||
set_option(CHORUSFX_TYPE, CHORUSFX_POSITION, CHORUS_TYPE_CE);
|
|
||||||
for (x=0; x<=99; x++)
|
|
||||||
set_option(CE_CHORUS_SPEED, CHORUSFX_POSITION, x);
|
|
||||||
for (x=0; x<=99; x++)
|
|
||||||
set_option(CE_CHORUS_DEPTH, CHORUSFX_POSITION, x);
|
|
||||||
|
|
||||||
set_option(CHORUSFX_TYPE, CHORUSFX_POSITION, CHORUS_TYPE_DUAL);
|
|
||||||
for (x=0; x<=99; x++)
|
|
||||||
set_option(DUAL_CHORUS_SPEED, CHORUSFX_POSITION, x);
|
|
||||||
for (x=0; x<=99; x++)
|
|
||||||
set_option(DUAL_CHORUS_DEPTH, CHORUSFX_POSITION, x);
|
|
||||||
for (x=0; x<=99; x++)
|
|
||||||
set_option(DUAL_CHORUS_LEVEL, CHORUSFX_POSITION, x);
|
|
||||||
set_option(DUAL_CHORUS_WAVE, CHORUSFX_POSITION, WAVE_TRI);
|
|
||||||
set_option(DUAL_CHORUS_WAVE, CHORUSFX_POSITION, WAVE_SINE);
|
|
||||||
set_option(DUAL_CHORUS_WAVE, CHORUSFX_POSITION, WAVE_SQUARE);
|
|
||||||
|
|
||||||
set_option(CHORUSFX_TYPE, CHORUSFX_POSITION, CHORUS_TYPE_MULTI);
|
|
||||||
for (x=0; x<=99; x++)
|
|
||||||
set_option(MULTI_CHORUS_SPEED, CHORUSFX_POSITION, x);
|
|
||||||
for (x=0; x<=99; x++)
|
|
||||||
set_option(MULTI_CHORUS_DEPTH, CHORUSFX_POSITION, x);
|
|
||||||
for (x=0; x<=99; x++)
|
|
||||||
set_option(MULTI_CHORUS_LEVEL, CHORUSFX_POSITION, x);
|
|
||||||
set_option(MULTI_CHORUS_WAVE, CHORUSFX_POSITION, WAVE_TRI);
|
|
||||||
set_option(MULTI_CHORUS_WAVE, CHORUSFX_POSITION, WAVE_SINE);
|
|
||||||
set_option(MULTI_CHORUS_WAVE, CHORUSFX_POSITION, WAVE_SQUARE);
|
|
||||||
|
|
||||||
set_option(CHORUSFX_TYPE, CHORUSFX_POSITION, CHORUS_TYPE_FLANGER);
|
|
||||||
for (x=0; x<=99; x++)
|
|
||||||
set_option(FLANGER_SPEED, CHORUSFX_POSITION, x);
|
|
||||||
for (x=0; x<=99; x++)
|
|
||||||
set_option(FLANGER_DEPTH, CHORUSFX_POSITION, x);
|
|
||||||
for (x=0; x<=99; x++)
|
|
||||||
set_option(FLANGER_REGEN, CHORUSFX_POSITION, x);
|
|
||||||
for (x=0; x<=99; x++)
|
|
||||||
set_option(FLANGER_LEVEL, CHORUSFX_POSITION, x);
|
|
||||||
set_option(FLANGER_WAVE, CHORUSFX_POSITION, WAVE_TRI);
|
|
||||||
set_option(FLANGER_WAVE, CHORUSFX_POSITION, WAVE_SINE);
|
|
||||||
set_option(FLANGER_WAVE, CHORUSFX_POSITION, WAVE_SQUARE);
|
|
||||||
|
|
||||||
set_option(CHORUSFX_TYPE, CHORUSFX_POSITION, CHORUS_TYPE_MXR_FLANGER);
|
|
||||||
for (x=0; x<=99; x++)
|
|
||||||
set_option(MXR_FLANGER_SPEED, CHORUSFX_POSITION, x);
|
|
||||||
for (x=0; x<=99; x++)
|
|
||||||
set_option(MXR_FLANGER_WIDTH, CHORUSFX_POSITION, x);
|
|
||||||
for (x=0; x<=99; x++)
|
|
||||||
set_option(MXR_FLANGER_REGEN, CHORUSFX_POSITION, x);
|
|
||||||
for (x=0; x<=99; x++)
|
|
||||||
set_option(MXR_FLANGER_MANUAL, CHORUSFX_POSITION, x);
|
|
||||||
|
|
||||||
set_option(CHORUSFX_TYPE, CHORUSFX_POSITION, CHORUS_TYPE_PHASER);
|
|
||||||
for (x=0; x<=99; x++)
|
|
||||||
set_option(PHASER_SPEED, CHORUSFX_POSITION, x);
|
|
||||||
for (x=0; x<=99; x++)
|
|
||||||
set_option(PHASER_DEPTH, CHORUSFX_POSITION, x);
|
|
||||||
for (x=0; x<=99; x++)
|
|
||||||
set_option(PHASER_REGEN, CHORUSFX_POSITION, x);
|
|
||||||
for (x=0; x<=99; x++)
|
|
||||||
set_option(PHASER_LEVEL, CHORUSFX_POSITION, x);
|
|
||||||
set_option(PHASER_WAVE, CHORUSFX_POSITION, WAVE_TRI);
|
|
||||||
set_option(PHASER_WAVE, CHORUSFX_POSITION, WAVE_SINE);
|
|
||||||
set_option(PHASER_WAVE, CHORUSFX_POSITION, WAVE_SQUARE);
|
|
||||||
|
|
||||||
set_option(CHORUSFX_TYPE, CHORUSFX_POSITION, CHORUS_TYPE_VIBRATO);
|
|
||||||
for (x=0; x<=99; x++)
|
|
||||||
set_option(VIBRATO_SPEED, CHORUSFX_POSITION, x);
|
|
||||||
for (x=0; x<=99; x++)
|
|
||||||
set_option(VIBRATO_DEPTH, CHORUSFX_POSITION, x);
|
|
||||||
|
|
||||||
set_option(CHORUSFX_TYPE, CHORUSFX_POSITION, CHORUS_TYPE_ROTARY);
|
|
||||||
for (x=0; x<=99; x++)
|
|
||||||
set_option(ROTARY_SPEED, CHORUSFX_POSITION, x);
|
|
||||||
for (x=0; x<=99; x++)
|
|
||||||
set_option(ROTARY_INTENSITY, CHORUSFX_POSITION, x);
|
|
||||||
for (x=0; x<=99; x++)
|
|
||||||
set_option(ROTARY_DOPPLER, CHORUSFX_POSITION, x);
|
|
||||||
for (x=0; x<=99; x++)
|
|
||||||
set_option(ROTARY_CROSSOVER, CHORUSFX_POSITION, x);
|
|
||||||
|
|
||||||
set_option(CHORUSFX_TYPE, CHORUSFX_POSITION, CHORUS_TYPE_VIBROPAN);
|
|
||||||
for (x=0; x<=99; x++)
|
|
||||||
set_option(VIBROPAN_SPEED, CHORUSFX_POSITION, x);
|
|
||||||
for (x=0; x<=99; x++)
|
|
||||||
set_option(VIBROPAN_DEPTH, CHORUSFX_POSITION, x);
|
|
||||||
for (x=0; x<=99; x++)
|
|
||||||
set_option(VIBROPAN_VIBRA, CHORUSFX_POSITION, x);
|
|
||||||
set_option(VIBROPAN_WAVE, CHORUSFX_POSITION, WAVE_TRI);
|
|
||||||
set_option(VIBROPAN_WAVE, CHORUSFX_POSITION, WAVE_SINE);
|
|
||||||
set_option(VIBROPAN_WAVE, CHORUSFX_POSITION, WAVE_SQUARE);
|
|
||||||
|
|
||||||
set_option(CHORUSFX_TYPE, CHORUSFX_POSITION, CHORUS_TYPE_TREMOLO);
|
|
||||||
for (x=0; x<=99; x++)
|
|
||||||
set_option(TREMOLO_SPEED, CHORUSFX_POSITION, x);
|
|
||||||
for (x=0; x<=99; x++)
|
|
||||||
set_option(TREMOLO_DEPTH, CHORUSFX_POSITION, x);
|
|
||||||
set_option(TREMOLO_WAVE, CHORUSFX_POSITION, WAVE_TRI);
|
|
||||||
set_option(TREMOLO_WAVE, CHORUSFX_POSITION, WAVE_SINE);
|
|
||||||
set_option(TREMOLO_WAVE, CHORUSFX_POSITION, WAVE_SQUARE);
|
|
||||||
|
|
||||||
set_option(CHORUSFX_TYPE, CHORUSFX_POSITION, CHORUS_TYPE_PANNER);
|
|
||||||
for (x=0; x<=99; x++)
|
|
||||||
set_option(PANNER_SPEED, CHORUSFX_POSITION, x);
|
|
||||||
for (x=0; x<=99; x++)
|
|
||||||
set_option(PANNER_DEPTH, CHORUSFX_POSITION, x);
|
|
||||||
set_option(PANNER_WAVE, CHORUSFX_POSITION, WAVE_TRI);
|
|
||||||
set_option(PANNER_WAVE, CHORUSFX_POSITION, WAVE_SINE);
|
|
||||||
set_option(PANNER_WAVE, CHORUSFX_POSITION, WAVE_SQUARE);
|
|
||||||
|
|
||||||
set_option(CHORUSFX_TYPE, CHORUSFX_POSITION, CHORUS_TYPE_ENVELOPE);
|
|
||||||
for (x=0; x<=99; x++)
|
|
||||||
set_option(ENVELOPE_SENSITIVITY, CHORUSFX_POSITION, x);
|
|
||||||
for (x=0; x<=99; x++)
|
|
||||||
set_option(ENVELOPE_RANGE, CHORUSFX_POSITION, x);
|
|
||||||
|
|
||||||
set_option(CHORUSFX_TYPE, CHORUSFX_POSITION, CHORUS_TYPE_AUTOYA);
|
|
||||||
for (x=0; x<=99; x++)
|
|
||||||
set_option(AUTOYA_SPEED, CHORUSFX_POSITION, x);
|
|
||||||
for (x=0; x<=99; x++)
|
|
||||||
set_option(AUTOYA_INTENSITY, CHORUSFX_POSITION, x);
|
|
||||||
for (x=0; x<=0x31; x++)
|
|
||||||
set_option(AUTOYA_RANGE, CHORUSFX_POSITION, x);
|
|
||||||
|
|
||||||
set_option(CHORUSFX_TYPE, CHORUSFX_POSITION, CHORUS_TYPE_YAYA);
|
|
||||||
for (x=0; x<=99; x++)
|
|
||||||
set_option(YAYA_PEDAL, CHORUSFX_POSITION, x);
|
|
||||||
for (x=0; x<=99; x++)
|
|
||||||
set_option(YAYA_INTENSITY, CHORUSFX_POSITION, x);
|
|
||||||
for (x=0; x<=0x31; x++)
|
|
||||||
set_option(YAYA_RANGE, CHORUSFX_POSITION, x);
|
|
||||||
|
|
||||||
set_option(CHORUSFX_TYPE, CHORUSFX_POSITION, CHORUS_TYPE_STEP_FILTER);
|
|
||||||
for (x=0; x<=99; x++)
|
|
||||||
set_option(STEP_FILTER_SPEED, CHORUSFX_POSITION, x);
|
|
||||||
for (x=0; x<=99; x++)
|
|
||||||
set_option(STEP_FILTER_INTENSITY, CHORUSFX_POSITION, x);
|
|
||||||
|
|
||||||
set_option(CHORUSFX_TYPE, CHORUSFX_POSITION, CHORUS_TYPE_WHAMMY);
|
|
||||||
set_option(WHAMMY_AMOUNT, CHORUSFX_POSITION, WHAMMY_OCT_UP);
|
|
||||||
set_option(WHAMMY_AMOUNT, CHORUSFX_POSITION, WHAMMY_2OCT_UP);
|
|
||||||
set_option(WHAMMY_AMOUNT, CHORUSFX_POSITION, WHAMMY_2ND_DN);
|
|
||||||
set_option(WHAMMY_AMOUNT, CHORUSFX_POSITION, WHAMMY_RV_2ND);
|
|
||||||
set_option(WHAMMY_AMOUNT, CHORUSFX_POSITION, WHAMMY_4TH_DN);
|
|
||||||
set_option(WHAMMY_AMOUNT, CHORUSFX_POSITION, WHAMMY_OCT_DN);
|
|
||||||
set_option(WHAMMY_AMOUNT, CHORUSFX_POSITION, WHAMMY_2OCT_DN);
|
|
||||||
set_option(WHAMMY_AMOUNT, CHORUSFX_POSITION, WHAMMY_DIV_BMB);
|
|
||||||
set_option(WHAMMY_AMOUNT, CHORUSFX_POSITION, WHAMMY_M3_MA);
|
|
||||||
set_option(WHAMMY_AMOUNT, CHORUSFX_POSITION, WHAMMY_2ND_MA3);
|
|
||||||
set_option(WHAMMY_AMOUNT, CHORUSFX_POSITION, WHAMMY_3RD_4TH);
|
|
||||||
set_option(WHAMMY_AMOUNT, CHORUSFX_POSITION, WHAMMY_4TH_5TH);
|
|
||||||
set_option(WHAMMY_AMOUNT, CHORUSFX_POSITION, WHAMMY_5TH_OCT);
|
|
||||||
set_option(WHAMMY_AMOUNT, CHORUSFX_POSITION, WHAMMY_HOCT_UP);
|
|
||||||
set_option(WHAMMY_AMOUNT, CHORUSFX_POSITION, WHAMMY_HOCT_DN);
|
|
||||||
set_option(WHAMMY_AMOUNT, CHORUSFX_POSITION, WHAMMY_OCT_UD);
|
|
||||||
for (x=0; x<=99; x++)
|
|
||||||
set_option(WHAMMY_PEDAL, CHORUSFX_POSITION, x);
|
|
||||||
for (x=0; x<=99; x++)
|
|
||||||
set_option(WHAMMY_MIX, CHORUSFX_POSITION, x);
|
|
||||||
|
|
||||||
set_option(CHORUSFX_TYPE, CHORUSFX_POSITION, CHORUS_TYPE_PITCH_SHIFT);
|
|
||||||
for (x=0; x<=0x30; x++)
|
|
||||||
set_option(PITCH_AMOUNT, CHORUSFX_POSITION, x);
|
|
||||||
for (x=0; x<=99; x++)
|
|
||||||
set_option(PITCH_MIX, CHORUSFX_POSITION, x);
|
|
||||||
|
|
||||||
set_option(CHORUSFX_TYPE, CHORUSFX_POSITION, CHORUS_TYPE_DETUNE);
|
|
||||||
for (x=0; x<=0x30; x++)
|
|
||||||
set_option(DETUNE_AMOUNT, CHORUSFX_POSITION, x);
|
|
||||||
for (x=0; x<=99; x++)
|
|
||||||
set_option(DETUNE_LEVEL, CHORUSFX_POSITION, x);
|
|
||||||
|
|
||||||
set_option(CHORUSFX_TYPE, CHORUSFX_POSITION, CHORUS_TYPE_IPS);
|
|
||||||
set_option(IPS_SHIFT_AMOUNT, CHORUSFX_POSITION, IPS_OCT_D);
|
|
||||||
set_option(IPS_SHIFT_AMOUNT, CHORUSFX_POSITION, IPS_7TH_DN);
|
|
||||||
set_option(IPS_SHIFT_AMOUNT, CHORUSFX_POSITION, IPS_6TH_DN);
|
|
||||||
set_option(IPS_SHIFT_AMOUNT, CHORUSFX_POSITION, IPS_5TH_DN);
|
|
||||||
set_option(IPS_SHIFT_AMOUNT, CHORUSFX_POSITION, IPS_4TH_DN);
|
|
||||||
set_option(IPS_SHIFT_AMOUNT, CHORUSFX_POSITION, IPS_3RD_DN);
|
|
||||||
set_option(IPS_SHIFT_AMOUNT, CHORUSFX_POSITION, IPS_2ND_DN);
|
|
||||||
set_option(IPS_SHIFT_AMOUNT, CHORUSFX_POSITION, IPS_2ND_UP);
|
|
||||||
set_option(IPS_SHIFT_AMOUNT, CHORUSFX_POSITION, IPS_3RD_UP);
|
|
||||||
set_option(IPS_SHIFT_AMOUNT, CHORUSFX_POSITION, IPS_4TH_UP);
|
|
||||||
set_option(IPS_SHIFT_AMOUNT, CHORUSFX_POSITION, IPS_5TH_UP);
|
|
||||||
set_option(IPS_SHIFT_AMOUNT, CHORUSFX_POSITION, IPS_6TH_UP);
|
|
||||||
set_option(IPS_SHIFT_AMOUNT, CHORUSFX_POSITION, IPS_7TH_UP);
|
|
||||||
set_option(IPS_SHIFT_AMOUNT, CHORUSFX_POSITION, IPS_OCT_U);
|
|
||||||
set_option(IPS_KEY, CHORUSFX_POSITION, IPS_E);
|
|
||||||
set_option(IPS_KEY, CHORUSFX_POSITION, IPS_F);
|
|
||||||
set_option(IPS_KEY, CHORUSFX_POSITION, IPS_GB);
|
|
||||||
set_option(IPS_KEY, CHORUSFX_POSITION, IPS_G);
|
|
||||||
set_option(IPS_KEY, CHORUSFX_POSITION, IPS_AB);
|
|
||||||
set_option(IPS_KEY, CHORUSFX_POSITION, IPS_A);
|
|
||||||
set_option(IPS_KEY, CHORUSFX_POSITION, IPS_BB);
|
|
||||||
set_option(IPS_KEY, CHORUSFX_POSITION, IPS_B);
|
|
||||||
set_option(IPS_KEY, CHORUSFX_POSITION, IPS_C);
|
|
||||||
set_option(IPS_KEY, CHORUSFX_POSITION, IPS_DB);
|
|
||||||
set_option(IPS_KEY, CHORUSFX_POSITION, IPS_D);
|
|
||||||
set_option(IPS_KEY, CHORUSFX_POSITION, IPS_EB);
|
|
||||||
set_option(IPS_SCALE, CHORUSFX_POSITION, IPS_MAJOR);
|
|
||||||
set_option(IPS_SCALE, CHORUSFX_POSITION, IPS_MINOR);
|
|
||||||
set_option(IPS_SCALE, CHORUSFX_POSITION, IPS_DORIA);
|
|
||||||
set_option(IPS_SCALE, CHORUSFX_POSITION, IPS_MIXLYD);
|
|
||||||
set_option(IPS_SCALE, CHORUSFX_POSITION, IPS_LYDIAN);
|
|
||||||
set_option(IPS_SCALE, CHORUSFX_POSITION, IPS_HMINO);
|
|
||||||
for (x=0; x<=99; x++)
|
|
||||||
set_option(IPS_LEVEL, CHORUSFX_POSITION, x);
|
|
||||||
|
|
||||||
set_option(CHORUSFX_ON_OFF, CHORUSFX_POSITION, 1);
|
|
||||||
set_option(CHORUSFX_ON_OFF, CHORUSFX_POSITION, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
void test_delay()
|
|
||||||
{
|
|
||||||
int x;
|
|
||||||
|
|
||||||
set_option(DELAY_TYPE, DELAY_POSITION, DELAY_TYPE_ANALOG);
|
|
||||||
for (x=0; x<=139; x++)
|
|
||||||
set_option(DELAY_TIME, DELAY_POSITION, x);
|
|
||||||
for (x=0; x<=99; x++)
|
|
||||||
set_option(ANALOG_LEVEL, DELAY_POSITION, x);
|
|
||||||
for (x=0; x<=100; x++)
|
|
||||||
set_option(ANALOG_REPEATS, DELAY_POSITION, x);
|
|
||||||
|
|
||||||
set_option(DELAY_TYPE, DELAY_POSITION, DELAY_TYPE_DIGITAL);
|
|
||||||
for (x=0; x<=139; x++)
|
|
||||||
set_option(DELAY_TIME, DELAY_POSITION, x);
|
|
||||||
for (x=0; x<=99; x++)
|
|
||||||
set_option(DIGITAL_LEVEL, DELAY_POSITION, x);
|
|
||||||
for (x=0; x<=100; x++)
|
|
||||||
set_option(DIGITAL_REPEATS, DELAY_POSITION, x);
|
|
||||||
for (x=0; x<=99; x++)
|
|
||||||
set_option(DIGITAL_DUCKER_THRESH, DELAY_POSITION, x);
|
|
||||||
for (x=0; x<=99; x++)
|
|
||||||
set_option(DIGITAL_DUCKER_LEVEL, DELAY_POSITION, x);
|
|
||||||
|
|
||||||
set_option(DELAY_TYPE, DELAY_POSITION, DELAY_TYPE_MODULATED);
|
|
||||||
for (x=0; x<=139; x++)
|
|
||||||
set_option(DELAY_TIME, DELAY_POSITION, x);
|
|
||||||
for (x=0; x<=99; x++)
|
|
||||||
set_option(MODULATED_LEVEL, DELAY_POSITION, x);
|
|
||||||
for (x=0; x<=100; x++)
|
|
||||||
set_option(MODULATED_REPEATS, DELAY_POSITION, x);
|
|
||||||
for (x=0; x<=99; x++)
|
|
||||||
set_option(MODULATED_DEPTH, DELAY_POSITION, x);
|
|
||||||
|
|
||||||
set_option(DELAY_TYPE, DELAY_POSITION, DELAY_TYPE_PONG);
|
|
||||||
for (x=0; x<=139; x++)
|
|
||||||
set_option(DELAY_TIME, DELAY_POSITION, x);
|
|
||||||
for (x=0; x<=99; x++)
|
|
||||||
set_option(PONG_LEVEL, DELAY_POSITION, x);
|
|
||||||
for (x=0; x<=100; x++)
|
|
||||||
set_option(PONG_REPEATS, DELAY_POSITION, x);
|
|
||||||
for (x=0; x<=99; x++)
|
|
||||||
set_option(PONG_DUCKER_THRESH, DELAY_POSITION, x);
|
|
||||||
for (x=0; x<=99; x++)
|
|
||||||
set_option(PONG_DUCKER_LEVEL, DELAY_POSITION, x);
|
|
||||||
|
|
||||||
set_option(DELAY_TYPE, DELAY_POSITION, DELAY_TYPE_TAPE);
|
|
||||||
for (x=0; x<=139; x++)
|
|
||||||
set_option(DELAY_TIME, DELAY_POSITION, x);
|
|
||||||
for (x=0; x<=99; x++)
|
|
||||||
set_option(TAPE_LEVEL, DELAY_POSITION, x);
|
|
||||||
for (x=0; x<=100; x++)
|
|
||||||
set_option(TAPE_REPEATS, DELAY_POSITION, x);
|
|
||||||
for (x=0; x<=99; x++)
|
|
||||||
set_option(TAPE_WOW, DELAY_POSITION, x);
|
|
||||||
for (x=0; x<=99; x++)
|
|
||||||
set_option(TAPE_FLUTTER, DELAY_POSITION, x);
|
|
||||||
|
|
||||||
set_option(DELAY_ON_OFF, DELAY_POSITION, 1);
|
|
||||||
set_option(DELAY_ON_OFF, DELAY_POSITION, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
void test_reverb()
|
|
||||||
{
|
|
||||||
int x;
|
|
||||||
|
|
||||||
set_option(REVERB_TYPE, REVERB_POSITION, REVERB_TYPE_TWIN);
|
|
||||||
for (x=0; x<=99; x++)
|
|
||||||
set_option(TWIN_REVERB, REVERB_POSITION, x);
|
|
||||||
|
|
||||||
set_option(REVERB_TYPE, REVERB_POSITION, REVERB_TYPE_LEX_AMBIENCE);
|
|
||||||
for (x=0; x<=15; x++)
|
|
||||||
set_option(LEX_AMBIENCE_PREDELAY, REVERB_POSITION, x);
|
|
||||||
for (x=0; x<=99; x++)
|
|
||||||
set_option(LEX_AMBIENCE_DECAY, REVERB_POSITION, x);
|
|
||||||
for (x=0; x<=99; x++)
|
|
||||||
set_option(LEX_AMBIENCE_LIVELINESS, REVERB_POSITION, x);
|
|
||||||
for (x=0; x<=99; x++)
|
|
||||||
set_option(LEX_AMBIENCE_LEVEL, REVERB_POSITION, x);
|
|
||||||
|
|
||||||
set_option(REVERB_TYPE, REVERB_POSITION, REVERB_TYPE_LEX_STUDIO);
|
|
||||||
for (x=0; x<=15; x++)
|
|
||||||
set_option(LEX_STUDIO_PREDELAY, REVERB_POSITION, x);
|
|
||||||
for (x=0; x<=99; x++)
|
|
||||||
set_option(LEX_STUDIO_DECAY, REVERB_POSITION, x);
|
|
||||||
for (x=0; x<=99; x++)
|
|
||||||
set_option(LEX_STUDIO_LIVELINESS, REVERB_POSITION, x);
|
|
||||||
for (x=0; x<=99; x++)
|
|
||||||
set_option(LEX_STUDIO_LEVEL, REVERB_POSITION, x);
|
|
||||||
|
|
||||||
set_option(REVERB_TYPE, REVERB_POSITION, REVERB_TYPE_LEX_ROOM);
|
|
||||||
for (x=0; x<=15; x++)
|
|
||||||
set_option(LEX_ROOM_PREDELAY, REVERB_POSITION, x);
|
|
||||||
for (x=0; x<=99; x++)
|
|
||||||
set_option(LEX_ROOM_DECAY, REVERB_POSITION, x);
|
|
||||||
for (x=0; x<=99; x++)
|
|
||||||
set_option(LEX_ROOM_LIVELINESS, REVERB_POSITION, x);
|
|
||||||
for (x=0; x<=99; x++)
|
|
||||||
set_option(LEX_ROOM_LEVEL, REVERB_POSITION, x);
|
|
||||||
|
|
||||||
set_option(REVERB_TYPE, REVERB_POSITION, REVERB_TYPE_LEX_HALL);
|
|
||||||
for (x=0; x<=15; x++)
|
|
||||||
set_option(LEX_HALL_PREDELAY, REVERB_POSITION, x);
|
|
||||||
for (x=0; x<=99; x++)
|
|
||||||
set_option(LEX_HALL_DECAY, REVERB_POSITION, x);
|
|
||||||
for (x=0; x<=99; x++)
|
|
||||||
set_option(LEX_HALL_LIVELINESS, REVERB_POSITION, x);
|
|
||||||
for (x=0; x<=99; x++)
|
|
||||||
set_option(LEX_HALL_LEVEL, REVERB_POSITION, x);
|
|
||||||
|
|
||||||
set_option(REVERB_TYPE, REVERB_POSITION, REVERB_TYPE_EMT240_PLATE);
|
|
||||||
for (x=0; x<=15; x++)
|
|
||||||
set_option(EMT240_PLATE_PREDELAY, REVERB_POSITION, x);
|
|
||||||
for (x=0; x<=99; x++)
|
|
||||||
set_option(EMT240_PLATE_DECAY, REVERB_POSITION, x);
|
|
||||||
for (x=0; x<=99; x++)
|
|
||||||
set_option(EMT240_PLATE_LIVELINESS, REVERB_POSITION, x);
|
|
||||||
for (x=0; x<=99; x++)
|
|
||||||
set_option(EMT240_PLATE_LEVEL, REVERB_POSITION, x);
|
|
||||||
|
|
||||||
set_option(REVERB_ON_OFF, REVERB_POSITION, 1);
|
|
||||||
set_option(REVERB_ON_OFF, REVERB_POSITION, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
void test_usb()
|
|
||||||
{
|
|
||||||
int x;
|
|
||||||
|
|
||||||
for (x=0; x<=100; x++)
|
|
||||||
set_option(USB_AUDIO_PLAYBACK_MIX, USB_POSITION, x);
|
|
||||||
|
|
||||||
for (x=0; x<=36; x++)
|
|
||||||
set_option(USB_AUDIO_LEVEL, USB_POSITION, x);
|
|
||||||
}
|
|
||||||
|
|
||||||
void test_all()
|
|
||||||
{
|
|
||||||
test_wah();
|
|
||||||
test_compressor();
|
|
||||||
test_dist();
|
|
||||||
test_presets();
|
|
||||||
test_pickups();
|
|
||||||
test_eq();
|
|
||||||
test_noisegate();
|
|
||||||
test_chorusfx();
|
|
||||||
test_delay();
|
|
||||||
test_reverb();
|
|
||||||
test_usb();
|
|
||||||
}
|
|
||||||
35
tests.h
35
tests.h
@@ -1,35 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (c) 2009 Tomasz Moń <desowin@gmail.com>
|
|
||||||
*
|
|
||||||
* 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; under version 3 of the License.
|
|
||||||
*
|
|
||||||
* 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 GDIGI_TESTS_H
|
|
||||||
#define GDIGI_TESTS_H
|
|
||||||
|
|
||||||
#include "gdigi.h"
|
|
||||||
|
|
||||||
void test_wah();
|
|
||||||
void test_compressor();
|
|
||||||
void test_dist();
|
|
||||||
void test_presets();
|
|
||||||
void test_pickups();
|
|
||||||
void test_eq();
|
|
||||||
void test_noisegate();
|
|
||||||
void test_chorusfx();
|
|
||||||
void test_delay();
|
|
||||||
void test_reverb();
|
|
||||||
void test_usb();
|
|
||||||
void test_all();
|
|
||||||
|
|
||||||
#endif /* GDIGI_TESTS_H */
|
|
||||||
Reference in New Issue
Block a user