/************************************** * PROGRAMMA PER CODIFICA DA OGG A MP3 * ***************************************/ /********************** * INCLUSIONE LIBRERIE * **********************/ #include #include #include /************************************ * DICHIARAZIONE COSTANTI SIMBOLICHE * ************************************/ #define BSM 2000 /* banda segnale minima */ #define LSU 22050 /* limite superiore udibile */ #define LIU 0 /* limite inferiore udibile */ /********************************** * DICHIARAZIONE VARIABILI GLOBALI * **********************************/ GstElement *pipeline, *source, *parser, *decoder, *conv, *low_filter, *high_filter, *mp3enc, *sink; /************************* * DICHIARAZIONE FUNZIONI * *************************/ int set_conv_params(int *, double *, int *, int *, int *, int *, int *, double *, double *); void wanna_change(char *); void set_filters(int *, int *); void yes_or_no(char *); void get_param_value(int *, double *, int, int); /*********************** * DEFINIZIONE FUNZIONI * ***********************/ void yes_or_no(char *change) { /* dichiarazione variabili locali */ int sentinella; do { sentinella = 0; scanf("%s", change); if (strlen(change) >= 2) { printf("Invalid input lenght: insert only one character\n"); sentinella = -1; } else if (change[0] != 'y' && change[0] != 'n') sentinella = -1; } while (sentinella != 0); printf("%s\n", change); } void set_filters(int *lpf_on, int *hpf_on) { /* dichiarazione variabili locali */ char change[2]; printf("Do you want to activate a Low Pass Filter? (y/n) "); yes_or_no(change); if (change[0] == 'y') *lpf_on = 1; printf("Do you want to activate an High Pass Filter? (y/n) "); yes_or_no(change); if (change[0] == 'y') *hpf_on = 1; } static gboolean bus_call (GstBus *bus, GstMessage *msg, gpointer data) { /* dichiarazione variabili locali */ GMainLoop *loop = data; switch (GST_MESSAGE_TYPE (msg)) { case GST_MESSAGE_EOS: g_print ("End-Of-Stream\n"); g_main_loop_quit (loop); break; case GST_MESSAGE_ERROR: { gchar *debug; GError *err; gst_message_parse_error (msg, &err, &debug); g_print ("Debug: %s\n", debug); g_free (debug); g_print ("Error: %s\n", err->message); g_error_free (err); g_main_loop_quit (loop); break; } default: break; } return TRUE; } static void new_pad (GstElement *element, GstPad *pad, gpointer data) { GstPad *sinkpad; /* We can now link this pad with the audio decoder */ g_print ("Dynamic pad created, linking parser/decoder\n"); sinkpad = gst_element_get_pad (decoder, "sink"); gst_pad_link (pad, sinkpad); gst_object_unref (sinkpad); } static gboolean cb_print_position (GstElement *pipeline) { /* dichiarazione variabili locali */ GstFormat fmt = GST_FORMAT_TIME; gint64 pos, len; if (gst_element_query_position (pipeline, &fmt, &pos) && gst_element_query_duration (pipeline, &fmt, &len)) { g_print ("Time: %" GST_TIME_FORMAT " / %" GST_TIME_FORMAT "\r", GST_TIME_ARGS (pos), GST_TIME_ARGS (len)); } /* call me again */ return TRUE; } int main (int argc, char *argv[]) { /* dichiarazione variabili locali */ GMainLoop *loop; GstBus *bus; int bitrate = 128, quality = 5, mode = 4, br_mode = 0, lpf_on = 0, hpf_on = 0, errori = 0; double comp_ratio = 0, lpf_freq = 440, hpf_freq = 440; /* char mode_str[7], br_mode_str[5]; */ /* initialize GStreamer */ gst_init (&argc, &argv); loop = g_main_loop_new (NULL, FALSE); /* check input arguments */ if (argc != 3) { g_print ("Usage: %s \n", argv[0]); return -1; } /* stampa a video l'header del programma */ printf("\n***************************************\n"); printf("* PROGRAMMA PER CODIFICA DA OGG A MP3 *\n"); printf("***************************************\n"); set_filters(&lpf_on, &hpf_on); set_conv_params(&bitrate, &comp_ratio, &quality, &mode, &br_mode, &lpf_on, &hpf_on, &lpf_freq, &hpf_freq); /* create elements */ pipeline = gst_pipeline_new ("ogg2mp3-converter"); source = gst_element_factory_make ("filesrc", "file-input"); parser = gst_element_factory_make ("oggdemux", "ogg-parser"); decoder = gst_element_factory_make ("vorbisdec", "vorbis-decoder"); conv = gst_element_factory_make ("audioconvert", "converter"); if (lpf_on) low_filter = gst_element_factory_make ("ladspa-lpf", "low-pass-filter"); if (hpf_on) high_filter = gst_element_factory_make ("ladspa-hpf", "high-pass-filter"); mp3enc = gst_element_factory_make ("lame", "mp3encoder"); sink = gst_element_factory_make ("filesink", "file-output"); if (!pipeline || !source || !parser || !decoder || !conv || !mp3enc || !sink) { errori++; return -1; } if (lpf_on && !low_filter) { errori++; return -1; } if (hpf_on && !high_filter) { errori++; return -1; } if (errori != 0) g_print ("One element could not be created\n"); /* set filename property on the file source. Also add a message * handler. */ g_object_set (G_OBJECT (source), "location", argv[1], NULL); g_object_set (G_OBJECT (mp3enc), "bitrate", bitrate, NULL); g_object_set (G_OBJECT (mp3enc), "compression-ratio", comp_ratio, NULL); g_object_set (G_OBJECT (mp3enc), "quality", quality, NULL); if (lpf_on) g_object_set (G_OBJECT (low_filter), "Cutoff-Frequency", lpf_freq, NULL); if (hpf_on) g_object_set (G_OBJECT (high_filter), "Cutoff-Frequency", hpf_freq, NULL); /* switch(mode) { case 0: strcpy(mode_str, "stereo"); break; case 1: strcpy(mode_str, "joint"); break; case 2: strcpy(mode_str, "dual"); break; case 3: strcpy(mode_str, "mono"); break; default: strcpy(mode_str, "auto"); break; */ g_object_set (G_OBJECT (mp3enc), "mode", mode/* mode_str */, NULL); /* } switch(br_mode) { case 1: strcpy(br_mode_str, "old"); break; case 2: strcpy(br_mode_str, "abr"); break; case 3: strcpy(br_mode_str, "new"); break; default: strcpy(br_mode_str, "none"); break; */ g_object_set (G_OBJECT (mp3enc), "vbr", br_mode/* br_mode_str */, NULL); /* } */ g_object_set (G_OBJECT (sink), "location", argv[2], NULL); bus = gst_pipeline_get_bus (GST_PIPELINE (pipeline)); gst_bus_add_watch (bus, bus_call, loop); gst_object_unref (bus); /* put all elements in a bin */ gst_bin_add_many (GST_BIN (pipeline), source, parser, decoder, conv, mp3enc, sink, NULL); if (lpf_on) gst_bin_add(GST_BIN (pipeline), low_filter); if (hpf_on) gst_bin_add(GST_BIN (pipeline), high_filter); /* link together - note that we cannot link the parser and * decoder yet, becuse the parser uses dynamic pads. For that, * we set a pad-added signal handler. */ gst_element_link(source, parser); gst_element_link(decoder, conv); if (lpf_on && hpf_on) gst_element_link_many(conv, low_filter, high_filter, mp3enc, sink, NULL); else if (lpf_on) gst_element_link_many(conv, low_filter, mp3enc, sink, NULL); else if (hpf_on) gst_element_link_many(conv, high_filter, mp3enc, sink, NULL); else gst_element_link_many(conv, mp3enc, sink, NULL); g_signal_connect (parser, "pad-added", G_CALLBACK (new_pad), NULL); /* Now set to playing and iterate. */ g_print ("Setting to PLAYING\n"); gst_element_set_state (pipeline, GST_STATE_PLAYING); g_print ("Running\n"); g_timeout_add (200, (GSourceFunc) cb_print_position, pipeline); g_main_loop_run (loop); /* clean up nicely */ g_print ("Returned, stopping playback\n"); gst_element_set_state (pipeline, GST_STATE_NULL); g_print ("Deleting pipeline\n"); gst_object_unref (GST_OBJECT (pipeline)); return 0; } int set_conv_params(int *bitrate, double *comp_ratio, int *quality, int *mode, int *br_mode, int *lpf_on, int *hpf_on, double *lpf_freq, double *hpf_freq) { /* dichiarazione variabili locali */ char change[2]; int parameter, sent_bms = 0, nullint = -1; double nulldbl = -1; printf("Current conversion parameters are: BitRate = 128kbps, Compression Ratio = None, Quality = Medium, Mode = Auto, BitRate Mode = Constant"); if (*lpf_on) printf(", Low Pass Filter Frequency Cut Off = %ez", *lpf_freq); if (*hpf_on) printf(", High Pass Filter Frequency Cut Off = %ehz", *lpf_freq); printf("\n"); wanna_change(change); do { if ((change[0] == 'y') || (sent_bms != 0)) { printf("What parameter would you like to change?\n" "(1)\tBitRate\n" "(2)\tCompression Ratio\n" "(3)\tQuality\n" "(4)\tMode\n" "(5)\tBitRate Mode\n"); if (*lpf_on) printf ("(%d)\tLow Pass Filter Cut-off Frequency\n", 5 + *lpf_on); if (*hpf_on) printf ("(%d)\tHigh Pass Filter Cut-off Frequency\n", 5 + *lpf_on + *hpf_on); printf("(%d)\tAbort\n", 5 + *lpf_on + *hpf_on + 1); get_param_value(¶meter, &nulldbl, 1, 5 + *lpf_on + *hpf_on + 1); if (parameter < 5 + *lpf_on + *hpf_on + 1) { if ((parameter >= 1) && (parameter <= 5)) { switch (parameter) { case 1: { printf("Range: 8 (Min) - 320 (Max) kbps\tDefault = 128\n"); get_param_value(bitrate, &nulldbl, 8, 320); break; } case 2: { printf("Range: 0 (Min) - 200 (Max)\tDefault = 0\n"); get_param_value(&nullint, comp_ratio, 0, 200); break; } case 3: { printf("Range: 0 (Best) - 9 (Worst)\tDefault = 5\n"); get_param_value(quality, &nulldbl, 0, 9); break; } case 4: { printf("Values: 0 = Stereo, 1 = Joint Stereo, 2 = Dual Channel, 3 = Mono, 4 = Auto (Default)\n"); get_param_value(mode, &nulldbl, 0, 4); break; } case 5: { printf("Values: 0 = CBR (Default), 1 = Old VBR, 2 = Average VBR, 3 = New VBR\n"); get_param_value(br_mode, &nulldbl, 0, 3); break; } default: break; } } else if (parameter == 6 && *lpf_on) { printf("Range: %d - %d hz\tDefault = 440\n", LIU, LSU); get_param_value(&nullint, lpf_freq, LIU, LSU); } else if (parameter == 7 || (parameter == 6 && !*lpf_on)) { printf("Range: %d - %d hz\tDefault = 440\n", LIU, LSU); get_param_value(&nullint, hpf_freq, LIU, LSU); } else {}; } else printf("Operation aborted by user\n"); /* controllo banda minima garantita */ if (*lpf_on + *hpf_on == 2) { if (*lpf_freq > *hpf_freq) { if (*lpf_freq < *hpf_freq + BSM) { printf("Signal Band will be now recalculated\n"); if (LSU - *lpf_freq >= BSM) { *lpf_freq += BSM - *lpf_freq - *hpf_freq; printf("Low Pass Cut Off Frequency set to %ehz\n", *lpf_freq); } else /* se non c'e' abbastanza banda sopra */ { *hpf_freq -= BSM - *lpf_freq - *hpf_freq; printf("High Pass Cut Off Frequency set to %ehz\n", *hpf_freq); } } else printf("Signal band is fine. (>= than %dhz)\n", BSM); } else { printf("Error: all signal spectrum will be lost with current cut off frequencies.\n"); printf("You must set a Low Pass Filter Frequency higher than High Pass Filter one\n"); sent_bms = -1; } } } if (change[0] == 'y') wanna_change(change); } while ((change[0] == 'y') || (sent_bms != 0)); return 0; } void get_param_value(int *valore, double *valore2, int min, int max) { /* dichiarazione variabili locali */ int sentinella; do { sentinella = 0; if (*valore2 == -1) /* intero */ { scanf(" %d", valore); if (!(*valore >= min && *valore <= max)) sentinella = -1; } else { scanf(" %lf", valore2); if (!(*valore2 >= min && *valore2 <= max)) sentinella = -1; } } while (sentinella != 0); } void wanna_change(char *change) { printf("Do you want to change any (other) conversion parameters? (y/n) "); yes_or_no(change); }