This is not a GNU-style ChangeLog but you sort of get the idea what was
changed.
-[v3.74 - prerelase]
+[v3.80 - prerelease]
+- Reworked the mastergui for better usabilty and less space consumption, yes,
+ terminatorX now features a boring menubar - which helps using it on small
+ displays quite a bit, and should be easier to handle for first time users.
+- Implemented a suggestions from Darrick Servis <darrick@dcn.davis.ca.us> that
+ stops clipping in the mixer routine. The outgoing signal is now limited as it
+ should be, which improves the output quality for signals too loud
+ significantly.
+- MIDI mappings are now store with the (new) tX set files.
+- Applied a patch from Arthur Peters <amp@singingwizard.org> which brings
+ preliminary MIDI support to terminatorX. This is realized via the ALSA
+ sequencer interface, so in order for it to compile you have to have
+ the ALSA devel packages installed. ./configure will autodetect them.
- Fixed a bug in XML serialization that dropped strings' contents.
-- You can now hit "F11" to turn fullscreen mode on off - this will help using
+- You can now hit "F11" to turn fullscreen mode on/off - this will help using
terminatorX on small DJ laptops. Note that the key will have no effect in
scratch - hit it before you get that engine running.
- terminatorX now stores set files as XML documents, too - so terminatorX has
longer builds with gtk+ 1.2 - you have to upgrade to gtk+ Version 2 to be
able to build terminatorX.
- fixed a gcc 3.2 compilation bug - thanks to
- Adam Duck <duck@informatik.uni-frankfurt.de>
+ Adam Duck <duck@informatik.uni-frankfurt.de> and other reporters
[v3.73]
- Fixed a compilation bug ocurring on big endian systems only.
- All users who send feedback
-- Andy Lo A Foe <andy@alsa-project.org> for good tips, autoconf inspiration
- and a really cool program: alsaplayer
- (checkout: http://www.alsa-project.org/~andy/)
+In politically correct alphabetical order:
- Adrian Reber <adrian@fht-esslingen.de> for being the *BEST* Linux
sysadmin ;), for numerous code contributions and the fabrication of
terminatorX-rpms.
-- Paul Kellett <paul.kellett@maxim.abel.co.uk> for his lowpass filter published
- in reso_lop.txt
- (checkout: http://www.abel.co.uk/~maxim/)
+- Andy Lo A Foe <andy@alsa-project.org> for good tips, autoconf inspiration
+ and a really cool program: alsaplayer
+ (checkout: http://www.alsa-project.org/~andy/)
+
+- Arthur Peters <amp@singingwizard.org> for contributing the ALSA MIDI
+ support
+
+- Darrick Servis <darrick@dcn.davis.ca.us> for telling me to implement the
+ Anti-Clip-Device (checkout his audio file library:
+ http://osalp.sourceforge.net)
- Benno Senoner <sbenno@gardena.net> for his mmap() patch, all the low
latency kernel work and tips
(checkout: http://www.gardena.net/benno/linux/audio/)
-- Michael Kahl <m.kahl@student.hu-berlin.de> for the cool MK II icon
+- Michael Kahl <m.kahl@student.hu-berlin.de> for the cool MK II icon that I
+ no longer use
+
+- Paul Kellett <paul.kellett@maxim.abel.co.uk> for his lowpass filter published
+ in reso_lop.txt
+ (checkout: http://www.abel.co.uk/~maxim/)
-- Robert Dale <rob@nb.net> for makeing his already gone 3DNow!-Header
+- Robert Dale <rob@nb.net> for making his already gone 3DNow!-Header
temporarily available again
- Scott C. Knight <scknight@indiana.edu> for helping me to get this thing
running on big endian machines again.
+And:
+
- Everybody who contributed scratches...
- The LAD people for all the help and support
# include <unistd.h>
#endif
+#include <string.h>
+#include <errno.h>
+#include <stdlib.h>
+
void tX_audiodevice :: init()
{
samples_per_buffer=0;
#ifdef BIG_ENDIAN_MACHINE
swapbuffer (buffer, samples_per_buffer);
#endif
- write(fd, buffer, blocksize);
+ int res=write(fd, buffer, blocksize);
+ if (res==-1) {
+ tX_error("failed to write to audiodevice: %s", strerror(errno));
+ exit(-1);
+ }
}
#endif //USE_OSS
#define restore_string_ac(s, i, init); if ((!elementFound) && (!xmlStrcmp(cur->name, (const xmlChar *) s))) { elementFound=1; if (xmlNodeListGetString(doc, cur->xmlChildrenNode, 1)) {strcpy(i, (const char *) xmlNodeListGetString(doc, cur->xmlChildrenNode, 1)); init; }}
#define restore_bool_ac(s, i, init); if ((!elementFound) && (!xmlStrcmp(cur->name, (const xmlChar *) s))) { elementFound=1; if (xmlNodeListGetString(doc, cur->xmlChildrenNode, 1)) {if (xmlStrcmp(xmlNodeListGetString(doc, cur->xmlChildrenNode, 1), (const xmlChar *) "true")==0) i=true; else i=false; init; }}
-#define restore_int_id(s, i, sp, init); if ((!elementFound) && (!xmlStrcmp(cur->name, (const xmlChar *) s))) { elementFound=1; if (xmlNodeListGetString(doc, cur->xmlChildrenNode, 1)) { sscanf((char *) xmlNodeListGetString(doc, cur->xmlChildrenNode, 1), "%i", &i); pid_attr=(char* ) xmlGetProp(cur, (xmlChar *) "id"); if (pid_attr) { sscanf(pid_attr, "%i", &pid); sp.set_persistence_id(pid); } init; }}
-#define restore_float_id(s, i, sp, init); if ((!elementFound) && (!xmlStrcmp(cur->name, (const xmlChar *) s))) { elementFound=1; if (xmlNodeListGetString(doc, cur->xmlChildrenNode, 1)) {sscanf((char *) xmlNodeListGetString(doc, cur->xmlChildrenNode, 1), "%lf", &dvalue); i=dvalue; pid_attr=(char* ) xmlGetProp(cur, (xmlChar *) "id"); if (pid_attr) { sscanf(pid_attr, "%i", &pid); sp.set_persistence_id(pid); } init; }}
-#define restore_bool_id(s, i, sp, init); if ((!elementFound) && (!xmlStrcmp(cur->name, (const xmlChar *) s))) { elementFound=1; if (xmlNodeListGetString(doc, cur->xmlChildrenNode, 1)) {if (xmlStrcmp(xmlNodeListGetString(doc, cur->xmlChildrenNode, 1), (const xmlChar *) "true")==0) i=true; else i=false; pid_attr=(char* ) xmlGetProp(cur, (xmlChar *)"id"); if (pid_attr) { sscanf(pid_attr, "%i", &pid); sp.set_persistence_id(pid); } init; }}
+//#define restore_int_id(s, i, sp, init); if ((!elementFound) && (!xmlStrcmp(cur->name, (const xmlChar *) s))) { elementFound=1; if (xmlNodeListGetString(doc, cur->xmlChildrenNode, 1)) { sscanf((char *) xmlNodeListGetString(doc, cur->xmlChildrenNode, 1), "%i", &i); pid_attr=(char* ) xmlGetProp(cur, (xmlChar *) "id"); if (pid_attr) { sscanf(pid_attr, "%i", &pid); sp.set_persistence_id(pid); } init; }}
+//#define restore_float_id(s, i, sp, init); if ((!elementFound) && (!xmlStrcmp(cur->name, (const xmlChar *) s))) { elementFound=1; if (xmlNodeListGetString(doc, cur->xmlChildrenNode, 1)) {sscanf((char *) xmlNodeListGetString(doc, cur->xmlChildrenNode, 1), "%lf", &dvalue); i=dvalue; pid_attr=(char* ) xmlGetProp(cur, (xmlChar *) "id"); if (pid_attr) { sscanf(pid_attr, "%i", &pid); sp.set_persistence_id(pid); } init; }}
+//#define restore_bool_id(s, i, sp, init); if ((!elementFound) && (!xmlStrcmp(cur->name, (const xmlChar *) s))) { elementFound=1; if (xmlNodeListGetString(doc, cur->xmlChildrenNode, 1)) {if (xmlStrcmp(xmlNodeListGetString(doc, cur->xmlChildrenNode, 1), (const xmlChar *) "true")==0) i=true; else i=false; pid_attr=(char* ) xmlGetProp(cur, (xmlChar *)"id"); if (pid_attr) { sscanf(pid_attr, "%i", &pid); sp.set_persistence_id(pid); } init; }}
#define store_int(s, i); fprintf(rc, "%s<%s>%i</%s>\n", indent, s,(int) i, s);
#define store_float(s, i); fprintf(rc, "%s<%s>%lf</%s>\n", indent, s,(double) i, s);
#define store_float_id(s, i, id); fprintf(rc, "%s<%s id=\"%i\">%lf</%s>\n", indent, s, id, (double) i, s);
#define store_bool_id(s, i, id); fprintf(rc, "%s<%s id=\"%i\">%s</%s>\n", indent, s, id, i ? "true" : "false", s);
+#define store_int_sp(name, i, sp); { fprintf(rc, "%s<%s ", indent, name); sp.store_meta(rc); fprintf(rc, ">%i</%s>\n", (int) i, name); }
+#define store_float_sp(name, i, sp); { fprintf(rc, "%s<%s ", indent, name); sp.store_meta(rc); fprintf(rc, ">%lf</%s>\n", (double) i, name); }
+#define store_bool_sp(name, i, sp); { fprintf(rc, "%s<%s ", indent, name); sp.store_meta(rc); fprintf(rc, ">%s</%s>\n", i ? "true" : "false", name); }
+
+#define restore_int_id(s, i, sp, init); if ((!elementFound) && (!xmlStrcmp(cur->name, (const xmlChar *) s))) { elementFound=1; if (xmlNodeListGetString(doc, cur->xmlChildrenNode, 1)) { sscanf((char *) xmlNodeListGetString(doc, cur->xmlChildrenNode, 1), "%i", &i); init; } sp.restore_meta(cur); }
+#define restore_float_id(s, i, sp, init); if ((!elementFound) && (!xmlStrcmp(cur->name, (const xmlChar *) s))) { elementFound=1; if (xmlNodeListGetString(doc, cur->xmlChildrenNode, 1)) {sscanf((char *) xmlNodeListGetString(doc, cur->xmlChildrenNode, 1), "%lf", &dvalue); i=dvalue; init; } sp.restore_meta(cur);}
+#define restore_bool_id(s, i, sp, init); if ((!elementFound) && (!xmlStrcmp(cur->name, (const xmlChar *) s))) { elementFound=1; if (xmlNodeListGetString(doc, cur->xmlChildrenNode, 1)) {if (xmlStrcmp(xmlNodeListGetString(doc, cur->xmlChildrenNode, 1), (const xmlChar *) "true")==0) i=true; else i=false; init; } sp.restore_meta(cur);}
+
#ifdef __cplusplus
}
#endif /* __cplusplus */
using namespace std;
+/*
+ disabled
void tX_midievent::print( const char* prefix ) const
{
cerr << prefix << ": channel=" << channel << ", type=" << type << ", number=" << number
<< ", value=" << value << ", is_noteon=" << is_noteon << endl;
}
-
+*/
tX_midiin::tX_midiin()
{
int portid;
if (snd_seq_open(&ALSASeqHandle, "default", SND_SEQ_OPEN_INPUT, 0) < 0) {
- tX_error("tx_midiin(): failed to open the default sequencer device.");
+ tX_error("tX_midiin(): failed to open the default sequencer device.");
return;
}
snd_seq_set_client_name(ALSASeqHandle, "TerminatorX");
| SND_SEQ_PORT_CAP_SUBS_WRITE,
SND_SEQ_PORT_TYPE_APPLICATION);
if (portid < 0) {
- cerr << "Error creating sequencer port." << endl;
+ tX_error("tX_midiin(): error creating sequencer port.");
return;
}
#ifndef _tx_midiin_h
#define _tx_midiin_h 1
-#include <config.h>
-#ifdef USE_ALSA_MIDI_IN
-
-#include <alsa/asoundlib.h>
-#include <gtk/gtk.h>
-
class vtt_class;
class tX_midievent
value = 0;
is_noteon = false;
}
-
- void print( const char* prefix ) const;
+
+ /* not being used anyway */
+ // void print( const char* prefix ) const;
};
+#include <config.h>
+#ifdef USE_ALSA_MIDI_IN
+
+#include <alsa/asoundlib.h>
+#include <gtk/gtk.h>
+
class tX_midiin
{
snd_seq_t *ALSASeqHandle;
else return "Master Track";
}
+void tX_seqpar :: restore_meta(xmlNodePtr node) {
+ char *buffer;
+
+ buffer=(char *) xmlGetProp(node, (xmlChar *) "id");
+ if (buffer) { sscanf(buffer, "%i", &persistence_id); }
+ else { tX_error("no ID for seqpar %s", this->get_name()); }
+
+ buffer=(char *) xmlGetProp(node, (xmlChar *) "midiType");
+ if (buffer) {
+ if (strcmp("cc", buffer)==0) {
+ bound_midi_event.type=tX_midievent::CC;
+ } else if (strcmp("note", buffer)==0) {
+ bound_midi_event.type=tX_midievent::NOTE;
+ } else if (strcmp("pitchbend", buffer)==0) {
+ bound_midi_event.type=tX_midievent::PITCHBEND;
+ } else {
+ tX_error("unknown midiType \"%s\" for seqpar %s", buffer, this->get_name());
+ }
+
+ buffer=(char *) xmlGetProp(node, (xmlChar *) "midiChannel");
+ if (buffer) { sscanf(buffer, "%i", &bound_midi_event.channel); }
+ else { tX_error("no midiChannel for seqpar %s", this->get_name()); }
+
+ buffer=(char *) xmlGetProp(node, (xmlChar *) "midiNumber");
+ if (buffer) { sscanf(buffer, "%i", &bound_midi_event.number); }
+ else { tX_error("no midiNumber for seqpar %s", this->get_name()); }
+ }
+ /* else: no MIDI init.... */
+}
+
+void tX_seqpar :: store_meta(FILE *output) {
+ char buffer[256];
+
+ if (bound_midi_event.type!=tX_midievent::NONE) {
+ char *type;
+
+ switch (bound_midi_event.type) {
+ case tX_midievent::NOTE: type="note"; break;
+ case tX_midievent::CC: type="cc"; break;
+ case tX_midievent::PITCHBEND: type="pitchbend"; break;
+ default: type="error";
+ }
+ sprintf(buffer, "id=\"%i\" midiType=\"%s\" midiChannel=\"%i\" midiNumber=\"%i\"", persistence_id, type, bound_midi_event.channel, bound_midi_event.number);
+ } else {
+ sprintf(buffer, "id=\"%i\"", persistence_id);
+ }
+ fprintf(output, buffer);
+}
+
+
const char * tX_seqpar :: get_name()
{
return "This string means trouble!";
#include <gtk/gtk.h>
#include "tX_extdial.h"
#include "tX_midiin.h"
+#include "tX_global.h"
#ifndef _tx_seqpar_h
#define _tx_seqpar_h 1
#define NO_MOUSE_MAPPING 0
#define MOUSE_MAPPING_OK 1
+#include <libxml/xmlmemory.h>
+#include <libxml/parser.h>
+
/* required for gcc>=3.0 */
using namespace std;
static list <tX_seqpar *> all;
void *vtt; /* have to make this void as tX_vtt.h includes this */
-#ifdef USE_ALSA_MIDI_IN
tX_midievent bound_midi_event;
-#endif
+
protected:
static list <tX_seqpar *> update;
static pthread_mutex_t update_lock;
public:
int is_mappable;
+ void restore_meta(xmlNodePtr node);
+ void store_meta(FILE *output);
};
class tX_seqpar_update : public tX_seqpar
}
store_bool("sync_master", is_sync_master);
store_bool("autotrigger", autotrigger);
- store_bool_id("loop", loop, sp_loop.get_persistence_id());
+ store_bool_sp("loop", loop, sp_loop);
- store_bool_id("sync_client", is_sync_client, sp_sync_client.get_persistence_id());
- store_int_id("sync_cycles", sync_cycles, sp_sync_cycles.get_persistence_id());
+ store_bool_sp("sync_client", is_sync_client, sp_sync_client);
+ store_int_sp("sync_cycles", sync_cycles, sp_sync_cycles);
- store_float_id("volume", rel_volume, sp_volume.get_persistence_id());
- store_float_id("pitch", rel_pitch, sp_pitch.get_persistence_id());
- store_bool_id("mute", mute, sp_mute.get_persistence_id());
- store_float_id("pan", pan, sp_pan.get_persistence_id());
+ store_float_sp("volume", rel_volume, sp_volume);
+ store_float_sp("pitch", rel_pitch, sp_pitch);
+ store_bool_sp("mute", mute, sp_mute);
+ store_float_sp("pan", pan, sp_pan);
- store_bool_id("lowpass_enable", lp_enable, sp_lp_enable.get_persistence_id());
- store_float_id("lowpass_gain", lp_gain, sp_lp_gain.get_persistence_id());
- store_float_id("lowpass_reso", lp_reso, sp_lp_reso.get_persistence_id());
- store_float_id("lowpass_freq", lp_freq, sp_lp_freq.get_persistence_id());
+ store_bool_sp("lowpass_enable", lp_enable, sp_lp_enable);
+ store_float_sp("lowpass_gain", lp_gain, sp_lp_gain);
+ store_float_sp("lowpass_reso", lp_reso, sp_lp_reso);
+ store_float_sp("lowpass_freq", lp_freq, sp_lp_freq);
- store_bool_id("echo_enable", ec_enable, sp_ec_enable.get_persistence_id());
- store_float_id("echo_length", ec_length, sp_ec_length.get_persistence_id());
- store_float_id("echo_feedback", ec_feedback, sp_ec_feedback.get_persistence_id());
- store_float_id("echo_pan", ec_pan, sp_ec_pan.get_persistence_id());
- store_float_id("echo_volume", ec_volume, sp_ec_volume.get_persistence_id());
+ store_bool_sp("echo_enable", ec_enable, sp_ec_enable);
+ store_float_sp("echo_length", ec_length, sp_ec_length);
+ store_float_sp("echo_feedback", ec_feedback, sp_ec_feedback);
+ store_float_sp("echo_pan", ec_pan, sp_ec_pan);
+ store_float_sp("echo_volume", ec_volume, sp_ec_volume);
store_id("speed", sp_speed.get_persistence_id());
store_id("trigger", sp_trigger.get_persistence_id());
//store_int(vtt_amount); obsolete
- store_float_id("master_volume", master_volume, sp_master_volume.get_persistence_id());
- store_float_id("master_pitch", globals.pitch, sp_master_pitch.get_persistence_id());
+ store_float_sp("master_volume", master_volume, sp_master_volume);
+ store_float_sp("master_pitch", globals.pitch, sp_master_pitch);
for (vtt=main_list.begin(); vtt!=main_list.end(); vtt++) {
res+=(*vtt)->save(rc, indent);
f_prec gui_get_audio_x_zoom(vtt_class *vtt) {
return gtk_tx_get_zoom(GTK_TX(vtt->gui.display));
}
+
+int vttgui_zoom_depth=0;
+
extern void gui_set_audio_x_zoom(vtt_class *vtt, f_prec value) {
- gtk_tx_set_zoom(GTK_TX(vtt->gui.display), value);
+ if (vttgui_zoom_depth==0) {
+ vttgui_zoom_depth=1;
+ gtk_range_set_value(GTK_RANGE(vtt->gui.zoom), value);
+ vttgui_zoom_depth=0;
+ } else {
+ gtk_tx_set_zoom(GTK_TX(vtt->gui.display), value);
+ }
}