/***************************************************************************
 *   Copyright (C) 2004 by Predrag Viceic                                  *
 *   viceic@net2000.ch                                            *
 *                                                                         *
 *   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; if not, write to the                         *
 *   Free Software Foundation, Inc.,                                       *
 *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
 ***************************************************************************/ 
 
/*
 * Example of creating a SoundFont from multiple audio samples
 * Josh Green - Sep 14, 2004
 * Use this example as you please (public domain)
 */
 
 /*
 	This is the modified version of the example file by Josh Green. It takes waves at the output and 
	generates the sf2 file with each sound as the separate note of the single sf2 instrument and preset.
	This file is not finished yet, but may work. The output patch can be used with MIDI file generated by Freecycle.
	For compiling instructions please refer to libinstpatch of the swami project [http://swami.sourceforge.net/]
	--Predrag Viceic 2 march 2005
 */
#include <stdio.h>
#include <libinstpatch/libinstpatch.h>

int
main (int argc, char *argv[])
{
  IpatchSF2 *sf2;
  IpatchFile *file;
  IpatchSF2File *sffile;
  IpatchSF2Sample *sample;
  IpatchSF2Inst *inst;
  IpatchSF2Preset *preset;
  IpatchConverter *conv;
  GType convtype;
  GError *err = NULL;
  char *fname, *name;
  int i;

  if (argc < 2)
    {
      fprintf (stderr, "Usage: create_sf2 sample1.wav [sample2.wav sample3.aiff ..]\n");
      return (1);
    }

  /* initialize libInstPatch */
  ipatch_init ();

  sf2 = ipatch_sf2_new ();	/* ++ ref new SoundFont object */

 /*create new SoundFont instrument (++ ref) */
  inst = ipatch_sf2_inst_new ();
  g_object_set (inst, "name", "freecycle export instrument", NULL); /* set instrument name */
/* append instrument to SoundFont (ensure that its name is unique) */
    ipatch_container_add_unique (IPATCH_CONTAINER (sf2),IPATCH_ITEM (inst));
/* create new SoundFont preset (++ ref) */
      preset = ipatch_sf2_preset_new ();
      g_object_set (preset, "name", "freecycle export preset", NULL); /* set preset name */
/* append preset to SoundFont (ensure name/bank/preset # are unique) */
      ipatch_container_add_unique (IPATCH_CONTAINER (sf2),IPATCH_ITEM (preset));
/* create new preset zone and link instrument to it */
      ipatch_sf2_preset_new_zone (preset, inst);

  /* loop over file names (command line args) */
  for (i = 1; i < argc; i++)
    {
      fname = argv[i];

      /* identify and open file (++ new object reference) */
      file = ipatch_file_identify_open (fname, "r", &err);
      if (!file)
	{
	  fprintf (stderr, "Failed to identify file '%s': %s\n", fname,
		   ipatch_gerror_message (err));
	  g_clear_error (&err);
	  continue;
	}

      /* lookup converter type for the given conversion (file -> SF2Sample) */
      convtype = ipatch_find_converter (G_OBJECT_TYPE (file),
					IPATCH_TYPE_SF2_SAMPLE,
					IPATCH_CONVERTER_FIND_PARENT, 0);
      if (!convtype)		/* conversion type found? */
	{
	  fprintf (stderr, "Unable to convert file '%s', type %s to %s\n",
		   fname, g_type_name (G_OBJECT_TYPE (file)),
		   g_type_name (IPATCH_TYPE_SF2_SAMPLE));

	  g_object_unref (file); /* remove file reference */

	  continue;
	}

      sample = ipatch_sf2_sample_new (); /* ++ ref new SoundFont sample */
      

      conv = g_object_new (convtype, NULL); /* ++ ref new converter object */

      /* set input and output object of converter */
      ipatch_converter_add_input (conv, G_OBJECT (file));
      ipatch_converter_add_output (conv, G_OBJECT (sample));

      /* convert the sample file to a SoundFont sample */
      if (!ipatch_converter_convert (conv, &err))
	{
	  fprintf (stderr,
		   "Failed to convert sample file to SoundFont sample: %s\n",
		   ipatch_gerror_message (err));

	  g_clear_error (&err);

	  g_object_unref (conv); /* -- unref converter */
	  g_object_unref (sample); /* -- unref SoundFont sample */
	  g_object_unref (file); /* -- unref file */

	  continue;
	}

      g_object_unref (conv);	/* -- unref the converter */

      /* append sample to SoundFont (ensure that its name is unique) */
      ipatch_container_add_unique (IPATCH_CONTAINER (sf2),
				   IPATCH_ITEM (sample));

      g_object_get (sample, "name", &name, NULL); /* get the sample's name */
      g_object_set (sample, "root-note", 35+i, NULL); /* set the sample's root-note */      

      /* create new instrument zone and link sample to it */
      IpatchSF2IZone* zone=ipatch_sf2_izone_new();
      ipatch_sf2_zone_set_item (IPATCH_SF2_ZONE (zone), IPATCH_ITEM (sample));
      ipatch_container_add (IPATCH_CONTAINER (inst), IPATCH_ITEM (zone));
      
      IpatchRange* range=ipatch_range_new();
      range->low=35+i;
      range->high=35+i;
      g_object_set(zone,"key-range", range, NULL);

      ipatch_range_free(range);
      g_object_unref(zone);
      g_object_unref (sample); /* -- unref SoundFont sample */
      g_free (name);  /* free the name (returned from g_object_get) */
      g_object_unref (file);	/* -- unref file */
      
    }
    g_object_unref (inst);	/* -- unref SoundFont instrument */
    g_object_unref (preset);

    


  /* create SoundFont file object, set its name and open for writing */
  sffile = ipatch_sf2_file_new ();

  if (!ipatch_file_open (IPATCH_FILE (sffile), "output.sf2", "w", &err))
    {
      fprintf (stderr, "Failed to open 'output.sf2' for writing: %s\n",
	       ipatch_gerror_message (err));

      g_object_unref (sffile);	/* -- unref SoundFont file */
      g_object_unref (sf2);	/* -- unref SoundFont object */

      return (1);
    }

  /* lookup converter type for SoundFont -> File (save) */
  convtype = ipatch_find_converter (IPATCH_TYPE_SF2, IPATCH_TYPE_FILE,
				    0, IPATCH_CONVERTER_FIND_CHILD);

  conv = g_object_new (convtype, NULL);	/* ++ ref new converter */

  /* set input and output objects of converter */
  ipatch_converter_add_input (conv, G_OBJECT (sf2));
  ipatch_converter_add_output (conv, G_OBJECT (sffile));

  if (!ipatch_converter_convert (conv, &err))
    {
      fprintf (stderr, "Failed to save SoundFont to file: %s\n",
	       ipatch_gerror_message (err));
      g_clear_error (&err);
    }

  g_object_unref (conv);	/* -- unref converter */
  g_object_unref (sffile);	/* -- unref SoundFont file */
  g_object_unref (sf2);		/* -- unref SoundFont object */

  return (0);			/* we done, yeah! :) */
}
