All pastes #584317 Raw Edit

Untitled

public text v1 · immutable
·published 2007-06-22 18:23 UTC
rendered paste body

//  Player mp3 con visualizzazione tramite FFT+filtro Goom, oppure generazione di un flusso audio di test con parametri variabili a tempo
//  d'esecuzione con relativa visualizzazione tramite FFT+filtro Goom e salvataggio di un file mp3.
//

#include <gst/gst.h>
#include <gst/controller/gstcontroller.h>
#include <stdio.h>

GstElement *pipeline1, *gen, *conv_g1, *tee_g, 
	   *conv_g2, *queue_g1, *asink_g,
	   *conv_g3, *queue_g2, *spectrum_g, *goom_g, *vsink_g, 
	   *conv_g4, *queue_g3, *mp3_enc, *mp3_parser_g, *mp3_sink; 

GstElement *pipeline2, *mp3_file, *mp3_parser_p, *mp3_dec, *conv_p1, *tee_p, 
           *conv_p2, *queue_p1, *asink_p,
	   *conv_p3, *queue_p2, *spectrum_p, *goom_p, *vsink_p;

static gboolean bus_call (GstBus *bus, GstMessage *msg, gpointer data)
{
      GMainLoop *loop = data;
      switch (GST_MESSAGE_TYPE (msg)) {
            case GST_MESSAGE_EOS:
            {
                  g_print ("\nHo finito di leggere il file!\n\nEsco...\n\n");
                  g_main_loop_quit (loop);
                  exit(0);
                  break;
            }
            case GST_MESSAGE_ERROR:
            {
                  gchar *debug;
                  GError *err;
                  gst_message_parse_error (msg, &err, &debug);
                  g_free (debug);
                  g_print ("Errore: %s\n", err->message);
                  g_error_free (err);
                  g_main_loop_quit (loop);
                  break;
            }
            default:
            {     break;
            }
      }
      return TRUE;
}

int main (int argc, char *argv[])
{
	/* inizializzo i valori con cui generare l'onda */
	int total_time = 20;			//durata del file generato (s)
	float attack = 1.0;			//valore del volume d'attacco (0.0 - 1.0)
	int attack_time = 5;			//istante del massimo volume d'attacco (s)
	float sustain = 1.0;			//valore del volume di sustain (0.0 - 1.0)
	int sustain_time = 17;			//istante del massimo volume di sustain (s)
	float decay = 0.0;			//valore del volume finale (fissato a 0 per evitare clip)
	int decay_time = (total_time-1);	//istante del volume finale (s, fisso in base alla durata totale)
	float init_freq = 220.0;		//frequenza iniziale (Hz)
	float middle_freq = 7000.0;		//frequenza di mezzo (Hz)
	int middle_freq_time = 10;		//istante dove viene raggiunta la frequenza di mezzo (s)
	float final_freq = 500;			//frequenza finale (Hz)
	int final_freq_time = (total_time-1);	//istante dove viene raggiunta la frequenza finale (s, fisso in base alla durata totale)
	
	int res;
	char ch1 = 0;
	char ch2 = 0;
	GstController *ctrl;
	GstClock *clock;
	GstClockID clock_id;
	GstClockReturn wait_ret;
	GValue vol = { 0, };
	GMainLoop *loop;
	GstBus *bus;

	/* initialize Gstreamer */  
	gst_init (&argc, &argv);
	gst_controller_init (&argc, &argv);
  
  
	loop = g_main_loop_new (NULL, FALSE);
  
	/* build pipeline */
	pipeline1 = gst_pipeline_new ("pipeline1");
	clock = gst_pipeline_get_clock (GST_PIPELINE (pipeline1));
	gen = gst_element_factory_make ("audiotestsrc", "gen");
	conv_g1 = gst_element_factory_make ("audioconvert", "conv_g1");
	tee_g = gst_element_factory_make ("tee", "tee_g");
	conv_g2 = gst_element_factory_make ("audioconvert", "conv_g2");
	queue_g1 = gst_element_factory_make ("queue", "queue_g1");
	asink_g = gst_element_factory_make ("alsasink", "asink_g");
	conv_g3 = gst_element_factory_make ("audioconvert", "conv_g3");
	queue_g2 = gst_element_factory_make ("queue", "queue_g2");
	spectrum_g = gst_element_factory_make ("spectrum", "spectrum_g");
	goom_g = gst_element_factory_make ("goom", "goom_g");
	vsink_g = gst_element_factory_make ("ximagesink", "vsink_g");
	conv_g4 = gst_element_factory_make ("audioconvert", "conv_g4");
	queue_g3 = gst_element_factory_make ("queue", "queue_g3");
	mp3_enc = gst_element_factory_make ("lame", "mp3_enc");
	mp3_parser_g = gst_element_factory_make ("mp3parse", "mp3_parser_g");
	mp3_sink = gst_element_factory_make ("filesink", "mp3_sink");
     
	gst_bin_add_many (GST_BIN (pipeline1), gen, conv_g1, tee_g, 
				       conv_g2, queue_g1, asink_g, 
				       conv_g3, queue_g2, spectrum_g, goom_g, vsink_g, 
				       conv_g4, queue_g3, mp3_enc, mp3_parser_g, mp3_sink, NULL);

	if (!gst_element_link_many (gen, conv_g1, tee_g, NULL)) {  
		GST_WARNING ("can't link elements");
	        goto Error;
	}	

	if (!gst_element_link_many (tee_g, conv_g2, queue_g1, asink_g, NULL)) {  
	        GST_WARNING ("can't link elements");
	        goto Error;
	}
     
	if (!gst_element_link_many (tee_g, conv_g3, queue_g2, spectrum_g, goom_g, vsink_g, NULL)) {  
	        GST_WARNING ("can't link elements");
	        goto Error;
	}	 
  
	if (!gst_element_link_many (tee_g, conv_g4, queue_g3, mp3_enc, mp3_parser_g, mp3_sink, NULL)) {  
	        GST_WARNING ("can't link elements");
	        goto Error;
	}
  
	/* add a controller to the source */
	if (!(ctrl = gst_controller_new (G_OBJECT (gen), "freq", "volume", NULL))) { 
	        GST_WARNING ("can't control source element");
	        goto Error;
	}

	/* set interpolation */
	gst_controller_set_interpolation_mode (ctrl, "volume", GST_INTERPOLATE_LINEAR);
	gst_controller_set_interpolation_mode (ctrl, "freq", GST_INTERPOLATE_LINEAR);

  	/* create elements */
	pipeline2 = gst_pipeline_new ("mp3-player");
	mp3_file = gst_element_factory_make ("filesrc", "mp3_file");
	mp3_parser_p = gst_element_factory_make ("mp3parse", "mp3_parser_p");
	mp3_dec = gst_element_factory_make ("mad", "mp3_dec");
	conv_p1 = gst_element_factory_make ("audioconvert", "conv_p1");
	tee_p = gst_element_factory_make ("tee", "tee_p");
	conv_p2 = gst_element_factory_make ("audioconvert", "conv_p2");
	queue_p1 = gst_element_factory_make ("queue", "queue_p1");
	asink_p = gst_element_factory_make ("alsasink", "asink_p");
	conv_p3 = gst_element_factory_make ("audioconvert", "conv_p3");
	queue_p2 = gst_element_factory_make ("queue", "queue_p2");
	spectrum_p = gst_element_factory_make ("spectrum", "spectrum_p");
	goom_p = gst_element_factory_make ("goom", "goom_p");
	vsink_p = gst_element_factory_make ("ximagesink", "vsink_p");
	  
	if (!pipeline2 || !mp3_file || !mp3_parser_p || !mp3_dec || !conv_p1 || !tee_p || 
	    !conv_p2 || !queue_p1 || !asink_p || 
	    !conv_p3 || !queue_p2 || !spectrum_p || !goom_p || !vsink_p) 
	{ 
	  g_print ("One element could not be created\n");
	  return -1;
	}
  
	/* put all elements in a bin */
	gst_bin_add_many (GST_BIN (pipeline2), mp3_file, mp3_parser_p, mp3_dec, conv_p1, tee_p, 
				   conv_p2, queue_p1, asink_p, 
				   conv_p3, queue_p2, spectrum_p, goom_p, vsink_p, NULL);

	/* link together */
	if (!gst_element_link_many (mp3_file, mp3_parser_p, mp3_dec, conv_p1, tee_p, NULL)) {  
		GST_WARNING ("can't link elements");
		goto Error;
	}	
  
	if (!gst_element_link_many (tee_p, conv_p2, queue_p1, asink_p, NULL)) {  
		GST_WARNING ("can't link elements");
		goto Error;
	}
 
	if (!gst_element_link_many (tee_p, conv_p3, queue_p2, spectrum_p, goom_p, vsink_p, NULL)) {  
		GST_WARNING ("can't link elements");
		goto Error;
	}	

	/* check input arguments */
	if (argc != 2) 
	{
		g_print ("\nSintassi: %s <filename.mp3>\n\n", argv[0]);
		g_print ("Non ho trovato il file, vuoi generare, riprodurre e salvare un file mp3 di test? [s/n]\n\n");
		ch1 = getchar();
		if (ch1 == 's') 
		{
			g_print ("\nVuoi Inserire i parametri o usare quelli di Default? [i/d]\n\n");
			g_print ("\ttotal_time = 20;\t\t\tdurata del file generato (s)\n");
			g_print ("\tattack = 1.0;\t\t\t\tvalore del volume d'attacco (0.0 - 1.0)\n");
			g_print ("\tattack_time = 5;\t\t\tistante del massimo volume d'attacco (s)\n");
			g_print ("\tsustain = 1.0;\t\t\t\tvalore del volume di sustain (0.0 - 1.0)\n");
			g_print ("\tsustain_time = 17;\t\t\tistante del massimo volume di sustain (s)\n");
			g_print ("\tinit_freq = 220.0;\t\t\tfrequenza iniziale (Hz)\n");
			g_print ("\tmiddle_freq = 7000.0;\t\t\tfrequenza di mezzo (Hz)\n");
			g_print ("\tmiddle_freq_time = 10;\t\t\tistante dove viene raggiunta la frequenza di mezzo (s)\n");
			g_print ("\tfinal_freq = 500;\t\t\tfrequenza finale (Hz)\n\n");
			scanf (" %s", &ch2);			
			if (ch2 == 'i') 
			{	
				g_print ("\n\ttotal_time = ");
				scanf ("%d", &total_time);
				g_print ("\tattack = ");
				scanf ("%f", &attack);
				g_print ("\tattack_time = ");
				scanf ("%d", &attack_time);
				g_print ("\tsustain = ");
				scanf ("%f", &sustain);
				g_print ("\tsustain_time = ");
				scanf ("%d", &sustain_time);
				g_print ("\tinit_freq = ");
				scanf ("%f", &init_freq);
				g_print ("\tmiddle_freq = ");
				scanf ("%f", &middle_freq);
				g_print ("\tmiddle_freq_time = ");
				scanf ("%d", &middle_freq_time);
				g_print ("\tfinal_freq = ");
				scanf ("%f", &final_freq);
			}
			 
			/* object properties */
			g_object_set (G_OBJECT(gen), "wave", 0, NULL);
			g_object_set (G_OBJECT(mp3_sink), "location", "test.mp3", NULL);
		
			/* set control values */
			g_value_init (&vol, G_TYPE_DOUBLE);
			g_value_set_double (&vol, 0.0);
			gst_controller_set (ctrl, "volume", 0 * GST_SECOND, &vol);
			g_value_set_double (&vol, attack);
			gst_controller_set (ctrl, "volume", attack_time * GST_SECOND, &vol);
			g_value_set_double (&vol, sustain);
			gst_controller_set (ctrl, "volume", sustain_time * GST_SECOND, &vol);
			g_value_set_double (&vol, decay);
			gst_controller_set (ctrl, "volume", decay_time * GST_SECOND, &vol);
			g_value_set_double (&vol, init_freq);
			gst_controller_set (ctrl, "freq", 0 * GST_SECOND, &vol);
			g_value_set_double (&vol, middle_freq);
			gst_controller_set (ctrl, "freq", middle_freq_time * GST_SECOND, &vol);
			g_value_set_double (&vol, final_freq);
			gst_controller_set (ctrl, "freq", final_freq_time * GST_SECOND, &vol);

			clock_id = gst_clock_new_single_shot_id (clock, gst_clock_get_time (clock) + (total_time * GST_SECOND));
		
			/* run for x seconds */
			if (gst_element_set_state (pipeline1, GST_STATE_PLAYING)) 
		 	{
				if ((wait_ret = gst_clock_id_wait (clock_id, NULL)) != GST_CLOCK_OK) 
				{
					GST_WARNING ("clock_id_wait returned: %d", wait_ret);
				}
				gst_element_set_state (pipeline1, GST_STATE_NULL);
			}
	
			/* cleanup */
			g_object_unref (G_OBJECT (ctrl));
			gst_object_unref (G_OBJECT (clock));
			gst_object_unref (G_OBJECT (pipeline1));
			printf("\nHo generato il file 'test.mp3'\n\n");			
			res = 0;
			//return (0);
						
		}    
		else 
		{
			Error:
			printf ("Esco...\n\n");
			return -1;
		} 
	}
	else 
	{
	 	/* set filename property on the file source. Also add a message handler. */
	  	g_object_set (G_OBJECT (mp3_file), "location", argv[1], NULL);
	  	bus = gst_pipeline_get_bus (GST_PIPELINE (pipeline2));
	  	gst_bus_add_watch (bus, bus_call, loop);
	  	gst_object_unref (bus);
	
	  	/* Now set to playing and iterate. */	  
		  	
		g_print ("Setting to PLAYING\n");
	  	gst_element_set_state (pipeline2, GST_STATE_PLAYING);
	  	g_print ("Running\n");
	  	g_main_loop_run (loop);
	
	  	/* clean up nicely */
	  	g_print ("Returned, stopping playback\n");
	  	gst_element_set_state (pipeline2, GST_STATE_NULL);
	  	g_print ("Deleting pipeline\n");
	  	gst_object_unref (GST_OBJECT (pipeline2));  	
	}

	return res;      	
}