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;
}