18 Commits
0.1.5 ... 0.1.7

Author SHA1 Message Date
Tomasz Moń
29124043ba add RP500 distortion settings 2009-04-14 23:23:41 +02:00
Tomasz Moń
e93e6bd16b add compability mode dialog 2009-04-14 21:00:10 +02:00
Tomasz Moń
f7ddd5e0d6 add RP500 chorusfx settings 2009-04-14 18:22:32 +02:00
Tomasz Moń
6a082acc53 add RP500 delay settings 2009-04-13 11:42:15 +02:00
Tomasz Moń
1abcc82829 add RP500 equalizer settings 2009-04-12 20:55:17 +02:00
Tomasz Moń
c964d38c17 add RP500 compressor and amp settings 2009-04-12 18:36:41 +02:00
Tomasz Moń
12c2ccc87f Use single header includes 2009-04-11 22:32:21 +02:00
Tomasz Moń
a6d07fd802 disconnect adjustment signals on gtk_knob_destroy 2009-04-10 14:23:23 +02:00
Tomasz Moń
215683b167 actually g_type_class_peek_parent makes more sense 2009-04-10 13:32:03 +02:00
Tomasz Moń
741482afd4 Added tag 0.1.6 for changeset 80e56807413b 2009-03-26 15:21:18 +01:00
Tomasz Moń
991527418a Don't use deprecated functions in GtkKnob; optipng knob.png 2009-03-24 22:21:01 +01:00
Tomasz Moń
96317d5ac5 actually 'is it connected' doesn't make sense here 2009-03-17 15:36:16 +01:00
Tomasz Moń
d24cc97f5d add error reporting to create_preset_from_xml_file 2009-03-17 12:54:46 +01:00
Tomasz Moń
cac7e74d71 display preset number in preset list 2009-03-15 20:12:58 +01:00
Tomasz Moń
74583e9a7c make GUI more compact 2009-03-15 20:06:18 +01:00
Tomasz Moń
03c3c48ecf remove reduntant text 2009-03-15 18:52:14 +01:00
Tomasz Moń
aa2cc7bbb1 some Doxygen work 2009-03-14 18:51:08 +01:00
Tomasz Moń
ec14a41869 Added tag 0.1.5 for changeset 45f897c02e72 2009-03-14 14:27:12 +01:00
12 changed files with 1462 additions and 526 deletions

1
TODO
View File

@@ -4,3 +4,4 @@
-buildsystem (install knob.png to share dir, don't use inline knob pixbuf)
-add expression pedal settings to gui
-read asynchronously from MIDI IN
-guess device port when user doesn't explicitly provide it (don't use hardcoded "hw:1,0,0")

1136
effects.c

File diff suppressed because it is too large Load Diff

View File

@@ -17,41 +17,42 @@
#ifndef GDIGI_EFFECTS_H
#define GDIGI_EFFECTS_H
#include <glib/gtypes.h>
#include <glib.h>
typedef struct {
gdouble min; /* Minumum value */
gdouble max; /* Maximum value */
GStrv labels; /* value labels */
gdouble min; /**< Minumum value */
gdouble max; /**< Maximum value */
GStrv labels; /**< value labels */
} EffectValues;
typedef struct {
gchar *label; /* Parameter name */
guint id; /* ID (to set parameter) */
guint position; /* position */
EffectValues *values; /* valid parameter values */
gchar *label; /**< Parameter name */
guint id; /**< ID (to set parameter) */
guint position; /**< position */
EffectValues *values; /**< valid parameter values */
} EffectSettings;
typedef struct {
guint type; /* value (type) */
gchar *label; /* Effect name */
guint id; /* ID (to set effect type) */
guint position; /* position */
EffectSettings *settings; /* possible parameters */
gint settings_amt; /* possible parameters length */
guint type; /**< value (type) */
gchar *label; /**< Effect name */
guint id; /**< ID (to set effect type) */
guint position; /**< position */
EffectSettings *settings; /**< possible parameters */
gint settings_amt; /**< possible parameters length */
} EffectGroup;
typedef struct {
gchar *label; /* Base effect name */
guint id; /* ID (to set effect on/off) */
guint position; /* position */
EffectGroup *group; /* possible effect types */
gint group_amt; /* possible effect types length */
gchar *label; /**< Group label */
guint id; /**< ID to set effect on/off, or if it isn't on/off group then -1 */
guint position; /**< position */
EffectGroup *group; /**< possible effect types */
gint group_amt; /**< possible effect types length */
} Effect;
typedef struct {
Effect *effect; /* list of supported effects */
gint amt; /* list of supported effects length */
gchar *label; /**< base effect name */
Effect *effect; /**< list of supported effects */
gint amt; /**< list of supported effects length */
} EffectList;
typedef struct {
@@ -59,7 +60,16 @@ typedef struct {
gint group_amt;
} ModifierGroup;
typedef struct {
gchar *name;
EffectList *list;
int n_list;
} SupportedDevices;
ModifierGroup *modifier_linkable_list();
void modifier_group_free(ModifierGroup *modifier_group);
gboolean get_effect_list(unsigned char device_id, unsigned char family_id,
unsigned char product_id,
EffectList **list, int *n_list);
#endif /* GDIGI_EFFECTS_H */

119
gdigi.c
View File

@@ -31,13 +31,12 @@ static snd_rawmidi_t *input = NULL;
static char *device = "hw:1,0,0";
/**
* calculate_checksum:
* @array: data to calculate checksum
* @length: data length
* \param array data to calculate checksum
* \param length data length
*
* Calculates message checksum
* Calculates message checksum.
*
* Return value: calculated checksum
* \return calculated checksum.
**/
static char calculate_checksum(gchar *array, gint length)
{
@@ -52,11 +51,9 @@ static char calculate_checksum(gchar *array, gint length)
}
/**
* open_device:
*
* Opens MIDI device. This function modifies global input and output variables.
*
* Return value: FALSE on success, TRUE on error.
* \return FALSE on success, TRUE on error.
**/
gboolean open_device()
{
@@ -80,9 +77,8 @@ gboolean open_device()
}
/**
* send_data:
* @data: data to be sent
* @length: data length
* \param data data to be sent
* \param length data length
*
* Sends data to device. This function uses global output variable.
**/
@@ -92,13 +88,12 @@ void send_data(char *data, int length)
}
/**
* pack_data:
* @data: data to be packed
* @len: data length
* \param data data to be packed
* \param len data length
*
* Packs data using method used on all newer DigiTech products.
*
* Return value: GString containing packed data
* \return GString containing packed data
**/
GString *pack_data(gchar *data, gint len)
{
@@ -131,8 +126,7 @@ GString *pack_data(gchar *data, gint len)
}
/**
* unpack_message:
* @msg: message to unpack
* \param msg message to unpack
*
* Unpacks message data. This function modifies given GString.
**/
@@ -175,11 +169,9 @@ static void unpack_message(GString *msg)
}
/**
* read_data:
*
* Reads data from MIDI IN. This function uses global input variable.
*
* Return value: GString containing data, or NULL when no data was read.
* \return GString containing data, or NULL when no data was read.
**/
GString* read_data()
{
@@ -245,10 +237,9 @@ GString* read_data()
}
/**
* send_message:
* @procedure: procedure ID
* @data: unpacked message data
* @len: data length
* \param procedure procedure ID
* \param data unpacked message data
* \param len data length
*
* Creates SysEx message then sends it. This function uses folowing global variables: device_id, family_id and product_id.
**/
@@ -278,16 +269,15 @@ void send_message(gint procedure, gchar *data, gint len)
}
/**
* get_message_id:
* @msg: SysEx message
* \param msg SysEx message
*
* Checks message ID.
*
* Return value: MessageID, or -1 on error.
* \return MessageID, or -1 on error.
**/
static MessageID get_message_id(GString *msg)
{
/* TODO: sanity checks */
/** \todo check if msg is valid SysEx message */
g_return_val_if_fail(msg != NULL, -1);
if (msg->len > 7) {
@@ -297,12 +287,11 @@ static MessageID get_message_id(GString *msg)
}
/**
* get_message_by_id:
* @id: MessageID of requested message
* \param id MessageID of requested message
*
* Reads data from MIDI IN until message with matching id is found.
*
* Return value: GString containing unpacked message.
* \return GString containing unpacked message.
**/
GString *get_message_by_id(MessageID id)
{
@@ -320,9 +309,8 @@ GString *get_message_by_id(MessageID id)
}
/**
* append_value:
* @msg: message to append value
* @value: value to append
* \param msg message to append value
* \param value value to append
*
* Packs value using scheme used on all newer DigiTech products.
**/
@@ -354,10 +342,9 @@ void append_value(GString *msg, guint value)
}
/**
* set_option:
* @id: Parameter ID
* @position: Parameter position
* @value: Parameter value
* \param id Parameter ID
* \param position Parameter position
* \param value Parameter value
*
* Forms SysEx message to set parameter then sends it to device.
**/
@@ -373,9 +360,8 @@ void set_option(guint id, guint position, guint value)
}
/**
* switch_preset:
* @bank: preset bank
* @x: preset index
* \param bank preset bank
* \param x preset index
*
* Switches to selected preset.
**/
@@ -392,9 +378,8 @@ void switch_preset(guint bank, guint x)
}
/**
* store_preset_name:
* @x: preset index
* @name: preset name
* \param x preset index
* \param name preset name
*
* Stores current edit buffer in user presets bank.
**/
@@ -411,9 +396,8 @@ void store_preset_name(int x, const gchar *name)
}
/**
* set_preset_name:
* @x: preset index
* @name: preset name
* \param x preset index
* \param name preset name
*
* Sets preset name.
**/
@@ -429,12 +413,11 @@ void set_preset_name(int x, gchar *name)
}
/**
* query_preset_names:
* @bank: preset bank
* \param bank preset bank
*
* Queries preset names.
*
* Return value: GStrv which must be freed with g_strfreev, or NULL on error.
* \return GStrv which must be freed with g_strfreev, or NULL on error.
**/
GStrv query_preset_names(gchar bank)
{
@@ -471,11 +454,9 @@ GStrv query_preset_names(gchar bank)
}
/**
* get_current_preset:
*
* Queries current edit buffer.
*
* Return value: GString containing RECEIVE_PRESET_PARAMETERS SysEx message.
* \return GString containing RECEIVE_PRESET_PARAMETERS SysEx message.
**/
GString *get_current_preset()
{
@@ -490,14 +471,13 @@ GString *get_current_preset()
}
/**
* request_who_am_i:
* @device_id: Variable to hold device ID
* @family_id: Variable to hold family ID
* @product_id: Variable to hold product ID
* \param device_id Variable to hold device ID
* \param family_id Variable to hold family ID
* \param product_id Variable to hold product ID
*
* Requests device information.
*
* Return value: TRUE on success, FALSE on error.
* \return TRUE on success, FALSE on error.
**/
static gboolean request_who_am_i(unsigned char *device_id, unsigned char *family_id,
unsigned char *product_id)
@@ -555,11 +535,15 @@ static void request_device_configuration()
}
}
#ifndef DOXYGEN_SHOULD_SKIP_THIS
static GOptionEntry options[] = {
{"device", 'd', G_OPTION_FLAG_IN_MAIN, G_OPTION_ARG_STRING, &device, "MIDI device port to use", NULL},
{NULL}
};
#endif /* DOXYGEN_SHOULD_SKIP_THIS */
int main(int argc, char *argv[]) {
GError *error = NULL;
GOptionContext *context;
@@ -580,11 +564,22 @@ int main(int argc, char *argv[]) {
show_error_message(NULL, "Failed to open MIDI device");
} else {
if (request_who_am_i(&device_id, &family_id, &product_id) == FALSE) {
show_error_message(NULL, "No suitable reply from device - is it connected?");
show_error_message(NULL, "No suitable reply from device");
} else {
gui_create();
gtk_main();
gui_free();
EffectList *list = NULL;
int n_list = -1;
if (get_effect_list(device_id, family_id, product_id, &list, &n_list) == FALSE) {
if (unsupported_device_dialog(&list, &n_list) == FALSE) {
g_message("Shutting down");
}
}
if (list != NULL && n_list != -1) {
gui_create(list, n_list);
gtk_main();
gui_free();
}
}
}

190
gdigi.h
View File

@@ -20,6 +20,8 @@
#include <glib.h>
#include <glib-object.h>
#ifndef DOXYGEN_SHOULD_SKIP_THIS
enum {
WAH_TYPE_CRY = 132,
WAH_TYPE_FULLRANGE = 133,
@@ -39,7 +41,8 @@ enum {
enum {
COMP_TYPE_DIGI = 195,
COMP_TYPE_CS = 196
COMP_TYPE_CS = 196,
COMP_TYPE_DYNA = 197
};
#define COMP_TYPE 207
@@ -50,6 +53,8 @@ enum {
#define COMP_TONE 209
#define COMP_ATTACK 211
#define COMP_LEVEL 210
#define COMP_SENSITIVITY 213
#define COMP_OUTPUT 212
enum {
PICKUP_TYPE_HB_SC = 66,
@@ -63,8 +68,10 @@ enum {
enum {
DIST_TYPE_SCREAMER = 1280,
DIST_TYPE_808 = 1292,
DIST_TYPE_SPARKDRIVE = 1286,
DIST_TYPE_GUYOD = 1285,
DIST_TYPE_DOD250 = 1283,
DIST_TYPE_REDLINE = 1297,
DIST_TYPE_RODENT = 1281,
DIST_TYPE_MX = 1291,
DIST_TYPE_DS = 1282,
@@ -72,6 +79,9 @@ enum {
DIST_TYPE_ZONE = 1289,
DIST_TYPE_DEATH = 1294,
DIST_TYPE_GONK = 1293,
DIST_TYPE_8TAVIA = 1290,
DIST_TYPE_FUZZLATOR = 1295,
DIST_TYPE_CLASSIC_FUZZ = 1296,
DIST_TYPE_FUZZY = 1288,
DIST_TYPE_MP = 1284
};
@@ -83,41 +93,74 @@ enum {
#define DIST_SCREAMER_DRIVE 2434
#define DIST_SCREAMER_TONE 2435
#define DIST_SCREAMER_LVL 2436
#define DIST_808_OVERDRIVE 2473
#define DIST_808_TONE 2474
#define DIST_808_LVL 2475
#define DIST_SPARKDRIVE_GAIN 2450
#define DIST_SPARKDRIVE_TONE 2451
#define DIST_SPARKDRIVE_CLEAN 2452
#define DIST_SPARKDRIVE_VOLUME 2453
#define DIST_GUYOD_DRIVE 2448
#define DIST_GUYOD_LVL 2449
#define DIST_DOD250_GAIN 2443
#define DIST_DOD250_LVL 2444
#define DIST_REDLINE_GAIN 2488
#define DIST_REDLINE_LOW 2489
#define DIST_REDLINE_HIGH 2490
#define DIST_REDLINE_LEVEL 2491
#define DIST_RODENT_DIST 2437
#define DIST_RODENT_FILTER 2438
#define DIST_RODENT_LVL 2439
#define DIST_MX_DIST 2468
#define DIST_MX_OUTPUT 2469
#define DIST_DS_GAIN 2440
#define DIST_DS_TONE 2441
#define DIST_DS_LVL 2442
#define DIST_GRUNGE_GRUNGE 2454
#define DIST_GRUNGE_FACE 2456
#define DIST_GRUNGE_LOUD 2457
#define DIST_GRUNGE_BUTT 2455
#define DIST_ZONE_GAIN 2460
#define DIST_ZONE_LOW 2463
#define DIST_ZONE_MID_LVL 2462
#define DIST_ZONE_MID_FREQ 2461
#define DIST_ZONE_HIGH 2464
#define DIST_ZONE_LEVEL 2465
#define DIST_DEATH_LOW 2477
#define DIST_DEATH_MID 2476
#define DIST_DEATH_HIGH 2479
#define DIST_DEATH_LVL 2478
#define DIST_GONK_GONK 2480
#define DIST_GONK_SMEAR 2471
#define DIST_GONK_SUCK 2470
#define DIST_GONK_HEAVE 2472
#define DIST_8TAVIA_DRIVE 2466
#define DIST_8TAVIA_VOLUME 2467
#define DIST_FUZZLATOR_FUZZ 2481
#define DIST_FUZZLATOR_TONE 2482
#define DIST_FUZZLATOR_LOOSETIGHT 2483
#define DIST_FUZZLATOR_VOLUME 2484
#define DIST_CLASSIC_FUZZ_FUZZ 2485
#define DIST_CLASSIC_FUZZ_TONE 2486
#define DIST_CLASSIC_FUZZ_VOLUME 2487
#define DIST_FUZZY_FUZZ 2458
#define DIST_FUZZY_VOLUME 2459
#define DIST_MP_SUSTAIN 2445
#define DIST_MP_TONE 2446
#define DIST_MP_VOLUME 2447
@@ -129,24 +172,55 @@ enum {
AMP_TYPE_TWEED_CHAMP = 307,
AMP_TYPE_TWEED_DELUXE = 308,
AMP_TYPE_TWEED_BASSMAN = 309,
AMP_TYPE_BROWN_BASSMAN = 310,
AMP_TYPE_BLACKFACE_TWIN = 311,
AMP_TYPE_BLACKFACE_DELUXE = 312,
AMP_TYPE_PLEXI_JTM_45 = 313,
AMP_TYPE_SUPER_LEAD_PLEXI = 314,
AMP_TYPE_PLEXI_JUMP_PANEL = 315,
AMP_TYPE_MASTER_VOLUME = 316,
AMP_TYPE_JCM800 = 317,
AMP_TYPE_JCM900 = 318,
AMP_TYPE_JCM2000 = 319,
AMP_TYPE_AC15 = 322,
AMP_TYPE_AC30TB = 323,
AMP_TYPE_HIWATT_100 = 324,
AMP_TYPE_BOOGIE_MARK_II = 320,
AMP_TYPE_BOOGIE_MARK_IV = 371,
AMP_TYPE_DUAL_RECTIFIER = 321,
AMP_TYPE_TRIPLE_RECTIFIER = 370,
AMP_TYPE_LEGACY_VL100 = 327,
AMP_TYPE_MATCHLESS_HC30 = 326,
AMP_TYPE_SOLDANO_100 = 325,
AMP_TYPE_SUPERGROUP = 381,
AMP_TYPE_GA40 = 380,
AMP_TYPE_OR120 = 372,
AMP_TYPE_PV5150II = 373,
AMP_TYPE_RG100 = 374,
AMP_TYPE_JC120_JAZZ = 375,
AMP_TYPE_SOLAR100 = 376,
AMP_TYPE_SOLO = 331,
AMP_TYPE_METAL = 332,
AMP_TYPE_BRIGHT = 333,
AMP_TYPE_CHUNK = 334,
AMP_TYPE_CLEAN = 335,
AMP_TYPE_HIGH_GAIN = 337,
AMP_TYPE_BLUES = 338,
AMP_TYPE_FUZZ = 339,
AMP_TYPE_SPANK = 330,
AMP_TYPE_GSP2101_CLEAN_TUBE = 328,
AMP_TYPE_GSP2101_SAT_TUBE = 329,
AMP_TYPE_CRUNCH = 336,
AMP_TYPE_MONSTER = 377,
AMP_TYPE_TWEEDFACE = 378,
AMP_TYPE_BLACKBASS = 379,
AMP_TYPE_STONER_ROCK = 368,
AMP_TYPE_DARK_METAL = 369,
AMP_TYPE_TRANSISTOR = 382,
AMP_TYPE_BROWN_SOUND = 383,
AMP_TYPE_MOSH = 384,
AMP_TYPE_ACOUSTIC = 341,
AMP_TYPE_JUMBO_ACOUSTIC = 340,
AMP_TYPE_DIRECT = 306
};
@@ -163,6 +237,9 @@ enum {
#define AMP_GAIN 2497
#define AMP_LEVEL 2498
#define AMP_BASS 2507
#define AMP_MID 2508
#define AMP_TREBLE 2509
#define AMP_CAB_TYPE 2560
#define AMP_CAB_POSITION 9
@@ -171,18 +248,29 @@ enum {
#define AMP_CAB_DIRECT 570
#define AMP_CAB_CHAMP 571
#define AMP_CAB_DELUXE 572
#define AMP_CAB_DELUXE_REVERB 573
#define AMP_CAB_BRITISH1_12 623
#define AMP_CAB_GA1_12 624
#define AMP_CAB_BLONDE2_12 577
#define AMP_CAB_TWIN 576
#define AMP_CAB_BRITISH2_12 613
#define AMP_CAB_JAZZ2_12 626
#define AMP_CAB_BASSMAN 579
#define AMP_CAB_BRITISH4_12 614
#define AMP_CAB_BRITISH_GREEN 616
#define AMP_CAB_FANE4_12 584
#define AMP_CAB_BOUTIQUE4_12 583
#define AMP_CAB_VINTAGE 622
#define AMP_CAB_RECTO4_12 625
#define AMP_CAB_DIGI_SOLO 609
#define AMP_CAB_DIGI_BRIGHT 611
#define AMP_CAB_DIGI_METAL 618
#define AMP_CAB_DIGI_ROCK 619
#define AMP_CAB_DIGI_ALT 620
#define AMP_CAB_DIGI_VNTG 621
#define AMP_CAB_DIGI_CHUNK 612
#define AMP_CAB_DIGI_SPANK2_12 608
#define AMP_CAB_DIGI_SPKR_COMP 585
#define EQ_TYPE 3202
#define EQ_ON_OFF 3212
@@ -193,6 +281,15 @@ enum {
#define EQ_MID_HZ 3206
#define EQ_TREBLE 3205
#define EQ_TREBLE_HZ 3211
#define EQ_LOW_LEVEL 3203
#define EQ_MID_LEVEL 3204
#define EQ_HIGH_LEVEL 3205
#define EQ_LOW_FREQ 3213
#define EQ_MID_FREQ 3214
#define EQ_HIGH_FREQ 3215
#define EQ_LOW_BANDWIDTH 3216
#define EQ_MID_BANDWIDTH 3217
#define EQ_HIGH_BANDWIDTH 3218
enum {
NOISEGATE_GATE = 768,
@@ -214,24 +311,40 @@ enum {
enum {
CHORUS_TYPE_CE = 0x37B,
CHORUS_TYPE_TC = 0x37C,
CHORUS_TYPE_DUAL = 0x379,
CHORUS_TYPE_GLISTEN = 0x392,
CHORUS_TYPE_MULTI = 0x37a,
CHORUS_TYPE_FLANGER = 0x37d,
CHORUS_TYPE_TRIGGERED_FLANGER = 0x37e,
CHORUS_TYPE_MXR_FLANGER = 0x37f,
CHORUS_TYPE_EH_FLANGER = 0x380,
CHORUS_TYPE_AD_FLANGER = 0x393,
CHORUS_TYPE_PHASER = 0x381,
CHORUS_TYPE_TRIGGERED_PHASER = 0x382,
CHORUS_TYPE_MX_PHASER = 0x383,
CHORUS_TYPE_EH_PHASER = 0x384,
CHORUS_TYPE_VIBRATO = 0x360,
CHORUS_TYPE_ROTARY = 0x361,
CHORUS_TYPE_VIBROPAN = 0x38f,
CHORUS_TYPE_UNOVIBE = 0x390,
CHORUS_TYPE_TREMOLO = 0x35e,
CHORUS_TYPE_SCATTER_TREM = 0x394,
CHORUS_TYPE_OPTO_TREMOLO = 0x388,
CHORUS_TYPE_BIAS_TREMOLO = 0x389,
CHORUS_TYPE_PANNER = 0x35f,
CHORUS_TYPE_ENVELOPE = 0x38a,
CHORUS_TYPE_FX25 = 0x38e,
CHORUS_TYPE_AUTOYA = 0x38b,
CHORUS_TYPE_YAYA = 0x38c,
CHORUS_TYPE_SYNTH_TALK = 0x391,
CHORUS_TYPE_STEP_FILTER = 0x38d,
CHORUS_TYPE_SAMPLE_HOLD = 0x395,
CHORUS_TYPE_WHAMMY = 0x540,
CHORUS_TYPE_PITCH_SHIFT = 0x543,
CHORUS_TYPE_DETUNE = 0x542,
CHORUS_TYPE_IPS = 0x541
CHORUS_TYPE_IPS = 0x541,
CHORUS_TYPE_OCTAVER = 0x385,
};
#define CHORUSFX_TYPE 768
@@ -241,6 +354,9 @@ enum {
#define CE_CHORUS_SPEED 837
#define CE_CHORUS_DEPTH 838
#define CHORUS_WIDTH 848
#define CHORUS_INTENSITY 849
#define DUAL_CHORUS_SPEED 837
#define DUAL_CHORUS_DEPTH 838
#define DUAL_CHORUS_LEVEL 836
@@ -257,17 +373,39 @@ enum {
#define FLANGER_LEVEL 901
#define FLANGER_WAVE 905
#define TRIG_FLANGER_SPEED 1030
#define TRIG_FLANGER_SENS 1031
#define TRIG_FLANGER_LFO_START 1028
#define TRIG_FLANGER_LEVEL 1032
#define MXR_FLANGER_SPEED 902
#define MXR_FLANGER_WIDTH 914
#define MXR_FLANGER_REGEN 904
#define MXR_FLANGER_MANUAL 917
#define EH_FLANGER_RATE 918
#define EH_FLANGER_RANGE 919
#define EH_FLANGER_COLOR 916
#define AD_FLANGER_ENHANCE 920
#define AD_FLANGER_HARMONICS 921
#define PHASER_SPEED 962
#define PHASER_DEPTH 963
#define PHASER_REGEN 966
#define PHASER_LEVEL 965
#define PHASER_WAVE 967
#define TRIG_PHASER_SPEED 1094
#define TRIG_PHASER_SENS 1095
#define TRIG_PHASER_LFO_START 1092
#define TRIG_PHASER_LEVEL 1096
#define MX_PHASER_INTENSITY 976
#define EH_PHASER_RATE 979
#define EH_PHASER_COLOR 977
#define VIBRATO_SPEED 1284
#define VIBRATO_DEPTH 1285
@@ -281,6 +419,11 @@ enum {
#define VIBROPAN_VIBRA 1316
#define VIBROPAN_WAVE 1317
#define UNOVIBE_PEDAL_SPEED 2884
#define UNOVIBE_INTENSITY 2883
#define UNOVIBE_CHORUS_VIBRATO 2882
#define UNOVIBE_VOLUME 2885
#define TREMOLO_SPEED 1156
#define TREMOLO_DEPTH 1155
#define TREMOLO_WAVE 1157
@@ -291,6 +434,7 @@ enum {
#define ENVELOPE_SENSITIVITY 1606
#define ENVELOPE_RANGE 1605
#define ENVELOPE_BLEND 1608
#define AUTOYA_SPEED 1478
#define AUTOYA_INTENSITY 1482
@@ -300,9 +444,18 @@ enum {
#define YAYA_INTENSITY 1417
#define YAYA_RANGE 1418
#define SYNTH_TALK_ATTACK 1542
#define SYNTH_TALK_RELEASE 1547
#define SYNTH_TALK_SENS 1544
#define SYNTH_TALK_VOX 1540
#define SYNTH_TALK_BALANCE 1545
#define STEP_FILTER_SPEED 3010
#define STEP_FILTER_INTENSITY 3011
#define SAMPLE_HOLD_SPEED 3012
#define SAMPLE_HOLD_INTENSITY 3013
#define WHAMMY_AMOUNT 1797
#define WHAMMY_PEDAL 1795
#define WHAMMY_MIX 1796
@@ -318,6 +471,10 @@ enum {
#define IPS_SCALE 2755
#define IPS_LEVEL 2757
#define OCTAVER_OCTAVE1 1746
#define OCTAVER_OCTAVE2 1747
#define OCTAVER_DRY_LEVEL 1748
/* DUAL_CHORUS_WAVE, MULTI_CHORUS_WAVE, FLANGER_WAVE, PHASER_WAVE,
VIBROPAN_WAVE, TREMOLO_WAVE, PANNER_WAVE valid values */
#define WAVE_TRI 0x00
@@ -385,7 +542,16 @@ enum {
DELAY_TYPE_DIGITAL = 1045,
DELAY_TYPE_MODULATED = 1047,
DELAY_TYPE_PONG = 1048,
DELAY_TYPE_TAPE = 1049
DELAY_TYPE_TAPE = 1049,
DELAY_RP500_TYPE_DIGITAL = 1052,
DELAY_RP500_TYPE_ANALOG = 1053,
DELAY_RP500_TYPE_DM = 1058,
DELAY_RP500_TYPE_ECHOPLEX = 1057,
DELAY_RP500_TYPE_MODULATED = 1054,
DELAY_RP500_TYPE_PONG = 1055,
DELAY_RP500_TYPE_REVERSE = 1064,
DELAY_RP500_TYPE_TAPE = 1056,
};
#define DELAY_TYPE 1856
@@ -416,6 +582,22 @@ enum {
#define TAPE_WOW 1891
#define TAPE_FLUTTER 1892
#define DELAY_LEVEL 1860
#define DELAY_REPEATS 1863
#define DELAY_TAP_TIME 1868
#define DELAY_DUCK_THRESH 1889
#define DELAY_DUCK_LEVEL 1890
#define DELAY_REPEAT_RATE 1898
#define DELAY_ECHO 1895
#define DELAY_INTENSITY 1896
#define DELAY_TIME_0_760 1899
#define DELAY_VOLUME 1893
#define DELAY_REPEATS_0_99 1874
#define DELAY_DEPTH 1873
#define DELAY_TAP_TIME_0_4990 1900
#define DELAY_MIX 1902
#define DELAY_TIME_0_4650 1901
enum {
REVERB_TYPE_TWIN = 1146,
REVERB_TYPE_LEX_AMBIENCE = 1150,
@@ -539,6 +721,8 @@ enum {
#define USB_AUDIO_PLAYBACK_MIX 12297
#define USB_AUDIO_LEVEL 12307
#endif /* DOXYGEN_SHOULD_SKIP_THIS */
typedef enum {
PRESETS_SYSTEM = 0,
PRESETS_USER = 1,

123
gtkknob.c
View File

@@ -20,12 +20,10 @@
* along with this program; if not, write to the Free Software
* 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"
@@ -74,22 +72,23 @@ static GtkWidgetClass *parent_class = NULL;
* gtk_knob_get_type()
*
*****************************************************************************/
guint
GType
gtk_knob_get_type(void) {
static guint knob_type = 0;
static GType knob_type = 0;
if (!knob_type) {
GtkTypeInfo knob_info = {
"GtkKnob",
sizeof (GtkKnob),
static const GTypeInfo knob_info = {
sizeof (GtkKnobClass),
(GtkClassInitFunc) gtk_knob_class_init,
(GtkObjectInitFunc) gtk_knob_init,
NULL,
NULL,
(GClassInitFunc) gtk_knob_class_init,
NULL,
NULL,
sizeof (GtkKnob),
0,
(GInstanceInitFunc) gtk_knob_init,
};
knob_type = gtk_type_unique (gtk_widget_get_type (), &knob_info);
knob_type = g_type_register_static (GTK_TYPE_WIDGET, "GtkKnob", &knob_info, 0);
}
return knob_type;
@@ -102,14 +101,14 @@ gtk_knob_get_type(void) {
*
*****************************************************************************/
static void
gtk_knob_class_init (GtkKnobClass *class) {
gtk_knob_class_init (GtkKnobClass *klass) {
GtkObjectClass *object_class;
GtkWidgetClass *widget_class;
object_class = (GtkObjectClass*) class;
widget_class = (GtkWidgetClass*) class;
object_class = (GtkObjectClass*) klass;
widget_class = (GtkWidgetClass*) klass;
parent_class = gtk_type_class (gtk_widget_get_type ());
parent_class = g_type_class_peek_parent(klass);
object_class->destroy = gtk_knob_destroy;
@@ -160,7 +159,7 @@ gtk_knob_new(GtkAdjustment *adjustment, GtkKnobAnim *anim) {
g_return_val_if_fail (anim != NULL, NULL);
g_return_val_if_fail (GDK_IS_PIXBUF (anim->pixbuf), NULL);
knob = gtk_type_new (gtk_knob_get_type ());
knob = g_object_new (gtk_knob_get_type (), NULL);
gtk_knob_set_animation (knob, anim);
@@ -189,10 +188,7 @@ gtk_knob_destroy(GtkObject *object) {
knob = GTK_KNOB (object);
if (knob->adjustment) {
gtk_object_unref (GTK_OBJECT (knob->adjustment));
knob->adjustment = NULL;
}
gtk_knob_set_adjustment (knob, NULL);
/* FIXME: needs ref counting for automatic GtkKnobAnim cleanup
if (knob->anim) {
gtk_knob_anim_unref (knob->anim);
@@ -201,16 +197,16 @@ gtk_knob_destroy(GtkObject *object) {
*/
if (knob->mask) {
gdk_bitmap_unref (knob->mask);
g_object_unref (knob->mask);
knob->mask = NULL;
}
if (knob->mask_gc) {
gdk_gc_unref (knob->mask_gc);
g_object_unref (knob->mask_gc);
knob->mask_gc = NULL;
}
if (knob->red_gc) {
gdk_gc_unref (knob->red_gc);
g_object_unref (knob->red_gc);
knob->red_gc = NULL;
}
@@ -262,27 +258,30 @@ gtk_knob_set_adjustment(GtkKnob *knob, GtkAdjustment *adjustment) {
g_return_if_fail (GTK_IS_KNOB (knob));
if (knob->adjustment) {
gtk_signal_disconnect_by_data (GTK_OBJECT (knob->adjustment),
(gpointer)knob);
gtk_object_unref (GTK_OBJECT (knob->adjustment));
g_signal_handlers_disconnect_matched(knob->adjustment,
G_SIGNAL_MATCH_DATA,
0, 0, NULL, NULL,
knob);
g_object_unref (knob->adjustment);
}
knob->adjustment = adjustment;
gtk_object_ref (GTK_OBJECT (knob->adjustment));
gtk_object_sink (GTK_OBJECT (knob->adjustment));
if (adjustment) {
g_object_ref_sink (adjustment);
gtk_signal_connect (GTK_OBJECT (adjustment), "changed",
GTK_SIGNAL_FUNC (gtk_knob_adjustment_changed),
(gpointer)knob);
gtk_signal_connect (GTK_OBJECT (adjustment), "value_changed",
GTK_SIGNAL_FUNC (gtk_knob_adjustment_value_changed),
(gpointer)knob);
g_signal_connect (adjustment, "changed",
G_CALLBACK(gtk_knob_adjustment_changed),
knob);
g_signal_connect (adjustment, "value_changed",
G_CALLBACK(gtk_knob_adjustment_value_changed),
knob);
knob->old_value = adjustment->value;
knob->old_lower = adjustment->lower;
knob->old_upper = adjustment->upper;
knob->old_value = adjustment->value;
knob->old_lower = adjustment->lower;
knob->old_upper = adjustment->upper;
gtk_knob_update (knob);
gtk_knob_update (knob);
}
}
@@ -395,6 +394,7 @@ gtk_knob_expose(GtkWidget *widget, GdkEventExpose *event) {
g_return_val_if_fail (widget != NULL, FALSE);
g_return_val_if_fail (GTK_IS_KNOB (widget), 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)
return FALSE;
@@ -433,19 +433,18 @@ gtk_knob_scroll(GtkWidget *widget, GdkEventScroll *event) {
g_return_val_if_fail (widget != NULL, FALSE);
g_return_val_if_fail (GTK_IS_KNOB (widget), 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);
switch (event->direction) {
case GDK_SCROLL_UP:
knob->adjustment->value += knob->adjustment->step_increment;
gtk_signal_emit_by_name (GTK_OBJECT (knob->adjustment),
"value_changed");
g_signal_emit_by_name (knob->adjustment, "value_changed");
break;
case GDK_SCROLL_DOWN:
knob->adjustment->value -= knob->adjustment->step_increment;
gtk_signal_emit_by_name (GTK_OBJECT (knob->adjustment),
"value_changed");
g_signal_emit_by_name (knob->adjustment, "value_changed");
break;
default:
break;
@@ -467,6 +466,7 @@ gtk_knob_button_press(GtkWidget *widget, GdkEventButton *event) {
g_return_val_if_fail (widget != NULL, FALSE);
g_return_val_if_fail (GTK_IS_KNOB (widget), 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);
@@ -485,8 +485,7 @@ gtk_knob_button_press(GtkWidget *widget, GdkEventButton *event) {
knob->adjustment->value = floor ((knob->adjustment->lower +
knob->adjustment->upper + 1.0)
* 0.5);
gtk_signal_emit_by_name (GTK_OBJECT (knob->adjustment),
"value_changed");
g_signal_emit_by_name (knob->adjustment, "value_changed");
break;
}
break;
@@ -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 (GTK_IS_KNOB (widget), 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);
@@ -526,8 +526,7 @@ gtk_knob_button_release(GtkWidget *widget, GdkEventButton *event) {
if (knob->policy != GTK_UPDATE_CONTINUOUS
&& knob->old_value != knob->adjustment->value)
{
gtk_signal_emit_by_name (GTK_OBJECT (knob->adjustment),
"value_changed");
g_signal_emit_by_name (knob->adjustment, "value_changed");
}
break;
}
@@ -545,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 (GTK_IS_KNOB (widget), 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);
@@ -630,10 +630,10 @@ gtk_knob_timer(GtkKnob *knob) {
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_ADJUSTMENT (knob->adjustment), FALSE);
if (knob->policy == GTK_UPDATE_DELAYED) {
gtk_signal_emit_by_name (GTK_OBJECT (knob->adjustment),
"value_changed");
g_signal_emit_by_name (knob->adjustment, "value_changed");
}
/* don't keep running this timer */
@@ -648,21 +648,21 @@ gtk_knob_timer(GtkKnob *knob) {
*****************************************************************************/
static void
gtk_knob_update_mouse_update(GtkKnob *knob) {
g_return_if_fail(GTK_IS_ADJUSTMENT (knob->adjustment));
if (knob->policy == GTK_UPDATE_CONTINUOUS) {
gtk_signal_emit_by_name (GTK_OBJECT (knob->adjustment),
"value_changed");
g_signal_emit_by_name (knob->adjustment, "value_changed");
}
else {
gtk_widget_draw (GTK_WIDGET (knob), NULL);
gtk_widget_queue_draw (GTK_WIDGET (knob));
if (knob->policy == GTK_UPDATE_DELAYED) {
if (knob->timer) {
gtk_timeout_remove (knob->timer);
g_source_remove (knob->timer);
}
knob->timer = gtk_timeout_add (SCROLL_DELAY_LENGTH,
(GtkFunction) gtk_knob_timer,
(gpointer) knob);
knob->timer = g_timeout_add (SCROLL_DELAY_LENGTH,
(GSourceFunc) gtk_knob_timer,
(gpointer) knob);
}
}
}
@@ -680,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 (GTK_IS_KNOB (knob));
g_return_if_fail (GTK_IS_ADJUSTMENT (knob->adjustment));
old_value = knob->adjustment->value;
@@ -725,6 +726,7 @@ gtk_knob_update(GtkKnob *knob) {
g_return_if_fail (knob != NULL);
g_return_if_fail (GTK_IS_KNOB (knob));
g_return_if_fail (GTK_IS_ADJUSTMENT (knob->adjustment));
if (knob->adjustment->step_increment == 1) {
new_value = floor (knob->adjustment->value + 0.5);
@@ -743,11 +745,10 @@ gtk_knob_update(GtkKnob *knob) {
if (new_value != knob->adjustment->value) {
knob->adjustment->value = new_value;
gtk_signal_emit_by_name (GTK_OBJECT (knob->adjustment),
"value_changed");
g_signal_emit_by_name (knob->adjustment, "value_changed");
}
gtk_widget_draw (GTK_WIDGET (knob), NULL);
gtk_widget_queue_draw (GTK_WIDGET (knob));
}

View File

@@ -3,7 +3,7 @@
* Most of this code comes from gAlan 0.2.0, copyright (C) 1999
* Tony Garnock-Jones, with modifications by Sean Bolton,
* 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
* modify it under the terms of the GNU General Public License
@@ -22,17 +22,15 @@
#ifndef __GTK_KNOB_H__
#define __GTK_KNOB_H__
#include <gdk/gdk.h>
#include <gtk/gtkadjustment.h>
#include <gtk/gtkwidget.h>
#include <gtk/gtk.h>
#ifdef __cplusplus
extern "C" {
#endif
#define GTK_KNOB(obj) GTK_CHECK_CAST(obj, gtk_knob_get_type(), GtkKnob)
#define GTK_KNOB_CLASS(klass) GTK_CHECK_CLASS_CAST(klass, gtk_knob_get_type(), GtkKnobClass)
#define GTK_IS_KNOB(obj) GTK_CHECK_TYPE(obj, gtk_knob_get_type())
#define GTK_KNOB(obj) G_TYPE_CHECK_INSTANCE_CAST(obj, gtk_knob_get_type(), GtkKnob)
#define GTK_KNOB_CLASS(klass) G_TYPE_CHECK_CLASS_CAST(klass, gtk_knob_get_type(), GtkKnobClass)
#define GTK_IS_KNOB(obj) G_TYPE_CHECK_INSTANCE_TYPE(obj, gtk_knob_get_type())
typedef struct _GtkKnob GtkKnob;
typedef struct _GtkKnobClass GtkKnobClass;
@@ -82,7 +80,7 @@ typedef struct _GtkKnobAnim GtkKnobAnim;
extern GtkWidget *gtk_knob_new(GtkAdjustment *adjustment, GtkKnobAnim *anim);
extern guint gtk_knob_get_type(void);
extern GType gtk_knob_get_type(void);
extern GtkAdjustment *gtk_knob_get_adjustment(GtkKnob *knob);
extern void gtk_knob_set_update_policy(GtkKnob *knob, GtkUpdateType policy);
extern void gtk_knob_set_adjustment(GtkKnob *knob, GtkAdjustment *adjustment);

308
gui.c
View File

@@ -22,27 +22,25 @@
#include "gtkknob.h"
#include "knob.h"
extern EffectList effects[];
extern int n_effects;
typedef struct {
GtkObject *widget;
gint id;
gint position;
/* used for combo boxes, if widget isn't combo box, then both value and x are -1 */
gint value; /* effect type value */
gint x; /* combo box item number */
gint value; /**< effect type value */
gint x; /**< combo box item number */
} WidgetListElem;
#ifndef DOXYGEN_SHOULD_SKIP_THIS
static GtkKnobAnim *knob_anim = NULL; /* animation used by knobs */
static GList *widget_list = NULL; /* this list contains WidgetListElem data elements */
static gboolean allow_send = FALSE; /* if FALSE GUI parameter changes won't be sent to device */
#endif /* DOXYGEN_SHOULD_SKIP_THIS */
static GList *widget_list = NULL; /**< this list contains WidgetListElem data elements */
static gboolean allow_send = FALSE; /**< if FALSE GUI parameter changes won't be sent to device */
/**
* show_error_message:
* @parent: transient parent, or NULL for none
* @message: error description
* \param parent transient parent, or NULL for none
* \param message error description
*
* Shows error message dialog.
**/
@@ -61,9 +59,8 @@ void show_error_message(GtkWidget *parent, gchar *message)
}
/**
* value_changed_option_cb:
* @adj: the object which emitted the signal
* @setting: setting controlled by adj
* \param adj the object which emitted the signal
* \param setting setting controlled by adj
*
* Sets effect value.
**/
@@ -93,9 +90,8 @@ void value_changed_option_cb(GtkAdjustment *adj, EffectSettings *setting)
}
/**
* toggled_cb:
* @button: the object which emitted the signal
* @effect: effect controlled by button
* \param button the object which emitted the signal
* \param effect effect controlled by button
*
* Turns effect on/off basing on state of button.
**/
@@ -110,12 +106,11 @@ void toggled_cb(GtkToggleButton *button, Effect *effect)
}
/**
* widget_list_add:
* @widget: GtkObject to add to widget list
* @id: object controlled ID
* @position: object controlled position
* @value: effect value type (if widget is GtkComboBox, otherwise -1)
* @x: combo box item number (if widget is GtkComboBox, otherwise -1)
* \param widget GtkObject to add to widget list
* \param id object controlled ID
* \param position object controlled position
* \param value effect value type (if widget is GtkComboBox, otherwise -1)
* \param x combo box item number (if widget is GtkComboBox, otherwise -1)
*
* Adds widget to widget list.
**/
@@ -134,9 +129,8 @@ static void widget_list_add(GtkObject *widget, gint id, gint position, gint valu
}
/**
* apply_widget_setting:
* @el: widget list element
* @param: parameter to set
* \param el widget list element
* \param param parameter to set
*
* Sets widget list element value to param value.
**/
@@ -156,8 +150,7 @@ static void apply_widget_setting(WidgetListElem *el, SettingParam *param)
}
/**
* apply_preset_to_gui:
* @preset: preset to sync
* \param preset preset to sync
*
* Synces GUI with preset.
**/
@@ -181,8 +174,6 @@ static void apply_preset_to_gui(Preset *preset)
}
/**
* apply_current_preset:
*
* Synces GUI with device current edit buffer.
**/
static void apply_current_preset()
@@ -195,13 +186,12 @@ static void apply_current_preset()
}
/**
* create_table:
* @settings: effect parameters
* @amt: amount of effect parameters
* \param settings effect parameters
* \param amt amount of effect parameters
*
* Creates knobs that allow user to set effect parameters.
*
* Return value: GtkTable containing necessary widgets to set effect parameters.
* \return GtkTable containing necessary widgets to set effect parameters.
**/
GtkWidget *create_table(EffectSettings *settings, gint amt)
{
@@ -240,16 +230,19 @@ GtkWidget *create_table(EffectSettings *settings, gint amt)
}
/**
* create_on_off_button:
* @effect: Effect that can be turned on/off
* \param effect Effect that can be turned on/off
*
* Creates toggle button that allow user to turn effect on/off.
*
* Return value: GtkToggleButton
* \return GtkToggleButton
**/
GtkWidget *create_on_off_button(Effect *effect)
{
GtkWidget *button = gtk_toggle_button_new_with_label(effect->label);
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);
g_signal_connect(G_OBJECT(button), "toggled", G_CALLBACK(toggled_cb), effect);
widget_list_add(GTK_OBJECT(button), effect->id, effect->position, -1, -1);
@@ -257,32 +250,33 @@ GtkWidget *create_on_off_button(Effect *effect)
}
typedef struct {
gint type; /* effect group type (value) */
gint id; /* option ID */
gint position; /* position */
GtkWidget *child; /* child widget */
gint type; /**< effect group type (value) */
gint id; /**< option ID */
gint position; /**< position */
GtkWidget *child; /**< child widget */
} EffectSettingsGroup;
/**
* effect_settings_group_free:
* @group: group to be freed
* \param group group to be freed
*
* Frees all memory used by group
**/
void effect_settings_group_free(EffectSettingsGroup *group)
{
/* destroy widget without parent */
if (gtk_widget_get_parent(group->child) == NULL)
gtk_widget_destroy(group->child);
if (group->child != NULL) {
/* destroy widget without parent */
if (gtk_widget_get_parent(group->child) == NULL)
gtk_widget_destroy(group->child);
g_object_unref(group->child);
}
g_object_unref(group->child);
g_slice_free(EffectSettingsGroup, group);
}
/**
* combo_box_changed_cb:
* @widget: the object which emitted the signal
* @data: user data (unused, can be anything)
* \param widget the object which emitted the signal
* \param data user data (unused, can be anything)
*
* Switches effect type and shows widgets allowing to set selected effect type parameters.
**/
@@ -309,20 +303,22 @@ void combo_box_changed_cb(GtkComboBox *widget, gpointer data)
if (child != NULL) {
gtk_container_remove(GTK_CONTAINER(gtk_widget_get_parent(gtk_widget_get_parent(vbox))), child);
}
gtk_container_add(GTK_CONTAINER(gtk_widget_get_parent(gtk_widget_get_parent(vbox))), settings->child);
gtk_widget_show_all(gtk_widget_get_parent(gtk_widget_get_parent(vbox)));
if (settings->child != NULL) {
gtk_container_add(GTK_CONTAINER(gtk_widget_get_parent(gtk_widget_get_parent(vbox))), settings->child);
gtk_widget_show_all(gtk_widget_get_parent(gtk_widget_get_parent(vbox)));
}
g_object_set_data(G_OBJECT(widget), "active_child", settings->child);
}
}
/**
* create_widget_container:
* @group: Effect type groups
* @amt: amount of effect groups
* \param group Effect type groups
* \param amt amount of effect groups
*
* Creates widget allowing user to choose effect type.
*
* Return value: 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)
{
@@ -347,14 +343,18 @@ GtkWidget *create_widget_container(EffectGroup *group, gint amt)
gtk_combo_box_append_text(GTK_COMBO_BOX(combo_box), group[x].label);
cmbox_no++;
widget = create_table(group[x].settings, group[x].settings_amt);
g_object_ref_sink(widget);
if ((group[x].settings != NULL) && (group[x].settings > 0)) {
widget = create_table(group[x].settings, group[x].settings_amt);
g_object_ref_sink(widget);
} else
widget = NULL;
settings = g_slice_new(EffectSettingsGroup);
settings->id = group[x].id;
settings->type = group[x].type;
settings->position = group[x].position;
settings->child = widget;
widget_list_add(GTK_OBJECT(combo_box), group[x].id, group[x].position, group[x].type, x);
name = g_strdup_printf("SettingsGroup%d", cmbox_no);
@@ -370,37 +370,53 @@ GtkWidget *create_widget_container(EffectGroup *group, gint amt)
}
/**
* create_vbox:
* @widgets: Effect descriptions
* @amt: amount of effect descriptions
* \param widgets Effect descriptions
* \param amt amount of effect descriptions
* \param label frame label (can be NULL)
*
* Creates vbox containing widgets allowing user to set effect options.
* Creates frame (with optional label) containing widgets allowing user to set effect options.
*
* Return value: widget that allow user to set effect options.
* \return widget that allow user to set effect options.
**/
GtkWidget *create_vbox(Effect *widgets, gint amt)
GtkWidget *create_vbox(Effect *widgets, gint amt, gchar *label)
{
GtkWidget *vbox;
GtkWidget *hbox;
GtkWidget *widget;
GtkWidget *table;
GtkWidget *container;
GtkWidget *frame;
int x;
int y;
frame = gtk_frame_new(label);
vbox = gtk_vbox_new(FALSE, 0);
hbox = gtk_hbox_new(FALSE, 0);
gtk_box_set_homogeneous(GTK_BOX(hbox), TRUE);
table = gtk_table_new(2, amt, FALSE);
gtk_table_set_col_spacings(GTK_TABLE(table), 2);
for (x = 0; x<amt; x++) {
widget = create_on_off_button(&widgets[x]);
gtk_box_pack_start(GTK_BOX(hbox), widget, TRUE, TRUE, 2);
if ((widgets[x].id != -1) && (widgets[x].position != -1)) {
widget = create_on_off_button(&widgets[x]);
gtk_table_attach_defaults(GTK_TABLE(table), widget, 0, 1, x, x+1);
table = create_widget_container(widgets[x].group, widgets[x].group_amt);
gtk_box_pack_start(GTK_BOX(hbox), table, TRUE, TRUE, 2);
if (widgets[x].label)
y = 1;
else
y = 0;
} else if (widgets[x].label) {
widget = gtk_label_new(widgets[x].label);
gtk_table_attach_defaults(GTK_TABLE(table), widget, 0, 1, x, x+1);
}
container = create_widget_container(widgets[x].group, widgets[x].group_amt);
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), hbox, FALSE, FALSE, 2);
return vbox;
gtk_container_add(GTK_CONTAINER(frame), vbox);
return frame;
}
enum {
@@ -411,11 +427,10 @@ enum {
};
/**
* row_activate_cb:
* @treeview: the object which emitted the signal
* @path: the GtkTreePath for the activated row
* @column: the GtkTreeViewColumn in which the activation occurred
* @model: model holding preset names
* \param treeview the object which emitted the signal
* \param path the GtkTreePath for the activated row
* \param column the GtkTreeViewColumn in which the activation occurred
* \param model model holding preset names
*
* Sets active device preset to preset selected by user.
**/
@@ -434,10 +449,9 @@ void row_activate_cb(GtkTreeView *treeview, GtkTreePath *path, GtkTreeViewColumn
}
/**
* fill_store_with_presets:
* @model: model to fill
* @bank: preset bank
* @name: preset bank description visible to user
* \param model model to fill
* \param bank preset bank
* \param name preset bank description visible to user
*
* Appends to model preset names found in device preset bank.
**/
@@ -458,19 +472,22 @@ static void fill_store_with_presets(GtkTreeStore *model, guint bank, gchar *name
-1);
for (x=0; x<g_strv_length(presets); x++) {
gchar *tmp = g_strdup_printf("%d - %s", x+1, presets[x]);
gtk_tree_store_append(model, &child_iter, &iter);
gtk_tree_store_set(model, &child_iter,
PRESET_NAME_COLUMN, presets[x],
PRESET_NAME_COLUMN, tmp,
PRESET_NUMBER_COLUMN, x,
PRESET_BANK_COLUMN, bank,
-1);
g_free(tmp);
}
g_strfreev(presets);
}
/**
* fill_store:
* @model: model to fill
* \param model model to fill
*
* Fills model with preset names found on device.
**/
@@ -481,11 +498,9 @@ static void fill_store(GtkTreeStore *model)
}
/**
* create_preset_tree:
*
* Creates treeview showing list of presets available on device.
*
* Return value: treeview containing all preset names found on device.
* \return treeview containing all preset names found on device.
**/
GtkWidget *create_preset_tree()
{
@@ -513,9 +528,8 @@ GtkWidget *create_preset_tree()
}
/**
* show_store_preset_window:
* @window: application toplevel window
* @default_name: default preset name
* \param window application toplevel window
* \param default_name default preset name
*
* Shows window allowing user to store current edit buffer.
**/
@@ -568,8 +582,7 @@ static void show_store_preset_window(GtkWidget *window, gchar *default_name)
}
/**
* action_store_cb:
* @action: the object which emitted the signal
* \param action the object which emitted the signal
*
* Shows store preset window.
**/
@@ -580,8 +593,7 @@ static void action_store_cb(GtkAction *action)
}
/**
* action_show_about_dialog_cb:
* @action: the object which emitted the signal
* \param action the object which emitted the signal
*
* Shows about dialog.
**/
@@ -603,6 +615,8 @@ static void action_show_about_dialog_cb(GtkAction *action)
NULL);
}
#ifndef DOXYGEN_SHOULD_SKIP_THIS
typedef struct {
gchar *name;
gchar *suffix;
@@ -610,12 +624,15 @@ typedef struct {
static SupportedFileTypes file_types[] = {
{"RP250Preset", "*.rp250p"},
{"RP500Preset", "*.rp500p"},
};
static guint n_file_types = G_N_ELEMENTS(file_types);
#endif /* DOXYGEN_SHOULD_SKIP_THIS */
/**
* action_open_preset_cb:
* @action: the object which emitted the signal
* \param action the object which emitted the signal
*
* Shows file chooser dialog.
* If user opens valid preset file, the preset gets applied to edit buffer and store preset window is shown.
@@ -653,9 +670,14 @@ static void action_open_preset_cb(GtkAction *action)
gboolean loaded = FALSE;
while (!loaded && gtk_dialog_run(GTK_DIALOG(dialog)) == GTK_RESPONSE_ACCEPT) {
GError *error = NULL;
gchar *filename = gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(dialog));
Preset *preset = create_preset_from_xml_file(filename);
if (preset != NULL) {
Preset *preset = create_preset_from_xml_file(filename, &error);
if (error) {
show_error_message(window, error->message);
g_error_free(error);
error = NULL;
} else if (preset != NULL) {
apply_preset_to_gui(preset);
gtk_widget_hide(dialog);
@@ -706,8 +728,7 @@ static void action_open_preset_cb(GtkAction *action)
}
/**
* widget_list_free:
* @list: widget list to be freed
* \param list widget list to be freed
*
* Frees all memory used by widget list.
*/
@@ -721,8 +742,7 @@ static void widget_list_free(GList *list)
}
/**
* action_quit_cb:
* @action: the object which emitted the signal
* \param action the object which emitted the signal
*
* Destroys action object "window" data, then stops gtk main loop.
**/
@@ -734,6 +754,8 @@ static void action_quit_cb(GtkAction *action)
gtk_main_quit();
}
#ifndef DOXYGEN_SHOULD_SKIP_THIS
static GtkActionEntry entries[] = {
{"File", NULL, "_File"},
{"Preset", NULL, "_Preset"},
@@ -762,11 +784,12 @@ static const gchar *menu_info =
" </menubar>"
"</ui>";
#endif /* DOXYGEN_SHOULD_SKIP_THIS */
/**
* add_action_data:
* @ui: GtkUIManager to lookup actions
* @path: path to action
* @window: toplevel window
* \param ui GtkUIManager to lookup actions
* \param path path to action
* \param window toplevel window
*
* Sets action object "window" data to toplevel window.
**/
@@ -781,9 +804,8 @@ static void add_action_data(GtkUIManager *ui, const gchar *path, GtkWidget *wind
}
/**
* add_menubar:
* @window: toplevel window
* @vbox: vbox to hold menubar
* \param window toplevel window
* \param vbox vbox to hold menubar
*
* Creates menubar (adds accel group to toplevel window as well) and packs it into vbox.
**/
@@ -819,11 +841,9 @@ static void add_menubar(GtkWidget *window, GtkWidget *vbox)
}
/**
* gui_create:
*
* Creates main window.
**/
void gui_create()
void gui_create(EffectList *effects, int n_effects)
{
GtkWidget *window;
GtkWidget *vbox;
@@ -856,11 +876,11 @@ void gui_create()
knob_anim = gtk_knob_animation_new_from_inline(knob_pixbuf);
for (x = 0; x<n_effects; x++) {
if ((x % 3) == 0) {
hbox = gtk_hbox_new(TRUE, 0);
if ((x % ((n_effects+1)/2)) == 0) {
hbox = gtk_hbox_new(FALSE, 0);
gtk_box_pack_start(GTK_BOX(vbox), hbox, TRUE, TRUE, 2);
}
widget = create_vbox(effects[x].effect, effects[x].amt);
widget = create_vbox(effects[x].effect, effects[x].amt, effects[x].label);
gtk_box_pack_start(GTK_BOX(hbox), widget, TRUE, TRUE, 2);
}
@@ -871,8 +891,6 @@ void gui_create()
}
/**
* gui_free:
*
* Frees memory allocated by gui_create which is not explicitly freed when main window is destroyed.
**/
void gui_free()
@@ -883,3 +901,57 @@ void gui_free()
gtk_knob_animation_free(knob_anim);
knob_anim = NULL;
}
/**
* \param list Variable to hold effect list
* \param n_list Variable to hold length of effect list
*
* Displays dialogbox stating that device is unsupported.
*
* \return TRUE if user selects "compability mode", otherwise FALSE.
**/
gboolean unsupported_device_dialog(EffectList **list, int *n_list)
{
extern SupportedDevices supported_devices[];
extern int n_supported_devices;
GtkWidget *dialog;
GtkWidget *label;
GtkWidget *combo_box;
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);
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(GTK_DIALOG(dialog)->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(GTK_DIALOG(dialog)->vbox), combo_box);
gtk_widget_show_all(GTK_DIALOG(dialog)->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);
*list = supported_devices[number].list;
*n_list = supported_devices[number].n_list;
gtk_widget_destroy(dialog);
return TRUE;
}
}
gtk_widget_destroy(dialog);
return FALSE;
}

6
gui.h
View File

@@ -17,8 +17,12 @@
#ifndef GDIGI_GUI_H
#define GDIGI_GUI_H
#include <glib.h>
#include "effects.h"
void show_error_message(GtkWidget *parent, gchar *message);
void gui_create();
void gui_create(EffectList *list, int n_list);
void gui_free();
gboolean unsupported_device_dialog(EffectList **list, int *n_list);
#endif /* GDIGI_GUI_H */

BIN
knob.png

Binary file not shown.

Before

Width:  |  Height:  |  Size: 72 KiB

After

Width:  |  Height:  |  Size: 62 KiB

View File

@@ -19,6 +19,8 @@
#include <string.h>
#include "preset.h"
#ifndef DOXYGEN_SHOULD_SKIP_THIS
enum {
PARSER_TYPE_NOT_SET = -1,
PARSER_TYPE_PRESET_NAME = 0,
@@ -112,24 +114,27 @@ static void XMLCALL text_cb(void *data, const char* text, int len)
g_free(value);
}
#endif /* DOXYGEN_SHOULD_SKIP_THIS */
/**
* create_preset_from_xml_file:
* @filename: valid path to file
* \param filename valid path to file
* \param error return location for an error
*
* Tries to open file pointed by path, then parses it.
*
* Return value: 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_xml_file(gchar *filename)
Preset *create_preset_from_xml_file(gchar *filename, GError **error)
{
GFile *file;
GError *error = NULL;
GError *err = NULL;
gchar *contents;
file = g_file_new_for_path(filename);
if (g_file_get_contents(filename, &contents, NULL, &error) == FALSE) {
g_message("Failed to get %s contents: %s", filename, error->message);
g_error_free(error);
if (g_file_get_contents(filename, &contents, NULL, &err) == FALSE) {
g_message("Failed to get %s contents: %s", filename, err->message);
*error = g_error_copy(err);
g_error_free(err);
g_object_unref(file);
return NULL;
}
@@ -148,9 +153,9 @@ Preset *create_preset_from_xml_file(gchar *filename)
XML_SetCharacterDataHandler(p, text_cb);
if (XML_Parse(p, contents, strlen(contents), XML_TRUE) != XML_STATUS_OK) {
g_warning("Parse error at line %d:\n%s",
(int)XML_GetCurrentLineNumber(p),
XML_ErrorString(XML_GetErrorCode(p)));
g_set_error(error, 0, 0, "Parse error at line %d:\n%s",
(int)XML_GetCurrentLineNumber(p),
XML_ErrorString(XML_GetErrorCode(p)));
preset_free(ad->preset);
g_slice_free(AppData, ad);
g_free(contents);
@@ -170,12 +175,11 @@ Preset *create_preset_from_xml_file(gchar *filename)
}
/**
* create_preset_from_data:
* @data: unpacked RECEIVE_PRESET_PARAMETERS message
* \param data unpacked RECEIVE_PRESET_PARAMETERS message
*
* Parses message
*
* Return value: 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)
{
@@ -187,6 +191,8 @@ Preset *create_preset_from_data(GString *data)
gint x;
gint tmp;
g_return_val_if_fail(data != NULL, NULL);
x = 0x09;
n = 0;
total = (unsigned char)data->str[x];
@@ -226,8 +232,7 @@ Preset *create_preset_from_data(GString *data)
}
/**
* preset_free:
* @preset: preset to be freed
* \param preset preset to be freed
*
* Frees all memory used by preset.
**/

View File

@@ -30,7 +30,7 @@ typedef struct {
GList *params;
} Preset;
Preset *create_preset_from_xml_file(gchar *filename);
Preset *create_preset_from_xml_file(gchar *filename, GError **error);
Preset *create_preset_from_data(GString *data);
void preset_free(Preset *preset);