/* Freebirth
 * Copyright (C) 1999 topher lafata <topher@topher.com>,
 *		      Jake Donham <jake@bitmechanic.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; either
 * version 2 of the License, or (at your option) any later version.
 *
 * 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 (see COPYING); if not, write to the
 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
 * Boston, MA 02111-1307, USA.
 */

#include <sys/ioctl.h>
#ifdef __FreeBSD__
 #include <machine/soundcard.h>
#else
 #include <sys/soundcard.h>
#endif
#include <fcntl.h>
#include <stdio.h>
#include <unistd.h>
#include <math.h>
#include <stdlib.h>
#include <glib.h>

#include "freebirth.h"
#include "xpm/q.xpm" 
#include "xpm/cutoff.xpm" 
#include "xpm/attack.xpm" 
#include "xpm/release.xpm" 
#include "xpm/amp_release.xpm" 
#include "xpm/amp_attack.xpm" 
#include "xpm/play.xpm" 
#include "xpm/pause.xpm" 
#include "xpm/iactive_led.xpm"
#include "xpm/active_led.xpm"
#include "xpm/sin.xpm"
#include "xpm/saw.xpm"
#include "xpm/sqr.xpm"
#include "xpm/blend.xpm"
#include "xpm/phase.xpm"
#include "xpm/freq.xpm"
#include "xpm/mixer.xpm"
#include "xpm/bd.xpm"
#include "xpm/sd.xpm"
#include "xpm/ch.xpm"
#include "xpm/oh.xpm"
#include "xpm/smp.xpm"
#include "xpm/bas.xpm"
#include "xpm/freebirth.xpm"


/* local stuff */

/*#define DEBUG        */



static char **xpms[] = {
  smp_xpm,
  oh_xpm,
  ch_xpm,
  sd_xpm,
  bd_xpm,
  bas_xpm
};


GSList *sl; /* list of all sample_producers, for next_buffer() calls */
void next_buffer(sample_producer *sp, void *data) {
  if (sp)
    sp->next_buffer(sp);
}

extern int play_buffer(gpointer data, gint source, GdkInputCondition cond);

#if 0
int play_buffer(gpointer data, gint source,GdkInputCondition condition)
{
  

#ifdef DEBUG
  int i, len;
  short *buffer;
  seq_step(sequencer);
  buffer = main_out->get_buffer(main_out);
  for(i = 0; i < TBASS_BUFF_SIZE;i++)
    printf("%d\n",buffer[i]);
  
#else
  sample *buffer;
  short out[TBASS_BUFF_SIZE];

  g_slist_foreach(sl, (GFunc)next_buffer, NULL);
  seq_step(sequencer);      
  
  buffer = main_out->get_buffer(main_out);
  for(i = 0; i < TBASS_BUFF_SIZE;i++)
    {
      sample tmp = buffer[i];
      if((tmp < CLIP) && (tmp >-CLIP))
	out[i] = (short)tmp;
      else if(tmp >0)
	out[i] = (short)MIX_MAX_AMP-(CLIP_A/(CLIP_B+tmp));
      else
	out[i] = (short)-(MIX_MAX_AMP - (CLIP_A/(CLIP_B - tmp)));

    }
  write(fd,out,
	TBASS_BUFF_SIZE * sizeof(short));
  
#endif 

  return TRUE;


}
#endif

#ifdef FUSE_LOOPS
extern void fuse_loops(sample_producer *, sample_producer *, FILE *);

int main(int argc, char* argv[])
{
  init_tbass();
  fuse_loops((sample_producer *)left_mixer,
	     (sample_producer *)right_mixer,
	     stdout);
  return 0;
}
#else
extern void filter_init_lookup_table();
void init_soundcard();

extern sample_producer *sp[];
int find(sample_producer *node) {
  sample_producer **spp;
  for (spp = sp; *spp; spp++)
    if (node == *spp)
      return 1;
  return 0;
}

sample_producer **spp;
void init_sps(sample_producer *node) {
  if (find(node))
    return;
  else {
    sample_producer **children;
    for (children = node->get_children(node);
	 *children;
	 children++) {
      init_sps(*children);
    }
    *spp++ = node;
  }
}

int main(int argc, char* argv[])
{
  init_soundcard();
  init_tbass();
  spp = sp;
  init_sps((sample_producer *)left_mixer);
  init_sps((sample_producer *)right_mixer);
  filter_init_lookup_table();
  init_interface(argc, argv);
  return 0;
}
#endif

void init_soundcard()
{
  int result;  
  int frag;

  /* open up and configure sound device */
  result = fd = open("/dev/dsp",O_WRONLY,0);
  if (result == -1) {
    fprintf(stderr, "Unable to open audio device.\n"); exit(1);
  }
  frag   = 0x00200009;
  result = ioctl(fd,SNDCTL_DSP_SETFRAGMENT, &frag);
  if (result == -1) {
    fprintf(stderr, "Unable to set fragment size.\n"); exit(1);
  }
  format = AFMT_S16_LE;
  result = ioctl(fd,SNDCTL_DSP_SETFMT, &format);
  if (result == -1) {
    fprintf(stderr, "Unable to set sample format.\n"); exit(1);
  }
  stereo = 1;
  result = ioctl(fd, SNDCTL_DSP_STEREO, &stereo);
  if (result == -1) {
    fprintf(stderr, "Unable to set channels.\n"); exit(1);
  }
  speed = 44100;
  result = ioctl(fd, SNDCTL_DSP_SPEED, &speed); 
  if (result == -1) {
    fprintf(stderr, "Unable to set sample rate.\n"); exit(1);
  }
}

int samp_handle[NUM_SAMPLES];
void init_tbass()
{
  /* create instance of bass osc */
  
  bass_sqr      = osc_new(65,SQR);
  sl = g_slist_append(NULL, bass_sqr);
  bass_sin      = osc_new(65,SIN);
  sl = g_slist_append(sl, bass_sin);
  bass_saw      = osc_new(65,SAW);
  sl = g_slist_append(sl, bass_saw);
  
  sources = (sample_producer**)
    malloc(sizeof(sample_producer*) * 4);

  sources[0] = (sample_producer*)bass_saw;
  sources[1] = (sample_producer*)bass_sqr;
  sources[2] = (sample_producer*)bass_sin;
  sources[4] = NULL;

  
  osc_blender = blender_new(sources);
  sl = g_slist_append(sl, osc_blender);
  blender_set_strength(osc_blender,MIX_MAX_AMP,0);
  blender_set_strength(osc_blender,0,1);
  blender_set_strength(osc_blender,0,2);


  /*connect the osc stuff */
  filt_e    = env_new(1024,22050, NULL);
  sl = g_slist_append(sl, filt_e);
  bass_filt = filter_new(2000, 2,
			 (sample_producer *)filt_e,
			 (sample_producer *)osc_blender);
  sl = g_slist_append(sl, bass_filt);
  bass_e    = env_new(1025,10000,(sample_producer *)bass_filt);
  //bass_e    = env_new(1025,10000,(sample_producer *)osc_blender);
  sl = g_slist_append(sl, bass_e);

  kick   = raw_wave_new("raw/kick.raw");
  sl = g_slist_append(sl, kick);
  snare  = raw_wave_new("raw/snare.raw");
  sl = g_slist_append(sl, snare);
  cl_hat = raw_wave_new("raw/cl_hat.raw");
  sl = g_slist_append(sl, cl_hat);
  op_hat = raw_wave_new("raw/op_hat.raw");
  sl = g_slist_append(sl, op_hat);
  samp_1 = raw_wave_new("raw/samp_1.raw");
  sl = g_slist_append(sl, samp_1);

  sources = (sample_producer**)
    malloc(sizeof(sample_producer*) * (NUM_SAMPLES + 2));
  sources[KICK_INDEX]   = (sample_producer*)kick;
  sources[SNARE_INDEX]  = (sample_producer*)snare;
  sources[CL_HAT_INDEX] = (sample_producer*)cl_hat;
  sources[OP_HAT_INDEX] = (sample_producer*)op_hat;
  sources[SAMP1_INDEX]  = (sample_producer*)samp_1;
  sources[BASS_INDEX]   = (sample_producer*)bass_e;
  sources[NUM_SAMPLES + 1] = NULL;
  
  /* aux 1 bus */
  aux_1 = mixer_new(sources);
  sl = g_slist_append(sl, aux_1);
  mixer_set_amplitude(aux_1,0,KICK_INDEX);
  mixer_set_amplitude(aux_1,0,SNARE_INDEX);
  mixer_set_amplitude(aux_1,0,CL_HAT_INDEX);
  mixer_set_amplitude(aux_1,0,OP_HAT_INDEX);
  mixer_set_amplitude(aux_1,0,SAMP1_INDEX);
  mixer_set_amplitude(aux_1,0,BASS_INDEX);

  /* aux 2 bus */
  aux_2 = mixer_new(sources);
  sl = g_slist_append(sl, aux_2);
  mixer_set_amplitude(aux_2,0,KICK_INDEX);
  mixer_set_amplitude(aux_2,0,SNARE_INDEX);
  mixer_set_amplitude(aux_2,0,CL_HAT_INDEX);
  mixer_set_amplitude(aux_2,0,OP_HAT_INDEX);
  mixer_set_amplitude(aux_2,0,SAMP1_INDEX);
  mixer_set_amplitude(aux_2,0,BASS_INDEX);

  eff_1  = multi_tap_delay_new(3,(sample_producer *)aux_1);
  sl = g_slist_append(sl, eff_1);
  eff_2  = reverb_new((sample_producer *)aux_2);
  sl = g_slist_append(sl, eff_2);

  sources = (sample_producer**)
    malloc(sizeof(sample_producer*) * (NUM_SAMPLES + 4));
  sources[KICK_INDEX]   = (sample_producer*)kick;
  sources[SNARE_INDEX]  = (sample_producer*)snare;
  sources[CL_HAT_INDEX] = (sample_producer*)cl_hat;
  sources[OP_HAT_INDEX] = (sample_producer*)op_hat;
  sources[SAMP1_INDEX]  = (sample_producer*)samp_1;
  sources[BASS_INDEX]   = (sample_producer*)bass_e;
  sources[6]		= (sample_producer *)eff_1;
  sources[7]		= (sample_producer *)eff_2;
  sources[8] = NULL;

  left_mixer = mixer_new(sources);
  sl = g_slist_append(sl, left_mixer);
  mixer_set_amplitude(left_mixer,MIX_MAX_AMP/4,KICK_INDEX);
  mixer_set_amplitude(left_mixer,MIX_MAX_AMP/4,SNARE_INDEX);
  mixer_set_amplitude(left_mixer,MIX_MAX_AMP/4,CL_HAT_INDEX);
  mixer_set_amplitude(left_mixer,MIX_MAX_AMP/4,OP_HAT_INDEX);
  mixer_set_amplitude(left_mixer,MIX_MAX_AMP/4,SAMP1_INDEX);
  mixer_set_amplitude(left_mixer,MIX_MAX_AMP/4,BASS_INDEX);
  mixer_set_amplitude(left_mixer,MIX_MAX_AMP/4,6);
  mixer_set_amplitude(left_mixer,MIX_MAX_AMP/4,7);
  
  right_mixer = mixer_new(sources);
  sl = g_slist_append(sl, right_mixer);
  mixer_set_amplitude(right_mixer,MIX_MAX_AMP/4,KICK_INDEX);
  mixer_set_amplitude(right_mixer,MIX_MAX_AMP/4,SNARE_INDEX);
  mixer_set_amplitude(right_mixer,MIX_MAX_AMP/4,CL_HAT_INDEX);
  mixer_set_amplitude(right_mixer,MIX_MAX_AMP/4,OP_HAT_INDEX);
  mixer_set_amplitude(right_mixer,MIX_MAX_AMP/4,SAMP1_INDEX);
  mixer_set_amplitude(right_mixer,MIX_MAX_AMP/4,BASS_INDEX);
  mixer_set_amplitude(right_mixer,MIX_MAX_AMP/4,6);
  mixer_set_amplitude(right_mixer,MIX_MAX_AMP/4,7);
  
  sequencer = seq_new(NUM_STEPS,120,EIGHTH_NOTE,sequencer_step_callback);
  bass_saw_event_handle   = seq_register_victim(sequencer,
						(sample_producer *)bass_saw);
  bass_sqr_event_handle   = seq_register_victim(sequencer,
						(sample_producer *)bass_sqr);
  bass_sin_event_handle   = seq_register_victim(sequencer,
						(sample_producer *)bass_sin);
  bass_env_event_handle   = seq_register_victim(sequencer,
						(sample_producer *)bass_e);
  filter_env_event_handle = seq_register_victim(sequencer,
						(sample_producer *)filt_e);

  samp_handle[KICK_INDEX] = seq_register_victim(sequencer,
						(sample_producer *)kick);
  samp_handle[SNARE_INDEX] = seq_register_victim(sequencer,
						 (sample_producer *)snare);
  samp_handle[CL_HAT_INDEX] = seq_register_victim(sequencer,
						  (sample_producer *)cl_hat);
  samp_handle[OP_HAT_INDEX] = seq_register_victim(sequencer,
						  (sample_producer *)op_hat);
  samp_handle[SAMP1_INDEX] = seq_register_victim(sequencer,
						   (sample_producer *)samp_1);

}


GtkStyle *create_style (GdkColor fg, 
			GdkColor text, 
			GdkColor bg,
			GdkPixmap *pixmap)
{
    GtkStyle *defstyle;
    GtkStyle *style;
    int i;

    /* --- Get the default style --- */
    defstyle = gtk_widget_get_default_style ();

    /* --- Make a copy of it. --- */
    style = gtk_style_copy (defstyle);

    /* --- Set the colors for each state --- */
    for (i = 0; i < 5; i++) {

        /* --- Set the colors for the style --- */
        style->fg[i] = fg;
        style->text[i] = text;
        style->bg[i] = bg;
	style->bg_pixmap[i] = pixmap;
    }

    /* --- All done, here's new style --- */
    return (style);
}

/* this should maybe go somewhere else */
typedef struct panner_model {
  int channel;
  int volume;
  int pan;
} panner_model;

panner_model *panner_model_new(int channel, int volume, int pan) {
  panner_model *out = (panner_model *)malloc(sizeof(panner_model));
  out->channel = channel;
  out->volume = volume;
  out->pan = pan;
  return out;
}

void init_interface(int argc, char* argv[])
{
 
  int i;

  GtkWidget *window;
  GtkWidget *effect_window;
  GtkWidget *sample_freq_window;
  GtkWidget *sample_freq_box;
  GtkWidget *effect_box;
  GtkWidget *dly_panel;
  GtkWidget *rvb_panel;
  GtkWidget *samp_freq_strip;
  GtkWidget *button;
  GtkWidget *sample_box;
  GtkWidget *step_box;
  GtkWidget *led_box;

  GtkWidget *app_box;
  GtkWidget *seq_box;
  GtkWidget *mix_box;
  GtkWidget *mix_seq_box;
  GtkWidget *filter_box;
  GtkWidget *control_box;
  GtkWidget *separator;
  GtkWidget *table;
  GtkWidget *freq_select_box;
  GtkObject *slider_range;
  GtkWidget *scroll_bar;
  GtkObject *spin_range;
  GtkWidget *spin_display;
  GtkWidget *dial;
  GtkObject *dial_range;
  GtkWidget *label;


  GtkWidget *pmap;
  GdkPixmap *pixmap;
  GdkBitmap *mask;
  GtkStyle  *pixmap_style;
  

  GdkColor red          = {0, 0xffff, 0x0000, 0x0000};
  GdkColor light_blue   = {0, 0x0000, 0x0000, 0x9999};
  GdkColor green        = {0, 0x0000, 0xffff, 0x0000};
  GdkColor yellow       = {0, 0xffff, 0xffff, 0x0000};
  GdkColor purple       = {0, 0xffff, 0x0000, 0xffff};
  GdkColor orange       = {0, 0xffff, 0x9999, 0x0000};
  GdkColor cyan         = {0, 0x0000, 0xffff, 0xffff};
  GdkColor black        = {0, 0x0000, 0x0000, 0x0000};
  GdkColor dark_grey    = {0, 0xaaaa, 0xaaaa, 0xaaaa};
  GdkColor white        = {0, 0xffff, 0xffff, 0xffff};
    
  gtk_init(&argc,&argv);

  gdk_color_alloc (gdk_colormap_get_system (), &red);
  gdk_color_alloc (gdk_colormap_get_system (), &light_blue);
  gdk_color_alloc (gdk_colormap_get_system (), &green);
  gdk_color_alloc (gdk_colormap_get_system (), &yellow);
  gdk_color_alloc (gdk_colormap_get_system (), &purple);
  gdk_color_alloc (gdk_colormap_get_system (), &orange);
  gdk_color_alloc (gdk_colormap_get_system (), &cyan);
  gdk_color_alloc (gdk_colormap_get_system (), &black);
  gdk_color_alloc (gdk_colormap_get_system (), &white);
  gdk_color_alloc (gdk_colormap_get_system (), &dark_grey);

  /* make interface style elements */
  window_style  = create_style(white,white,dark_grey, NULL);
  ia_step_style = create_style(orange,black,light_blue, NULL);
  a_step_style  = create_style(orange,black,red, NULL);
  slider_style  = create_style(orange,black,dark_grey, NULL);
  dial_style    = create_style(black,white,dark_grey, NULL);
  label_style   = create_style(orange,black,black, NULL);


  window = gtk_window_new (GTK_WINDOW_TOPLEVEL);

  gtk_widget_realize(window);


  gtk_widget_set_style(window,window_style);
  gtk_window_set_title(GTK_WINDOW (window), "FREEBIRTH  v0.3.2");
  gtk_signal_connect( GTK_OBJECT (window), "delete_event",
		      GTK_SIGNAL_FUNC(delete_event), NULL);
  gtk_container_border_width(GTK_CONTAINER (window), 20);


  
  pixmap_style = gtk_widget_get_style(window);
    

  seq_box = gtk_vbox_new(FALSE,10);
  for (i=0; i < NUM_SAMPLES; i++) {
    int j;
    /*make sample box*/
    sample_box = gtk_hbox_new(TRUE,10);
    for(j = 0; j < NUM_STEPS; j++)
      {
	event_bookeeper *eb = e_bookeeper_new(j, samp_handle[i]);
	button = gtk_toggle_button_new_with_label("  ");
	gtk_widget_set_usize(button,15,12);
	gtk_toggle_button_set_state(GTK_TOGGLE_BUTTON(button),0);
	gtk_signal_connect(GTK_OBJECT (button), "toggled",
			   GTK_SIGNAL_FUNC (sample_step_callback),
			   (gpointer)eb );
	gtk_box_pack_start(GTK_BOX(sample_box),button,FALSE,FALSE,SEQ_SPACING);
	if((j + 1) % 4 == 0 && j != NUM_STEPS - 1)
	{
	  GtkWidget *sep = gtk_vseparator_new();
	  gtk_box_pack_start(GTK_BOX(sample_box),sep,FALSE,FALSE,0);
	  gtk_widget_show(sep);
	}
	/*      gtk_widget_set_style(button,ia_step_style); */
	gtk_widget_show(button);
      }
    gtk_widget_show(sample_box);
    gtk_box_pack_start(GTK_BOX(seq_box),sample_box,FALSE,FALSE,0);
  }

  /* make box for freq sliders */
  freq_select_box = gtk_hbox_new(TRUE,10);

  for(i = 0; i < NUM_STEPS; i++)
    {

      event_bookeeper *eb = e_bookeeper_new(i, 0);

      slider_range =  gtk_adjustment_new(155.0,0.0,155.0,1.0,1,1.0);
      scroll_bar = gtk_vscrollbar_new(GTK_ADJUSTMENT(slider_range));
      gtk_signal_connect (GTK_OBJECT (slider_range), "value_changed",
			  GTK_SIGNAL_FUNC (freq_callback), (gpointer)eb );

      freq_callback(GTK_ADJUSTMENT(slider_range),(gpointer)eb);
      gtk_box_pack_start(GTK_BOX(freq_select_box),scroll_bar,FALSE,FALSE,
			 SEQ_SPACING);
      if((i + 1) % 4 == 0 && i != NUM_STEPS - 1)
	{
	  GtkWidget *sep = gtk_vseparator_new();
	  gtk_box_pack_start(GTK_BOX(freq_select_box),
			     sep,FALSE,FALSE,0);
	  gtk_widget_show(sep);
	}

      gtk_widget_set_style(scroll_bar,slider_style);
      gtk_widget_show(scroll_bar);
    }
    
  /* make step toggle switches box*/  
  step_box = gtk_hbox_new(TRUE,10);
  for(i = 0; i < NUM_STEPS; i++)
    {
      event_bookeeper *eb = e_bookeeper_new(i, 0);
      button = gtk_toggle_button_new_with_label("  ");
      gtk_toggle_button_set_state(GTK_TOGGLE_BUTTON(button),0);
      gtk_signal_connect (GTK_OBJECT (button), "toggled",
		       GTK_SIGNAL_FUNC (step_callback), (gpointer)eb );
      gtk_box_pack_start(GTK_BOX(step_box),button,FALSE,FALSE,SEQ_SPACING);
      if((i + 1) % 4 == 0 && i != NUM_STEPS - 1)
	{
	  GtkWidget *sep = gtk_vseparator_new();
	  gtk_box_pack_start(GTK_BOX(step_box),
			     sep,FALSE,FALSE,SEQ_SPACING);
	  gtk_widget_show(sep);
	}

      gtk_widget_set_style(button,ia_step_style);
      step_btn_addr[i] = button;
      gtk_widget_show(button);
    }


  /*make led box */
  led_box = gtk_hbox_new(TRUE,10);



  a_led = gdk_pixmap_create_from_xpm_d( window->window,  &mask,
				  &pixmap_style->bg[GTK_STATE_NORMAL],
					 (gchar **)active_led_xpm );
  i_led = gdk_pixmap_create_from_xpm_d( window->window,  &mask,
				   &pixmap_style->bg[GTK_STATE_NORMAL],
					(gchar **)iactive_led_xpm );

  for(i = 0; i < 16; i++)
    {
      pmap = gtk_pixmap_new( i_led, mask );
      gtk_container_add(GTK_CONTAINER(led_box),pmap);
      if((i + 1) % 4 == 0 && i != 15)
	{
	  GtkWidget *sep = gtk_vseparator_new();
	  gtk_box_pack_start(GTK_BOX(led_box),
			     sep,FALSE,FALSE,SEQ_SPACING);
	  gtk_widget_show(sep);
	}

      step_led_addr[i] = pmap;
      gtk_widget_show(pmap);
    }
  /*make 1st step ready and waiting */
  sequencer_step_callback(0);


  /* make mix box */
  mix_box = gtk_hbox_new(TRUE,0);
  table  = gtk_table_new(8,9,FALSE);

  pixmap = gdk_pixmap_create_from_xpm_d( window->window,  &mask,
					 &pixmap_style->bg[GTK_STATE_NORMAL],
					 (gchar **)mixer_xpm );
  pmap = gtk_pixmap_new( pixmap, mask );
  gtk_table_attach(GTK_TABLE(table),pmap,1,6,0,2,0,0,3,0);
  gtk_widget_show(pmap);

  for (i=0; i<NUM_SAMPLES+1; i++) {
    panner_model *pm = panner_model_new(i, MIX_MAX_AMP / 4, 0);

    /*aux 1*/
    dial_range =  gtk_adjustment_new(0,0,MIX_MAX_AMP ,10,10,10.0);
    dial       = gtk_dial_new(GTK_ADJUSTMENT(dial_range));
    gtk_signal_connect (GTK_OBJECT (dial_range), "value_changed",
			GTK_SIGNAL_FUNC (aux_1_callback), 
			(gpointer)i);
    gtk_table_attach(GTK_TABLE(table),dial,i+1,i+2,2,3,0,0,3,0);
    gtk_widget_set_usize(dial,20,20);
    gtk_widget_set_style(dial,dial_style);
    gtk_widget_show(dial);

    /*aux 2*/
    dial_range =  gtk_adjustment_new(0,0,MIX_MAX_AMP ,1,1,1);
    dial       = gtk_dial_new(GTK_ADJUSTMENT(dial_range));
    gtk_signal_connect (GTK_OBJECT (dial_range), "value_changed",
			GTK_SIGNAL_FUNC (aux_2_callback), 
			(gpointer)i);
    gtk_table_attach(GTK_TABLE(table),dial,i+1,i+2,3,4,0,0,3,0);
    gtk_widget_set_usize(dial,20,20);
    gtk_widget_set_style(dial,dial_style);
    gtk_widget_show(dial);

    /* panner */
    dial_range =  gtk_adjustment_new(0,-MIX_MAX_AMP,MIX_MAX_AMP, 10, 10, 10.0);
    dial       = gtk_dial_new(GTK_ADJUSTMENT(dial_range));
    gtk_signal_connect (GTK_OBJECT (dial_range), "value_changed",
			GTK_SIGNAL_FUNC (panner_callback), 
			(gpointer)pm);
    gtk_table_attach(GTK_TABLE(table),dial,i+1,i+2,4,5,0,0,3,0);
    gtk_widget_set_usize(dial,20,20);
    gtk_widget_set_style(dial,dial_style);
    gtk_widget_show(dial);

    /* fader */
    slider_range =  gtk_adjustment_new(3 * MIX_MAX_AMP/4,0,MIX_MAX_AMP  
				       ,10,10,10.0);
    scroll_bar   = gtk_vscrollbar_new(GTK_ADJUSTMENT(slider_range));
    gtk_signal_connect (GTK_OBJECT (slider_range), "value_changed",
			GTK_SIGNAL_FUNC (mixer_callback), 
			(gpointer)pm);
    gtk_table_attach(GTK_TABLE(table),scroll_bar,i+1,i+2,5,7,0,0,3,0);
    gtk_widget_set_usize(scroll_bar,15,100);
    gtk_widget_show(scroll_bar);

    pixmap = gdk_pixmap_create_from_xpm_d( window->window,  &mask,
					   &pixmap_style->bg[GTK_STATE_NORMAL],
					   (gchar **)xpms[i]);
    pmap = gtk_pixmap_new( pixmap, mask );
    gtk_table_attach(GTK_TABLE(table),pmap,i+1,i+2,7,8,0,0,3,0);
    gtk_widget_show(pmap);
 
    button = gtk_toggle_button_new_with_label("M");
    gtk_widget_set_usize(button,12,10);
    gtk_signal_connect(GTK_OBJECT (button), "toggled",
		       GTK_SIGNAL_FUNC (mixer_mute_callback),
		       (gpointer)i );
    gtk_table_attach(GTK_TABLE(table),button,i+1,i+2,8,9,0,0,3,0);
    gtk_widget_show(button);
  }

  /* fader/panner for effects returns */
  for (i=6; i<8; i++) {
    panner_model *pm = panner_model_new(i, MIX_MAX_AMP / 4, 0);

    /* panner */
    dial_range =  gtk_adjustment_new(0,-MIX_MAX_AMP,MIX_MAX_AMP, 10, 10, 10.0);
    dial       = gtk_dial_new(GTK_ADJUSTMENT(dial_range));
    gtk_signal_connect (GTK_OBJECT (dial_range), "value_changed",
			GTK_SIGNAL_FUNC (panner_callback), 
			(gpointer)pm);
    gtk_table_attach(GTK_TABLE(table),dial,i+1,i+2,4,5,0,0,3,0);
    gtk_widget_set_usize(dial,20,20);
    gtk_widget_set_style(dial,dial_style);
    gtk_widget_show(dial);

    /* fader */
    slider_range =  gtk_adjustment_new(3 * MIX_MAX_AMP/4,0,MIX_MAX_AMP  
				       ,10,10,10.0);
    scroll_bar   = gtk_vscrollbar_new(GTK_ADJUSTMENT(slider_range));
    gtk_signal_connect (GTK_OBJECT (slider_range), "value_changed",
			GTK_SIGNAL_FUNC (mixer_callback), 
			(gpointer)pm);
    gtk_table_attach(GTK_TABLE(table),scroll_bar,i+1,i+2,5,7,0,0,3,0);
    gtk_widget_set_usize(scroll_bar,15,100);
    gtk_widget_show(scroll_bar);
  }

  /*attach table to mix_box */
  gtk_widget_show(table);
  gtk_container_add(GTK_CONTAINER(mix_box),table);


  /* make control box */
  control_box = gtk_hbox_new(TRUE,0);
  table  = gtk_table_new(5,10,FALSE);


  /*bpm counter*/
  spin_range = gtk_adjustment_new(120,60,360,1,1,1);
  spin_display = gtk_spin_button_new(GTK_ADJUSTMENT(spin_range),1,0);
  gtk_signal_connect (GTK_OBJECT (spin_range), "value_changed",
		      GTK_SIGNAL_FUNC (bpm_callback), (gpointer)i );
  gtk_table_attach(GTK_TABLE(table),spin_display,0,1,0,1,0,0,3,0);
  gtk_widget_show(spin_display);  

  label = gtk_label_new("BPM");
  gtk_table_attach(GTK_TABLE(table),label,0,1,1,2,0,0,3,0);
  gtk_widget_show(label);  

  /*start button*/
  button = gtk_button_new();
  gtk_signal_connect (GTK_OBJECT (button), "clicked",
		      GTK_SIGNAL_FUNC (play_callback), NULL );
  gtk_table_attach(GTK_TABLE(table),button,1,2,0,1,0,0,3,0);
  pixmap = gdk_pixmap_create_from_xpm_d( window->window,  &mask,
				  &pixmap_style->bg[GTK_STATE_NORMAL],
					 (gchar **)play_xpm );
  pmap = gtk_pixmap_new( pixmap, mask );
  gtk_container_add(GTK_CONTAINER(button),pmap);
  gtk_widget_show(pmap);
  gtk_widget_show(button);

  /*stop button*/
  button = gtk_button_new();
  gtk_signal_connect (GTK_OBJECT (button), "clicked",
		      GTK_SIGNAL_FUNC (stop_callback), NULL );
  gtk_table_attach(GTK_TABLE(table),button,1,2,1,2,0,0,3,0);
  pixmap = gdk_pixmap_create_from_xpm_d( window->window,  &mask,
				  &pixmap_style->bg[GTK_STATE_NORMAL],
					 (gchar **)pause_xpm );
  pmap = gtk_pixmap_new( pixmap, mask );
  gtk_container_add(GTK_CONTAINER(button),pmap);
  gtk_widget_show(pmap);
  gtk_widget_show(button);
  
  /* envelope attack */
  dial_range =  gtk_adjustment_new(1025,512,44000,100,10,10.0);
  dial       = gtk_dial_new(GTK_ADJUSTMENT(dial_range));
  gtk_signal_connect (GTK_OBJECT (dial_range), "value_changed",
		      GTK_SIGNAL_FUNC (env_attack_callback), (gpointer)bass_e);
  gtk_table_attach(GTK_TABLE(table),dial,0,1,3,4,0,0,3,0);
  gtk_widget_set_style(dial,dial_style);
  gtk_widget_show(dial);



  /*env release pixmap */
  pixmap = gdk_pixmap_create_from_xpm_d( window->window,  &mask,
					 &pixmap_style->bg[GTK_STATE_NORMAL],
					 (gchar **)amp_attack_xpm );
  pmap = gtk_pixmap_new( pixmap, mask );
  gtk_table_attach(GTK_TABLE(table),pmap,1,2,3,4,0,0,3,0);
  gtk_widget_show(pmap);

  /* envelope release */
  dial_range =  gtk_adjustment_new(11025,2205,90000,100,10,10.0);
  dial       = gtk_dial_new(GTK_ADJUSTMENT(dial_range));
  gtk_signal_connect (GTK_OBJECT (dial_range), "value_changed",
		      GTK_SIGNAL_FUNC(env_release_callback), (gpointer)bass_e);
  gtk_table_attach(GTK_TABLE(table),dial,0,1,4,5,0,0,3,0);
    gtk_widget_set_style(dial,dial_style);
  gtk_widget_show(dial);


  /*env release pixmap */
  pixmap = gdk_pixmap_create_from_xpm_d( window->window,  &mask,
					 &pixmap_style->bg[GTK_STATE_NORMAL],
					 (gchar **)amp_release_xpm );
  pmap = gtk_pixmap_new( pixmap, mask );
  gtk_table_attach(GTK_TABLE(table),pmap,1,2,4,5,0,0,3,0);
  gtk_widget_show(pmap);

  /* saw pixmap */
  pixmap = gdk_pixmap_create_from_xpm_d( window->window,  &mask,
					 &pixmap_style->bg[GTK_STATE_NORMAL],
					 (gchar **)saw_xpm );
  pmap = gtk_pixmap_new( pixmap, mask );
  gtk_table_attach(GTK_TABLE(table),pmap,2,3,2,3,0,0,3,0);
  gtk_widget_show(pmap);

  /* sqr pixmap */
  pixmap = gdk_pixmap_create_from_xpm_d( window->window,  &mask,
					 &pixmap_style->bg[GTK_STATE_NORMAL],
					 (gchar **)sqr_xpm );
  pmap = gtk_pixmap_new( pixmap, mask );
  gtk_table_attach(GTK_TABLE(table),pmap,2,3,3,4,0,0,3,0);
  gtk_widget_show(pmap);

  /* sin pixmap */
  pixmap = gdk_pixmap_create_from_xpm_d( window->window,  &mask,
					 &pixmap_style->bg[GTK_STATE_NORMAL],
					 (gchar **)sin_xpm );
  pmap = gtk_pixmap_new( pixmap, mask );
  gtk_table_attach(GTK_TABLE(table),pmap,2,3,4,5,0,0,3,0);
  gtk_widget_show(pmap);

  /* saw level */
  dial_range =  gtk_adjustment_new(MIX_MAX_AMP,MIX_MIN_AMP,MIX_MAX_AMP,1,1,1);
  dial       = gtk_dial_new(GTK_ADJUSTMENT(dial_range));
  gtk_signal_connect (GTK_OBJECT (dial_range), "value_changed",
		     GTK_SIGNAL_FUNC (saw_amp_callback), (gpointer)i );
  gtk_table_attach(GTK_TABLE(table),dial,3,4,2,3,0,0,3,0);
  gtk_widget_set_style(dial,dial_style);
  gtk_widget_show(dial);

  /*saw level pixmap */
  pixmap = gdk_pixmap_create_from_xpm_d( window->window,  &mask,
					 &pixmap_style->bg[GTK_STATE_NORMAL],
					 (gchar **)blend_xpm );
  pmap = gtk_pixmap_new( pixmap, mask );
  gtk_table_attach(GTK_TABLE(table),pmap,4,5,2,3,0,0,3,0);
  gtk_widget_show(pmap);

  /* sqr level */
  dial_range =  gtk_adjustment_new(MIX_MIN_AMP,MIX_MIN_AMP,MIX_MAX_AMP,1,1,1);
  dial       = gtk_dial_new(GTK_ADJUSTMENT(dial_range));
  gtk_signal_connect (GTK_OBJECT (dial_range), "value_changed",
		     GTK_SIGNAL_FUNC (sqr_amp_callback), (gpointer)i );
  gtk_table_attach(GTK_TABLE(table),dial,3,4,3,4,0,0,3,0);
  gtk_widget_set_style(dial,dial_style);
  gtk_widget_show(dial);

  /*sqr level pixmap */
  pmap = gtk_pixmap_new( pixmap, mask );
  gtk_table_attach(GTK_TABLE(table),pmap,4,5,3,4,0,0,3,0);
  gtk_widget_show(pmap);

  /* sin level */
  dial_range =  gtk_adjustment_new(MIX_MIN_AMP,MIX_MIN_AMP,MIX_MAX_AMP,1,1,1);
  dial       = gtk_dial_new(GTK_ADJUSTMENT(dial_range));
  gtk_signal_connect (GTK_OBJECT (dial_range), "value_changed",
		     GTK_SIGNAL_FUNC (sin_amp_callback), (gpointer)i );
  gtk_table_attach(GTK_TABLE(table),dial,3,4,4,5,0,0,3,0);
  gtk_widget_set_style(dial,dial_style);
  gtk_widget_show(dial);

  /*sin level pixmap */
  pmap = gtk_pixmap_new( pixmap, mask );
  gtk_table_attach(GTK_TABLE(table),pmap,4,5,4,5,0,0,3,0);
  gtk_widget_show(pmap);

  /*saw phase*/
  dial_range =  gtk_adjustment_new(0,0,22050,1,1,1);
  dial       = gtk_dial_new(GTK_ADJUSTMENT(dial_range));
  gtk_signal_connect (GTK_OBJECT (dial_range), "value_changed",
		  GTK_SIGNAL_FUNC (saw_phase_callback), (gpointer)i );
  gtk_table_attach(GTK_TABLE(table),dial,5,6,2,3,0,0,3,0);
  gtk_widget_set_style(dial,dial_style);
  gtk_widget_show(dial);

  /*saw phase pixmap */
  pixmap = gdk_pixmap_create_from_xpm_d( window->window,  &mask,
					 &pixmap_style->bg[GTK_STATE_NORMAL],
					(gchar **)phase_xpm );
  pmap = gtk_pixmap_new( pixmap, mask );
  gtk_table_attach(GTK_TABLE(table),pmap,6,7,2,3,0,0,3,0);
  gtk_widget_show(pmap);

  /*sqr phase*/
  dial_range =  gtk_adjustment_new(0,0,22050,1,1,1);
  dial       = gtk_dial_new(GTK_ADJUSTMENT(dial_range));
  gtk_signal_connect (GTK_OBJECT (dial_range), "value_changed",
		  GTK_SIGNAL_FUNC (sqr_phase_callback), (gpointer)i );
  gtk_table_attach(GTK_TABLE(table),dial,5,6,3,4,0,0,3,0);
  gtk_widget_set_style(dial,dial_style);
  gtk_widget_show(dial);

  /*sqr phae pixmap */
  pmap = gtk_pixmap_new( pixmap, mask );
  gtk_table_attach(GTK_TABLE(table),pmap,6,7,3,4,0,0,3,0);
  gtk_widget_show(pmap);


  /*sin phase*/
  dial_range =  gtk_adjustment_new(0,0,22050,1,1,1);
  dial       = gtk_dial_new(GTK_ADJUSTMENT(dial_range));
  gtk_signal_connect (GTK_OBJECT (dial_range), "value_changed",
		  GTK_SIGNAL_FUNC (sin_phase_callback), (gpointer)i );
  gtk_table_attach(GTK_TABLE(table),dial,5,6,4,5,0,0,3,0);
  gtk_widget_set_style(dial,dial_style);
  gtk_widget_show(dial);

  /*sin phase pixmap */
  pmap = gtk_pixmap_new( pixmap, mask );
  gtk_table_attach(GTK_TABLE(table),pmap,6,7,4,5,0,0,3,0);
  gtk_widget_show(pmap);

  /*saw freq offset*/
  dial_range =  gtk_adjustment_new(0,0,MAX_FREQ_OFFSET,1,1,1);
  dial       = gtk_dial_new(GTK_ADJUSTMENT(dial_range));
  gtk_signal_connect (GTK_OBJECT (dial_range), "value_changed",
		  GTK_SIGNAL_FUNC (saw_freq_offset_callback), (gpointer)i );
  gtk_table_attach(GTK_TABLE(table),dial,7,8,2,3,0,0,3,0);
  gtk_widget_set_style(dial,dial_style);
  gtk_widget_show(dial);

  /*saw phase pixmap */
  pixmap = gdk_pixmap_create_from_xpm_d( window->window,  &mask,
					 &pixmap_style->bg[GTK_STATE_NORMAL],
					(gchar **)freq_xpm );
  pmap = gtk_pixmap_new( pixmap, mask );
  gtk_table_attach(GTK_TABLE(table),pmap,8,9,2,3,0,0,3,0);
  gtk_widget_show(pmap);


  /*sqr freq offset*/
  dial_range =  gtk_adjustment_new(0,0,MAX_FREQ_OFFSET,1,1,1);
  dial       = gtk_dial_new(GTK_ADJUSTMENT(dial_range));
  gtk_signal_connect (GTK_OBJECT (dial_range), "value_changed",
		  GTK_SIGNAL_FUNC (sqr_freq_offset_callback), (gpointer)i );
  gtk_table_attach(GTK_TABLE(table),dial,7,8,3,4,0,0,3,0);
  gtk_widget_set_style(dial,dial_style);
  gtk_widget_show(dial);

  /*sqr freq pixmap */
  pmap = gtk_pixmap_new( pixmap, mask );
  gtk_table_attach(GTK_TABLE(table),pmap,8,9,3,4,0,0,3,0);
  gtk_widget_show(pmap);

  /*sin freq offset*/
  dial_range =  gtk_adjustment_new(0,0,MAX_FREQ_OFFSET,1,1,1);
  dial       = gtk_dial_new(GTK_ADJUSTMENT(dial_range));
  gtk_signal_connect (GTK_OBJECT (dial_range), "value_changed",
		  GTK_SIGNAL_FUNC (sin_freq_offset_callback), (gpointer)i );
  gtk_table_attach(GTK_TABLE(table),dial,7,8,4,5,0,0,3,0);
  gtk_widget_set_style(dial,dial_style);
  gtk_widget_show(dial);

  /*sqr freq pixmap */
  pmap = gtk_pixmap_new( pixmap, mask );
  gtk_table_attach(GTK_TABLE(table),pmap,8,9,4,5,0,0,3,0);
  gtk_widget_show(pmap);


  filter_box = gtk_hbox_new(FALSE,10);

  /* tmp q */
  dial_range =  gtk_adjustment_new( MIN_Q +(Q_INCREMENT * 10)
				   ,MIN_Q, MAX_Q - MIN_Q - 1,Q_INCREMENT,
				   Q_INCREMENT, Q_INCREMENT);
  dial = gtk_dial_new(GTK_ADJUSTMENT(dial_range));
  gtk_signal_connect (GTK_OBJECT (dial_range), "value_changed",
		      GTK_SIGNAL_FUNC (q_callback), (gpointer)i );
  gtk_box_pack_start(GTK_BOX(filter_box),dial,FALSE,FALSE,0);
  /*  gtk_table_attach(GTK_TABLE(table),dial,2,3,0,1,0,0,3,0); */
  gtk_widget_set_style(dial,dial_style);
  gtk_widget_show(dial);


  /* q label */
  pixmap = gdk_pixmap_create_from_xpm_d( window->window,  &mask,
					 &pixmap_style->bg[GTK_STATE_NORMAL],
					 (gchar **)q_xpm );
  pmap = gtk_pixmap_new( pixmap, mask );
  gtk_box_pack_start(GTK_BOX(filter_box),pmap,FALSE,FALSE,0);
  /*  gtk_table_attach(GTK_TABLE(table),pmap,3,4,0,1,0,0,3,0); */
  gtk_widget_show(pmap);

  /* tmp cutoff*/
  dial_range =  gtk_adjustment_new(2000,20,MAX_FC - MIN_FC-  1,1,1,1);
  dial = gtk_dial_new(GTK_ADJUSTMENT(dial_range));
  gtk_signal_connect (GTK_OBJECT (dial_range), "value_changed",
		      GTK_SIGNAL_FUNC (cutoff_callback), (gpointer)i );
  gtk_box_pack_start(GTK_BOX(filter_box),dial,FALSE,FALSE,3);
  /*  gtk_table_attach(GTK_TABLE(table),dial,4,5,0,1,0,0,3,0); */
  gtk_widget_set_style(dial,dial_style);
  gtk_widget_show(dial);

  /*cutoff pixmap */
  pixmap = gdk_pixmap_create_from_xpm_d( window->window,  &mask,
					 &pixmap_style->bg[GTK_STATE_NORMAL],
					 (gchar **)cutoff_xpm );
  pmap = gtk_pixmap_new( pixmap, mask );
  gtk_box_pack_start(GTK_BOX(filter_box),pmap,FALSE,FALSE,0);
  /*  gtk_table_attach(GTK_TABLE(table),pmap,5,7,0,1,0,0,3,0); */
  gtk_widget_show(pmap);



  /* tmp filt attack*/
  dial_range =  gtk_adjustment_new(1024,1024,22050,1,10,10.0);
  dial = gtk_dial_new(GTK_ADJUSTMENT(dial_range));
  gtk_signal_connect (GTK_OBJECT (dial_range), "value_changed",
		      GTK_SIGNAL_FUNC(env_attack_callback), (gpointer)filt_e);
  gtk_box_pack_start(GTK_BOX(filter_box),dial,FALSE,FALSE,0);
  /*  gtk_table_attach(GTK_TABLE(table),dial,7,8,0,1,0,0,3,0); */
  gtk_widget_set_style(dial,dial_style);
  gtk_widget_show(dial);


  /*attack pixmap */
  pixmap = gdk_pixmap_create_from_xpm_d( window->window,  &mask,
					 &pixmap_style->bg[GTK_STATE_NORMAL],
					 (gchar **)attack_xpm );
  pmap = gtk_pixmap_new( pixmap, mask );
  gtk_box_pack_start(GTK_BOX(filter_box),pmap,FALSE,FALSE,0);
  /*  gtk_table_attach(GTK_TABLE(table),pmap,8,9,0,1,0,0,3,0); */
  gtk_widget_show(pmap);


  /* tmp filt release*/
  dial_range =  gtk_adjustment_new(22050,5000,90000,1,10,10.0);
  dial = gtk_dial_new(GTK_ADJUSTMENT(dial_range));
  gtk_signal_connect (GTK_OBJECT (dial_range), "value_changed",
		      GTK_SIGNAL_FUNC(env_release_callback), (gpointer)filt_e);
  gtk_box_pack_start(GTK_BOX(filter_box),dial,FALSE,FALSE,0);
  /*  gtk_table_attach(GTK_TABLE(table),dial,9,10,0,1,0,0,3,0); */
  gtk_widget_set_style(dial,dial_style);
  gtk_widget_show(dial);

  /*release pixmap */
  pixmap = gdk_pixmap_create_from_xpm_d( window->window,  &mask,
					 &pixmap_style->bg[GTK_STATE_NORMAL],
					 (gchar **)release_xpm );
  pmap = gtk_pixmap_new( pixmap, mask );
  gtk_box_pack_start(GTK_BOX(filter_box),pmap,FALSE,FALSE,0);
  /*  gtk_table_attach(GTK_TABLE(table),pmap,10,11,0,1,0,0,3,0); */
  gtk_widget_show(pmap);
  
  gtk_widget_show(filter_box);
  gtk_table_attach(GTK_TABLE(table),filter_box,2,10,0,1,0,0,3,0);
  /* freebirth pixmap */
  pixmap = gdk_pixmap_create_from_xpm_d( window->window,  &mask,
					 &pixmap_style->bg[GTK_STATE_NORMAL],
					 (gchar **)freebirth_xpm );
  pmap = gtk_pixmap_new( pixmap, mask );
  gtk_table_attach(GTK_TABLE(table),pmap,9,10,1,5,0,0,3,0); 
  gtk_widget_show(pmap);

 

 
  /*attach table to control_box */
  gtk_widget_show(table);
  gtk_container_add(GTK_CONTAINER(control_box),table);

  
  /*put it all together */

  app_box = gtk_vbox_new(FALSE,10);

  gtk_box_pack_start(GTK_BOX(seq_box),freq_select_box,FALSE,FALSE,0);
  gtk_box_pack_start(GTK_BOX(seq_box),step_box,FALSE,FALSE,0);
  gtk_box_pack_start(GTK_BOX(seq_box),led_box,FALSE,FALSE,0);

  mix_seq_box = gtk_hbox_new(FALSE,10);
  gtk_box_pack_start(GTK_BOX(mix_seq_box),seq_box,FALSE,FALSE,0);
  separator = gtk_vseparator_new();
  gtk_widget_show(separator);
  gtk_box_pack_start(GTK_BOX(mix_seq_box),separator,FALSE,FALSE,2);
  gtk_box_pack_start(GTK_BOX(mix_seq_box),mix_box,FALSE,FALSE,0);

  gtk_box_pack_start(GTK_BOX(app_box),mix_seq_box,FALSE,FALSE,0);
  separator = gtk_hseparator_new();
  gtk_widget_show(separator);
  gtk_box_pack_start(GTK_BOX(app_box),separator,FALSE,FALSE,0);
  gtk_box_pack_start(GTK_BOX(app_box),control_box,FALSE,FALSE,0);
  
  gtk_container_add(GTK_CONTAINER (window), app_box);
  gtk_window_set_policy(GTK_WINDOW(window),0,0,1);

  gtk_widget_show(led_box);
  gtk_widget_show(mix_box);
  gtk_widget_show(seq_box);
  gtk_widget_show(mix_seq_box);
  gtk_widget_show(step_box);
  gtk_widget_show(freq_select_box);
  gtk_widget_show(control_box);
  gtk_widget_show(app_box);

  

  /*effect window */
  effect_window = gtk_window_new (GTK_WINDOW_DIALOG);
  gtk_window_set_title(GTK_WINDOW (effect_window), "Effects");
  gtk_widget_set_style(effect_window,window_style);
  effect_box    = gtk_vbox_new(FALSE,10);

  dly_panel = delay_panel_new(eff_1,dial_style);
  gtk_container_add(GTK_CONTAINER(effect_box),dly_panel);
  gtk_widget_show(dly_panel);
  
  separator = gtk_hseparator_new();
  gtk_widget_show(separator);
  gtk_container_add(GTK_CONTAINER(effect_box),separator);

  rvb_panel = reverb_panel_new(eff_2,dial_style);
  gtk_container_add(GTK_CONTAINER(effect_box),rvb_panel);
  gtk_widget_show(rvb_panel);
  
  gtk_widget_show(effect_box);
  gtk_container_add((GTK_CONTAINER(effect_window)),effect_box);

  
  /* sample freq window */
  sample_freq_window = gtk_window_new (GTK_WINDOW_DIALOG);
  gtk_window_set_title(GTK_WINDOW (sample_freq_window), "Sample Pitch");
  sample_freq_box    = gtk_vbox_new(TRUE,10);
  gtk_widget_set_style(sample_freq_window,window_style);
  
  for(i = 0; i < NUM_SAMPLES;i++)
    {
      samp_freq_strip = sample_freq_strip_new(samp_handle[i], sequencer ,
					      NUM_STEPS, dial_style);
      gtk_container_add(GTK_CONTAINER(sample_freq_box),samp_freq_strip);
      gtk_widget_show(samp_freq_strip);
    }

  gtk_widget_show(sample_freq_box);
  gtk_container_add(GTK_CONTAINER(sample_freq_window),sample_freq_box);

  gtk_widget_show(window);
  gtk_widget_set_uposition(window,100,100);
  gtk_widget_set_uposition(sample_freq_window,200,500);
  gtk_window_position(GTK_WINDOW(effect_window),GTK_WIN_POS_MOUSE),
  gtk_widget_show(effect_window);
  gtk_widget_show(sample_freq_window);

  gtk_main();


}

  
void step_callback (GtkWidget *widget, gpointer data)
{

  event *env_trig;
  event *filt_env_trig;
  event_bookeeper *eb;

  eb = (event_bookeeper*)data;
  if(((GtkToggleButton *)widget)->active){

    env_trig      = event_new_trigger(bass_env_event_handle); 
    filt_env_trig = event_new_trigger(filter_env_event_handle); 

    seq_register_event(sequencer,eb->step,env_trig);
    seq_register_event(sequencer,eb->step,
		       filt_env_trig);


    event_list_add(eb->last_events, env_trig);
    event_list_add(eb->last_events, filt_env_trig);

    gtk_widget_set_style(step_btn_addr[eb->step],a_step_style);
    
  }
  else{
    clean_bookeeper((event_bookeeper *)data,sequencer);
    gtk_widget_set_style(step_btn_addr[eb->step],ia_step_style);
  }
}

void sample_step_callback (GtkWidget *widget, gpointer data)
{
  event *trig;
  event_bookeeper *eb;

  eb = (event_bookeeper*)data;
  if(((GtkToggleButton *)widget)->active){
    trig = event_new_trigger(eb->seq_handle); 
    seq_register_event(sequencer,eb->step, trig);
    event_list_add(eb->last_events, trig);
  }
  else
    clean_bookeeper(eb,sequencer);
}




void freq_callback (GtkAdjustment *adj, gpointer data)
{

  event *e1;
  event *e2;
  event *e3;
  event_bookeeper *eb;
  int value = 220 - adj->value; /* should do this in terms of #defines */

  e1 = event_freq_change_new(bass_saw_event_handle,value);
  e2 = event_freq_change_new(bass_sqr_event_handle,value);
  e3 = event_freq_change_new(bass_sin_event_handle,value);
  eb = (event_bookeeper*)data;
  if(eb != NULL)
    clean_bookeeper(eb,sequencer);

  seq_register_event(sequencer,eb->step,e1);
  seq_register_event(sequencer,eb->step,e2);
  seq_register_event(sequencer,eb->step,e3);

  event_list_add(eb->last_events, e1);
  event_list_add(eb->last_events, e2);
  event_list_add(eb->last_events, e3);
}

void env_attack_callback (GtkAdjustment *adj, gpointer data)
{

  env_set_attack((env *)data,(int)adj->value);

}

void env_release_callback (GtkAdjustment *adj, gpointer data)
{

 env_set_release((env *)data,(int)adj->value);

}


void bpm_callback(GtkAdjustment *adj, gpointer data)
{
  seq_set_bpm(sequencer,adj->value);

}

void cutoff_callback(GtkAdjustment *adj, gpointer data)
{
  filter_set_cutoff(bass_filt,(double)adj->value);

}

void q_callback(GtkAdjustment *adj, gpointer data)
{
  filter_set_q (bass_filt,(double)adj->value); 
}

void gain_callback(GtkAdjustment *adj, gpointer data)
{
  filter_set_gain (bass_filt,(double)adj->value); 
}

void delete_event (GtkWidget *widget, GdkEvent *event, gpointer data)
{

  gtk_main_quit();

}

void set_panner(panner_model *pm)
{
  if (pm->pan < 0) {
    mixer_set_amplitude(left_mixer, pm->volume, pm->channel);
    mixer_set_amplitude(right_mixer,
			pm->volume * (MIX_MAX_AMP + pm->pan) / MIX_MAX_AMP,
			pm->channel);
  }
  else if (pm->pan > 0) {
    mixer_set_amplitude(left_mixer,
			pm->volume * (MIX_MAX_AMP - pm->pan) / MIX_MAX_AMP,
			pm->channel);
    mixer_set_amplitude(right_mixer, pm->volume, pm->channel);
  }
  else {
    mixer_set_amplitude(left_mixer, pm->volume, pm->channel);
    mixer_set_amplitude(right_mixer, pm->volume, pm->channel);
  }
}

void mixer_callback(GtkAdjustment *adj, gpointer data)
{
  panner_model *pm = (panner_model *)data;
  pm->volume = MIX_MAX_AMP - adj->value;
  set_panner(pm);
}


void panner_callback(GtkAdjustment *adj, gpointer data)
{
  panner_model *pm = (panner_model *)data;
  pm->pan = adj->value;
  set_panner(pm);
}

void aux_1_callback(GtkAdjustment *adj, gpointer data)
{

  mixer_set_amplitude(aux_1,(int)adj->value,(int)data);

}


void aux_2_callback(GtkAdjustment *adj, gpointer data)
{
  mixer_set_amplitude(aux_2,(int)adj->value,(int)data);

}

void mixer_mute_callback(GtkWidget *widget, gpointer data)
{
  mixer_set_amplitude(left_mixer,MUTE_SWITCH,(int)data);
  mixer_set_amplitude(right_mixer,MUTE_SWITCH,(int)data);
  mixer_set_amplitude(aux_1,MUTE_SWITCH,(int)data);
  mixer_set_amplitude(aux_2,MUTE_SWITCH,(int)data);

}

void play_callback(GtkWidget *widget, gpointer data)
{
  playing = 1;
  select_id = 
    gdk_input_add(fd,GDK_INPUT_WRITE,(GdkInputFunction) play_buffer, NULL);
}

void stop_callback(GtkWidget *widget, gpointer data)
{
  int i = 0;
  /*take care of resetting the LEDS appropriately */
  gtk_pixmap_set((GtkPixmap *)step_led_addr[i++],a_led,NULL); 
  for(;i < NUM_STEPS;i++)
    gtk_pixmap_set((GtkPixmap *)step_led_addr[i],i_led,NULL);

  seq_reset(sequencer);
  playing = 0;
  gdk_input_remove(select_id);
}

void set_bass_type(int type)
{
  /* osc_set_type(bass,type); */
}

void saw_amp_callback(GtkAdjustment *adj, gpointer data)
{
  blender_set_strength(osc_blender,(int)adj->value,0);
}

void sqr_amp_callback(GtkAdjustment *adj, gpointer data)
{
  blender_set_strength(osc_blender,(int)adj->value,1);
}
void sin_amp_callback(GtkAdjustment *adj, gpointer data)
{
  blender_set_strength(osc_blender,(int)adj->value,2);
}

void saw_phase_callback(GtkAdjustment *adj, gpointer data)
{
  osc_set_phase_offset(bass_saw,(int)adj->value);
}

void sqr_phase_callback(GtkAdjustment *adj, gpointer data)
{
  osc_set_phase_offset(bass_sqr,(int)adj->value);
}

void sin_phase_callback(GtkAdjustment *adj, gpointer data)
{
  osc_set_phase_offset(bass_sin,(int)adj->value);
}


void saw_freq_offset_callback(GtkAdjustment *adj, gpointer data)
{

  osc_set_freq_offset(bass_saw,(int)adj->value);
}

void sqr_freq_offset_callback(GtkAdjustment *adj, gpointer data)
{

  osc_set_freq_offset(bass_sqr,(double)adj->value);
}

void sin_freq_offset_callback(GtkAdjustment *adj, gpointer data)
{

  osc_set_freq_offset(bass_sin,(double)adj->value);
}

void sequencer_step_callback(int step)
{
  int current_step,last_step;

  current_step = step;
  last_step = (current_step == 0) ? NUM_STEPS - 1 : step - 1;
  
  gtk_pixmap_set((GtkPixmap *)step_led_addr[step],a_led,NULL);
  gtk_pixmap_set((GtkPixmap *)step_led_addr[last_step],i_led,NULL);

}

/*
  Local Variables:
  mode: font-lock
  End:
*/

