All pastes #369163 Raw Edit

Stuff

public text v1 · immutable
#369163 ·published 2007-02-23 16:50 UTC
rendered paste body
/**************************************
* PROGRAMMA PER CODIFICA DA OGG A MP3 *
***************************************/

/**********************
* INCLUSIONE LIBRERIE *
**********************/
#include <gst/gst.h>
#include <stdio.h>
#include <string.h>

/************************************
* 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 <Ogg/Vorbis filename> <MP3/Lame filename>\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(&parameter, &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);
}