}
}
-#define min(a,b) ((a) < (b) ? (a) : (b))
-
void tX_audiodevice_pulse::stream_write_callback(pa_stream *stream, size_t length) {
size_t sample_length = length/2;
while (outbuffer_pos<sample_length) {
int16_t *data=engine->render_cycle();
- sample = min(vtt_class::samples_in_mix_buffer, (sample_length - outbuffer_pos));
+ sample = tX_min(vtt_class::samples_in_mix_buffer, (sample_length - outbuffer_pos));
memcpy(&outbuffer[outbuffer_pos], data, sizeof(int16_t) * sample);
outbuffer_pos+=sample;
# include <audiofile.h>
#endif
-#define min(a,b) ((a) < (b) ? (a) : (b))
-
tx_audiofile :: tx_audiofile()
{
mem_type=TX_AUDIO_UNDEFINED;
#endif
while (wav_in.len>allbytes)
{
- bytes = fread(p, 1, min(1024, wav_in.len-allbytes), wav_in.handle);
+ bytes = fread(p, 1, tX_min(1024, wav_in.len-allbytes), wav_in.handle);
#ifdef ENABLE_DEBUG_OUTPUT
if (output) { tX_debug("tX_audiofile::load_wav() read %zu Bytes [%04x %04x %04x %04x %04x %04x ..]", bytes, (unsigned int) p[0], (unsigned int) p[1], (unsigned int) p[2], (unsigned int) p[3], (unsigned int) p[4], (unsigned int) p[5]); }
unsigned int pos;
if (buffer->first_call) {
- bs=min(TX_MAD_BLOCKSIZE, buffer->size);
+ bs=tX_min(TX_MAD_BLOCKSIZE, buffer->size);
mad_stream_buffer(stream, buffer->start, bs);
buffer->first_call=false;
return MAD_FLOW_CONTINUE;
if (!stream->next_frame) return MAD_FLOW_STOP;
pos=stream->next_frame-buffer->start;
- bs=min(TX_MAD_BLOCKSIZE, buffer->size-pos);
+ bs=tX_min(TX_MAD_BLOCKSIZE, buffer->size-pos);
//tX_debug("last: %08x, new %08x, bs: %i, pos: %i", buffer->last_frame, stream->next_frame, bs, pos);
mad_stream_buffer(stream, stream->next_frame, bs);
} else {
globals.knob_size_override = 0;
}
-
+
+ globals.wav_display_history=(gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(lookup_widget(dialog, "wav_display_history")))==TRUE);
+
/* Audio Colors */
strcpy(globals.wav_display_bg_focus, (char *) g_object_get_data(G_OBJECT(lookup_widget(dialog, "wav_display_bg_focus")), "Color"));
} else {
gtk_range_set_value(GTK_RANGE(lookup_widget(dialog, "knob_size")), 48);
}
+
+ gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(lookup_widget(dialog, "wav_display_history")), globals.wav_display_history);
+
/* Audio Colors */
int ctr=0;
globals.alsa_free_hwstats=0;
globals.filename_length=20;
globals.restore_midi_connections=1;
-
+
+ globals.wav_display_history=1;
+
strcpy(globals.wav_display_bg_focus, "#00004C");
strcpy(globals.wav_display_bg_no_focus, "#000000");
restore_int("confirm_events", globals.confirm_events);
restore_float("vtt_inertia", globals.vtt_inertia);
restore_int("restore_midi_connections", globals.restore_midi_connections);
-
+
+ restore_int("wav_display_history", globals.wav_display_history);
restore_string("wav_display_bg_focus", globals.wav_display_bg_focus);
restore_string("wav_display_bg_no_focus", globals.wav_display_bg_no_focus);
restore_string("wav_display_fg_focus", globals.wav_display_fg_focus);
store_string("last_path", globals.current_path);
store_int("restore_midi_connections", globals.restore_midi_connections);
+ store_int("wav_display_history", globals.wav_display_history);
store_string("wav_display_bg_focus", globals.wav_display_bg_focus);
store_string("wav_display_bg_no_focus", globals.wav_display_bg_no_focus);
store_string("wav_display_fg_focus", globals.wav_display_fg_focus);
#define tX_msg(fmt, args...); { fprintf(stderr, "- tX_msg: "); fprintf(stderr, fmt , ## args); fprintf(stderr, "\n"); }
#define tX_plugin_warning(fmt, args...); { if (globals.verbose_plugin_loading) { fprintf(stderr, "+ tX_warning: "); fprintf(stderr, fmt , ## args); fprintf(stderr, "\n"); }}
+#define tX_min(a,b) ((a) < (b) ? (a) : (b))
+#define tX_max(a,b) ((a) > (b) ? (a) : (b))
+
#ifdef MEM_DEBUG
#define tX_freemem(ptr, varname, comment); fprintf(stderr, "** free() [%s] at %08x. %s.\n", varname, ptr, comment); free(ptr);
#define tX_malloc(ptr, varname, comment, size, type); fprintf(stderr, "**[1/2] malloc() [%s]. Size: %i. %s.\n", varname, size, comment); ptr=type malloc(size); fprintf(stderr, "**[2/2] malloc() [%s]. ptr: %08x.\n", varname, ptr);
int filename_length;
int restore_midi_connections;
+ int wav_display_history;
char wav_display_bg_focus[8];
char wav_display_bg_no_focus[8];
GtkWidget *label45;
GtkWidget *label46;
GtkWidget *label47;
+ GtkWidget *wav_display_history;
GtkWidget *wav_display_bg_focus;
GtkWidget *wav_display_bg_no_focus;
GtkWidget *wav_display_fg_focus;
gtk_scale_set_value_pos (GTK_SCALE (knob_size), GTK_POS_LEFT);
gtk_scale_set_digits (GTK_SCALE (knob_size), 0);
+ label38 = gtk_label_new("Highlight:");
+ gtk_widget_show (label38);
+ gtk_grid_attach (GTK_GRID (grid2), label38, 0, 9, 1, 1);
+ gtk_widget_set_halign(label38, GTK_ALIGN_START);
+
+ wav_display_history = gtk_check_button_new_with_mnemonic ("Highlight recently played back samples");
+ gtk_widget_show (wav_display_history);
+ gtk_grid_attach (GTK_GRID (grid2), wav_display_history, 1, 9, 1, 1);
+ gtk_widget_set_tooltip_text(wav_display_history, "Adds visual history to the turntable cursor or needles.");
+
label2 = gtk_label_new ("User Interface");
gtk_widget_show (label2);
gtk_notebook_set_tab_label (GTK_NOTEBOOK (notebook1), gtk_notebook_get_nth_page (GTK_NOTEBOOK (notebook1), 2), label2);
TX_UI_HOOKUP_OBJECT (tx_options, label_knob_size, "label_knob_size");
TX_UI_HOOKUP_OBJECT (tx_options, knob_size, "knob_size");
TX_UI_HOOKUP_OBJECT (tx_options, override_knob_size, "override_knob_size");
+ TX_UI_HOOKUP_OBJECT (tx_options, wav_display_history, "wav_display_history");
return tx_options;
}
widget_class->size_allocate = gtk_tx_size_allocate;
}
+#define COL_FOCUS 0
+#define COL_NO_FOCUS 1
+
#define COL_BG_FOCUS 0
#define COL_BG_NO_FOCUS 1
#define COL_FG_FOCUS 2
#define COL_CURSOR_MUTE 5
void gtk_tx_update_colors(GtkTx *tx) {
+ int step;
+
gdk_rgba_parse(&tx->colors[COL_BG_FOCUS], globals.wav_display_bg_focus);
tx->colors[COL_BG_FOCUS].alpha=1.0;
gdk_rgba_parse(&tx->colors[COL_BG_NO_FOCUS], globals.wav_display_bg_no_focus);
tx->colors[COL_CURSOR].alpha=1.0;
gdk_rgba_parse(&tx->colors[COL_CURSOR_MUTE], globals.wav_display_cursor_mute);
tx->colors[COL_CURSOR_MUTE].alpha=1.0;
+
+ for (step = 0; step < GTK_TX_HISTORY_LENGTH; step++) {
+ double frac = (1.0 / ((double) GTK_TX_HISTORY_LENGTH + 2.0)) * ((double) step + 1.0);
+
+ GdkRGBA *color = &tx->history_colors[step];
+ color->red = tx->colors[COL_CURSOR].red;
+ color->green = tx->colors[COL_CURSOR].green;
+ color->blue = tx->colors[COL_CURSOR].blue;
+ color->alpha = frac*frac/2;
+// printf("%i, %lf\n", step, frac);
+ }
}
#endif
memset(tx->colors, 0, sizeof(tx->colors));
-
+ memset(tx->history_colors, 0, sizeof(tx->history_colors));
+
gtk_tx_update_colors(tx);
tx->current_fg=tx->audio_colors_focus;
}
static void gtk_tx_get_preferred_height (GtkWidget *widget, gint *minimal_height, gint *natural_height) {
- *minimal_height = *natural_height = TX_DEFAULT_SIZE_Y;
+ *minimal_height = *natural_height = TX_DEFAULT_SIZE_Y;
}
static void gtk_tx_reallocate_disp_data(GtkWidget *widget) {
cairo_set_line_width(cr, 1);
if (tx->disp_data) {
- int src_x;
-
+ int src_x, step;
int x_offset;
+
if (tx->zoom > 0.0) {
x_offset= tx->cursor_pos > tx->xc ? tx->cursor_pos-tx->xc : 0;
if (x_offset+tx->xmax > tx->display_width) {
}
}
+ tx->cursor_history[tx->cursor_history_offset] = tx->cursor_pos;
+ tx->cursor_history_offset++;
+ if (tx->cursor_history_offset >= GTK_TX_HISTORY_LENGTH) {
+ tx->cursor_history_offset -= GTK_TX_HISTORY_LENGTH;
+ }
+
+ if (globals.wav_display_history && !tx->mute) {
+ int prev_sample_pos = -1;
+ /* draw history */
+
+ for (step = 0; step < GTK_TX_HISTORY_LENGTH; step++) {
+ int history_pos = tx->cursor_history_offset - step;
+
+ if (history_pos < 0) {
+ history_pos += GTK_TX_HISTORY_LENGTH;
+ }
+
+ int sample_pos = tx->cursor_history[history_pos];
+
+ if ((sample_pos >= 0) && (prev_sample_pos >= 0)) {
+ int sample_x_pos = sample_pos - tx->display_x_offset;
+ int prev_sample_x_pos = prev_sample_pos - tx->display_x_offset;
+ int min, max;
+
+ if (prev_sample_x_pos > sample_x_pos) {
+ min = sample_x_pos;
+ max = prev_sample_x_pos;
+ } else {
+ min = prev_sample_x_pos;
+ max = sample_x_pos;
+ }
+
+ if ((max - min) <= tx->xc) {
+ for (x=min; x < max; x++) {
+ int value = tx->disp_data[x+tx->display_x_offset];
+ draw_sample(x, tx->yc-value, tx->yc+value+1, &tx->history_colors[GTK_TX_HISTORY_LENGTH-step]);
+ }
+ } else {
+ for (x = 0; x < min; x++) {
+ int value = tx->disp_data[x+tx->display_x_offset];
+ draw_sample(x, tx->yc-value, tx->yc+value+1, &tx->history_colors[GTK_TX_HISTORY_LENGTH-step]);
+ }
+ for (x= max; x < tx->xmax; x++) {
+ int value = tx->disp_data[x+tx->display_x_offset];
+ draw_sample(x, tx->yc-value, tx->yc+value+1, &tx->history_colors[GTK_TX_HISTORY_LENGTH-step]);
+ }
+ }
+ }
+
+ prev_sample_pos = sample_pos;
+ }
+ }
/* draw cursor */
draw_sample(tx->cursor_x_pos, 0, tx->ymax, tx->mute ? &tx->colors[COL_CURSOR_MUTE] : &tx->colors[COL_CURSOR]);
} else {
void gtk_tx_cleanup_pos_display(GtkTx * tx) {
GtkWidget *widget;
GtkAllocation allocation;
+ int step;
widget = GTK_WIDGET(tx);
gtk_widget_get_allocation(widget, &allocation);
tx->display_x_offset=0;
tx->cursor_pos=-1;
tx->cursor_x_pos=-1;
+
+ for (step = 0; step < GTK_TX_HISTORY_LENGTH; step++) {
+ tx->cursor_history[step] = -1;
+ }
gtk_widget_queue_draw(widget);
}
extern "C" {
#endif /* __cplusplus */
-
#define GTK_TX(obj) G_TYPE_CHECK_INSTANCE_CAST (obj, gtk_tx_get_type (), GtkTx)
#define GTK_TX_CLASS(klass) GTK_CHECK_CLASS_CAST (klass, gtk_tx_get_type (), GtkTxClass)
#define GTK_IS_TX(obj) G_TYPE_CHECK_INSTANCE_TYPE (obj, gtk_tx_get_type ())
MOTION_RIGHT
} tx_widget_motion;
+#define GTK_TX_HISTORY_LENGTH 4
+
struct _GtkTx {
GtkWidget widget;
int samples;
GdkRGBA colors[6];
+ GdkRGBA history_colors[GTK_TX_HISTORY_LENGTH];
GdkRGBA *current_fg;
GdkRGBA *current_bg;
int cursor_pos;
int cursor_x_pos;
int mute;
+ int cursor_history[GTK_TX_HISTORY_LENGTH];
+ int cursor_history_offset;
int display_width;
int display_x_offset;