1) Require libxml-2 and build new file preset_xml.c
2) In effects.c, some EffectsValues are changed to better reflect the
strings used in the XML.
3) New EffectSettings are added for use when writing out effects to XML.
4) Added an XmlLabel structure for mapping a value to a string. Generally,
these are the union of the set of all values over the set of supported
devices.
5) There's a large array of XmlSettings used to derive the translation of
a preset to XML.
6) Add an enum for product_id and use it to set a filter for file suffix.
7) Minor cleanup in push_message() that suppresses spurious error messages.
8) Fixed a bad memset in read_data_thread().
9) In gdigi.h, a few changes in names to be consistent with XML.
There are some new definitions of LFO and VSWITCH parameters that
need to be computed.
10) In gui.c, fixed up a compiler warning.
Added a map from device id to file type and code to set a default filter
in the read dialog.
Wired up the 'save to XML' callback and reorganized the menue entries to
better distinguish between 'save to file' and 'store to device'.
In preset.c, sort the params so that what we write as XML more closely
matches what is generated on the windows side.
This commit is contained in:
6
Makefile
6
Makefile
@@ -1,10 +1,10 @@
|
|||||||
CC = gcc
|
CC = gcc
|
||||||
EXTRA_CFLAGS ?=
|
EXTRA_CFLAGS ?=
|
||||||
EXTRA_LDFLAGS ?=
|
EXTRA_LDFLAGS ?=
|
||||||
CFLAGS := $(shell pkg-config --cflags glib-2.0 gio-2.0 gtk+-3.0) -Wall -g -ansi -std=c99 $(EXTRA_CFLAGS)
|
CFLAGS := $(shell pkg-config --cflags glib-2.0 gio-2.0 gtk+-3.0 libxml-2.0) -Wall -g -ansi -std=c99 $(EXTRA_CFLAGS)
|
||||||
LDFLAGS = $(EXTRA_LDFLAGS) -Wl,--as-needed
|
LDFLAGS = $(EXTRA_LDFLAGS) -Wl,--as-needed
|
||||||
LDADD := $(shell pkg-config --libs glib-2.0 gio-2.0 gtk+-3.0 gthread-2.0 alsa) -lexpat
|
LDADD := $(shell pkg-config --libs glib-2.0 gio-2.0 gtk+-3.0 gthread-2.0 alsa libxml-2.0) -lexpat
|
||||||
OBJECTS = gdigi.o gui.o effects.o preset.o gtkknob.o
|
OBJECTS = gdigi.o gui.o effects.o preset.o gtkknob.o preset_xml.o
|
||||||
DEPFILES = $(foreach m,$(OBJECTS:.o=),.$(m).m)
|
DEPFILES = $(foreach m,$(OBJECTS:.o=),.$(m).m)
|
||||||
|
|
||||||
.PHONY : clean distclean all
|
.PHONY : clean distclean all
|
||||||
|
|||||||
15
effects.h
15
effects.h
@@ -19,7 +19,7 @@
|
|||||||
|
|
||||||
#include <glib.h>
|
#include <glib.h>
|
||||||
|
|
||||||
enum {
|
typedef enum {
|
||||||
VALUE_TYPE_PLAIN = 0, /**< value displayed directly */
|
VALUE_TYPE_PLAIN = 0, /**< value displayed directly */
|
||||||
VALUE_TYPE_SUFFIX = 1 << 0, /**< use suffix for displaying */
|
VALUE_TYPE_SUFFIX = 1 << 0, /**< use suffix for displaying */
|
||||||
VALUE_TYPE_OFFSET = 1 << 1, /**< use value offset */
|
VALUE_TYPE_OFFSET = 1 << 1, /**< use value offset */
|
||||||
@@ -27,6 +27,7 @@ enum {
|
|||||||
VALUE_TYPE_LABEL = 1 << 3, /**< use value labels (overrides any other option) */
|
VALUE_TYPE_LABEL = 1 << 3, /**< use value labels (overrides any other option) */
|
||||||
VALUE_TYPE_EXTRA = 1 << 4, /**< use extra values */
|
VALUE_TYPE_EXTRA = 1 << 4, /**< use extra values */
|
||||||
VALUE_TYPE_DECIMAL= 1 << 5, /**< display decimal places */
|
VALUE_TYPE_DECIMAL= 1 << 5, /**< display decimal places */
|
||||||
|
VALUE_TYPE_NONE = 1 << 6, /**< no value displayed */
|
||||||
} ValueType;
|
} ValueType;
|
||||||
|
|
||||||
typedef struct _EffectValues {
|
typedef struct _EffectValues {
|
||||||
@@ -93,6 +94,18 @@ typedef struct {
|
|||||||
PresetBank bank;
|
PresetBank bank;
|
||||||
} Banks;
|
} Banks;
|
||||||
|
|
||||||
|
enum product_id {
|
||||||
|
RP150 = 1,
|
||||||
|
RP250 = 2,
|
||||||
|
GNX4 = 3,
|
||||||
|
GNX3000 = 4,
|
||||||
|
RP500 = 5,
|
||||||
|
RP1000 = 6,
|
||||||
|
RP155 = 7,
|
||||||
|
RP255 = 8,
|
||||||
|
RP355 = 9,
|
||||||
|
};
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
gchar *name;
|
gchar *name;
|
||||||
unsigned char family_id;
|
unsigned char family_id;
|
||||||
|
|||||||
10
gdigi.c
10
gdigi.c
@@ -25,7 +25,7 @@
|
|||||||
|
|
||||||
static unsigned char device_id = 0x7F;
|
static unsigned char device_id = 0x7F;
|
||||||
static unsigned char family_id = 0x7F;
|
static unsigned char family_id = 0x7F;
|
||||||
static unsigned char product_id = 0x7F;
|
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;
|
||||||
@@ -265,10 +265,12 @@ void push_message(GString *msg)
|
|||||||
GDK_THREADS_ENTER();
|
GDK_THREADS_ENTER();
|
||||||
g_timeout_add(0, apply_current_preset_to_gui, NULL);
|
g_timeout_add(0, apply_current_preset_to_gui, NULL);
|
||||||
GDK_THREADS_LEAVE();
|
GDK_THREADS_LEAVE();
|
||||||
} else
|
} else {
|
||||||
g_message("%d %d moved to %d %d", str[9], str[10], str[11], str[12]);
|
g_message("%d %d moved to %d %d", str[9], str[10], str[11], str[12]);
|
||||||
|
}
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
g_message("Received unhandled device notification");
|
g_message("Received unhandled device notification 0x%x", str[11]);
|
||||||
}
|
}
|
||||||
g_string_free(msg, TRUE);
|
g_string_free(msg, TRUE);
|
||||||
return;
|
return;
|
||||||
@@ -300,7 +302,7 @@ gpointer read_data_thread(gboolean *stop)
|
|||||||
|
|
||||||
/* SysEx messages can't contain bytes with 8th bit set.
|
/* 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 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);
|
memset(buf, '\0', sizeof(buf));
|
||||||
|
|
||||||
err = poll(pfds, npfds, 200);
|
err = poll(pfds, npfds, 200);
|
||||||
if (err < 0 && errno == EINTR)
|
if (err < 0 && errno == EINTR)
|
||||||
|
|||||||
232
gdigi.h
232
gdigi.h
@@ -29,6 +29,8 @@
|
|||||||
#define GNX_CABINET_WARP 263
|
#define GNX_CABINET_WARP 263
|
||||||
#define GNX_CHANNEL_FS_MODE 264
|
#define GNX_CHANNEL_FS_MODE 264
|
||||||
|
|
||||||
|
unsigned char product_id;
|
||||||
|
|
||||||
enum {
|
enum {
|
||||||
GNX3K_WAH_TYPE_CRY = 129,
|
GNX3K_WAH_TYPE_CRY = 129,
|
||||||
GNX3K_WAH_TYPE_BOUTIQUE = 130,
|
GNX3K_WAH_TYPE_BOUTIQUE = 130,
|
||||||
@@ -48,6 +50,9 @@ enum {
|
|||||||
#define WAH_ON_OFF 129
|
#define WAH_ON_OFF 129
|
||||||
#define WAH_POSITION 3
|
#define WAH_POSITION 3
|
||||||
|
|
||||||
|
#define WAH_PEDAL_POSITION 132
|
||||||
|
#define WAH_VOLUME_BOOST 133
|
||||||
|
|
||||||
#define WAH_LEVEL 133
|
#define WAH_LEVEL 133
|
||||||
|
|
||||||
enum {
|
enum {
|
||||||
@@ -93,8 +98,8 @@ enum {
|
|||||||
#define COMP_OUTPUT 212
|
#define COMP_OUTPUT 212
|
||||||
|
|
||||||
enum {
|
enum {
|
||||||
|
PICKUP_TYPE_SC_HB = 65,
|
||||||
PICKUP_TYPE_HB_SC = 66,
|
PICKUP_TYPE_HB_SC = 66,
|
||||||
PICKUP_TYPE_SC_HB = 65
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#define PICKUP_TYPE 64
|
#define PICKUP_TYPE 64
|
||||||
@@ -227,6 +232,9 @@ enum {
|
|||||||
#define DIST_MP_TONE 2446
|
#define DIST_MP_TONE 2446
|
||||||
#define DIST_MP_VOLUME 2447
|
#define DIST_MP_VOLUME 2447
|
||||||
|
|
||||||
|
#define VOLUME_PRE_FX_POSITION 13
|
||||||
|
#define VOLUME_POST_FX_POSITION 17
|
||||||
|
|
||||||
#define PRESET_POSITION 18
|
#define PRESET_POSITION 18
|
||||||
#define PRESET_LEVEL 2626
|
#define PRESET_LEVEL 2626
|
||||||
|
|
||||||
@@ -239,7 +247,7 @@ enum {
|
|||||||
AMP_TYPE_BLACKFACE_DELUXE = 312,
|
AMP_TYPE_BLACKFACE_DELUXE = 312,
|
||||||
AMP_TYPE_PLEXI_JTM_45 = 313,
|
AMP_TYPE_PLEXI_JTM_45 = 313,
|
||||||
AMP_TYPE_SUPER_LEAD_PLEXI = 314,
|
AMP_TYPE_SUPER_LEAD_PLEXI = 314,
|
||||||
AMP_TYPE_PLEXI_JUMP_PANEL = 315,
|
AMP_TYPE_68_MARSHALL_JUMP = 315,
|
||||||
AMP_TYPE_MASTER_VOLUME = 316,
|
AMP_TYPE_MASTER_VOLUME = 316,
|
||||||
AMP_TYPE_JCM800 = 317,
|
AMP_TYPE_JCM800 = 317,
|
||||||
AMP_TYPE_JCM900 = 318,
|
AMP_TYPE_JCM900 = 318,
|
||||||
@@ -267,7 +275,7 @@ enum {
|
|||||||
AMP_TYPE_METAL = 332,
|
AMP_TYPE_METAL = 332,
|
||||||
AMP_TYPE_BRIGHT = 333,
|
AMP_TYPE_BRIGHT = 333,
|
||||||
AMP_TYPE_CHUNK = 334,
|
AMP_TYPE_CHUNK = 334,
|
||||||
AMP_TYPE_CLEAN = 335,
|
AMP_TYPE_DIGITECH_CLEAN = 335,
|
||||||
AMP_TYPE_HIGH_GAIN = 337,
|
AMP_TYPE_HIGH_GAIN = 337,
|
||||||
AMP_TYPE_BLUES = 338,
|
AMP_TYPE_BLUES = 338,
|
||||||
AMP_TYPE_FUZZ = 339,
|
AMP_TYPE_FUZZ = 339,
|
||||||
@@ -308,7 +316,7 @@ enum {
|
|||||||
#define AMP_TYPE 2496
|
#define AMP_TYPE 2496
|
||||||
#define AMP_ON_OFF 265
|
#define AMP_ON_OFF 265
|
||||||
#define AMP_POSITION 8
|
#define AMP_POSITION 8
|
||||||
#define CH2_AMP_POSITION 10
|
#define AMP_B_POSITION 10
|
||||||
|
|
||||||
#define AMP_LOOP_ON_OFF 3649
|
#define AMP_LOOP_ON_OFF 3649
|
||||||
#define AMP_LOOP_POSITION 33
|
#define AMP_LOOP_POSITION 33
|
||||||
@@ -316,11 +324,12 @@ enum {
|
|||||||
#define AMP_BYPASS_ON_OFF 12361
|
#define AMP_BYPASS_ON_OFF 12361
|
||||||
#define AMP_BYPASS_POSITION 0
|
#define AMP_BYPASS_POSITION 0
|
||||||
|
|
||||||
#define AMP_SELECT 256
|
#define AMP_CHANNEL 256
|
||||||
#define AMP_SELECT_POSITION 7
|
#define AMP_CHANNEL_POSITION 7
|
||||||
|
|
||||||
#define AMP_CHANNEL_A 0
|
#define AMP_CHANNEL_A 0
|
||||||
#define AMP_CHANNEL_B 1
|
#define AMP_CHANNEL_B 1
|
||||||
|
#define AMP_CHANNEL_WARP 2
|
||||||
|
|
||||||
#define AMP_GAIN 2497
|
#define AMP_GAIN 2497
|
||||||
#define AMP_LEVEL 2498
|
#define AMP_LEVEL 2498
|
||||||
@@ -339,7 +348,7 @@ enum {
|
|||||||
#define AMP_CAB_TYPE 2560
|
#define AMP_CAB_TYPE 2560
|
||||||
#define AMP_CAB_TUNING 2561
|
#define AMP_CAB_TUNING 2561
|
||||||
#define AMP_CAB_POSITION 9
|
#define AMP_CAB_POSITION 9
|
||||||
#define CH2_AMP_CAB_POSITION 11
|
#define AMP_CAB_B_POSITION 11
|
||||||
|
|
||||||
enum {
|
enum {
|
||||||
AMP_CAB_DIRECT = 570,
|
AMP_CAB_DIRECT = 570,
|
||||||
@@ -406,23 +415,24 @@ enum {
|
|||||||
GNX_AMP_CAB_SVT_BASS8_10 = 595,
|
GNX_AMP_CAB_SVT_BASS8_10 = 595,
|
||||||
};
|
};
|
||||||
|
|
||||||
#define EQ_TYPE 3202
|
#define EQ_A_POSITION 24
|
||||||
#define EQ_ON_OFF 3212
|
#define EQ_B_POSITION 25
|
||||||
#define EQ_POSITION 24
|
|
||||||
#define EQ_POSITION_B 25
|
|
||||||
|
|
||||||
|
#define EQ_TYPE 3202
|
||||||
#define EQ_BASS 3203
|
#define EQ_BASS 3203
|
||||||
#define EQ_MID 3204
|
#define EQ_MID 3204
|
||||||
#define EQ_MID_HZ 3206
|
#define EQ_TREB 3205
|
||||||
#define EQ_TREBLE 3205
|
#define EQ_MID_FREQ 3206
|
||||||
#define EQ_PRESENCE 3207
|
#define EQ_PRESENCE 3207
|
||||||
#define EQ_TREBLE_HZ 3211
|
#define EQ_TREB_FREQ 3211
|
||||||
#define EQ_LOW_LEVEL 3203
|
#define EQ_ENABLE 3212
|
||||||
#define EQ_MID_LEVEL 3204
|
|
||||||
#define EQ_HIGH_LEVEL 3205
|
|
||||||
#define EQ_LOW_FREQ 3213
|
#define EQ_LOW_FREQ 3213
|
||||||
#define EQ_MID_FREQ 3214
|
#define EQ_MID_FREQ_XXX 3214
|
||||||
#define EQ_HIGH_FREQ 3215
|
#define EQ_HIGH_FREQ 3215
|
||||||
|
|
||||||
|
#define EQ_TREBLE_FREQ 3215
|
||||||
#define EQ_LOW_BANDWIDTH 3216
|
#define EQ_LOW_BANDWIDTH 3216
|
||||||
#define EQ_MID_BANDWIDTH 3217
|
#define EQ_MID_BANDWIDTH 3217
|
||||||
#define EQ_HIGH_BANDWIDTH 3218
|
#define EQ_HIGH_BANDWIDTH 3218
|
||||||
@@ -467,49 +477,54 @@ enum {
|
|||||||
};
|
};
|
||||||
|
|
||||||
enum {
|
enum {
|
||||||
CHORUS_TYPE_CE = 0x37B,
|
CHORUS_TYPE_CE = 891,
|
||||||
CHORUS_TYPE_TC = 0x37C,
|
CHORUS_TYPE_TC = 892,
|
||||||
CHORUS_TYPE_DUAL = 0x379,
|
CHORUS_TYPE_DUAL = 889,
|
||||||
CHORUS_TYPE_GLISTEN = 0x392,
|
CHORUS_TYPE_GLISTEN = 914,
|
||||||
CHORUS_TYPE_MULTI = 0x37a,
|
CHORUS_TYPE_MULTI = 890,
|
||||||
CHORUS_TYPE_VOO_DOO = 0x396,
|
CHORUS_TYPE_VOO_DOO = 918,
|
||||||
CHORUS_TYPE_CLONE = 0x397,
|
CHORUS_TYPE_CLONE = 919,
|
||||||
CHORUS_TYPE_FLANGER = 0x37d,
|
CHORUS_TYPE_FLANGER = 893,
|
||||||
CHORUS_TYPE_TRIGGERED_FLANGER = 0x37e,
|
CHORUS_TYPE_TRIGGERED_FLANGER = 894,
|
||||||
CHORUS_TYPE_FLTFLANGER = 0x398,
|
CHORUS_TYPE_FLTFLANGER = 920,
|
||||||
CHORUS_TYPE_MXR_FLANGER = 0x37f,
|
CHORUS_TYPE_MXR_FLANGER = 895,
|
||||||
CHORUS_TYPE_EH_FLANGER = 0x380,
|
CHORUS_TYPE_EH_FLANGER = 896,
|
||||||
CHORUS_TYPE_AD_FLANGER = 0x393,
|
CHORUS_TYPE_AD_FLANGER = 915,
|
||||||
CHORUS_TYPE_PHASER = 0x381,
|
CHORUS_TYPE_PHASER = 897,
|
||||||
CHORUS_TYPE_TRIGGERED_PHASER = 0x382,
|
CHORUS_TYPE_TRIGGERED_PHASER = 898,
|
||||||
CHORUS_TYPE_MX_PHASER = 0x383,
|
CHORUS_TYPE_MX_PHASER = 899,
|
||||||
CHORUS_TYPE_EH_PHASER = 0x384,
|
CHORUS_TYPE_EH_PHASER = 900,
|
||||||
CHORUS_TYPE_VIBRATO = 0x360,
|
CHORUS_TYPE_VIBRATO = 864,
|
||||||
CHORUS_TYPE_ROTARY = 0x361,
|
CHORUS_TYPE_ROTARY = 865,
|
||||||
CHORUS_TYPE_VIBROPAN = 0x38f,
|
CHORUS_TYPE_VIBROPAN = 911,
|
||||||
CHORUS_TYPE_UNOVIBE = 0x390,
|
CHORUS_TYPE_UNOVIBE = 912,
|
||||||
CHORUS_TYPE_TREMOLO = 0x35e,
|
CHORUS_TYPE_TREMOLO = 862,
|
||||||
CHORUS_TYPE_SCATTER_TREM = 0x394,
|
CHORUS_TYPE_SCATTER_TREM = 916,
|
||||||
CHORUS_TYPE_OPTO_TREMOLO = 0x388,
|
CHORUS_TYPE_OPTO_TREMOLO = 904,
|
||||||
CHORUS_TYPE_BIAS_TREMOLO = 0x389,
|
CHORUS_TYPE_BIAS_TREMOLO = 905,
|
||||||
CHORUS_TYPE_PANNER = 0x35f,
|
CHORUS_TYPE_PANNER = 863,
|
||||||
CHORUS_TYPE_ENVELOPE = 0x38a,
|
CHORUS_TYPE_ENVELOPE = 906,
|
||||||
CHORUS_TYPE_FX25 = 0x38e,
|
CHORUS_TYPE_FX25 = 910,
|
||||||
CHORUS_TYPE_AUTOYA = 0x38b,
|
CHORUS_TYPE_AUTOYA = 907,
|
||||||
CHORUS_TYPE_YAYA = 0x38c,
|
CHORUS_TYPE_YAYA = 908,
|
||||||
CHORUS_TYPE_SYNTH_TALK = 0x391,
|
CHORUS_TYPE_SYNTH_TALK = 913,
|
||||||
CHORUS_TYPE_STEP_FILTER = 0x38d,
|
CHORUS_TYPE_STEP_FILTER = 909,
|
||||||
CHORUS_TYPE_SAMPLE_HOLD = 0x395,
|
CHORUS_TYPE_SAMPLE_HOLD = 917,
|
||||||
CHORUS_TYPE_WHAMMY = 0x540,
|
CHORUS_TYPE_WHAMMY = 1344,
|
||||||
CHORUS_TYPE_PITCH_SHIFT = 0x543,
|
CHORUS_TYPE_PITCH_SHIFT = 1347,
|
||||||
CHORUS_TYPE_DETUNE = 0x542,
|
CHORUS_TYPE_DETUNE = 1346,
|
||||||
CHORUS_TYPE_IPS = 0x541,
|
CHORUS_TYPE_IPS = 1345, // Also known as Harmony
|
||||||
CHORUS_TYPE_OCTAVER = 0x385,
|
CHORUS_TYPE_OCTAVER = 901,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#define MOD_TYPE 768
|
||||||
|
#define MOD_POSITION 768
|
||||||
|
#define MOD_PRE_POST 1798
|
||||||
|
|
||||||
#define CHORUSFX_TYPE 768
|
#define CHORUSFX_TYPE 768
|
||||||
#define CHORUSFX_ON_OFF 769
|
#define CHORUSFX_ON_OFF 769
|
||||||
#define CHORUSFX_PRE_POST 770
|
#define CHORUSFX_PRE_POST 770
|
||||||
|
|
||||||
#define CHORUSFX_POSITION 14
|
#define CHORUSFX_POSITION 14
|
||||||
#define CHORUSFX_PRE 1543
|
#define CHORUSFX_PRE 1543
|
||||||
#define CHORUSFX_POST 1544
|
#define CHORUSFX_POST 1544
|
||||||
@@ -521,6 +536,12 @@ enum {
|
|||||||
#define CHORUS_WIDTH 848
|
#define CHORUS_WIDTH 848
|
||||||
#define CHORUS_INTENSITY 849
|
#define CHORUS_INTENSITY 849
|
||||||
|
|
||||||
|
enum {
|
||||||
|
CHORUS_WAVEFORM_TRI = 0,
|
||||||
|
CHORUS_WAVEFORM_SINE = 1,
|
||||||
|
CHORUS_WAVEFORM_SQUARE = 2,
|
||||||
|
};
|
||||||
|
|
||||||
#define CHORUS_LEVEL 836
|
#define CHORUS_LEVEL 836
|
||||||
#define CHORUS_WAVE 840
|
#define CHORUS_WAVE 840
|
||||||
#define CHORUS_BALANCE 841
|
#define CHORUS_BALANCE 841
|
||||||
@@ -638,6 +659,25 @@ enum {
|
|||||||
#define WHAMMY_PEDAL 1795
|
#define WHAMMY_PEDAL 1795
|
||||||
#define WHAMMY_MIX 1796
|
#define WHAMMY_MIX 1796
|
||||||
|
|
||||||
|
enum whammy_amt {
|
||||||
|
WHAMMY_TYPE_OCT_UP = 0,
|
||||||
|
WHAMMY_TYPE_2OCT_UP = 1,
|
||||||
|
WHAMMY_TYPE_2ND_DN = 2,
|
||||||
|
WHAMMY_TYPE_RV2ND_DN = 3,
|
||||||
|
WHAMMY_TYPE_4TH_DN = 4,
|
||||||
|
WHAMMY_TYPE_OCT_DN = 5,
|
||||||
|
WHAMMY_TYPE_2OCT_DN = 6,
|
||||||
|
WHAMMY_TYPE_DIV_BMB = 7,
|
||||||
|
WHAMMY_TYPE_M3_GT_MA3 = 8,
|
||||||
|
WHAMMY_TYPE_2ND_MA3 = 9,
|
||||||
|
WHAMMY_TYPE_3RD_4TH = 10,
|
||||||
|
WHAMMY_TYPE_4TH_5TH = 11,
|
||||||
|
WHAMMY_TYPE_5TH_OCT = 12,
|
||||||
|
WHAMMY_TYPE_HOCT_UP = 13,
|
||||||
|
WHAMMY_TYPE_HOCT_DN = 14,
|
||||||
|
WHAMMY_TYPE_OCT_GT_D = 15,
|
||||||
|
};
|
||||||
|
|
||||||
#define PITCH_AMOUNT 1730
|
#define PITCH_AMOUNT 1730
|
||||||
#define PITCH_BALANCE 1733
|
#define PITCH_BALANCE 1733
|
||||||
#define PITCH_MIX 1745
|
#define PITCH_MIX 1745
|
||||||
@@ -651,6 +691,47 @@ enum {
|
|||||||
#define IPS_SCALE 2755
|
#define IPS_SCALE 2755
|
||||||
#define IPS_LEVEL 2757
|
#define IPS_LEVEL 2757
|
||||||
|
|
||||||
|
enum {
|
||||||
|
IPS_KEY_E = 0,
|
||||||
|
IPS_KEY_F = 1,
|
||||||
|
IPS_KEY_Gb = 2,
|
||||||
|
IPS_KEY_G = 3,
|
||||||
|
IPS_KEY_Ab = 4,
|
||||||
|
IPS_KEY_A = 5,
|
||||||
|
IPS_KEY_Bb = 6,
|
||||||
|
IPS_KEY_B = 7,
|
||||||
|
IPS_KEY_C = 8,
|
||||||
|
IPS_KEY_Db = 9,
|
||||||
|
IPS_KEY_D = 10,
|
||||||
|
IPS_KEY_Eb = 11,
|
||||||
|
};
|
||||||
|
|
||||||
|
enum {
|
||||||
|
IPS_SHIFT_OCT_DN = 0,
|
||||||
|
IPS_SHIFT_7TH_DN = 1,
|
||||||
|
IPS_SHIFT_6TH_DN = 2,
|
||||||
|
IPS_SHIFT_5TH_DN = 3,
|
||||||
|
IPS_SHIFT_4TH_DN = 4,
|
||||||
|
IPS_SHIFT_3RD_DN = 5,
|
||||||
|
IPS_SHIFT_2ND_DN = 6,
|
||||||
|
IPS_SHIFT_2ND_UP = 7,
|
||||||
|
IPS_SHIFT_3RD_UP = 8,
|
||||||
|
IPS_SHIFT_4TH_UP = 9,
|
||||||
|
IPS_SHIFT_5TH_UP = 10,
|
||||||
|
IPS_SHIFT_6TH_UP = 11,
|
||||||
|
IPS_SHIFT_7TH_UP = 12,
|
||||||
|
IPS_SHIFT_OCT_UP = 13,
|
||||||
|
};
|
||||||
|
|
||||||
|
enum {
|
||||||
|
IPS_SCALE_MAJOR = 0,
|
||||||
|
IPS_SCALE_MINOR = 1,
|
||||||
|
IPS_SCALE_DORIAN = 2,
|
||||||
|
IPS_SCALE_MIXOLYDIAN = 3,
|
||||||
|
IPS_SCALE_LYDIAN = 4,
|
||||||
|
IPS_SCALE_HMINOR = 5,
|
||||||
|
};
|
||||||
|
|
||||||
#define OCTAVER_OCTAVE1 1746
|
#define OCTAVER_OCTAVE1 1746
|
||||||
#define OCTAVER_OCTAVE2 1747
|
#define OCTAVER_OCTAVE2 1747
|
||||||
#define OCTAVER_DRY_LEVEL 1748
|
#define OCTAVER_DRY_LEVEL 1748
|
||||||
@@ -757,19 +838,58 @@ enum {
|
|||||||
#define REVERB_LEVEL 1925
|
#define REVERB_LEVEL 1925
|
||||||
|
|
||||||
#define EXP_TYPE 8194
|
#define EXP_TYPE 8194
|
||||||
|
#define EXP_ASSIGN1 8194
|
||||||
#define EXP_POSITION 19
|
#define EXP_POSITION 19
|
||||||
|
|
||||||
|
#define EXP_VOLUME_PRE_FX 854594
|
||||||
|
#define EXP_VOLUME_POST_FX 1116738
|
||||||
|
|
||||||
#define EXP_MIN 8195
|
#define EXP_MIN 8195
|
||||||
#define EXP_MAX 8196
|
#define EXP_MAX 8196
|
||||||
|
|
||||||
#define LFO_TYPE 8258
|
#define LFO_TYPE 8258
|
||||||
|
#define LFO_MIN 8259
|
||||||
|
#define LFO_MAX 8260
|
||||||
|
#define LFO_SPEED 8262
|
||||||
|
#define LFO_WAVEFORM 8263
|
||||||
|
|
||||||
|
#define LFO_WAVEFORM_TRI 0
|
||||||
|
#define LFO_WAVEFORM_SINE 1
|
||||||
|
#define LFO_WAVEFORM_SQUARE 2
|
||||||
|
|
||||||
#define LFO1_POSITION 22
|
#define LFO1_POSITION 22
|
||||||
#define LFO2_POSITION 23
|
#define LFO2_POSITION 23
|
||||||
|
|
||||||
|
// The LFO and VSWITCH defines are temporary.
|
||||||
|
#define LFO_ASSIGN_NONE 0
|
||||||
|
#define LFO_ASSIGN_PICKUP_ON 131137
|
||||||
|
#define LFO_ASSIGN_COMP_ON 262337
|
||||||
|
#define LFO_ASSIGN_SUSTAN 262352
|
||||||
|
|
||||||
|
#define VSWITCH_ASSIGN 8384
|
||||||
|
#define VSWITCH_MIN 8385
|
||||||
|
#define VSWITCH_MAX 8386
|
||||||
|
#define VSWITCH_TYPE 8393
|
||||||
|
#define VSWITCH_ENABLE 8449
|
||||||
|
#define VSWITCH_ASSIGN_POSITION 21
|
||||||
|
|
||||||
|
#define VSWITCH_TYPE_TOGGLE 0
|
||||||
|
#define VSWITCH_PEDAL_ASSIGN_WAH 196740
|
||||||
|
#define VSWITCH_ASSIGN_WAH_ENABLE 196737
|
||||||
|
|
||||||
#define LIBRARY_TONE 8704
|
#define LIBRARY_TONE 8704
|
||||||
#define LIBRARY_EFFECTS 8705
|
#define LIBRARY_EFFECTS 8705
|
||||||
#define EFFECTS_LEVEL 8706
|
#define EFFECTS_LEVEL 8706
|
||||||
|
|
||||||
#define LIBRARY_POSITION 25
|
#define LIBRARY_POSITION 25
|
||||||
|
#define LIB_POSITION 26
|
||||||
|
|
||||||
|
#define TONE_LIB_TYPE 8704
|
||||||
|
#define FX_LIB_TYPE 8705
|
||||||
|
#define FX_LIB_LEVEL 8706
|
||||||
|
#define FX_LIB_LEVEL_MAX1 8708
|
||||||
|
#define FX_LIB_LEVEL_MAX2 8710
|
||||||
|
#define FX_LIB_LEVEL_MAX3 8712
|
||||||
|
|
||||||
enum {
|
enum {
|
||||||
TONE_LIB_OVERDRIVE = 1793,
|
TONE_LIB_OVERDRIVE = 1793,
|
||||||
|
|||||||
39
gdigi_xml.h
Normal file
39
gdigi_xml.h
Normal file
@@ -0,0 +1,39 @@
|
|||||||
|
/*
|
||||||
|
* 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_XML_H
|
||||||
|
#define GDIGI_XML_H
|
||||||
|
|
||||||
|
#include <glib.h>
|
||||||
|
#include "effects.h"
|
||||||
|
typedef struct {
|
||||||
|
guint type;
|
||||||
|
gchar *label;
|
||||||
|
} XmlLabel;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
guint id;
|
||||||
|
guint position;
|
||||||
|
gchar *label;
|
||||||
|
EffectValues *values;
|
||||||
|
XmlLabel *xml_labels; /* 'type' id's have a label group. */
|
||||||
|
guint xml_labels_amt;
|
||||||
|
} XmlSettings;
|
||||||
|
|
||||||
|
// XmlSettings *get_xml_settings(guint id, guint position);
|
||||||
|
// gchar *get_xml_label(guint id, guint position, gint type);
|
||||||
|
|
||||||
|
#endif /* GDIGI_XML_H */
|
||||||
103
gui.c
103
gui.c
@@ -51,7 +51,7 @@ void show_error_message(GtkWidget *parent, gchar *message)
|
|||||||
GTK_DIALOG_MODAL,
|
GTK_DIALOG_MODAL,
|
||||||
GTK_MESSAGE_ERROR,
|
GTK_MESSAGE_ERROR,
|
||||||
GTK_BUTTONS_OK,
|
GTK_BUTTONS_OK,
|
||||||
message);
|
"%s", message);
|
||||||
|
|
||||||
gtk_dialog_run(GTK_DIALOG(msg));
|
gtk_dialog_run(GTK_DIALOG(msg));
|
||||||
gtk_widget_destroy(msg);
|
gtk_widget_destroy(msg);
|
||||||
@@ -861,20 +861,25 @@ typedef struct {
|
|||||||
gchar *suffix;
|
gchar *suffix;
|
||||||
} SupportedFileTypes;
|
} SupportedFileTypes;
|
||||||
|
|
||||||
static SupportedFileTypes file_types[] = {
|
SupportedFileTypes file_types[] = {
|
||||||
{"RP150Preset", "*.rp150p"},
|
[ RP150] = {"RP150Preset", "*.rp150p"},
|
||||||
{"RP155Preset", "*.rp155p"},
|
[ RP155 ] = {"RP155Preset", "*.rp155p"},
|
||||||
{"RP250Preset", "*.rp250p"},
|
[ RP250 ] = {"RP250Preset", "*.rp250p"},
|
||||||
{"RP255Preset", "*.rp255p"},
|
[ RP255 ] = {"RP255Preset", "*.rp255p"},
|
||||||
{"RP355Preset", "*.rp355p"},
|
[ RP355 ] = {"RP355Preset", "*.rp355p"},
|
||||||
{"RP500Preset", "*.rp500p"},
|
[ RP500 ] = {"RP500Preset", "*.rp500p"},
|
||||||
{"RP1000Preset", "*.rp1000p"},
|
[ RP1000 ] = {"RP1000Preset", "*.rp1000p"},
|
||||||
{"GNX4 Preset", "*.g4p"},
|
[ GNX4 ] = {"GNX4 Preset", "*.g4p"},
|
||||||
{"GNX3kPreset", "*.g3kp"},
|
[ GNX3000 ] = {"GNX3kPreset", "*.g3kp"},
|
||||||
};
|
};
|
||||||
|
|
||||||
static guint n_file_types = G_N_ELEMENTS(file_types);
|
static guint n_file_types = G_N_ELEMENTS(file_types);
|
||||||
|
|
||||||
|
gchar *
|
||||||
|
get_preset_filename (int prod_id)
|
||||||
|
{
|
||||||
|
return file_types[prod_id].name;
|
||||||
|
}
|
||||||
#endif /* DOXYGEN_SHOULD_SKIP_THIS */
|
#endif /* DOXYGEN_SHOULD_SKIP_THIS */
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -906,12 +911,21 @@ static void action_open_preset_cb(GtkAction *action)
|
|||||||
int x;
|
int x;
|
||||||
for (x=0; x<n_file_types; x++) {
|
for (x=0; x<n_file_types; x++) {
|
||||||
GtkFileFilter *current_filter = gtk_file_filter_new();
|
GtkFileFilter *current_filter = gtk_file_filter_new();
|
||||||
|
if (file_types[x].name == NULL) {
|
||||||
|
g_message("Skipping NULL array entry");
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
gtk_file_filter_set_name(current_filter, file_types[x].name);
|
gtk_file_filter_set_name(current_filter, file_types[x].name);
|
||||||
gtk_file_filter_add_pattern(current_filter, file_types[x].suffix);
|
gtk_file_filter_add_pattern(current_filter, file_types[x].suffix);
|
||||||
gtk_file_filter_add_pattern(filter, file_types[x].suffix);
|
gtk_file_filter_add_pattern(filter, file_types[x].suffix);
|
||||||
|
|
||||||
gtk_file_chooser_add_filter(GTK_FILE_CHOOSER(dialog), current_filter);
|
gtk_file_chooser_add_filter(GTK_FILE_CHOOSER(dialog), current_filter);
|
||||||
|
if (x == product_id) {
|
||||||
|
|
||||||
|
gtk_file_chooser_set_filter(GTK_FILE_CHOOSER(dialog), current_filter);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
gboolean loaded = FALSE;
|
gboolean loaded = FALSE;
|
||||||
@@ -1009,6 +1023,57 @@ static void action_open_preset_cb(GtkAction *action)
|
|||||||
dialog = NULL;
|
dialog = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \param action the object which emitted the signal
|
||||||
|
*
|
||||||
|
* Shows file chooser dialog.
|
||||||
|
* If the user chooses a file, the preset in the edit buffer is
|
||||||
|
* written out in XML format.
|
||||||
|
**/
|
||||||
|
static void action_save_preset_cb(GtkAction *action)
|
||||||
|
{
|
||||||
|
static GtkWidget *dialog = NULL;
|
||||||
|
|
||||||
|
if (dialog != NULL)
|
||||||
|
return;
|
||||||
|
|
||||||
|
GtkWidget *window = g_object_get_data(G_OBJECT(action), "window");
|
||||||
|
|
||||||
|
dialog = gtk_file_chooser_dialog_new("Save Preset", GTK_WINDOW(window),
|
||||||
|
GTK_FILE_CHOOSER_ACTION_SAVE,
|
||||||
|
GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
|
||||||
|
GTK_STOCK_SAVE, GTK_RESPONSE_ACCEPT,
|
||||||
|
NULL);
|
||||||
|
if (gtk_dialog_run(GTK_DIALOG(dialog)) == GTK_RESPONSE_ACCEPT) {
|
||||||
|
GError *error = NULL;
|
||||||
|
gchar *filename = gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(dialog));
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
if (error) {
|
||||||
|
show_error_message(window, error->message);
|
||||||
|
g_error_free(error);
|
||||||
|
error = NULL;
|
||||||
|
} else {
|
||||||
|
gchar real_filename[256];
|
||||||
|
GList *list = get_current_preset();
|
||||||
|
Preset *preset = create_preset_from_data(list);
|
||||||
|
|
||||||
|
snprintf(real_filename, 256, "%s.%s",
|
||||||
|
filename, file_types[product_id].suffix + 2);
|
||||||
|
|
||||||
|
gtk_widget_hide(dialog);
|
||||||
|
write_preset_to_xml(preset, real_filename);
|
||||||
|
|
||||||
|
preset_free(preset);
|
||||||
|
}
|
||||||
|
g_free(filename);
|
||||||
|
}
|
||||||
|
|
||||||
|
gtk_widget_destroy(dialog);
|
||||||
|
dialog = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* \param list widget tree list to be freed
|
* \param list widget tree list to be freed
|
||||||
*
|
*
|
||||||
@@ -1040,11 +1105,12 @@ static void action_quit_cb(GtkAction *action)
|
|||||||
|
|
||||||
static GtkActionEntry entries[] = {
|
static GtkActionEntry entries[] = {
|
||||||
{"File", NULL, "_File"},
|
{"File", NULL, "_File"},
|
||||||
{"Preset", NULL, "_Preset"},
|
|
||||||
{"Help", NULL, "_Help"},
|
|
||||||
{"Open", GTK_STOCK_OPEN, "_Open", "<control>O", "Open preset file", G_CALLBACK(action_open_preset_cb)},
|
|
||||||
{"Quit", GTK_STOCK_QUIT, "_Quit", "<control>Q", "Quit", G_CALLBACK(action_quit_cb)},
|
{"Quit", GTK_STOCK_QUIT, "_Quit", "<control>Q", "Quit", G_CALLBACK(action_quit_cb)},
|
||||||
{"Store", NULL, "_Store", "<control>S", "Store", G_CALLBACK(action_store_cb)},
|
{"Preset", NULL, "_Preset"},
|
||||||
|
{"Store", NULL, "_Store Preset to Device", "<control>D", "Store Preset to Device", G_CALLBACK(action_store_cb)},
|
||||||
|
{"Load", GTK_STOCK_OPEN, "_Load Preset from File", "<control>O", "Load Preset from File", G_CALLBACK(action_open_preset_cb)},
|
||||||
|
{"Save", GTK_STOCK_SAVE, "_Save Preset to File", "<control>S", "Save Preset to File", G_CALLBACK(action_save_preset_cb)},
|
||||||
|
{"Help", NULL, "_Help"},
|
||||||
{"About", GTK_STOCK_ABOUT, "_About", "<control>A", "About", G_CALLBACK(action_show_about_dialog_cb)},
|
{"About", GTK_STOCK_ABOUT, "_About", "<control>A", "About", G_CALLBACK(action_show_about_dialog_cb)},
|
||||||
};
|
};
|
||||||
static guint n_entries = G_N_ELEMENTS(entries);
|
static guint n_entries = G_N_ELEMENTS(entries);
|
||||||
@@ -1053,12 +1119,14 @@ static const gchar *menu_info =
|
|||||||
"<ui>"
|
"<ui>"
|
||||||
" <menubar name='MenuBar'>"
|
" <menubar name='MenuBar'>"
|
||||||
" <menu action='File'>"
|
" <menu action='File'>"
|
||||||
" <menuitem action='Open'/>"
|
|
||||||
" <separator/>"
|
" <separator/>"
|
||||||
" <menuitem action='Quit'/>"
|
" <menuitem action='Quit'/>"
|
||||||
" </menu>"
|
" </menu>"
|
||||||
" <menu action='Preset'>"
|
" <menu action='Preset'>"
|
||||||
" <menuitem action='Store'/>"
|
" <menuitem action='Store'/>"
|
||||||
|
" <separator/>"
|
||||||
|
" <menuitem action='Load'/>"
|
||||||
|
" <menuitem action='Save'/>"
|
||||||
" </menu>"
|
" </menu>"
|
||||||
" <menu action='Help'>"
|
" <menu action='Help'>"
|
||||||
" <menuitem action='About'/>"
|
" <menuitem action='About'/>"
|
||||||
@@ -1115,8 +1183,9 @@ static void add_menubar(GtkWidget *window, GtkWidget *vbox)
|
|||||||
FALSE, FALSE, 0);
|
FALSE, FALSE, 0);
|
||||||
|
|
||||||
add_action_data(ui, "/MenuBar/File/Quit", window);
|
add_action_data(ui, "/MenuBar/File/Quit", window);
|
||||||
add_action_data(ui, "/MenuBar/File/Open", window);
|
|
||||||
add_action_data(ui, "/MenuBar/Preset/Store", window);
|
add_action_data(ui, "/MenuBar/Preset/Store", window);
|
||||||
|
add_action_data(ui, "/MenuBar/Preset/Save", window);
|
||||||
|
add_action_data(ui, "/MenuBar/Preset/Load", window);
|
||||||
add_action_data(ui, "/MenuBar/Help/About", window);
|
add_action_data(ui, "/MenuBar/Help/About", window);
|
||||||
|
|
||||||
g_object_unref(ui);
|
g_object_unref(ui);
|
||||||
|
|||||||
2
gui.h
2
gui.h
@@ -17,9 +17,11 @@
|
|||||||
#ifndef GDIGI_GUI_H
|
#ifndef GDIGI_GUI_H
|
||||||
#define GDIGI_GUI_H
|
#define GDIGI_GUI_H
|
||||||
|
|
||||||
|
#include <gtk/gtk.h>
|
||||||
#include <glib.h>
|
#include <glib.h>
|
||||||
#include "effects.h"
|
#include "effects.h"
|
||||||
|
|
||||||
|
gchar * get_preset_filename(int prod_id);
|
||||||
void show_error_message(GtkWidget *parent, gchar *message);
|
void show_error_message(GtkWidget *parent, gchar *message);
|
||||||
void apply_setting_param_to_gui(SettingParam *param);
|
void apply_setting_param_to_gui(SettingParam *param);
|
||||||
gboolean apply_current_preset_to_gui(gpointer data);
|
gboolean apply_current_preset_to_gui(gpointer data);
|
||||||
|
|||||||
17
preset.c
17
preset.c
@@ -260,6 +260,21 @@ Preset *create_preset_from_xml_file(gchar *filename, GError **error)
|
|||||||
return preset;
|
return preset;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
gint params_cmp(gconstpointer a, gconstpointer b)
|
||||||
|
{
|
||||||
|
const SettingParam *param_a = a;
|
||||||
|
const SettingParam *param_b = b;
|
||||||
|
|
||||||
|
if (param_a->position != param_b->position) {
|
||||||
|
return (param_a->position > param_b->position) ? 1 : -1;
|
||||||
|
}
|
||||||
|
if (param_a->id != param_b->id) {
|
||||||
|
return (param_a->id > param_b->id) ? 1 : -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* \param list list containing unpacked preset SysEx messages.
|
* \param list list containing unpacked preset SysEx messages.
|
||||||
*
|
*
|
||||||
@@ -314,7 +329,7 @@ Preset *create_preset_from_data(GList *list)
|
|||||||
g_message("%d ID %d Position %d Value %d", n, param->id, param->position, param->value);
|
g_message("%d ID %d Position %d Value %d", n, param->id, param->position, param->value);
|
||||||
} while ((x < data->len) && n<total);
|
} while ((x < data->len) && n<total);
|
||||||
g_message("TOTAL %d", total);
|
g_message("TOTAL %d", total);
|
||||||
preset->params = g_list_reverse(preset->params);
|
preset->params = g_list_sort(preset->params, params_cmp);
|
||||||
break;
|
break;
|
||||||
case RECEIVE_PRESET_END:
|
case RECEIVE_PRESET_END:
|
||||||
break;
|
break;
|
||||||
|
|||||||
2
preset.h
2
preset.h
@@ -28,5 +28,5 @@ typedef struct {
|
|||||||
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(GList *list);
|
Preset *create_preset_from_data(GList *list);
|
||||||
void preset_free(Preset *preset);
|
void preset_free(Preset *preset);
|
||||||
|
void write_preset_to_xml(Preset *preset, gchar *filename);
|
||||||
#endif /* GDIGI_PRESET_H */
|
#endif /* GDIGI_PRESET_H */
|
||||||
|
|||||||
262
preset_xml.c
Normal file
262
preset_xml.c
Normal file
@@ -0,0 +1,262 @@
|
|||||||
|
/*
|
||||||
|
* 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 <gio/gio.h>
|
||||||
|
#include <expat.h>
|
||||||
|
#include <libxml/encoding.h>
|
||||||
|
#include <libxml/xmlreader.h>
|
||||||
|
#include <libxml/xmlwriter.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include "preset.h"
|
||||||
|
#include "gdigi.h"
|
||||||
|
#include "gui.h"
|
||||||
|
#include "gdigi_xml.h"
|
||||||
|
|
||||||
|
#ifndef DOXYGEN_SHOULD_SKIP_THIS
|
||||||
|
// FIXME: Bring the xml settings into this module?
|
||||||
|
extern XmlSettings xml_settings[];
|
||||||
|
extern guint n_xml_settings;
|
||||||
|
extern EffectValues values_on_off;
|
||||||
|
/**
|
||||||
|
* \param id modifier ID
|
||||||
|
* \param position modifier position
|
||||||
|
*
|
||||||
|
* Gets modifier info.
|
||||||
|
*
|
||||||
|
* \return Modifier which must not be freed, or NULL if no matching Modifier has been found.
|
||||||
|
*/
|
||||||
|
XmlSettings *get_xml_settings (guint id, guint position)
|
||||||
|
{
|
||||||
|
gint x;
|
||||||
|
|
||||||
|
for (x=0; x< n_xml_settings; x++) {
|
||||||
|
if ((xml_settings[x].id == id) && (xml_settings[x].position == position)) {
|
||||||
|
return xml_settings + x;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
gchar *
|
||||||
|
map_xml_value(XmlSettings *xml, gint value)
|
||||||
|
{
|
||||||
|
switch (xml->values->type) {
|
||||||
|
case VALUE_TYPE_LABEL:
|
||||||
|
if ((xml->values == &values_on_off) && (value > 1)) {
|
||||||
|
g_message("Skipping modifier->label %s\n", xml->label);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
if (value > xml->values->max || value < xml->values->min) {
|
||||||
|
g_message("%s value %d out of range %0.1f %0.1f", xml->label, value, xml->values->min, xml->values->max);
|
||||||
|
}
|
||||||
|
{
|
||||||
|
XmlLabel *labels = xml->xml_labels;
|
||||||
|
guint labels_amt = xml->xml_labels_amt;
|
||||||
|
gint i;
|
||||||
|
|
||||||
|
// Maybe this can be a computation: i = xml->values->min + val
|
||||||
|
for (i = 0; i < labels_amt; i++) {
|
||||||
|
if (labels[i].type == value) {
|
||||||
|
return (labels[i].label);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
gboolean value_is_extra (EffectValues *val, SettingParam *param)
|
||||||
|
{
|
||||||
|
if ((param->value < val->min) || (param->value > val->max)) {
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
#define GDIGI_ENCODING "utf-8"
|
||||||
|
void
|
||||||
|
write_preset_to_xml(Preset *preset, gchar *filename)
|
||||||
|
{
|
||||||
|
|
||||||
|
int rc;
|
||||||
|
xmlTextWriterPtr writer;
|
||||||
|
GList *iter_params = preset->params;
|
||||||
|
guint last_id = 0;
|
||||||
|
guint last_position = 0;
|
||||||
|
|
||||||
|
printf("Creating a new xml doc\n");
|
||||||
|
/* Create a new XmlWriter for uri, with no compression. */
|
||||||
|
writer = xmlNewTextWriterFilename(filename, 0);
|
||||||
|
if (writer == NULL) {
|
||||||
|
printf("testXmlwriterFilename: Error creating the xml writer\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Start the document with the xml default for the version,
|
||||||
|
* encoding and the default for the standalone declaration.
|
||||||
|
*/
|
||||||
|
rc = xmlTextWriterStartDocument(writer, NULL, GDIGI_ENCODING, NULL);
|
||||||
|
if (rc < 0) {
|
||||||
|
printf
|
||||||
|
("testXmlwriterFilename: Error at xmlTextWriterStartDocument\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
rc = xmlTextWriterSetIndent(writer, 1);
|
||||||
|
rc = xmlTextWriterSetIndentString(writer, BAD_CAST " ");
|
||||||
|
/* Write the tag identifying type of prefix, schema version and ns. */
|
||||||
|
rc = xmlTextWriterStartElement(writer, BAD_CAST get_preset_filename(product_id));
|
||||||
|
|
||||||
|
rc = xmlTextWriterWriteAttribute(writer, BAD_CAST "SchemaVersion",
|
||||||
|
BAD_CAST "1.2");
|
||||||
|
|
||||||
|
|
||||||
|
rc = xmlTextWriterWriteAttribute(writer, BAD_CAST "xmlns",
|
||||||
|
BAD_CAST "http://www.digitech.com/xml/preset");
|
||||||
|
|
||||||
|
/* Write the Name tag. */
|
||||||
|
rc = xmlTextWriterWriteElement(writer, BAD_CAST "Name", BAD_CAST preset->name);
|
||||||
|
|
||||||
|
rc = xmlTextWriterStartElement(writer, BAD_CAST "Params");
|
||||||
|
|
||||||
|
while (iter_params) {
|
||||||
|
XmlSettings *xml;
|
||||||
|
SettingParam *param = (SettingParam *) iter_params->data;
|
||||||
|
|
||||||
|
if (param->id == last_id && param->position == last_position) {
|
||||||
|
g_message("Skipping duplicate parameter id %d position %d",
|
||||||
|
last_id, last_position);
|
||||||
|
iter_params = iter_params->next;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
rc = xmlTextWriterStartElement(writer, BAD_CAST "Param");
|
||||||
|
|
||||||
|
rc = xmlTextWriterWriteFormatElement(writer, BAD_CAST "ID",
|
||||||
|
"%d", param->id);
|
||||||
|
rc = xmlTextWriterWriteFormatElement(writer, BAD_CAST "Position",
|
||||||
|
"%d", param->position);
|
||||||
|
rc = xmlTextWriterWriteFormatElement(writer, BAD_CAST "Value",
|
||||||
|
"%d", param->value);
|
||||||
|
|
||||||
|
last_id = param->id;
|
||||||
|
last_position = param->position;
|
||||||
|
xml = get_xml_settings(param->id, param->position);
|
||||||
|
if (!xml) {
|
||||||
|
printf("Failed to get xml settings for id %d position %d\n",
|
||||||
|
param->id, param->position);
|
||||||
|
} else {
|
||||||
|
ValueType type;
|
||||||
|
gchar *suffix = "";
|
||||||
|
gdouble step = 1.0;
|
||||||
|
gint offset = 0;
|
||||||
|
gboolean decimal = FALSE;
|
||||||
|
EffectValues *values = NULL;
|
||||||
|
|
||||||
|
rc = xmlTextWriterWriteElement(writer, BAD_CAST "Name",
|
||||||
|
BAD_CAST xml->label);
|
||||||
|
values = xml->values;
|
||||||
|
type = values->type;
|
||||||
|
while ((type & VALUE_TYPE_EXTRA) && value_is_extra(values, param)) {
|
||||||
|
values = values->extra;
|
||||||
|
type = values->type;
|
||||||
|
}
|
||||||
|
type &= ~VALUE_TYPE_EXTRA;
|
||||||
|
|
||||||
|
if (type & VALUE_TYPE_OFFSET) {
|
||||||
|
offset = values->offset;
|
||||||
|
type &= ~VALUE_TYPE_OFFSET;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (type & VALUE_TYPE_STEP) {
|
||||||
|
step = values->step;
|
||||||
|
type &= ~VALUE_TYPE_STEP;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (type & VALUE_TYPE_SUFFIX) {
|
||||||
|
suffix = values->suffix;
|
||||||
|
type &= ~VALUE_TYPE_SUFFIX;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (type & VALUE_TYPE_DECIMAL) {
|
||||||
|
decimal = TRUE;
|
||||||
|
type &= ~VALUE_TYPE_DECIMAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (type) {
|
||||||
|
case VALUE_TYPE_LABEL:
|
||||||
|
{
|
||||||
|
char *textp = map_xml_value(xml, param->value);
|
||||||
|
if (!textp) {
|
||||||
|
g_message("Unable to map %s value %d for id %d position %d",
|
||||||
|
xml->label, param->value, param->id, param->position);
|
||||||
|
textp = "";
|
||||||
|
}
|
||||||
|
rc = xmlTextWriterWriteElement(writer, BAD_CAST "Text",
|
||||||
|
BAD_CAST textp);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case VALUE_TYPE_PLAIN:
|
||||||
|
{
|
||||||
|
if (decimal) {
|
||||||
|
double value = (param->value + offset) * step;
|
||||||
|
rc = xmlTextWriterWriteFormatElement(writer, BAD_CAST "Text",
|
||||||
|
"%0.2f%s", value, suffix);
|
||||||
|
} else {
|
||||||
|
gint value = (param->value + offset) * step;
|
||||||
|
rc = xmlTextWriterWriteFormatElement(writer, BAD_CAST "Text",
|
||||||
|
"%d%s", value, suffix);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
}
|
||||||
|
case VALUE_TYPE_NONE:
|
||||||
|
rc = xmlTextWriterStartElement(writer, BAD_CAST "Text");
|
||||||
|
rc = xmlTextWriterEndElement(writer);
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
g_message("Unhandled value type %d", type);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
rc = xmlTextWriterEndElement(writer);
|
||||||
|
|
||||||
|
iter_params = iter_params->next;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Here we could close the elements ORDER and EXAMPLE using the
|
||||||
|
* function xmlTextWriterEndElement, but since we do not want to
|
||||||
|
* write any other elements, we simply call xmlTextWriterEndDocument,
|
||||||
|
* which will do all the work. */
|
||||||
|
rc = xmlTextWriterEndDocument(writer);
|
||||||
|
if (rc < 0) {
|
||||||
|
printf("testXmlwriterFilename: Error at xmlTextWriterEndDocument\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
xmlFreeTextWriter(writer);
|
||||||
|
}
|
||||||
|
#endif /* DOXYGEN_SHOULD_SKIP_THIS */
|
||||||
Reference in New Issue
Block a user