// 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 #include #include 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 \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; }