165 Commits

Author SHA1 Message Date
Tomasz Moń
cada964d61 Merge pull request #10 from acspike/master
additional modifiers for rp1000
2014-02-06 09:11:14 +01:00
Frederic DE WEVER
4bb78a5fe7 Fix Mid frequency Equalizer name ID error. 2014-01-05 09:20:00 +01:00
Aaron C. Spike
a2a4842fd9 additional modifiers for rp1000 2014-01-01 13:22:15 -06:00
Tim LaBerge
079547c20f Fix up some whitespace. 2013-12-26 10:29:03 -08:00
Tim LaBerge
e3447292c4 Restore modifier for delay tap time 4990. 2013-12-26 10:26:31 -08:00
Tim LaBerge
9f4bd66217 Remove duplicate RP1000 code.
Support for RP1000 has been merged upstream, so the rp1000 changes
in this branch are unneeded.
2013-12-26 10:20:53 -08:00
Tim LaBerge
85be87a636 Merge mainline RP1000 changes. 2013-12-26 10:16:05 -08:00
Tim LaBerge
d61e6c3046 Merge branch 'master' into rp1000 2013-12-26 09:49:19 -08:00
Tim LaBerge
196a7c2aa5 Fine tune debugging.
1) If get_modifier() fails, set the label to "Unknown pos/id". Thus, label
   will always be non-null and debugging should be easier. The minor downside
   is that the label string is leaked when we update the modifier group.

2) Restore the assert in update_modifier_vbox() and the now unnecessary
   test of group[x].label.
2013-12-25 14:10:57 -08:00
Tim LaBerge
f1aa3665ed Support for RP1000
1) Add missing support for DELAY_TAP_TIME, DELAY_MULTIPLIER, and
   AMP_LOOP_ON_OFF.

2) Add a warning when get_modifier() fails.

3) In update_modifier_linkable_list(), set label to "Unknown" when
   the lookup of a modfier fails.

4) In format ipv(), the warning message that's emitted if get_xml_settings()
   fails reversed position and id.

5) In update_modifier_vbox(), remove the assert that the group label is not
   null. Set the combo box text to "Unknown".
2013-12-25 13:52:15 -08:00
Aaron C. Spike
478f580e76 add values needed for rp1000 2013-12-22 18:04:02 -06:00
Tim LaBerge
dfec60e7b4 Add support for RP500 amp bypass. 2013-08-21 22:51:19 -07:00
Tim LaBerge
e7de6b2bb5 RP500 specific xml settings. 2013-08-20 21:53:56 -07:00
Tim LaBerge
17ff7063ec Need RP500 changes in modifiers array. 2013-08-18 09:14:19 -07:00
Tim LaBerge
f1bca1eabb Fix expression pedel for rp500 2013-08-17 10:19:19 -07:00
Ahmed Toulan
ba71876ebf Fix installed files permissions. 2013-01-30 00:32:14 +02:00
Ahmed Toulan
8591b0feb7 Change category GNOME to GTK 2013-01-30 00:31:58 +02:00
Tomasz Moń
f94ed1c93b Tag version 0.4.0. 2013-01-14 17:13:46 +01:00
Tomasz Moń
7023e1fa92 Add expression pedal setting for RP250, RP255, RP500 and RP1000. 2012-12-22 15:35:45 +01:00
Tim LaBerge
a51103964b Fix comments from code review.
1) #include gui.h in effects.c.

2) Copy/paste error in xml_settings for UNOVIBE_CHORUS_VIBRATO.

3) Use a gboolean instead of a guint.

4) Remove a warning that fires under normal circumstances on devices
   without LFO's.
2012-12-21 06:55:49 -08:00
Tim LaBerge
f6a2ba7420 Free allocated exp settings.
Code to properly free exp settings when we rebuild the modifer list.

1) Fix up mislabeled modifier settings for Presence.

2) Add missing xml settings (avoids crashes with -D a).

3) When we free the modifier group, free the data associated with the
   dynamically allocated settings for the EXP_POSITION combo box.
2012-12-20 20:52:22 -08:00
Tim LaBerge
bad10ed0f2 Add proper min/max settings to pedal assign effect.
1) Delete definition of pedal1_assign_settings since it should be calculated
   at runtime from the modifier list.

2) Delete the pedal1_assign_settings EffectSetting from
rp355_pedal1_assign_group.

3) Add "None" entries to the tone_lib_group[] and effect_lib_group[]. Otherwise,
   once a library tone or effect is selected, it can't be deselected.

4) Fix up some tracing of effect values that was displaying incorrect values.

5) Change 'update_modifier_combo_box()' to 'update_modifier_vbox()' and for
   the expression pedal let it handle instantiating per combo box entry
   settings.

6) Don't forget to free the links we remove from the list when we're cleaning
   the combo box. If there are per-combo box entry settings, free them using
   the usual destructor.

7) Poll the device for the appropriate settings for EXP_MIN/MAX after we
   we update the modifier list.
2012-12-18 21:49:57 -08:00
Tim LaBerge
cee33835a7 Enforce hysteresis on modifier list requests.
With the tone and effect libraries implemented on rp355, it appears that
the device will send multiple NOTIFY_MODIFIER_GROUP_CHANGED messages
in response to selecting a new tone or effect library.

If we receive a NOTIFY_MODIFIER_GROUP_CHANGED, but haven't yet processed
the RECEIVE_MODIFIER_LINKABLE_LIST from the previous notification,
we will drop the most recent.

This greatly reduces the device churn and time it takes to apply a new library
setting.
2012-12-17 21:40:04 -08:00
Tim LaBerge
0cd6727d45 Fix review comments for pull request.
1) Don't expose gui mode to the causual user. Hide under the DEVELOPMENT_MODE
   #define.

2) Add accessors for the ModifierLinkableList's interesting fields.

3) Free the ModifierLinkableList from modifier_linkable_list(). This allows
   us to make the free function static.

4) Rename modifier_linkable_list() to update_modifier_linkable_list().

5) In effects.h, reflect the renaming of update_modifier_linkable_list() and
   correct it's signature.

6) Whitespace fixups in gdigi.c.

7) In the handler for RECEIVE_GLOBAL_PARAMETERS, apply the parameter to the gui.

8) Fixup some merge damage ;-(

9) UnCamelCaseIze some variables.

10) When we create the gui, issue a single call to REQUEST_GLOBAL_PARAMETERS to
    retrieve the globals from the device, instead of polling each parameter
    individually.
2012-12-17 21:21:17 -08:00
Tim LaBerge
22aeaf8ffa Enable tone/effects library for rp355.
Implement the recent addition of the tone/effects library for the rp355.

Get rid of USB_POSITION.

Add tone lib A for rp355.

Minor comment changes.

Remove a couple of commented out lines.
2012-12-17 06:58:44 -08:00
Tim LaBerge
a389c785f7 Merge branch 'global'
Conflicts:
	.gitignore
	effects.c
	gdigi.c
	gdigi.h
	gdigi_xml.h
	gui.c
	gui.h
	preset.c
	preset_xml.c

effects.c: More effect_values_0_to_* arrays for various effects.
           VALUE_TYPE_POSID for linkable effects.
           Add the rest of the global settings (need to change USB_POSITION
           to GLOBAL_POSITION throughout).
           A few label typos.
           New settings, groups, and effects for linkables.
           Make the display three rows instead of two.
           Add missing modifiers.
           Add missing xml settings.
           Code for handling/updating the global modifier linkable list.

effects.h Add VALUE_TYPE_POSID.

gdigi.c   Tweaks for value formatting.
          Use NOTIFY_MODIFIER_GROUP_CHANGED to drive the update of the combo
          boxes for linkable effects.
          Use RECEIVE_MODIFIER_LINKABLE_LIST to handle the update of the
          combo boxes for linkable effects.

gdigi.h   Minor changes.

gui.c     Deprecate gtk_vbox_new().
          Use simpler API gtk_combo_box_text_append_text().
          Minor reformatting/whitespace changes.
          Code to update combo boxes for linkable effects.
          Code to retrieve global parameters from device at startup.

preset_xml.c
          Some tweaks to map_xml_value() so that it's passed resolved
          EffectValues for settings of type EXTRA.
2012-12-16 21:30:41 -08:00
Tim LaBerge
44dbbe7b72 Add remaining rp355 effects to modifiers array.
1) A few rp355 effects were missing from the modifiers array.
2) The EH_PHASER effects were missing from the xml_settings array.
3) Added a disambiguating string to the "Unable to map" warning in
   gdigi.c.
2012-12-16 11:12:10 -08:00
Tim LaBerge
3a3017b46f Add support for linkable parameters.
These changes allow gdigi to link parameters to the expression pedal,
LFO1, and LFO2. The changes have been implemented only for RP355, but
should be easily extendible to other devices.

The design is as follows:

The effect group entries for the linkable effects have only a placeholder
entry "None" at startup.

During startup, we send an unsolicited REQUEST_MODIFIER_LINKABLE_LIST. When we
receive RECEIVE_MODIFIER_LINKABLE_LIST in response, we use it to construct the
ModifierLinkableList and update the combo boxes for the Pedal Assign and LFO
effects.

Whenever the selected chorus/fx effect changes, the list of linkable parameters
also changes, so the device will send us a NOTIFY_MODIFIER_GROUP_CHANGED. Again,
we send a REQUEST_MODIFIER_LINKABLE_LIST and use the response to rebuild
ModifierLinkableList. Then we tear down and rebuild the state associated with
the affected combo boxes.

The changes made are as follows:

1) Add settings for pedal1_assign. This is the min/max value returned
   by the pedal.

2) Add separate EffectGroup for both pedal assignment and the LFO's
   for the non-combo box settings.

3) Fix up a few more missing effects in the xml and modifier lists.
   There is additional work to do here, but that will be in future
   commits.

4) Fixed a missing break in the RECEIVE_DEVICE_NOTIFICATION case
   in push_message().

5) When we receive a NOTIFY_MODIFIER_GROUP_CHANGED message, free the exisiting
   modifier group and send a REQUEST_MODIFIER_LINKABLE_LIST so we can
   rebuild it.

6) When we receive a RECEIVE_MODIFIER_LINKABLE_LIST, protect the calls to
   create_modifier_group() with GDK_THREADS_ENTER() so we don't crash
   because of interactions with the event/gui threads.

7) Added a BUG assert to an error leg in get_message_list().

8) Fix memory leak in get_digitech_devices() found by valgrind.

9) Add a function to tear down the state associated with the entries of a
   pedal assign or LFO combo box.

10) Add a function to build up the entries of a pedal assign or LFO combo
    box from the modifier linkable list received from the device.

11) Use gtk_combo_box_text_append_text() throughout.

12) A few whitespace/readability changes and more comments.
2012-12-16 09:29:16 -08:00
Tim LaBerge
8b998c636f Replace deprecated API's gtk_vbox/hbox_new().
The API's gtk_vbox_new() and gtk_hbox_new() are deprecated and result
in compilation warnings. Replace these API's with calls to
gtk_box_new() with GTK_ORIENTATION_VERTICAL and GTK_ORIENTATION_HORIZONTAL,
respectively.
2012-12-03 19:25:53 -08:00
Tim LaBerge
f389caffbc Fix RHold display for delay repeats.
This involved passing the EffectValue resulting from the resolution of
an VALUE_TYPE_EXTRA to map_xml_value() and some more careful range
checking.

Also, the delay repeats effect needed an xml_label for the special
'repeat forever' value 100, which maps to the string RHold.
2012-12-03 19:25:24 -08:00
Tim LaBerge
b5aa30d599 Fix up LFO speed EffectValues. 2012-12-03 12:19:35 -08:00
Tomasz Moń
29d33ce93a Add Mauro Carvalho Chehab to the authors list. 2012-12-03 10:48:12 +01:00
Tomasz Moń
27ffb9c65a Fix FSF address at gtkknob.c/gtkknob.h. 2012-12-03 10:46:14 +01:00
Tim LaBerge
4f40132742 Implement the LFO1 and LFO2 effects.
For now, this is just for rp355, though the code should work for other
devices with minimal modification.

1) The EffectValues for values_*_assign need to be VALUE_TYPE_POSID.

2) Disabmiguate "Delay Tape" for a couple of EffectSettings. This fixed
   some bugs in the creation of the global modifier group.

3) Remove #if 0's around the definition of the lfo2_settings.

4) Define proper lfo1 and lfo2 groups arrays.

5) Define the lfo2_effect[] array.

6) Add the lfo1 and lfo2 effects to the rp355_effects array.

7) Disambiguate "EQ B" from "Eq" for some effedts in the modifiers array.

8) In push_message(), after we receive the RECEIVE_MODIFIER_LINKABLE_LIST
   message, kick off the creation of the EXP, LFO1, and LFO2 effects.

9) Generalize the function used for the pedal1_assign effect and make it work
   for lfo1 and lfo2 as well. Convert printf's to debug_msg().

10) Since we're destroying the association of the grid with the placeholder
    combo box entry, steal the data so the child widget isn't destroyed.

11) Silence warning on exit about 0 unread messages in queue.
2012-12-02 21:59:26 -08:00
Mauro Carvalho Chehab
1a5fab5f5a Add Tone Lib/Effects support on RP255
RP255 (firmware version 1.1) has the Tone Library at position 25, instead of 26.
Add this library position alternative as "LIB_POSITION_B", renaming the existing
one to LIB_POSITION_A, and add the corresponding bits at effects.c.

Also, adds a menu there, to let it to be controlled via the library.
2012-12-02 15:00:52 +01:00
Tim LaBerge
cf239da94c Implement parameter linking to expression pedal. 2012-12-01 15:30:56 -08:00
Tomasz Moń
890d40f6c6 Fix problems found by Coverity scan.
CID #743175 Unchecked return value
CID #743176 Logically dead code
CID #743177 Dereference after null check
CID #743178 Dereference before null check
CID #743179 Uninitialized scalar variable
CID #743180 Uninitialized scalar variable
2012-11-12 21:38:15 +01:00
Tomasz Moń
c927b075a7 Fix trailing whitespaces. 2012-11-12 21:11:38 +01:00
Tomasz Moń
7691323989 Fix mouse scroll on GtkKnob widget. 2012-11-12 21:04:06 +01:00
Tomasz Moń
d90d7e4b70 Add missing libm linker flag 2012-07-05 23:25:44 +02:00
Tomasz Moń
79d80fee46 Merge pull request #3 from thelinuxer/master
Fix spelling mistakes
2012-05-22 08:03:05 -07:00
Ahmed Toulan
034f353aa9 Fix spelling mistakes 2012-05-22 16:30:25 +02:00
Tomasz Moń
db04032b46 Merge pull request #2 from andrewshadoura/patch-1
Update my last name
2012-05-06 08:14:26 -07:00
Andrew Shadura
d7043d471d Fix my last name 2012-05-06 16:27:00 +03:00
Andrew Shadura
c614783e87 Fix my last name 2012-05-06 16:25:21 +03:00
Tomasz Moń
06cee3eef1 Use gdigi icon. 2012-05-02 17:18:50 +02:00
Islam Alwazery
8a98e2703f Add gdigi icon. 2012-05-02 17:17:21 +02:00
Tomasz Moń
b1a8fb4a3b Merge pull request #1 from tlaberge/master
Refine debug/logging infrastructure
2012-04-09 09:21:57 -07:00
Tim LaBerge
2b1c74ac30 Cleanups on the Logging branch.
1) Add a more reasonable max value for the the pedal/vswitch assign values.
2) Minor format change in format_ipv().
3) Formatting cleanup in push_message(). Also change debug messages to
   emphasize message direction.
4) Cleanup startup messages and add one that emits device name.
5) Cleanup the option message so that it's complete and readable.
2012-04-08 09:41:04 -07:00
Tim LaBerge
baa5fdff85 Fix display of signed/unsigned debug msg.
Also twiddle the .gitignore file.
2012-04-07 20:05:04 -07:00
Tim LaBerge
d139a3d89a Add a .gitignore file. 2012-04-07 20:04:02 -07:00
Tim LaBerge
4291fa71b2 Fixup label range values.
A number of EffectValues of type label had invalid ranges. Make
them less invalid.

Also add SYNTH_TALK id's to xml settings.

Make format_ipv warn instead of crashing if an xml setting is not
found.
2012-04-07 19:46:36 -07:00
Tim LaBerge
ea80320531 Human readable debug
Leverage the code that writes a preset to XML so that messages
can be displayed in a human readable format.

E.g.,

(6, 2432, 1280)  Distortion: Dist Type: Screamer

The 3-tuple is position, id, value, which is followed by the
colon separated decode of the position, id, and the mapped value.
2012-04-07 19:45:50 -07:00
Tim LaBerge
88819a795b Fixup label range values.
A number of EffectValues of type label had invalid ranges. Make
them less invalid.

Also add SYNTH_TALK id's to xml settings.

Make format_ipv warn instead of crashing if an xml setting is not
found.
2012-04-06 10:06:12 -07:00
Tim LaBerge
3002d2256e Human readable debug
Leverage the code that writes a preset to XML so that messages
can be displayed in a human readable format.

E.g.,

(6, 2432, 1280)  Distortion: Dist Type: Screamer

The 3-tuple is position, id, value, which is followed by the
colon separated decode of the position, id, and the mapped value.
2012-04-06 08:57:08 -07:00
Tim LaBerge
1205a1639d Add 'Label' to modifier group log message. 2012-03-31 18:48:49 -07:00
Tim LaBerge
122bbcd823 More logging changes. 2012-03-31 18:48:22 -07:00
Tim LaBerge
5c42cad5e7 Add labels to debug messages.
Add a global settings settings to the xml settings array.

Start adding label strings to the debug messages. This
needs cleaning up, but it should help.
2012-03-31 18:25:19 -07:00
Tim LaBerge
7781063407 Presence effect in wrong place for some devices. 2012-03-31 18:25:10 -07:00
Tim LaBerge
e56884ecd9 Add missing effects to modifier array.
Change AMP_POSITION to AMP_A_POSITION.

Add AMP_B_POSITION to the modifier array.

Add AMP_PRESENCE to the modifier array and move it to follow Treble
in the Equalizer effect.

Add EQ_B_POSITION settings to the modifier array.

Change the formatting of the debug messages to print more
readable columns.

Conflicts:

	gdigi.c
2012-03-31 18:24:29 -07:00
Tim LaBerge
dd1f4408c9 Better message tracking. 2012-03-31 18:18:00 -07:00
Tim LaBerge
f3dbaf43ec Merge remote-tracking branch 'upstream/master' 2012-03-31 17:54:53 -07:00
Tim LaBerge
87ae4cd280 Add 'Label' to modifier group log message. 2012-03-31 17:45:12 -07:00
Tomasz Moń
eadaf198ba Update README. 2012-03-26 16:57:04 +02:00
Tomasz Moń
97547476e4 Add contributors to the about dialog. 2012-03-26 16:55:00 +02:00
Tim LaBerge
35e42dc653 Detect DigiTech devices on startup. If more than one device is found, ask user which one to use. 2012-03-26 16:17:03 +02:00
Tim LaBerge
ce296d2698 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.
2012-03-26 22:08:29 +08:00
Tim LaBerge
a073f5cde2 Refine logging infrastructure.
1) Make logging conditional on debug flags.

2) Add command line option for setting these flags.

3) Emit warnings with g_warning() instead of g_message().

4) Added note about how FX_LIB_LEVEL_MAX[1-3] is used.
2012-02-27 20:26:42 -08:00
Tim LaBerge
9fcf6939d0 Add labels to debug messages.
Add a global settings settings to the xml settings array.

Start adding label strings to the debug messages. This
needs cleaning up, but it should help.
2012-02-26 21:52:27 -08:00
Tim LaBerge
71e087cfd0 Presence effect in wrong place for some devices. 2012-02-26 21:27:54 -08:00
Tim LaBerge
6a16e66cbd Add missing effects to modifier array.
Change AMP_POSITION to AMP_A_POSITION.

Add AMP_B_POSITION to the modifier array.

Add AMP_PRESENCE to the modifier array and move it to follow Treble
in the Equalizer effect.

Add EQ_B_POSITION settings to the modifier array.

Change the formatting of the debug messages to print more
readable columns.
2012-02-26 21:21:27 -08:00
Tim LaBerge
4351613e72 Add a .gitignore file. 2012-02-26 20:45:26 -08:00
Tim LaBerge
2253833105 Add retrieval of global settings. Start LFO. 2012-02-26 08:37:51 -08:00
Tim LaBerge
87e6dcbb9c Better message tracking and retrieve usb settings. 2012-02-26 08:29:43 -08:00
Tim LaBerge
d92489348d Add the USB (global) effects. 2012-02-25 18:10:58 -08:00
Tim LaBerge
2b27302166 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.
2012-02-25 17:52:52 -08:00
Tomasz Moń
fd0369dc7c use GtkGrid instead of GtkTable 2011-10-15 16:24:57 +02:00
John Hammen
2c921df204 add RP150 support 2011-10-14 10:43:47 +02:00
Tomasz Moń
ee2fcd181e port to GTK+ 3 2011-09-28 15:32:30 +02:00
Ahmed Toulan
2eb4e97810 detect DigiTech devices on startup 2011-09-05 20:45:35 +02:00
John Hammen
907a3d0ed9 add RP155 support 2011-08-29 09:16:25 +02:00
Tomasz Moń
5dc5f0652f update HACKING file 2011-01-27 11:55:48 +01:00
Tomasz Moń
5a44076e4f Added tag 0.2.0 for changeset 6864af80db93 2010-10-07 11:09:14 +02:00
Tomasz Moń
0bb0f6db71 update manpage 2010-10-07 11:08:59 +02:00
Tomasz Moń
dcf66adfa9 fix RP1000 support 2010-08-25 11:15:29 +02:00
Tomasz Moń
0886ba00c1 add support for GNX4 and GNX3k patches 2010-06-17 19:20:58 +02:00
Jonathan A. Tice
e12de97fab add RP1000 support 2010-04-24 15:07:18 +02:00
Miklos Aubert
59753a61dc add RP255 support 2010-03-04 18:54:58 +01:00
Tomasz Moń
ff0be8230e fix some rp500 values 2010-02-05 09:43:21 +01:00
Tomasz Moń
07cfd70941 display values correctly (offsets, correct steps, suffixes, labels) 2010-01-03 14:18:53 +01:00
Rafael Moreno
2523b27205 add rp355p to SupportedFileTypes 2009-09-20 20:06:27 +02:00
Tomasz Moń
530dd397c5 remove USB settings from effect list as they're not part of Preset 2009-09-20 19:57:39 +02:00
Rafael Moreno
158fd081a5 fix RP355 amp B settings 2009-09-04 17:49:11 +02:00
Tomasz Moń
a8bac07f68 correct manpage 2009-08-11 12:18:03 +02:00
Andreas Karajannis
87bb59f43a don't use uninitialized value 2009-08-11 12:17:28 +02:00
Andrew O. Shadoura
cdeb821deb added manpage 2009-08-10 19:56:56 +01:00
Andrew O. Shadoura
ce463b29d8 added simple .desktop file 2009-08-08 21:04:40 +01:00
Andrew O. Shadoura
159bca158e use LDADD instead of LDFLAGS and -Wl,--as-needed; added install target 2009-08-08 20:53:07 +01:00
Tomasz Moń
6ae750c4fb GFile requires gio.h 2009-07-31 14:10:21 +02:00
Rafael Moreno
5f21c62a2f fix RP355 support 2009-07-28 11:38:24 +02:00
Tomasz Moń
08b20b398f remove redundant GFile 2009-07-19 18:52:57 +02:00
Tomasz Moń
1be664e82f rename Pickup to Pickup/USB as this frame contains both pickup and USB settings 2009-07-19 18:32:48 +02:00
Tomasz Moń
3ab55054c1 add restore_backup_file() 2009-07-19 16:15:23 +02:00
Tomasz Moń
97b8c9fd6d add create_backup_file() 2009-07-19 14:03:55 +02:00
Tomasz Moń
211df27cf8 fix typos in comments 2009-06-29 20:03:54 +02:00
Rafael Moreno
dfe28ac81d add RP355 support 2009-06-29 20:02:50 +02:00
Tomasz Moń
3da458d370 Added tag 0.1.8 for changeset 5e6d6124b5f2 2009-06-22 16:36:52 +02:00
Tomasz Moń
ba04930133 display GNX3000 settings in tabs 2009-06-21 20:05:42 +02:00
Stephen Rigler
18f137636d add GNX3000 amp channel settings 2009-05-20 20:51:10 +02:00
Jaco Kroon
eba8bbe5aa fix Makefile 2009-05-15 21:54:42 +02:00
Tomasz Moń
7a6e3b159c greatly reduce number of comparisions required to apply parameters to GUI 2009-05-15 20:59:28 +02:00
Tomasz Moń
cc85da9c71 update ignore list 2009-05-15 16:39:31 +02:00
Jaco Kroon
9586f6cd31 make buildsystem aware of header changes 2009-05-15 16:37:55 +02:00
Tomasz Moń
4a7ab848e7 remove id and position fields from EffectGroup 2009-05-15 10:20:42 +02:00
Jaco Kroon
2703e79d39 add GNX4 stompbox, noisegate, chorus, delay and reverb settings 2009-05-15 09:19:23 +02:00
Tomasz Moń
dbab804d52 actually the compressor settings are the same for both GNX3000 and GNX4 2009-05-13 12:19:44 +02:00
Tomasz Moń
c3f82416f5 rename values_synth_talk_balance as it's actually used for more effects 2009-05-13 12:10:40 +02:00
Tomasz Moń
145b41cb6c actually the whammy settings are the same for both GNX3000 and GNX4 2009-05-13 10:41:58 +02:00
Stephen Rigler
26d1db9e4f add GNX3000 amp channel + warping settings 2009-05-13 08:03:29 +02:00
Jaco Kroon
cc311f4f18 add GNX4 pickup, wah, compressor and whammy effect 2009-05-13 07:47:58 +02:00
Jaco Kroon
d85e83c89e make get_device_info interate over list of supported product and family ID 2009-05-13 07:27:11 +02:00
Tomasz Moń
55b9b08230 check RECEIVE_WHO_AM_I reply size 2009-05-12 21:51:43 +02:00
Tomasz Moń
400e221a4f make some devices happy 2009-05-12 21:14:46 +02:00
Jaco Kroon
5b93c91bfe fix unsigned comparisions 2009-05-12 19:43:17 +02:00
Tomasz Moń
cbd07a9709 revise create_preset_from_data 2009-05-11 23:32:17 +02:00
Tomasz Moń
def4917a07 revise mutex logic 2009-05-11 21:17:04 +02:00
Stephen Rigler
e9c0ed8b38 add GNX3000 reverb settings 2009-05-11 07:39:15 +02:00
Tomasz Moń
400a7d41f8 merge GNX3000 delay settings 2009-05-10 15:28:30 +02:00
Stephen Rigler
40a9d06e4c add GNX3000 delay settings 2009-05-10 14:13:40 +02:00
Stephen Rigler
e820ce0cc4 add GNX3000 chorus settings 2009-05-09 07:47:22 +02:00
Tomasz Moń
ebc603143e update TODO 2009-05-08 14:24:01 +02:00
Tomasz Moń
c74290d8e1 use gtk_dialog_get_content_area 2009-05-07 14:17:03 +02:00
Tomasz Moń
295e932bf1 update HACKING file 2009-05-06 17:57:51 +02:00
Tomasz Moń
1a65deb8d5 if get_message_by_id can't find message, wait until new message is pushed before retrying 2009-05-06 13:19:49 +02:00
Tomasz Moń
4509c14bbc make get_current_preset return list of messages describing preset rather than just one message with preset parameters 2009-05-06 13:10:46 +02:00
Stephen Rigler
d7f10eb509 add GNX3000 whammy/ips, preset level and noisegate settings 2009-05-06 08:14:27 +02:00
Tomasz Moń
b1a8d69dba Receive Who Am I can vary in length between versions 2009-05-04 17:39:46 +02:00
Tomasz Moń
20769ace01 Fix memory leak 2009-05-04 17:29:22 +02:00
Tomasz Moń
2633bac5d8 update GUI on remote preset change 2009-05-04 17:04:32 +02:00
Stephen Rigler
af1d3a2906 add GNX3000 pickup, wah and compressor settings 2009-05-04 15:26:15 +02:00
Tomasz Moń
06fd3eee66 apply asynchronous parameters changes to GUI 2009-05-03 22:17:41 +02:00
Tomasz Moń
acb1c1e273 introduce setting_param_new, setting_param_new_from_data and setting_param_free 2009-05-03 21:38:15 +02:00
Tomasz Moń
7bf55352b8 set device into GUI mode 2009-05-03 20:32:13 +02:00
Tomasz Moń
6a1d1de390 fix compiler warning 2009-05-02 14:25:50 +02:00
Tomasz Moń
b798d6ee39 remove reduntant defines 2009-05-01 20:33:09 +02:00
Tomasz Moń
ba810bf4f8 reuse widget table if possible 2009-05-01 16:12:58 +02:00
Tomasz Moń
24a1c2718b remove reduntant defines 2009-05-01 16:06:15 +02:00
Tomasz Moń
31a635839a add GNX3000 distortion settings 2009-05-01 07:53:23 +02:00
Tomasz Moń
d7b3f7a3d6 add Device struct 2009-04-30 17:27:55 +02:00
Tomasz Moń
6512696240 read MIDI IN messages in new thread 2009-04-30 10:32:24 +02:00
Tomasz Moń
f1359d18e4 open device in sync mode 2009-04-27 13:46:27 +02:00
Tomasz Moń
85ce157bb8 remove reduntant defines 2009-04-17 17:45:01 +02:00
Tomasz Moń
6daaf47cd8 remove tests as they are now obsolete 2009-04-17 17:32:55 +02:00
Tomasz Moń
3a849de954 add RP250 pickup settings 2009-04-17 17:30:50 +02:00
Tomasz Moń
a06c5dc07e Added tag 0.1.7 for changeset c622b5d3c3b3 2009-04-15 06:55:22 +02:00
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
25 changed files with 13292 additions and 1881 deletions

9
.gitignore vendored Normal file
View File

@@ -0,0 +1,9 @@
*.[om]
*.rp355p
cscope.*
tags
gdigi
*.orig
*.swp
images/gdigi_icon.h
core

View File

@@ -6,3 +6,7 @@ syntax: glob
*.o
*.patch
*.diff
*.m
*.orig
knob.h
gdigi

11
AUTHORS
View File

@@ -1 +1,12 @@
Tomasz Moń <desowin@gmail.com>
Stephen Rigler <riglersc@gmail.com>
Jaco Kroon <jaco@kroon.co.za>
Rafael Moreno <laocanfei@yahoo.com>
Andrew Shadura <bugzilla@tut.by>
Andreas Karajannis <aakara13@googlemail.com>
Miklos Aubert <miklos.aubert@gmail.com>
Jonathan A. Tice <jonandtice@gmail.com>
John Hammen <jhammen@gmail.com>
Ahmed Toulan <thelinuxer@gmail.com>
Tim LaBerge <tlaberge@visi.com>
Mauro Carvalho Chehab <maurochehab@gmail.com>

70
HACKING
View File

@@ -3,43 +3,57 @@ In general everything brings down to figure out:
-Position
-Possible value range
There seems to be two possible ways to figure that out.
There seems to be three possible ways to figure that out.
1) Use USB sniffer together with X-Edit
Once you set up X-Edit and usb sniffer, set some option.
USB sniffer should report something like this being sent to device:
(all numbers here are hex)
04 F0 00 00 04 10 00 5E 04 02 41 00 04 30 09 00 07 00 34 F7
To get SysEx command out of it, remove every 4th byte, so we have:
MIDI data is transferred over USB using 32-bit USB-MIDI Event Packets.
Byte 0 is Cable Number (high nibble) and Code Index Number (low nibble).
Bytes 1, 2 and 3 are data.
Every bulk transfer on USB MIDI endpoint contains atleast one such packet
(those are sent one after each other).
In case of Digitech devices, the Cable Number seems to be 0 (correct me,
if I'm wrong).
There are three different Code Index Numbers that are being used in this
particular case:
0x4 - SysEx starts or continues (Byte 1, 2 and 3 from this packet are
part of our MIDI message)
0x5 - SysEx ends with following single byte (we just need to take Byte 1
from this packet)
0x6 - SysEx ends with following two bytes (we just need to take Byte 1 and 2
from this packet)
0x7 - SysEx ends with following three bytes (we need to take Byte 1, 2 and 3
from this packet)
Unused bytes in USB-MIDI packets are supposed to be 0.
To get SysEx command out of it, apply above rules, so we have:
F0 00 00 10 00 5E 02 41 00 30 09 00 00 34 F7
SysEx message format seems to be formed like this:
magic bytes - F0 00 00 10 00 5E 02 41
status byte - in this example 00
SysEx start byte - F0
Manufacturer ID - 00 00 10
Device ID - 00
Family ID - 5E (RP)
Product ID - 02 (RP250)
Procedure - 41 (see MessageID in gdigi.h)
As MIDI messages must not contain bytes with MSB bit set, Digitech
devices use packing system.
First byte contains MSB bits from following 7 bytes (this scheme
continues as many times as needed) (see pack_data() and unpack_message() in
gdigi.c for details).
Assuming message has been unpacked, the meaning of next bytes:
ID - in this example 30 09
Position - in this example 00
Value - in this example 00 (can be more bytes long, see below)
Checksum - to calculate it, XOR all bytes, and then XOR it with 07
Checksum - to calculate it, XOR all bytes (of packed message)
Every message ends with F7
Status byte bits explained:
7th - ???
6th - if active add 80 to ID
5th - ???
4th - is active when value will start with length
In such case value can be something like:
01 12 or 02 12 34 or 03 12 34 56
and proper values are:
01 - 12
02 - 1234
03 - 123456
3rd - when 4th bit is also active, and first value byte is 01
then add 80 to value
2nd - when 4th bit is also active, and first value byte is 02
then add 80 to value
1st - when 4th bit is also active, and first value byte is 03
then add 80 to value
So for above example:
ID = 3009 (hex) = 12297 (decimal)
Position = 0
@@ -66,3 +80,13 @@ There seems to be two possible ways to figure that out.
save new patch
check patch file and note the change
while you don't have all possible values
3) Use gdigi
After starting gdigi turn the knobs on your device.
Check out console output, you should notice something like this:
** Message: Received parameter change ID: 210 Position: 4 Value: 0
ID is ID, Position is Position and Value is one of possible values.
To get all possible values keep turning knobs and watch the output.
If you change effect type usually there's more messages - where,
usually the first one is type change, and rest are default values.
This way you *CANNOT* gather all information (there're X-Edit only
controlled values, check device manual for more information).

View File

@@ -1,35 +1,49 @@
CC = gcc
CFLAGS = `pkg-config --cflags glib-2.0 gio-2.0 gtk+-2.0` -Wall -g -ansi -std=c99
OFLAG = -o
LIBS = `pkg-config --libs glib-2.0 gio-2.0 gtk+-2.0 alsa` -lexpat
EXTRA_CFLAGS ?=
EXTRA_LDFLAGS ?=
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
LDADD := $(shell pkg-config --libs glib-2.0 gio-2.0 gtk+-3.0 gthread-2.0 alsa libxml-2.0) -lexpat -lm
OBJECTS = gdigi.o gui.o effects.o preset.o gtkknob.o preset_xml.o
DEPFILES = $(foreach m,$(OBJECTS:.o=),.$(m).m)
.SUFFIXES : .o .c
.c.o :
.PHONY : clean distclean all
%.o : %.c
$(CC) $(CFLAGS) -c $<
.%.m : %.c
$(CC) $(CFLAGS) -M -MF $@ -MG $<
all: gdigi
gdigi: knob.h gdigi.o tests.o gui.o effects.o preset.o gtkknob.o
$(CC) $(LIBS) $(OFLAG) gdigi gdigi.o tests.o gui.o effects.o preset.o gtkknob.o
gdigi: $(OBJECTS)
$(CC) $(LDFLAGS) -o $@ $+ $(LDADD)
gdigi.o: gdigi.c
tests.o: tests.c
gui.o: gui.c
effects.o: effects.c
preset.o: preset.c
gtkknob.o: gtkknob.c
gtkknob.o: gtkknob.c
knob.h:
gdk-pixbuf-csource --name=knob_pixbuf knob.png > $@
images/gdigi_icon.h: images/icon.png
gdk-pixbuf-csource --raw --name=gdigi_icon $< > $@
clean:
rm *.o
rm -f *.o
distclean : clean
rm -f .*.m
rm -f images/gdigi_icon.h
rm -f gdigi
install: gdigi
install gdigi $(DESTDIR)/usr/bin
install -m 0644 gdigi.desktop $(DESTDIR)/usr/share/applications/
install -m 0644 images/gdigi.png $(DESTDIR)/usr/share/icons/
NODEP_TARGETS := clean distclean
depinc := 1
ifneq (,$(filter $(NODEP_TARGETS),$(MAKECMDGOALS)))
depinc := 0
endif
ifneq (,$(fitler-out $(NODEP_TARGETS),$(MAKECMDGOALS)))
depinc := 1
endif
ifeq ($(depinc),1)
-include $(DEPFILES)
endif

2
README
View File

@@ -1,4 +1,4 @@
Requirments: alsa, gtk+, glib, expat
Requirments: alsa, gtk+, glib, expat, libxml-2
Getting started guide:
-to compile: make

7
TODO
View File

@@ -1,6 +1,5 @@
-make complete gui
-effects level
-make complete gui (expression pedal settings, usb settings, effect level, preset level)
-handling presets (saving, exporting to xml patches)
-buildsystem (install knob.png to share dir, don't use inline knob pixbuf)
-add expression pedal settings to gui
-read asynchronously from MIDI IN
-various fixes to MIDI IN messages handling
-optimizations

4449
effects.c

File diff suppressed because it is too large Load Diff

View File

@@ -17,12 +17,34 @@
#ifndef GDIGI_EFFECTS_H
#define GDIGI_EFFECTS_H
#include <glib/gtypes.h>
#include <glib.h>
typedef struct {
typedef enum {
VALUE_TYPE_PLAIN = 0, /**< value displayed directly */
VALUE_TYPE_SUFFIX = 1 << 0, /**< use suffix for displaying */
VALUE_TYPE_OFFSET = 1 << 1, /**< use value offset */
VALUE_TYPE_STEP = 1 << 2, /**< use value step different than 1 */
VALUE_TYPE_LABEL = 1 << 3, /**< use value labels (overrides any other option) */
VALUE_TYPE_EXTRA = 1 << 4, /**< use extra values */
VALUE_TYPE_DECIMAL= 1 << 5, /**< display decimal places */
VALUE_TYPE_POSID = 1 << 6, /**< Packed Position/ID: (pos << 16) | id */
VALUE_TYPE_NONE = 1 << 7, /**< no value displayed */
} ValueType;
typedef struct _EffectValues {
gdouble min; /**< Minumum value */
gdouble max; /**< Maximum value */
gint type; /**< value type bitmask (ValueType) */
GStrv labels; /**< value labels */
gint offset; /**< value offset */
gdouble step; /**< value step */
gchar *suffix; /**< value suffix */
struct _EffectValues *extra;
/**< additional value range,
use it when there're different range types */
gint decimal; /**< amount of decimal places to display */
} EffectValues;
typedef struct {
@@ -35,8 +57,6 @@ typedef struct {
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 */
} EffectGroup;
@@ -44,6 +64,7 @@ typedef struct {
typedef struct {
gchar *label; /**< Group label */
guint id; /**< ID to set effect on/off, or if it isn't on/off group then -1 */
guint type; /**< ID to set effect type */
guint position; /**< position */
EffectGroup *group; /**< possible effect types */
gint group_amt; /**< possible effect types length */
@@ -56,11 +77,56 @@ typedef struct {
} EffectList;
typedef struct {
guint type; /**< ID to set effect type */
guint position;
EffectGroup *group;
gint group_amt;
} ModifierGroup;
ModifierGroup *modifier_linkable_list();
void modifier_group_free(ModifierGroup *modifier_group);
typedef struct {
gchar *name;
EffectList *effects;
gint n_effects;
gint n_rows;
} EffectPage;
typedef struct {
gchar *name;
PresetBank bank;
} Banks;
enum product_id {
RP150 = 1,
RP250 = 2,
GNX4 = 3,
GNX3000 = 4,
RP500 = 5,
RP1000 = 6,
RP155 = 7,
RP255 = 8,
RP355 = 9,
};
typedef struct {
gchar *name;
unsigned char family_id;
unsigned char product_id;
EffectPage *pages;
gint n_pages;
Banks *banks;
gint n_banks;
} Device;
gchar *get_position(guint position);
void update_modifier_linkable_list(GString* msg);
extern ModifierGroup *ModifierLinkableList;
EffectGroup *get_modifier_group(void);
guint get_modifier_amt(void);
void get_values_info(EffectValues *values,
gdouble *min, gdouble *max, gboolean *custom);
gboolean get_device_info(unsigned char device_id, unsigned char family_id,
unsigned char product_id,
Device **device);
#endif /* GDIGI_EFFECTS_H */

74
gdigi.1 Normal file
View File

@@ -0,0 +1,74 @@
.\" Hey, EMACS: -*- nroff -*-
.\" First parameter, NAME, should be all caps
.\" Second parameter, SECTION, should be 1-8, maybe w/ subsection
.\" other parameters are allowed: see man(7), man(1)
.TH GDIGI 1 "October 07, 2010"
.\" Please adjust this date whenever revising the manpage.
.\"
.\" Some roff macros, for reference:
.\" .nh disable hyphenation
.\" .hy enable hyphenation
.\" .ad l left justify
.\" .ad b justify to both left and right margins
.\" .nf disable filling
.\" .fi enable filling
.\" .br insert line break
.\" .sp <n> insert n+1 empty lines
.\" for manpage-specific macros, see man(7)
.SH NAME
gdigi \- utility to control DigiTech effect pedals
.SH SYNOPSIS
.B gdigi
.RI [OPTION...]
.SH DESCRIPTION
gdigi is a tool aimed to provide X-Edit functionality to Linux users
.PP
Supported devices:
.IP \(bu
RP250
.IP \(bu
RP255
.IP \(bu
RP355
.IP \(bu
RP500
.IP \(bu
RP1000
.IP \(bu
GNX3000
.IP \(bu
GNX4K
.PP
.SH OPTIONS
These programs follow the usual GNU command line syntax, with long
options starting with two dashes (`\-').
A summary of options is included below.
For a complete description, see the Info files.
.TP
.B \-?, \-\-help
Show summary of options.
.TP
.B \-\-help\-all
Show all help options.
.TP
.B \-\-help\-gtk
Show GTK+ options.
.TP
.B \-\-display=\fIDISPLAY\fR
X display to use.
.TP
.B \-d, \-\-device
MIDI device port to use.
.SH AUTHOR
gdigi was written by Tomasz Moń <desowin@gmail.com>.
.PP
Send comments, bug reports and patches to gdigi
mailinglist at Google Groups.
.PP
This manual page was written by Andrew O. Shadoura <bugzilla@tut.by>,
for the Debian project (but may be used by others).
.PP
Permission is granted to copy, distribute and/or modify this document under the
terms of the GNU General Public License as published by the Free Software
Foundation, under version 3 of the License.

1146
gdigi.c

File diff suppressed because it is too large Load Diff

9
gdigi.desktop Normal file
View File

@@ -0,0 +1,9 @@
[Desktop Entry]
Version=1.0
Type=Application
Name=gdigi
Exec=gdigi
Categories=GTK;Audio;AudioVideo;
Icon=gdigi
X-Desktop-File-Install-Version=0.20

990
gdigi.h

File diff suppressed because it is too large Load Diff

View File

@@ -14,22 +14,27 @@
* along with this program. If not, see <http://www.gnu.org/licenses>.
*/
#ifndef GDIGI_TESTS_H
#define GDIGI_TESTS_H
#ifndef GDIGI_XML_H
#define GDIGI_XML_H
#include "gdigi.h"
#include <glib.h>
#include "effects.h"
typedef struct {
guint type;
gchar *label;
} XmlLabel;
void test_wah();
void test_compressor();
void test_dist();
void test_presets();
void test_pickups();
void test_eq();
void test_noisegate();
void test_chorusfx();
void test_delay();
void test_reverb();
void test_usb();
void test_all();
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;
#endif /* GDIGI_TESTS_H */
XmlSettings *get_xml_settings(guint id, guint position);
gboolean value_is_extra(EffectValues *val, int value);
gchar * map_xml_value(XmlSettings *xml, EffectValues *values, gint value);
#endif /* GDIGI_XML_H */

463
gtkknob.c
View File

@@ -4,7 +4,7 @@
* Tony Garnock-Jones, with modifications from Sean Bolton,
* copyright (C) 2004, William Weston copyright (C) 2007,
* Pete Shorthose copyright (C) 2007, and Tomasz Moń,
* copyright (C) 2009
* copyright (C) 2009-2011
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
@@ -18,16 +18,16 @@
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
* MA 02110-1301 USA.
*****************************************************************************/
#include <math.h>
#include <stdio.h>
#include <gtk/gtkmain.h>
#include <gtk/gtksignal.h>
#include <gtk/gtk.h>
#include <gdk/gdkkeysyms.h>
#include <string.h>
#include "gtkknob.h"
#include "knob.h"
#ifndef M_PI
# define M_PI 3.14159265358979323846 /* pi */
@@ -46,11 +46,15 @@
static void gtk_knob_class_init(GtkKnobClass *klass);
static void gtk_knob_init(GtkKnob *knob);
static void gtk_knob_destroy(GtkObject *object);
static void gtk_knob_destroy(GtkWidget *object);
static void gtk_knob_realize(GtkWidget *widget);
static void gtk_knob_size_request(GtkWidget *widget, GtkRequisition *requisition);
static void gtk_knob_unrealize(GtkWidget *widget);
static void gtk_knob_map(GtkWidget *widget);
static void gtk_knob_unmap(GtkWidget *widget);
static void gtk_knob_get_preferred_width(GtkWidget *widget, gint *minimum_width, gint *natural_width);
static void gtk_knob_get_preferred_height(GtkWidget *widget, gint *minimum_height, gint *natural_height);
static void gtk_knob_size_allocate(GtkWidget *widget, GtkAllocation *allocation);
static gint gtk_knob_expose(GtkWidget *widget, GdkEventExpose *event);
static gboolean gtk_knob_draw(GtkWidget *widget, cairo_t *cr);
static gint gtk_knob_scroll(GtkWidget *widget, GdkEventScroll *event);
static gint gtk_knob_button_press(GtkWidget *widget, GdkEventButton *event);
static gint gtk_knob_button_release(GtkWidget *widget, GdkEventButton *event);
@@ -103,26 +107,28 @@ gtk_knob_get_type(void) {
*
*****************************************************************************/
static void
gtk_knob_class_init (GtkKnobClass *class) {
GtkObjectClass *object_class;
gtk_knob_class_init (GtkKnobClass *klass) {
GtkWidgetClass *widget_class;
object_class = (GtkObjectClass*) class;
widget_class = (GtkWidgetClass*) class;
widget_class = (GtkWidgetClass*) klass;
parent_class = g_type_class_ref (GTK_TYPE_WIDGET);
parent_class = g_type_class_peek_parent(klass);
object_class->destroy = gtk_knob_destroy;
widget_class->destroy = gtk_knob_destroy;
widget_class->realize = gtk_knob_realize;
widget_class->expose_event = gtk_knob_expose;
widget_class->size_request = gtk_knob_size_request;
widget_class->unrealize = gtk_knob_unrealize;
widget_class->draw = gtk_knob_draw;
widget_class->get_preferred_width = gtk_knob_get_preferred_width;
widget_class->get_preferred_height = gtk_knob_get_preferred_height;
widget_class->size_allocate = gtk_knob_size_allocate;
widget_class->scroll_event = gtk_knob_scroll;
widget_class->button_press_event = gtk_knob_button_press;
widget_class->button_release_event = gtk_knob_button_release;
widget_class->key_press_event = gtk_knob_key_press;
widget_class->motion_notify_event = gtk_knob_motion_notify;
widget_class->map = gtk_knob_map;
widget_class->unmap = gtk_knob_unmap;
}
@@ -133,19 +139,22 @@ gtk_knob_class_init (GtkKnobClass *class) {
*****************************************************************************/
static void
gtk_knob_init (GtkKnob *knob) {
knob->policy = GTK_UPDATE_CONTINUOUS;
knob->policy = GTK_KNOB_UPDATE_CONTINUOUS;
knob->state = STATE_IDLE;
knob->saved_x = 0;
knob->saved_y = 0;
knob->timer = 0;
knob->anim = NULL;
knob->mask = NULL;
knob->mask_gc = NULL;
knob->red_gc = NULL;
knob->old_value = 0.0;
knob->old_lower = 0.0;
knob->old_upper = 0.0;
knob->adjustment = NULL;
gtk_widget_set_can_focus(GTK_WIDGET(knob), TRUE);
gtk_widget_set_has_window(GTK_WIDGET(knob), FALSE);
gtk_widget_set_hexpand(GTK_WIDGET(knob), FALSE);
gtk_widget_set_vexpand(GTK_WIDGET(knob), FALSE);
gtk_widget_add_events(GTK_WIDGET(knob), GDK_SCROLL_MASK);
}
@@ -159,7 +168,6 @@ gtk_knob_new(GtkAdjustment *adjustment, GtkKnobAnim *anim) {
GtkKnob *knob;
g_return_val_if_fail (anim != NULL, NULL);
g_return_val_if_fail (GDK_IS_PIXBUF (anim->pixbuf), NULL);
knob = g_object_new (gtk_knob_get_type (), NULL);
@@ -182,7 +190,7 @@ gtk_knob_new(GtkAdjustment *adjustment, GtkKnobAnim *anim) {
*
*****************************************************************************/
static void
gtk_knob_destroy(GtkObject *object) {
gtk_knob_destroy(GtkWidget *object) {
GtkKnob *knob;
g_return_if_fail (object != NULL);
@@ -190,10 +198,7 @@ gtk_knob_destroy(GtkObject *object) {
knob = GTK_KNOB (object);
if (knob->adjustment) {
g_object_unref (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,22 +206,8 @@ gtk_knob_destroy(GtkObject *object) {
}
*/
if (knob->mask) {
g_object_unref (knob->mask);
knob->mask = NULL;
}
if (knob->mask_gc) {
g_object_unref (knob->mask_gc);
knob->mask_gc = NULL;
}
if (knob->red_gc) {
g_object_unref (knob->red_gc);
knob->red_gc = NULL;
}
if (GTK_OBJECT_CLASS (parent_class)->destroy) {
(*GTK_OBJECT_CLASS (parent_class)->destroy) (object);
if (GTK_WIDGET_CLASS(parent_class)->destroy) {
(*GTK_WIDGET_CLASS (parent_class)->destroy) (object);
}
}
@@ -242,7 +233,7 @@ gtk_knob_get_adjustment(GtkKnob *knob) {
*
*****************************************************************************/
void
gtk_knob_set_update_policy(GtkKnob *knob, GtkUpdateType policy) {
gtk_knob_set_update_policy(GtkKnob *knob, GtkKnobUpdateType policy) {
g_return_if_fail (knob != NULL);
g_return_if_fail (GTK_IS_KNOB (knob));
@@ -271,22 +262,23 @@ gtk_knob_set_adjustment(GtkKnob *knob, GtkAdjustment *adjustment) {
}
knob->adjustment = adjustment;
g_object_ref (GTK_OBJECT (knob->adjustment));
g_object_ref_sink (GTK_OBJECT (knob->adjustment));
if (adjustment) {
g_object_ref_sink (adjustment);
g_signal_connect (adjustment, "changed",
(GCallback) gtk_knob_adjustment_changed,
G_CALLBACK(gtk_knob_adjustment_changed),
knob);
g_signal_connect (adjustment, "value_changed",
(GCallback) gtk_knob_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 = gtk_adjustment_get_value(adjustment);
knob->old_lower = gtk_adjustment_get_lower(adjustment);
knob->old_upper = gtk_adjustment_get_upper(adjustment);
gtk_knob_update (knob);
}
}
/*****************************************************************************
@@ -297,66 +289,98 @@ gtk_knob_set_adjustment(GtkKnob *knob, GtkAdjustment *adjustment) {
static void
gtk_knob_realize(GtkWidget *widget) {
GtkKnob *knob;
GdkWindow *window;
GdkWindowAttr attributes;
GtkAllocation allocation;
gint attributes_mask;
GdkColor color = { 0, 0xffff, 0, 0 };
g_return_if_fail (widget != NULL);
g_return_if_fail (GTK_IS_KNOB (widget));
GTK_WIDGET_SET_FLAGS (widget, GTK_REALIZED);
GTK_WIDGET_SET_FLAGS (widget, GTK_CAN_FOCUS);
gtk_widget_get_allocation (widget, &allocation);
gtk_widget_set_realized(widget, TRUE);
knob = GTK_KNOB (widget);
attributes.x = widget->allocation.x;
attributes.y = widget->allocation.y;
attributes.width = widget->allocation.width;
attributes.height = widget->allocation.height;
attributes.wclass = GDK_INPUT_OUTPUT;
attributes.window_type = GDK_WINDOW_CHILD;
attributes.x = allocation.x;
attributes.y = allocation.y;
attributes.width = allocation.width;
attributes.height = allocation.height;
attributes.wclass = GDK_INPUT_ONLY;;
attributes.event_mask =
gtk_widget_get_events (widget) |
GDK_EXPOSURE_MASK | GDK_BUTTON_PRESS_MASK |
GDK_BUTTON_PRESS_MASK |
GDK_BUTTON_RELEASE_MASK | GDK_POINTER_MOTION_MASK |
GDK_POINTER_MOTION_HINT_MASK;
attributes.visual = gtk_widget_get_visual (widget);
attributes.colormap = gtk_widget_get_colormap (widget);
attributes_mask = GDK_WA_X | GDK_WA_Y | GDK_WA_VISUAL | GDK_WA_COLORMAP;
attributes_mask = GDK_WA_X | GDK_WA_Y;
widget->window = gdk_window_new (widget->parent->window,
&attributes, attributes_mask);
window = gtk_widget_get_parent_window(widget);
gtk_widget_set_window(widget, window);
g_object_ref(window);
widget->style = gtk_style_attach (widget->style, widget->window);
gdk_window_set_user_data (widget->window, widget);
gtk_style_set_background (widget->style, widget->window, GTK_STATE_NORMAL);
knob->mask_gc = gdk_gc_new (widget->window);
gdk_gc_copy (knob->mask_gc, widget->style->bg_gc[GTK_STATE_NORMAL]);
gdk_gc_set_clip_mask (knob->mask_gc, knob->mask);
knob->red_gc = gdk_gc_new (widget->window);
gdk_gc_copy (knob->red_gc, widget->style->bg_gc[GTK_STATE_NORMAL]);
gdk_colormap_alloc_color (attributes.colormap, &color, FALSE, TRUE);
gdk_gc_set_foreground (knob->red_gc, &color);
knob->event_window = gdk_window_new(window, &attributes, attributes_mask);
gdk_window_set_user_data(knob->event_window, knob);
}
/*****************************************************************************
*
* gtk_knob_size_request()
*
*****************************************************************************/
static void
gtk_knob_size_request (GtkWidget *widget, GtkRequisition *requisition) {
gtk_knob_unrealize(GtkWidget *widget)
{
GtkKnob *knob = GTK_KNOB(widget);
if (knob->event_window)
{
gdk_window_set_user_data(knob->event_window, NULL);
gdk_window_destroy(knob->event_window);
knob->event_window = NULL;
}
GTK_WIDGET_CLASS(parent_class)->unrealize(widget);
}
static void
gtk_knob_map(GtkWidget *widget)
{
GtkKnob *knob = GTK_KNOB(widget);
GTK_WIDGET_CLASS(parent_class)->map(widget);
if (knob->event_window)
gdk_window_show(knob->event_window);
}
static void
gtk_knob_unmap(GtkWidget *widget)
{
GtkKnob *knob = GTK_KNOB(widget);
if (knob->event_window)
gdk_window_hide(knob->event_window);
GTK_WIDGET_CLASS(parent_class)->unmap(widget);
}
static void
gtk_knob_get_preferred_width(GtkWidget *widget,
gint *minimum_width,
gint *natural_width)
{
g_return_if_fail (widget != NULL);
g_return_if_fail (GTK_IS_KNOB (widget));
requisition->width = GTK_KNOB (widget)->width;
requisition->height = GTK_KNOB (widget)->height;
*minimum_width = *natural_width = GTK_KNOB(widget)->width;
}
static void
gtk_knob_get_preferred_height(GtkWidget *widget,
gint *minimum_height,
gint *natural_height)
{
g_return_if_fail (widget != NULL);
g_return_if_fail (GTK_IS_KNOB (widget));
*minimum_height = *natural_height = GTK_KNOB(widget)->height;
}
@@ -373,11 +397,11 @@ gtk_knob_size_allocate (GtkWidget *widget, GtkAllocation *allocation) {
g_return_if_fail (GTK_IS_KNOB (widget));
g_return_if_fail (allocation != NULL);
widget->allocation = *allocation;
gtk_widget_set_allocation(widget, allocation);
knob = GTK_KNOB (widget);
if (GTK_WIDGET_REALIZED (widget)) {
gdk_window_move_resize (widget->window,
if (gtk_widget_get_realized (widget)) {
gdk_window_move_resize (knob->event_window,
allocation->x, allocation->y,
allocation->width, allocation->height);
}
@@ -386,38 +410,50 @@ gtk_knob_size_allocate (GtkWidget *widget, GtkAllocation *allocation) {
/*****************************************************************************
*
* gtk_knob_expose()
* gtk_knob_draw()
*
*****************************************************************************/
static gint
gtk_knob_expose(GtkWidget *widget, GdkEventExpose *event) {
static gboolean
gtk_knob_draw(GtkWidget *widget, cairo_t *cr) {
GtkKnob *knob;
gfloat dx, dy;
gdouble dx, dy;
gint frames;
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);
if (event->count > 0)
return FALSE;
g_return_val_if_fail (cr != NULL, FALSE);
g_return_val_if_fail (GTK_IS_ADJUSTMENT (GTK_KNOB (widget)->adjustment), FALSE);
knob = GTK_KNOB (widget);
frames = ((knob->anim->width / knob->anim->frame_width) - 1);
dx = knob->adjustment->value - knob->adjustment->lower; /* value, from 0 */
dy = knob->adjustment->upper - knob->adjustment->lower; /* range */
dx = gtk_adjustment_get_value(knob->adjustment) - gtk_adjustment_get_lower(knob->adjustment); /* value, from 0 */
dy = gtk_adjustment_get_upper(knob->adjustment) - gtk_adjustment_get_lower(knob->adjustment); /* range */
dx = (int)(frames * dx / dy) * knob->width; /* check this for height != width */
gdk_draw_pixbuf (widget->window, knob->mask_gc, knob->anim->pixbuf,
dx, 0, 0, 0, knob->width, knob->height,
GDK_RGB_DITHER_NONE, 0, 0);
cairo_surface_t *surface =
cairo_surface_create_for_rectangle(knob->anim->image,
dx, 0.0,
(double)knob->width,
(double)knob->height);
cairo_set_source_surface(cr, surface, 0, 0);
cairo_paint(cr);
cairo_surface_destroy(surface);
if (GTK_WIDGET_HAS_FOCUS(widget)) {
gtk_paint_focus (widget->style, widget->window, widget->state,
NULL, widget, NULL, 0, 0,
widget->allocation.width, widget->allocation.height);
if (gtk_widget_has_focus(widget)) {
GtkStyleContext *context;
context = gtk_widget_get_style_context(widget);
gtk_style_context_save(context);
gtk_style_context_set_state(context, gtk_widget_get_state_flags (widget));
cairo_save(cr);
gtk_render_focus(context, cr,
0, 0,
gtk_widget_get_allocated_width(widget),
gtk_widget_get_allocated_height(widget));
cairo_restore(cr);
gtk_style_context_restore(context);
}
return FALSE;
@@ -436,16 +472,21 @@ 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_adjustment_set_value(knob->adjustment,
gtk_adjustment_get_value(knob->adjustment) +
gtk_adjustment_get_step_increment(knob->adjustment));
g_signal_emit_by_name (knob->adjustment, "value_changed");
break;
case GDK_SCROLL_DOWN:
knob->adjustment->value -= knob->adjustment->step_increment;
gtk_adjustment_set_value(knob->adjustment,
gtk_adjustment_get_value(knob->adjustment) -
gtk_adjustment_get_step_increment(knob->adjustment));
g_signal_emit_by_name (knob->adjustment, "value_changed");
break;
default:
@@ -468,6 +509,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);
@@ -476,16 +518,17 @@ gtk_knob_button_press(GtkWidget *widget, GdkEventButton *event) {
switch (event->button) {
case 1:
case 3:
if (!GTK_WIDGET_HAS_FOCUS(widget))
if (!gtk_widget_has_focus(widget))
gtk_widget_grab_focus(widget);
knob->state = STATE_PRESSED;
knob->saved_x = event->x;
knob->saved_y = event->y;
break;
case 2:
knob->adjustment->value = floor ((knob->adjustment->lower +
knob->adjustment->upper + 1.0)
* 0.5);
gtk_adjustment_set_value(knob->adjustment,
floor ((gtk_adjustment_get_lower(knob->adjustment) +
gtk_adjustment_get_upper(knob->adjustment) + 1.0)
* 0.5));
g_signal_emit_by_name (knob->adjustment, "value_changed");
break;
}
@@ -508,6 +551,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);
@@ -523,8 +567,8 @@ gtk_knob_button_release(GtkWidget *widget, GdkEventButton *event) {
switch (event->button) {
case 1:
case 3:
if (knob->policy != GTK_UPDATE_CONTINUOUS
&& knob->old_value != knob->adjustment->value)
if (knob->policy != GTK_KNOB_UPDATE_CONTINUOUS
&& knob->old_value != gtk_adjustment_get_value(knob->adjustment))
{
g_signal_emit_by_name (knob->adjustment, "value_changed");
}
@@ -544,25 +588,26 @@ 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);
switch (event->keyval) {
case GDK_Up:
if (GTK_WIDGET_HAS_FOCUS (widget))
case GDK_KEY_Up:
if (gtk_widget_has_focus (widget))
{
gtk_adjustment_set_value (knob->adjustment,
knob->old_value + knob->adjustment->step_increment);
knob->old_value + gtk_adjustment_get_step_increment(knob->adjustment));
return TRUE;
}
return FALSE;
case GDK_Down:
if (GTK_WIDGET_HAS_FOCUS (widget))
case GDK_KEY_Down:
if (gtk_widget_has_focus (widget))
{
gtk_adjustment_set_value (knob->adjustment,
knob->old_value - knob->adjustment->step_increment);
knob->old_value - gtk_adjustment_get_step_increment(knob->adjustment));
return TRUE;
}
return FALSE;
@@ -581,7 +626,7 @@ static gint gtk_knob_key_press(GtkWidget *widget, GdkEventKey *event)
static gint
gtk_knob_motion_notify(GtkWidget *widget, GdkEventMotion *event) {
GtkKnob *knob;
GdkModifierType mods;
GdkWindow *window;
gint x, y;
g_return_val_if_fail (widget != NULL, FALSE);
@@ -593,10 +638,6 @@ gtk_knob_motion_notify(GtkWidget *widget, GdkEventMotion *event) {
x = event->x;
y = event->y;
if (event->is_hint || (event->window != widget->window)) {
gdk_window_get_pointer (widget->window, &x, &y, &mods);
}
switch (knob->state) {
case STATE_PRESSED:
@@ -604,6 +645,13 @@ gtk_knob_motion_notify(GtkWidget *widget, GdkEventMotion *event) {
/* fall through */
case STATE_DRAGGING:
window = gtk_widget_get_window(widget);
if (event->is_hint || (event->window != window)) {
GdkModifierType mods;
GdkDeviceManager *device_manager = gdk_display_get_device_manager(gdk_window_get_display(window));
GdkDevice *pointer = gdk_device_manager_get_client_pointer(device_manager);
gdk_window_get_device_position(window, pointer, &x, &y, &mods);
if (mods & GDK_BUTTON1_MASK) {
gtk_knob_update_mouse (knob, x, y, TRUE);
return TRUE;
@@ -612,6 +660,7 @@ gtk_knob_motion_notify(GtkWidget *widget, GdkEventMotion *event) {
gtk_knob_update_mouse (knob, x, y, FALSE);
return TRUE;
}
}
break;
}
@@ -629,8 +678,9 @@ 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) {
if (knob->policy == GTK_KNOB_UPDATE_DELAYED) {
g_signal_emit_by_name (knob->adjustment, "value_changed");
}
@@ -646,14 +696,15 @@ 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) {
if (knob->policy == GTK_KNOB_UPDATE_CONTINUOUS) {
g_signal_emit_by_name (knob->adjustment, "value_changed");
}
else {
gtk_widget_queue_draw (GTK_WIDGET (knob));
if (knob->policy == GTK_UPDATE_DELAYED) {
if (knob->policy == GTK_KNOB_UPDATE_DELAYED) {
if (knob->timer) {
g_source_remove (knob->timer);
}
@@ -672,13 +723,14 @@ gtk_knob_update_mouse_update(GtkKnob *knob) {
*****************************************************************************/
static void
gtk_knob_update_mouse(GtkKnob *knob, gint x, gint y, gboolean step) {
gfloat old_value, new_value, dv, dh;
gfloat angle;
gdouble old_value, new_value, dv, dh;
gdouble angle;
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;
old_value = gtk_adjustment_get_value(knob->adjustment);
angle = atan2f (-y + (knob->height >> 1), x - (knob->width >> 1));
@@ -695,17 +747,17 @@ gtk_knob_update_mouse(GtkKnob *knob, gint x, gint y, gboolean step) {
dh *= angle * angle;
}
new_value = knob->adjustment->value +
dv * (step ? knob->adjustment->step_increment : knob->adjustment->page_increment) +
dh * (knob->adjustment->upper -
knob->adjustment->lower) * 0.005; /* 0.005 == (1 / 200) */
new_value = gtk_adjustment_get_value(knob->adjustment) +
dv * (step ? gtk_adjustment_get_step_increment(knob->adjustment) : gtk_adjustment_get_page_increment(knob->adjustment)) +
dh * (gtk_adjustment_get_upper(knob->adjustment) -
gtk_adjustment_get_lower(knob->adjustment)) * 0.005; /* 0.005 == (1 / 200) */
new_value = MAX (MIN (new_value, knob->adjustment->upper),
knob->adjustment->lower);
new_value = MAX (MIN (new_value, gtk_adjustment_get_upper(knob->adjustment)),
gtk_adjustment_get_lower(knob->adjustment));
knob->adjustment->value = new_value;
gtk_adjustment_set_value(knob->adjustment, new_value);
if (knob->adjustment->value != old_value) {
if (gtk_adjustment_get_value(knob->adjustment) != old_value) {
gtk_knob_update_mouse_update (knob);
}
}
@@ -718,28 +770,29 @@ gtk_knob_update_mouse(GtkKnob *knob, gint x, gint y, gboolean step) {
*****************************************************************************/
static void
gtk_knob_update(GtkKnob *knob) {
gfloat new_value;
gdouble new_value;
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);
if (gtk_adjustment_get_step_increment(knob->adjustment) == 1) {
new_value = floor (gtk_adjustment_get_value(knob->adjustment) + 0.5);
}
else {
new_value = knob->adjustment->value;
new_value = gtk_adjustment_get_value(knob->adjustment);
}
if (new_value < knob->adjustment->lower) {
new_value = knob->adjustment->lower;
if (new_value < gtk_adjustment_get_lower(knob->adjustment)) {
new_value = gtk_adjustment_get_lower(knob->adjustment);
}
if (new_value > knob->adjustment->upper) {
new_value = knob->adjustment->upper;
if (new_value > gtk_adjustment_get_upper(knob->adjustment)) {
new_value = gtk_adjustment_get_upper(knob->adjustment);
}
if (new_value != knob->adjustment->value) {
knob->adjustment->value = new_value;
if (new_value != gtk_adjustment_get_value(knob->adjustment)) {
gtk_adjustment_set_value(knob->adjustment, new_value);
g_signal_emit_by_name (knob->adjustment, "value_changed");
}
@@ -761,15 +814,15 @@ gtk_knob_adjustment_changed(GtkAdjustment *adjustment, gpointer data) {
knob = GTK_KNOB (data);
if ((knob->old_value != adjustment->value) ||
(knob->old_lower != adjustment->lower) ||
(knob->old_upper != adjustment->upper))
if ((knob->old_value != gtk_adjustment_get_value(adjustment)) ||
(knob->old_lower != gtk_adjustment_get_lower(adjustment)) ||
(knob->old_upper != gtk_adjustment_get_upper(adjustment)))
{
gtk_knob_update (knob);
knob->old_value = adjustment->value;
knob->old_lower = adjustment->lower;
knob->old_upper = adjustment->upper;
knob->old_value = gtk_adjustment_get_value(adjustment);
knob->old_lower = gtk_adjustment_get_lower(adjustment);
knob->old_upper = gtk_adjustment_get_upper(adjustment);
}
}
@@ -788,9 +841,9 @@ gtk_knob_adjustment_value_changed (GtkAdjustment *adjustment, gpointer data) {
knob = GTK_KNOB (data);
if (knob->old_value != adjustment->value) {
if (knob->old_value != gtk_adjustment_get_value(adjustment)) {
gtk_knob_update (knob);
knob->old_value = adjustment->value;
knob->old_value = gtk_adjustment_get_value(adjustment);
}
}
@@ -805,29 +858,31 @@ gtk_knob_set_animation (GtkKnob *knob, GtkKnobAnim *anim) {
g_return_if_fail (knob != NULL);
g_return_if_fail (anim != NULL);
g_return_if_fail (GTK_IS_KNOB (knob));
g_return_if_fail (GDK_IS_PIXBUF (anim->pixbuf));
knob->anim = (GtkKnobAnim *)anim;
knob->width = anim->frame_width;
knob->height = anim->height;
if (GTK_WIDGET_REALIZED (knob)) {
if (gtk_widget_get_realized (GTK_WIDGET(knob))) {
gtk_widget_queue_resize (GTK_WIDGET (knob));
}
}
/**
* Reads embedded knob image
**/
static cairo_status_t
get_knob_image(void *closure, unsigned char *data, unsigned int length)
{
int *offset = (int *)closure;
/*****************************************************************************
*
* gtk_knob_animation_new_from_file()
*
*****************************************************************************/
GtkKnobAnim *
gtk_knob_animation_new_from_file(gchar *filename) {
GtkKnobAnim *anim;
if ((*offset + length) > sizeof (knob_png))
return CAIRO_STATUS_READ_ERROR;
anim = gtk_knob_animation_new_from_file_full (filename, -1, -1, KNOB_SIZE);
return anim;
memcpy (data, knob_png + *offset, length);
*offset = *offset + length;
return CAIRO_STATUS_SUCCESS;
}
/*****************************************************************************
@@ -836,68 +891,20 @@ gtk_knob_animation_new_from_file(gchar *filename) {
*
*****************************************************************************/
GtkKnobAnim *
gtk_knob_animation_new_from_inline(const guint8 *pixbuf) {
gtk_knob_animation_new_from_inline() {
GtkKnobAnim *anim = g_new0 (GtkKnobAnim, 1);
int offset = 0;
g_return_val_if_fail((pixbuf != NULL), NULL);
anim->image =
cairo_image_surface_create_from_png_stream(get_knob_image, &offset);
anim->pixbuf = gdk_pixbuf_new_from_inline(-1, pixbuf, FALSE, NULL);
if (anim->pixbuf == NULL) {
g_free(anim);
return NULL;
}
anim->height = gdk_pixbuf_get_height (anim->pixbuf);
anim->width = gdk_pixbuf_get_width (anim->pixbuf);
anim->width = cairo_image_surface_get_width(anim->image);
anim->height = cairo_image_surface_get_height(anim->image);
anim->frame_width = anim->height;
return anim;
}
/*****************************************************************************
*
* gtk_knob_new_from_file_full()
*
* frame_width: overrides the frame width (to make rectangular frames)
* but doesn't affect the image size width and height cause optional
* scaling if not set to -1 when they are derived from the native
* image size.
*
* FIXME: account for any problems where (width % frame_width != 0)
*
*****************************************************************************/
GtkKnobAnim *
gtk_knob_animation_new_from_file_full(gchar *filename, gint frame_width,
gint width, gint height) {
GtkKnobAnim *anim = g_new0 (GtkKnobAnim, 1);
g_return_val_if_fail ((filename != NULL), NULL);
GError *gerror = NULL;
#if GTK_MINOR_VERSION < 10
if (!(anim->pixbuf = gdk_pixbuf_new_from_file (filename, &gerror))) {
g_error_free(gerror);
gerror = NULL;
return NULL;
}
#else /* GTK_MINOR_VERSION >= 10 */
if (!(anim->pixbuf = gdk_pixbuf_new_from_file_at_size (filename, width,
height, &gerror))) {
g_error_free(gerror);
gerror = NULL;
return NULL;
}
#endif /* GTK_MINOR_VERSION < 10 */
else {
anim->height = gdk_pixbuf_get_height (anim->pixbuf);
anim->width = gdk_pixbuf_get_width (anim->pixbuf);
anim->frame_width = (frame_width != -1) ? frame_width : anim->height;
}
return anim;
}
/*****************************************************************************
*
* gtk_knob_animation_free()
@@ -907,8 +914,8 @@ void
gtk_knob_animation_free(GtkKnobAnim *anim) {
g_return_if_fail (anim != NULL);
if (anim->pixbuf)
g_object_unref (anim->pixbuf);
if (anim->image)
cairo_surface_destroy(anim->image);
g_free (anim);
}

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-2011
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
@@ -17,14 +17,13 @@
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
* MA 02110-1301 USA.
*****************************************************************************/
#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" {
@@ -38,9 +37,16 @@ typedef struct _GtkKnob GtkKnob;
typedef struct _GtkKnobClass GtkKnobClass;
typedef struct _GtkKnobAnim GtkKnobAnim;
typedef enum
{
GTK_KNOB_UPDATE_CONTINUOUS,
GTK_KNOB_UPDATE_DISCONTINUOUS,
GTK_KNOB_UPDATE_DELAYED
} GtkKnobUpdateType;
/* better to make this an object and let widgets ref/deref it perhaps */
struct _GtkKnobAnim {
GdkPixbuf *pixbuf;
cairo_surface_t *image;
gint width; /* derived from image width */
gint height; /* derived from image height. */
gint frame_width; /* derived from pixbuf (width / height) or provided override for rectangular frames */
@@ -49,6 +55,7 @@ typedef struct _GtkKnobAnim GtkKnobAnim;
struct _GtkKnob {
GtkWidget widget;
GdkWindow *event_window;
/* update policy (GTK_UPDATE_[CONTINUOUS/DELAYED/DISCONTINUOUS]) */
guint policy : 2;
@@ -63,14 +70,10 @@ typedef struct _GtkKnobAnim GtkKnobAnim;
GtkKnobAnim *anim;
gint width, height;
GdkBitmap *mask;
GdkGC *mask_gc;
GdkGC *red_gc;
/* Old values from adjustment stored so we know when something changes */
gfloat old_value;
gfloat old_lower;
gfloat old_upper;
gdouble old_value;
gdouble old_lower;
gdouble old_upper;
/* The adjustment object that stores the data for this knob */
GtkAdjustment *adjustment;
@@ -84,16 +87,11 @@ typedef struct _GtkKnobAnim GtkKnobAnim;
extern GtkWidget *gtk_knob_new(GtkAdjustment *adjustment, GtkKnobAnim *anim);
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_update_policy(GtkKnob *knob, GtkKnobUpdateType policy);
extern void gtk_knob_set_adjustment(GtkKnob *knob, GtkAdjustment *adjustment);
GtkKnobAnim *gtk_knob_animation_new_from_inline(const guint8 *pixbuf);
GtkKnobAnim *gtk_knob_animation_new_from_file_full(gchar *filename,
gint frame_width,
gint width,
gint height);
GtkKnobAnim *gtk_knob_animation_new_from_inline();
GtkKnobAnim *gtk_knob_animation_new_from_file(gchar *filename);
void gtk_knob_set_animation (GtkKnob *knob, GtkKnobAnim *anim);
void gtk_knob_animation_free(GtkKnobAnim *anim);

1140
gui.c

File diff suppressed because it is too large Load Diff

14
gui.h
View File

@@ -17,8 +17,20 @@
#ifndef GDIGI_GUI_H
#define GDIGI_GUI_H
#include <gtk/gtk.h>
#include <glib.h>
#include "effects.h"
gchar * get_preset_filename(int prod_id);
void show_error_message(GtkWidget *parent, gchar *message);
void gui_create();
void apply_setting_param_to_gui(SettingParam *param);
gboolean apply_current_preset_to_gui(gpointer data);
void gui_create(Device *device);
void gui_free();
gboolean unsupported_device_dialog(Device **device);
gint select_device_dialog (GList *devices);
const gchar* get_message_name(MessageID msgid);
void create_modifier_group (guint pos, guint id);
void modifier_settings_exp_free(EffectSettings *settings);
#endif /* GDIGI_GUI_H */

BIN
images/gdigi.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 20 KiB

BIN
images/icon.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 78 KiB

5324
knob.h Normal file

File diff suppressed because it is too large Load Diff

224
preset.c
View File

@@ -18,6 +18,7 @@
#include <expat.h>
#include <string.h>
#include "preset.h"
#include "gdigi.h"
#ifndef DOXYGEN_SHOULD_SKIP_THIS
@@ -28,12 +29,24 @@ enum {
PARSER_TYPE_PARAM_POSITION,
PARSER_TYPE_PARAM_VALUE,
PARSER_TYPE_PARAM_NAME,
PARSER_TYPE_PARAM_TEXT
PARSER_TYPE_PARAM_TEXT,
PARSER_TYPE_GENETX_VERSION,
PARSER_TYPE_GENETX_TYPE,
PARSER_TYPE_GENETX_CHANNEL,
PARSER_TYPE_GENETX_NAME,
PARSER_TYPE_GENETX_DATA
};
enum {
SECTION_NOT_SET = -1,
SECTION_PARAMS,
SECTION_GENETX
};
typedef struct {
int depth;
int id;
int section;
Preset *preset;
} AppData;
@@ -45,18 +58,20 @@ static void XMLCALL start(void *data, const char *el, const char **attr) {
if (ad->depth == 1) {
ad->id = PARSER_TYPE_PRESET_NAME;
} else if (ad->depth == 3) {
if (ad->section == SECTION_PARAMS) {
ad->id = PARSER_TYPE_PARAM_NAME;
} else if (ad->section == SECTION_GENETX) {
ad->id = PARSER_TYPE_GENETX_NAME;
}
}
}
if (g_strcmp0(el, "Params") == 0) {
ad->section = SECTION_PARAMS;
if (ad->preset->params != NULL)
g_message("Params aleady exists!");
g_warning("Params aleady exists!");
} else if (g_strcmp0(el, "Param") == 0) {
SettingParam *param = g_slice_new(SettingParam);
param->id = -1;
param->position = -1;
param->value = -1;
SettingParam *param = setting_param_new();
ad->preset->params = g_list_prepend(ad->preset->params, param);
} else if (g_strcmp0(el, "ID") == 0) {
ad->id = PARSER_TYPE_PARAM_ID;
@@ -66,6 +81,21 @@ static void XMLCALL start(void *data, const char *el, const char **attr) {
ad->id = PARSER_TYPE_PARAM_VALUE;
} else if (g_strcmp0(el, "Text") == 0) {
ad->id = PARSER_TYPE_PARAM_TEXT;
} else if (g_strcmp0(el, "Genetx") == 0) {
ad->section = SECTION_GENETX;
if (ad->preset->genetxs != NULL)
g_warning("Genetx already exists!");
} else if (g_strcmp0(el, "GenetxModel") == 0) {
SettingGenetx *genetx = setting_genetx_new();
ad->preset->genetxs = g_list_prepend(ad->preset->genetxs, genetx);
} else if (g_strcmp0(el, "Version") == 0) {
ad->id = PARSER_TYPE_GENETX_VERSION;
} else if (g_strcmp0(el, "Type") == 0) {
ad->id = PARSER_TYPE_GENETX_TYPE;
} else if (g_strcmp0(el, "Channel") == 0) {
ad->id = PARSER_TYPE_GENETX_CHANNEL;
} else if (g_strcmp0(el, "Data") == 0) {
ad->id = PARSER_TYPE_GENETX_DATA;
}
ad->depth++;
@@ -90,6 +120,7 @@ static void XMLCALL text_cb(void *data, const char* text, int len)
ad->preset->name = g_strndup(text, len);
}
if (ad->section == SECTION_PARAMS) {
if (ad->preset->params == NULL)
return;
@@ -112,6 +143,64 @@ static void XMLCALL text_cb(void *data, const char* text, int len)
}
g_free(value);
} else if (ad->section == SECTION_GENETX) {
if (ad->preset->genetxs == NULL)
return;
SettingGenetx *genetx = (SettingGenetx *) ad->preset->genetxs->data;
if (genetx == NULL)
return;
gchar *value = g_strndup(text, len);
switch (ad->id) {
case PARSER_TYPE_GENETX_VERSION:
if (g_strcmp0(value, "Version1") == 0) {
genetx->version = GENETX_VERSION_1;
} else if (g_strcmp0(value, "Version2") == 0) {
genetx->version = GENETX_VERSION_2;
} else {
g_warning("Unknown GeNetX version: %s", value);
}
break;
case PARSER_TYPE_GENETX_TYPE:
if (g_strcmp0(value, "Amp") == 0) {
genetx->type = GENETX_TYPE_AMP;
} else if (g_strcmp0(value, "Cabinet") == 0) {
genetx->type = GENETX_TYPE_CABINET;
} else {
g_warning("Unknown GeNetX type: %s", value);
}
break;
case PARSER_TYPE_GENETX_CHANNEL:
if (g_strcmp0(value, "Channel1") == 0) {
genetx->channel = GENETX_CHANNEL1;
} else if (g_strcmp0(value, "Channel2") == 0) {
genetx->channel = GENETX_CHANNEL2;
} else {
g_warning("Unknown GeNetX channel: %s", value);
}
break;
case PARSER_TYPE_GENETX_NAME:
/* reassign pointer */
genetx->name = value;
value = NULL;
break;
case PARSER_TYPE_GENETX_DATA:
{
guchar *data = NULL;
gsize length = 0;
data = g_base64_decode(value, &length);
genetx->data = g_string_new_len((gchar *) data, length);
g_free(data);
break;
}
}
g_free(value);
}
}
#endif /* DOXYGEN_SHOULD_SKIP_THIS */
@@ -126,16 +215,13 @@ static void XMLCALL text_cb(void *data, const char* text, int len)
**/
Preset *create_preset_from_xml_file(gchar *filename, GError **error)
{
GFile *file;
GError *err = NULL;
gchar *contents;
file = g_file_new_for_path(filename);
if (g_file_get_contents(filename, &contents, NULL, &err) == FALSE) {
g_message("Failed to get %s contents: %s", filename, err->message);
g_warning("Failed to get %s contents: %s", filename, err->message);
*error = g_error_copy(err);
g_error_free(err);
g_object_unref(file);
return NULL;
}
@@ -144,6 +230,7 @@ Preset *create_preset_from_xml_file(gchar *filename, GError **error)
ad->preset = g_slice_new(Preset);
ad->preset->name = NULL;
ad->preset->params = NULL;
ad->preset->genetxs = NULL;
ad->id = PARSER_TYPE_NOT_SET;
XML_Parser p;
@@ -159,72 +246,106 @@ Preset *create_preset_from_xml_file(gchar *filename, GError **error)
preset_free(ad->preset);
g_slice_free(AppData, ad);
g_free(contents);
g_object_unref(file);
return NULL;
}
Preset *preset = ad->preset;
preset->params = g_list_reverse(preset->params);
preset->genetxs = g_list_reverse(preset->genetxs);
XML_ParserFree(p);
g_slice_free(AppData, ad);
g_free(contents);
g_object_unref(file);
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 data unpacked RECEIVE_PRESET_PARAMETERS message
* \param list list containing unpacked preset SysEx messages.
*
* Parses message
*
* \return Preset which must be freed using preset_free, or NULL on error.
**/
Preset *create_preset_from_data(GString *data)
Preset *create_preset_from_data(GList *list)
{
gint total;
gint n;
gint id;
gint position;
guint value;
gint x;
gint tmp;
GString *data;
GList *iter;
gint total, n, x;
gint bank, number, modified;
gchar *name;
g_return_val_if_fail(list != NULL, NULL);
Preset *preset = g_slice_new(Preset);
preset->name = NULL;
preset->params = NULL;
preset->genetxs = NULL;
iter = list;
for (iter = list; iter; iter = g_list_next(iter)) {
data = (GString*) iter->data;
switch (get_message_id(data)) {
case RECEIVE_PRESET_START:
bank = (unsigned char)data->str[8];
number = (unsigned char)data->str[9];
name = g_strdup(&data->str[10]);
modified = (unsigned char)data->str[11+strlen(name)];
if ((bank == PRESETS_EDIT_BUFFER) && (number == 0)) {
debug_msg(DEBUG_MSG2HOST,
"RECEIVE_PRESET_START: current edit buffer");
} else {
debug_msg(DEBUG_MSG2HOST,
"RECEIVE_PRESET_START: preset %d from bank %d",
number, bank);
}
debug_msg(DEBUG_MSG2HOST, "Name: %s, %sodified",
name, modified ? "M" : "Not m");
preset->name = name;
break;
case RECEIVE_PRESET_PARAMETERS:
x = 0x09;
n = 0;
total = (unsigned char)data->str[x];
x++;
Preset *preset = g_slice_new(Preset);
preset->name = NULL; /* TODO */
preset->params = NULL;
do {
id = ((unsigned char)data->str[x] << 8) | (unsigned char)data->str[x+1];
position = (unsigned char)data->str[x+2];
x+=3;
value = data->str[x];
x++;
if (value > 0x80) {
tmp = value & 0x7F;
value = 0;
gint i;
for (i=0; i<tmp; i++) {
value |= ((unsigned char)data->str[x+i] << (8*(tmp-i-1)));
}
x+=tmp;
}
SettingParam *param = setting_param_new_from_data(&data->str[x], &x);
n++;
SettingParam *param = g_slice_new(SettingParam);
param->id = id;
param->position = position;
param->value = value;
preset->params = g_list_prepend(preset->params, param);
g_message("%d ID %d Position %d Value %d", n, id, position, value);
if (debug_flag_is_set(DEBUG_MSG2HOST)) {
GString *ipv = format_ipv(param->id, param->position, param->value);
debug_msg(DEBUG_MSG2HOST, "%3d %s", n, ipv->str);
g_string_free(ipv, TRUE);
}
} while ((x < data->len) && n<total);
g_message("TOTAL %d", total);
preset->params = g_list_reverse(preset->params);
debug_msg(DEBUG_MSG2HOST, "TOTAL %d", total);
preset->params = g_list_sort(preset->params, params_cmp);
break;
case RECEIVE_PRESET_END:
break;
default:
g_warning("Unhandled message 0x%x in preset messages list",
get_message_id(data));
}
}
return preset;
}
@@ -241,12 +362,19 @@ void preset_free(Preset *preset)
if (preset->params != NULL) {
GList *iter;
for (iter = preset->params; iter; iter = iter->next) {
g_slice_free(SettingParam, iter->data);
setting_param_free((SettingParam*)iter->data);
}
g_list_free(preset->params);
}
if (preset->name != NULL)
if (preset->genetxs != NULL) {
GList *iter;
for (iter = preset->genetxs; iter; iter = iter->next) {
setting_genetx_free((SettingGenetx*)iter->data);
}
g_list_free(preset->genetxs);
}
g_free(preset->name);
g_slice_free(Preset, preset);

View File

@@ -19,19 +19,14 @@
#include <glib.h>
typedef struct {
int id;
int position;
int value;
} SettingParam;
typedef struct {
gchar *name;
GList *params;
GList *genetxs;
} Preset;
Preset *create_preset_from_xml_file(gchar *filename, GError **error);
Preset *create_preset_from_data(GString *data);
Preset *create_preset_from_data(GList *list);
void preset_free(Preset *preset);
void write_preset_to_xml(Preset *preset, gchar *filename);
#endif /* GDIGI_PRESET_H */

261
preset_xml.c Normal file
View File

@@ -0,0 +1,261 @@
/*
* 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, EffectValues *values, gint value)
{
switch (values->type) {
case VALUE_TYPE_LABEL:
if ((values == &values_on_off) && (value > 1)) {
g_warning("Skipping modifier->label %s\n", xml->label);
return NULL;
}
if (value > values->max || value < values->min) {
g_warning("%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, int value)
{
if ((value < val->min) || (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_warning("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->value)) {
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, values, param->value);
if (!textp) {
g_warning("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_warning("Unhandled value type %d", type);
break;
}
}
rc = xmlTextWriterEndElement(writer);
iter_params = iter_params->next;
}
rc = xmlTextWriterEndDocument(writer);
if (rc < 0) {
printf("testXmlwriterFilename: Error at xmlTextWriterEndDocument\n");
return;
}
xmlFreeTextWriter(writer);
}
#endif /* DOXYGEN_SHOULD_SKIP_THIS */

644
tests.c
View File

@@ -1,644 +0,0 @@
/*
* Copyright (c) 2009 Tomasz Moń <desowin@gmail.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; under version 3 of the License.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses>.
*/
#include "gdigi.h"
void test_wah()
{
int x;
set_option(WAH_TYPE, WAH_POSITION, WAH_TYPE_CRY);
for (x=0; x<=99; x++)
set_option(WAH_MIN, WAH_POSITION_MIN_MAX, x);
for (x=0; x<=99; x++)
set_option(WAH_MAX, WAH_POSITION_MIN_MAX, x);
for (x=0; x<=12; x++)
set_option(WAH_LEVEL, WAH_POSITION, x);
set_option(WAH_TYPE, WAH_POSITION, WAH_TYPE_FULLRANGE);
for (x=0; x<=99; x++)
set_option(WAH_MIN, WAH_POSITION_MIN_MAX, x);
for (x=0; x<=99; x++)
set_option(WAH_MAX, WAH_POSITION_MIN_MAX, x);
for (x=0; x<=12; x++)
set_option(WAH_LEVEL, WAH_POSITION, x);
set_option(WAH_TYPE, WAH_POSITION, WAH_TYPE_CLYDE);
for (x=0; x<=99; x++)
set_option(WAH_MIN, WAH_POSITION_MIN_MAX, x);
for (x=0; x<=99; x++)
set_option(WAH_MAX, WAH_POSITION_MIN_MAX, x);
for (x=0; x<=12; x++)
set_option(WAH_LEVEL, WAH_POSITION, x);
set_option(WAH_ON_OFF, WAH_POSITION, 1);
set_option(WAH_ON_OFF, WAH_POSITION, 0);
}
void test_compressor()
{
int x;
set_option(COMP_TYPE, COMP_POSITION, COMP_TYPE_DIGI);
for (x=0; x<=99; x++)
set_option(COMP_SUSTAIN, COMP_POSITION, x);
for (x=0; x<=99; x++)
set_option(COMP_TONE, COMP_POSITION, x);
for (x=0; x<=99; x++)
set_option(COMP_ATTACK, COMP_POSITION, x);
for (x=0; x<=99; x++)
set_option(COMP_LEVEL, COMP_POSITION, x);
set_option(COMP_TYPE, COMP_POSITION, COMP_TYPE_CS);
for (x=0; x<=99; x++)
set_option(COMP_SUSTAIN, COMP_POSITION, x);
for (x=0; x<=99; x++)
set_option(COMP_ATTACK, COMP_POSITION, x);
for (x=0; x<=99; x++)
set_option(COMP_LEVEL, COMP_POSITION, x);
set_option(COMP_ON_OFF, COMP_POSITION, 1);
set_option(COMP_ON_OFF, COMP_POSITION, 0);
}
void test_dist()
{
int x;
set_option(DIST_TYPE, DIST_POSITION, DIST_TYPE_SCREAMER);
for (x=0; x<=99; x++)
set_option(DIST_SCREAMER_DRIVE, DIST_POSITION, x);
for (x=0; x<=99; x++)
set_option(DIST_SCREAMER_TONE, DIST_POSITION, x);
for (x=0; x<=99; x++)
set_option(DIST_SCREAMER_LVL, DIST_POSITION, x);
set_option(DIST_TYPE, DIST_POSITION, DIST_TYPE_808);
for (x=0; x<=99; x++)
set_option(DIST_808_OVERDRIVE, DIST_POSITION, x);
for (x=0; x<=99; x++)
set_option(DIST_808_TONE, DIST_POSITION, x);
for (x=0; x<=99; x++)
set_option(DIST_808_LVL, DIST_POSITION, x);
set_option(DIST_TYPE, DIST_POSITION, DIST_TYPE_GUYOD);
for (x=0; x<=99; x++)
set_option(DIST_GUYOD_DRIVE, DIST_POSITION, x);
for (x=0; x<=99; x++)
set_option(DIST_GUYOD_LVL, DIST_POSITION, x);
set_option(DIST_TYPE, DIST_POSITION, DIST_TYPE_DOD250);
for (x=0; x<=99; x++)
set_option(DIST_DOD250_GAIN, DIST_POSITION, x);
for (x=0; x<=99; x++)
set_option(DIST_DOD250_LVL, DIST_POSITION, x);
set_option(DIST_TYPE, DIST_POSITION, DIST_TYPE_RODENT);
for (x=0; x<=99; x++)
set_option(DIST_RODENT_DIST, DIST_POSITION, x);
for (x=0; x<=99; x++)
set_option(DIST_RODENT_FILTER, DIST_POSITION, x);
for (x=0; x<=99; x++)
set_option(DIST_RODENT_LVL, DIST_POSITION, x);
set_option(DIST_TYPE, DIST_POSITION, DIST_TYPE_MX);
for (x=0; x<=99; x++)
set_option(DIST_MX_DIST, DIST_POSITION, x);
for (x=0; x<=99; x++)
set_option(DIST_MX_OUTPUT, DIST_POSITION, x);
set_option(DIST_TYPE, DIST_POSITION, DIST_TYPE_DS);
for (x=0; x<=99; x++)
set_option(DIST_DS_GAIN, DIST_POSITION, x);
for (x=0; x<=99; x++)
set_option(DIST_DS_TONE, DIST_POSITION, x);
for (x=0; x<=99; x++)
set_option(DIST_DS_LVL, DIST_POSITION, x);
set_option(DIST_TYPE, DIST_POSITION, DIST_TYPE_GRUNGE);
for (x=0; x<=99; x++)
set_option(DIST_GRUNGE_GRUNGE, DIST_POSITION, x);
for (x=0; x<=99; x++)
set_option(DIST_GRUNGE_FACE, DIST_POSITION, x);
for (x=0; x<=99; x++)
set_option(DIST_GRUNGE_LOUD, DIST_POSITION, x);
for (x=0; x<=99; x++)
set_option(DIST_GRUNGE_BUTT, DIST_POSITION, x);
set_option(DIST_TYPE, DIST_POSITION, DIST_TYPE_ZONE);
for (x=0; x<=99; x++)
set_option(DIST_ZONE_GAIN, DIST_POSITION, x);
for (x=0; x<=99; x++)
set_option(DIST_ZONE_LOW, DIST_POSITION, x);
for (x=0; x<=99; x++)
set_option(DIST_ZONE_MID_LVL, DIST_POSITION, x);
for (x=0; x<=99; x++)
set_option(DIST_ZONE_MID_FREQ, DIST_POSITION, x);
for (x=0; x<=99; x++)
set_option(DIST_ZONE_HIGH, DIST_POSITION, x);
for (x=0; x<=99; x++)
set_option(DIST_ZONE_LEVEL, DIST_POSITION, x);
set_option(DIST_TYPE, DIST_POSITION, DIST_TYPE_DEATH);
for (x=0; x<=99; x++)
set_option(DIST_DEATH_LOW, DIST_POSITION, x);
for (x=0; x<=99; x++)
set_option(DIST_DEATH_MID, DIST_POSITION, x);
for (x=0; x<=99; x++)
set_option(DIST_DEATH_HIGH, DIST_POSITION, x);
for (x=0; x<=99; x++)
set_option(DIST_DEATH_LVL, DIST_POSITION, x);
set_option(DIST_TYPE, DIST_POSITION, DIST_TYPE_GONK);
for (x=0; x<=99; x++)
set_option(DIST_GONK_GONK, DIST_POSITION, x);
for (x=0; x<=99; x++)
set_option(DIST_GONK_SMEAR, DIST_POSITION, x);
for (x=0; x<=99; x++)
set_option(DIST_GONK_SUCK, DIST_POSITION, x);
for (x=0; x<=99; x++)
set_option(DIST_GONK_HEAVE, DIST_POSITION, x);
set_option(DIST_TYPE, DIST_POSITION, DIST_TYPE_FUZZY);
for (x=0; x<=99; x++)
set_option(DIST_FUZZY_FUZZ, DIST_POSITION, x);
for (x=0; x<=99; x++)
set_option(DIST_FUZZY_VOLUME, DIST_POSITION, x);
set_option(DIST_TYPE, DIST_POSITION, DIST_TYPE_MP);
for (x=0; x<=99; x++)
set_option(DIST_MP_SUSTAIN, DIST_POSITION, x);
for (x=0; x<=99; x++)
set_option(DIST_MP_TONE, DIST_POSITION, x);
for (x=0; x<=99; x++)
set_option(DIST_MP_VOLUME, DIST_POSITION, x);
set_option(DIST_ON_OFF, DIST_POSITION, 1);
set_option(DIST_ON_OFF, DIST_POSITION, 0);
}
void test_presets()
{
int x;
for (x=0; x<=60; x++)
switch_preset(PRESETS_USER, x);
for (x=0; x<=60; x++)
switch_preset(PRESETS_SYSTEM, x);
}
void test_pickups()
{
set_option(PICKUP_TYPE, PICKUP_POSITION, PICKUP_TYPE_HB_SC);
set_option(PICKUP_TYPE, PICKUP_POSITION, PICKUP_TYPE_SC_HB);
set_option(PICKUP_ON_OFF, PICKUP_POSITION, 1);
set_option(PICKUP_ON_OFF, PICKUP_POSITION, 0);
}
void test_eq()
{
int x;
set_option(EQ_TYPE, EQ_POSITION, EQ_TYPE_BRIGHT);
set_option(EQ_TYPE, EQ_POSITION, EQ_TYPE_MIDBOOST);
set_option(EQ_TYPE, EQ_POSITION, EQ_TYPE_SCOOP);
set_option(EQ_TYPE, EQ_POSITION, EQ_TYPE_WARM);
for (x=0; x<=99; x++)
set_option(AMP_GAIN, AMP_POSITION, x);
for (x=0; x<=99; x++)
set_option(AMP_LEVEL, AMP_POSITION, x);
for (x=0; x<=0x18; x++)
set_option(EQ_BASS, EQ_POSITION, x);
for (x=0; x<=0x18; x++)
set_option(EQ_MID, EQ_POSITION, x);
for (x=0; x<=4700; x++)
set_option(EQ_MID_HZ, EQ_POSITION, x);
for (x=0; x<=0x18; x++)
set_option(EQ_TREBLE, EQ_POSITION, x);
for (x=0; x<=7500; x++)
set_option(EQ_TREBLE_HZ, EQ_POSITION, x);
set_option(EQ_ON_OFF, EQ_POSITION, 1);
set_option(EQ_ON_OFF, EQ_POSITION, 0);
}
void test_noisegate()
{
int x;
set_option(NOISEGATE_TYPE, NOISEGATE_POSITION, NOISEGATE_GATE);
for (x=0; x<=99; x++)
set_option(NOISEGATE_GATE_TRESHOLD, NOISEGATE_POSITION, x);
for (x=0; x<=99; x++)
set_option(NOISEGATE_ATTACK, NOISEGATE_POSITION, x);
for (x=0; x<=99; x++)
set_option(NOISEGATE_RELEASE, NOISEGATE_POSITION, x);
for (x=0; x<=99; x++)
set_option(NOISEGATE_ATTN, NOISEGATE_POSITION, x);
set_option(NOISEGATE_TYPE, NOISEGATE_POSITION, NOISEGATE_SWELL);
for (x=0; x<=99; x++)
set_option(NOISEGATE_SWELL_SENS, NOISEGATE_POSITION, x);
for (x=0; x<=99; x++)
set_option(NOISEGATE_ATTACK, NOISEGATE_POSITION, x);
for (x=0; x<=99; x++)
set_option(NOISEGATE_RELEASE, NOISEGATE_POSITION, x);
for (x=0; x<=99; x++)
set_option(NOISEGATE_ATTN, NOISEGATE_POSITION, x);
set_option(NOISEGATE_ON_OFF, NOISEGATE_POSITION, 1);
set_option(NOISEGATE_ON_OFF, NOISEGATE_POSITION, 0);
}
void test_chorusfx()
{
int x;
set_option(CHORUSFX_TYPE, CHORUSFX_POSITION, CHORUS_TYPE_CE);
for (x=0; x<=99; x++)
set_option(CE_CHORUS_SPEED, CHORUSFX_POSITION, x);
for (x=0; x<=99; x++)
set_option(CE_CHORUS_DEPTH, CHORUSFX_POSITION, x);
set_option(CHORUSFX_TYPE, CHORUSFX_POSITION, CHORUS_TYPE_DUAL);
for (x=0; x<=99; x++)
set_option(DUAL_CHORUS_SPEED, CHORUSFX_POSITION, x);
for (x=0; x<=99; x++)
set_option(DUAL_CHORUS_DEPTH, CHORUSFX_POSITION, x);
for (x=0; x<=99; x++)
set_option(DUAL_CHORUS_LEVEL, CHORUSFX_POSITION, x);
set_option(DUAL_CHORUS_WAVE, CHORUSFX_POSITION, WAVE_TRI);
set_option(DUAL_CHORUS_WAVE, CHORUSFX_POSITION, WAVE_SINE);
set_option(DUAL_CHORUS_WAVE, CHORUSFX_POSITION, WAVE_SQUARE);
set_option(CHORUSFX_TYPE, CHORUSFX_POSITION, CHORUS_TYPE_MULTI);
for (x=0; x<=99; x++)
set_option(MULTI_CHORUS_SPEED, CHORUSFX_POSITION, x);
for (x=0; x<=99; x++)
set_option(MULTI_CHORUS_DEPTH, CHORUSFX_POSITION, x);
for (x=0; x<=99; x++)
set_option(MULTI_CHORUS_LEVEL, CHORUSFX_POSITION, x);
set_option(MULTI_CHORUS_WAVE, CHORUSFX_POSITION, WAVE_TRI);
set_option(MULTI_CHORUS_WAVE, CHORUSFX_POSITION, WAVE_SINE);
set_option(MULTI_CHORUS_WAVE, CHORUSFX_POSITION, WAVE_SQUARE);
set_option(CHORUSFX_TYPE, CHORUSFX_POSITION, CHORUS_TYPE_FLANGER);
for (x=0; x<=99; x++)
set_option(FLANGER_SPEED, CHORUSFX_POSITION, x);
for (x=0; x<=99; x++)
set_option(FLANGER_DEPTH, CHORUSFX_POSITION, x);
for (x=0; x<=99; x++)
set_option(FLANGER_REGEN, CHORUSFX_POSITION, x);
for (x=0; x<=99; x++)
set_option(FLANGER_LEVEL, CHORUSFX_POSITION, x);
set_option(FLANGER_WAVE, CHORUSFX_POSITION, WAVE_TRI);
set_option(FLANGER_WAVE, CHORUSFX_POSITION, WAVE_SINE);
set_option(FLANGER_WAVE, CHORUSFX_POSITION, WAVE_SQUARE);
set_option(CHORUSFX_TYPE, CHORUSFX_POSITION, CHORUS_TYPE_MXR_FLANGER);
for (x=0; x<=99; x++)
set_option(MXR_FLANGER_SPEED, CHORUSFX_POSITION, x);
for (x=0; x<=99; x++)
set_option(MXR_FLANGER_WIDTH, CHORUSFX_POSITION, x);
for (x=0; x<=99; x++)
set_option(MXR_FLANGER_REGEN, CHORUSFX_POSITION, x);
for (x=0; x<=99; x++)
set_option(MXR_FLANGER_MANUAL, CHORUSFX_POSITION, x);
set_option(CHORUSFX_TYPE, CHORUSFX_POSITION, CHORUS_TYPE_PHASER);
for (x=0; x<=99; x++)
set_option(PHASER_SPEED, CHORUSFX_POSITION, x);
for (x=0; x<=99; x++)
set_option(PHASER_DEPTH, CHORUSFX_POSITION, x);
for (x=0; x<=99; x++)
set_option(PHASER_REGEN, CHORUSFX_POSITION, x);
for (x=0; x<=99; x++)
set_option(PHASER_LEVEL, CHORUSFX_POSITION, x);
set_option(PHASER_WAVE, CHORUSFX_POSITION, WAVE_TRI);
set_option(PHASER_WAVE, CHORUSFX_POSITION, WAVE_SINE);
set_option(PHASER_WAVE, CHORUSFX_POSITION, WAVE_SQUARE);
set_option(CHORUSFX_TYPE, CHORUSFX_POSITION, CHORUS_TYPE_VIBRATO);
for (x=0; x<=99; x++)
set_option(VIBRATO_SPEED, CHORUSFX_POSITION, x);
for (x=0; x<=99; x++)
set_option(VIBRATO_DEPTH, CHORUSFX_POSITION, x);
set_option(CHORUSFX_TYPE, CHORUSFX_POSITION, CHORUS_TYPE_ROTARY);
for (x=0; x<=99; x++)
set_option(ROTARY_SPEED, CHORUSFX_POSITION, x);
for (x=0; x<=99; x++)
set_option(ROTARY_INTENSITY, CHORUSFX_POSITION, x);
for (x=0; x<=99; x++)
set_option(ROTARY_DOPPLER, CHORUSFX_POSITION, x);
for (x=0; x<=99; x++)
set_option(ROTARY_CROSSOVER, CHORUSFX_POSITION, x);
set_option(CHORUSFX_TYPE, CHORUSFX_POSITION, CHORUS_TYPE_VIBROPAN);
for (x=0; x<=99; x++)
set_option(VIBROPAN_SPEED, CHORUSFX_POSITION, x);
for (x=0; x<=99; x++)
set_option(VIBROPAN_DEPTH, CHORUSFX_POSITION, x);
for (x=0; x<=99; x++)
set_option(VIBROPAN_VIBRA, CHORUSFX_POSITION, x);
set_option(VIBROPAN_WAVE, CHORUSFX_POSITION, WAVE_TRI);
set_option(VIBROPAN_WAVE, CHORUSFX_POSITION, WAVE_SINE);
set_option(VIBROPAN_WAVE, CHORUSFX_POSITION, WAVE_SQUARE);
set_option(CHORUSFX_TYPE, CHORUSFX_POSITION, CHORUS_TYPE_TREMOLO);
for (x=0; x<=99; x++)
set_option(TREMOLO_SPEED, CHORUSFX_POSITION, x);
for (x=0; x<=99; x++)
set_option(TREMOLO_DEPTH, CHORUSFX_POSITION, x);
set_option(TREMOLO_WAVE, CHORUSFX_POSITION, WAVE_TRI);
set_option(TREMOLO_WAVE, CHORUSFX_POSITION, WAVE_SINE);
set_option(TREMOLO_WAVE, CHORUSFX_POSITION, WAVE_SQUARE);
set_option(CHORUSFX_TYPE, CHORUSFX_POSITION, CHORUS_TYPE_PANNER);
for (x=0; x<=99; x++)
set_option(PANNER_SPEED, CHORUSFX_POSITION, x);
for (x=0; x<=99; x++)
set_option(PANNER_DEPTH, CHORUSFX_POSITION, x);
set_option(PANNER_WAVE, CHORUSFX_POSITION, WAVE_TRI);
set_option(PANNER_WAVE, CHORUSFX_POSITION, WAVE_SINE);
set_option(PANNER_WAVE, CHORUSFX_POSITION, WAVE_SQUARE);
set_option(CHORUSFX_TYPE, CHORUSFX_POSITION, CHORUS_TYPE_ENVELOPE);
for (x=0; x<=99; x++)
set_option(ENVELOPE_SENSITIVITY, CHORUSFX_POSITION, x);
for (x=0; x<=99; x++)
set_option(ENVELOPE_RANGE, CHORUSFX_POSITION, x);
set_option(CHORUSFX_TYPE, CHORUSFX_POSITION, CHORUS_TYPE_AUTOYA);
for (x=0; x<=99; x++)
set_option(AUTOYA_SPEED, CHORUSFX_POSITION, x);
for (x=0; x<=99; x++)
set_option(AUTOYA_INTENSITY, CHORUSFX_POSITION, x);
for (x=0; x<=0x31; x++)
set_option(AUTOYA_RANGE, CHORUSFX_POSITION, x);
set_option(CHORUSFX_TYPE, CHORUSFX_POSITION, CHORUS_TYPE_YAYA);
for (x=0; x<=99; x++)
set_option(YAYA_PEDAL, CHORUSFX_POSITION, x);
for (x=0; x<=99; x++)
set_option(YAYA_INTENSITY, CHORUSFX_POSITION, x);
for (x=0; x<=0x31; x++)
set_option(YAYA_RANGE, CHORUSFX_POSITION, x);
set_option(CHORUSFX_TYPE, CHORUSFX_POSITION, CHORUS_TYPE_STEP_FILTER);
for (x=0; x<=99; x++)
set_option(STEP_FILTER_SPEED, CHORUSFX_POSITION, x);
for (x=0; x<=99; x++)
set_option(STEP_FILTER_INTENSITY, CHORUSFX_POSITION, x);
set_option(CHORUSFX_TYPE, CHORUSFX_POSITION, CHORUS_TYPE_WHAMMY);
set_option(WHAMMY_AMOUNT, CHORUSFX_POSITION, WHAMMY_OCT_UP);
set_option(WHAMMY_AMOUNT, CHORUSFX_POSITION, WHAMMY_2OCT_UP);
set_option(WHAMMY_AMOUNT, CHORUSFX_POSITION, WHAMMY_2ND_DN);
set_option(WHAMMY_AMOUNT, CHORUSFX_POSITION, WHAMMY_RV_2ND);
set_option(WHAMMY_AMOUNT, CHORUSFX_POSITION, WHAMMY_4TH_DN);
set_option(WHAMMY_AMOUNT, CHORUSFX_POSITION, WHAMMY_OCT_DN);
set_option(WHAMMY_AMOUNT, CHORUSFX_POSITION, WHAMMY_2OCT_DN);
set_option(WHAMMY_AMOUNT, CHORUSFX_POSITION, WHAMMY_DIV_BMB);
set_option(WHAMMY_AMOUNT, CHORUSFX_POSITION, WHAMMY_M3_MA);
set_option(WHAMMY_AMOUNT, CHORUSFX_POSITION, WHAMMY_2ND_MA3);
set_option(WHAMMY_AMOUNT, CHORUSFX_POSITION, WHAMMY_3RD_4TH);
set_option(WHAMMY_AMOUNT, CHORUSFX_POSITION, WHAMMY_4TH_5TH);
set_option(WHAMMY_AMOUNT, CHORUSFX_POSITION, WHAMMY_5TH_OCT);
set_option(WHAMMY_AMOUNT, CHORUSFX_POSITION, WHAMMY_HOCT_UP);
set_option(WHAMMY_AMOUNT, CHORUSFX_POSITION, WHAMMY_HOCT_DN);
set_option(WHAMMY_AMOUNT, CHORUSFX_POSITION, WHAMMY_OCT_UD);
for (x=0; x<=99; x++)
set_option(WHAMMY_PEDAL, CHORUSFX_POSITION, x);
for (x=0; x<=99; x++)
set_option(WHAMMY_MIX, CHORUSFX_POSITION, x);
set_option(CHORUSFX_TYPE, CHORUSFX_POSITION, CHORUS_TYPE_PITCH_SHIFT);
for (x=0; x<=0x30; x++)
set_option(PITCH_AMOUNT, CHORUSFX_POSITION, x);
for (x=0; x<=99; x++)
set_option(PITCH_MIX, CHORUSFX_POSITION, x);
set_option(CHORUSFX_TYPE, CHORUSFX_POSITION, CHORUS_TYPE_DETUNE);
for (x=0; x<=0x30; x++)
set_option(DETUNE_AMOUNT, CHORUSFX_POSITION, x);
for (x=0; x<=99; x++)
set_option(DETUNE_LEVEL, CHORUSFX_POSITION, x);
set_option(CHORUSFX_TYPE, CHORUSFX_POSITION, CHORUS_TYPE_IPS);
set_option(IPS_SHIFT_AMOUNT, CHORUSFX_POSITION, IPS_OCT_D);
set_option(IPS_SHIFT_AMOUNT, CHORUSFX_POSITION, IPS_7TH_DN);
set_option(IPS_SHIFT_AMOUNT, CHORUSFX_POSITION, IPS_6TH_DN);
set_option(IPS_SHIFT_AMOUNT, CHORUSFX_POSITION, IPS_5TH_DN);
set_option(IPS_SHIFT_AMOUNT, CHORUSFX_POSITION, IPS_4TH_DN);
set_option(IPS_SHIFT_AMOUNT, CHORUSFX_POSITION, IPS_3RD_DN);
set_option(IPS_SHIFT_AMOUNT, CHORUSFX_POSITION, IPS_2ND_DN);
set_option(IPS_SHIFT_AMOUNT, CHORUSFX_POSITION, IPS_2ND_UP);
set_option(IPS_SHIFT_AMOUNT, CHORUSFX_POSITION, IPS_3RD_UP);
set_option(IPS_SHIFT_AMOUNT, CHORUSFX_POSITION, IPS_4TH_UP);
set_option(IPS_SHIFT_AMOUNT, CHORUSFX_POSITION, IPS_5TH_UP);
set_option(IPS_SHIFT_AMOUNT, CHORUSFX_POSITION, IPS_6TH_UP);
set_option(IPS_SHIFT_AMOUNT, CHORUSFX_POSITION, IPS_7TH_UP);
set_option(IPS_SHIFT_AMOUNT, CHORUSFX_POSITION, IPS_OCT_U);
set_option(IPS_KEY, CHORUSFX_POSITION, IPS_E);
set_option(IPS_KEY, CHORUSFX_POSITION, IPS_F);
set_option(IPS_KEY, CHORUSFX_POSITION, IPS_GB);
set_option(IPS_KEY, CHORUSFX_POSITION, IPS_G);
set_option(IPS_KEY, CHORUSFX_POSITION, IPS_AB);
set_option(IPS_KEY, CHORUSFX_POSITION, IPS_A);
set_option(IPS_KEY, CHORUSFX_POSITION, IPS_BB);
set_option(IPS_KEY, CHORUSFX_POSITION, IPS_B);
set_option(IPS_KEY, CHORUSFX_POSITION, IPS_C);
set_option(IPS_KEY, CHORUSFX_POSITION, IPS_DB);
set_option(IPS_KEY, CHORUSFX_POSITION, IPS_D);
set_option(IPS_KEY, CHORUSFX_POSITION, IPS_EB);
set_option(IPS_SCALE, CHORUSFX_POSITION, IPS_MAJOR);
set_option(IPS_SCALE, CHORUSFX_POSITION, IPS_MINOR);
set_option(IPS_SCALE, CHORUSFX_POSITION, IPS_DORIA);
set_option(IPS_SCALE, CHORUSFX_POSITION, IPS_MIXLYD);
set_option(IPS_SCALE, CHORUSFX_POSITION, IPS_LYDIAN);
set_option(IPS_SCALE, CHORUSFX_POSITION, IPS_HMINO);
for (x=0; x<=99; x++)
set_option(IPS_LEVEL, CHORUSFX_POSITION, x);
set_option(CHORUSFX_ON_OFF, CHORUSFX_POSITION, 1);
set_option(CHORUSFX_ON_OFF, CHORUSFX_POSITION, 0);
}
void test_delay()
{
int x;
set_option(DELAY_TYPE, DELAY_POSITION, DELAY_TYPE_ANALOG);
for (x=0; x<=139; x++)
set_option(DELAY_TIME, DELAY_POSITION, x);
for (x=0; x<=99; x++)
set_option(ANALOG_LEVEL, DELAY_POSITION, x);
for (x=0; x<=100; x++)
set_option(ANALOG_REPEATS, DELAY_POSITION, x);
set_option(DELAY_TYPE, DELAY_POSITION, DELAY_TYPE_DIGITAL);
for (x=0; x<=139; x++)
set_option(DELAY_TIME, DELAY_POSITION, x);
for (x=0; x<=99; x++)
set_option(DIGITAL_LEVEL, DELAY_POSITION, x);
for (x=0; x<=100; x++)
set_option(DIGITAL_REPEATS, DELAY_POSITION, x);
for (x=0; x<=99; x++)
set_option(DIGITAL_DUCKER_THRESH, DELAY_POSITION, x);
for (x=0; x<=99; x++)
set_option(DIGITAL_DUCKER_LEVEL, DELAY_POSITION, x);
set_option(DELAY_TYPE, DELAY_POSITION, DELAY_TYPE_MODULATED);
for (x=0; x<=139; x++)
set_option(DELAY_TIME, DELAY_POSITION, x);
for (x=0; x<=99; x++)
set_option(MODULATED_LEVEL, DELAY_POSITION, x);
for (x=0; x<=100; x++)
set_option(MODULATED_REPEATS, DELAY_POSITION, x);
for (x=0; x<=99; x++)
set_option(MODULATED_DEPTH, DELAY_POSITION, x);
set_option(DELAY_TYPE, DELAY_POSITION, DELAY_TYPE_PONG);
for (x=0; x<=139; x++)
set_option(DELAY_TIME, DELAY_POSITION, x);
for (x=0; x<=99; x++)
set_option(PONG_LEVEL, DELAY_POSITION, x);
for (x=0; x<=100; x++)
set_option(PONG_REPEATS, DELAY_POSITION, x);
for (x=0; x<=99; x++)
set_option(PONG_DUCKER_THRESH, DELAY_POSITION, x);
for (x=0; x<=99; x++)
set_option(PONG_DUCKER_LEVEL, DELAY_POSITION, x);
set_option(DELAY_TYPE, DELAY_POSITION, DELAY_TYPE_TAPE);
for (x=0; x<=139; x++)
set_option(DELAY_TIME, DELAY_POSITION, x);
for (x=0; x<=99; x++)
set_option(TAPE_LEVEL, DELAY_POSITION, x);
for (x=0; x<=100; x++)
set_option(TAPE_REPEATS, DELAY_POSITION, x);
for (x=0; x<=99; x++)
set_option(TAPE_WOW, DELAY_POSITION, x);
for (x=0; x<=99; x++)
set_option(TAPE_FLUTTER, DELAY_POSITION, x);
set_option(DELAY_ON_OFF, DELAY_POSITION, 1);
set_option(DELAY_ON_OFF, DELAY_POSITION, 0);
}
void test_reverb()
{
int x;
set_option(REVERB_TYPE, REVERB_POSITION, REVERB_TYPE_TWIN);
for (x=0; x<=99; x++)
set_option(TWIN_REVERB, REVERB_POSITION, x);
set_option(REVERB_TYPE, REVERB_POSITION, REVERB_TYPE_LEX_AMBIENCE);
for (x=0; x<=15; x++)
set_option(LEX_AMBIENCE_PREDELAY, REVERB_POSITION, x);
for (x=0; x<=99; x++)
set_option(LEX_AMBIENCE_DECAY, REVERB_POSITION, x);
for (x=0; x<=99; x++)
set_option(LEX_AMBIENCE_LIVELINESS, REVERB_POSITION, x);
for (x=0; x<=99; x++)
set_option(LEX_AMBIENCE_LEVEL, REVERB_POSITION, x);
set_option(REVERB_TYPE, REVERB_POSITION, REVERB_TYPE_LEX_STUDIO);
for (x=0; x<=15; x++)
set_option(LEX_STUDIO_PREDELAY, REVERB_POSITION, x);
for (x=0; x<=99; x++)
set_option(LEX_STUDIO_DECAY, REVERB_POSITION, x);
for (x=0; x<=99; x++)
set_option(LEX_STUDIO_LIVELINESS, REVERB_POSITION, x);
for (x=0; x<=99; x++)
set_option(LEX_STUDIO_LEVEL, REVERB_POSITION, x);
set_option(REVERB_TYPE, REVERB_POSITION, REVERB_TYPE_LEX_ROOM);
for (x=0; x<=15; x++)
set_option(LEX_ROOM_PREDELAY, REVERB_POSITION, x);
for (x=0; x<=99; x++)
set_option(LEX_ROOM_DECAY, REVERB_POSITION, x);
for (x=0; x<=99; x++)
set_option(LEX_ROOM_LIVELINESS, REVERB_POSITION, x);
for (x=0; x<=99; x++)
set_option(LEX_ROOM_LEVEL, REVERB_POSITION, x);
set_option(REVERB_TYPE, REVERB_POSITION, REVERB_TYPE_LEX_HALL);
for (x=0; x<=15; x++)
set_option(LEX_HALL_PREDELAY, REVERB_POSITION, x);
for (x=0; x<=99; x++)
set_option(LEX_HALL_DECAY, REVERB_POSITION, x);
for (x=0; x<=99; x++)
set_option(LEX_HALL_LIVELINESS, REVERB_POSITION, x);
for (x=0; x<=99; x++)
set_option(LEX_HALL_LEVEL, REVERB_POSITION, x);
set_option(REVERB_TYPE, REVERB_POSITION, REVERB_TYPE_EMT240_PLATE);
for (x=0; x<=15; x++)
set_option(EMT240_PLATE_PREDELAY, REVERB_POSITION, x);
for (x=0; x<=99; x++)
set_option(EMT240_PLATE_DECAY, REVERB_POSITION, x);
for (x=0; x<=99; x++)
set_option(EMT240_PLATE_LIVELINESS, REVERB_POSITION, x);
for (x=0; x<=99; x++)
set_option(EMT240_PLATE_LEVEL, REVERB_POSITION, x);
set_option(REVERB_ON_OFF, REVERB_POSITION, 1);
set_option(REVERB_ON_OFF, REVERB_POSITION, 0);
}
void test_usb()
{
int x;
for (x=0; x<=100; x++)
set_option(USB_AUDIO_PLAYBACK_MIX, USB_POSITION, x);
for (x=0; x<=36; x++)
set_option(USB_AUDIO_LEVEL, USB_POSITION, x);
}
void test_all()
{
test_wah();
test_compressor();
test_dist();
test_presets();
test_pickups();
test_eq();
test_noisegate();
test_chorusfx();
test_delay();
test_reverb();
test_usb();
}